Skip to content

Commit 23836f4

Browse files
committed
feat(DataLoader): Added (findByIds, count, connection, findMany, findOne)
1 parent c330d51 commit 23836f4

5 files changed

+317
-75
lines changed

lib/composeWithDataLoader.js

Lines changed: 131 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,27 +7,142 @@ exports.composeWithDataLoader = composeWithDataLoader;
77

88
var _graphqlCompose = require('graphql-compose');
99

10+
var _dataloader = require('dataloader');
11+
12+
var _dataloader2 = _interopRequireDefault(_dataloader);
13+
14+
var _objectHash = require('object-hash');
15+
16+
var _objectHash2 = _interopRequireDefault(_objectHash);
17+
18+
var _singleContinous = require('./singleContinous');
19+
20+
var _singleContinous2 = _interopRequireDefault(_singleContinous);
21+
22+
var _definitions = require('./definitions');
23+
24+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25+
1026
function composeWithDataLoader(typeComposer) {
27+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
28+
1129

12-
if (!(typeComposer instanceof _graphqlCompose.TypeComposer)) {
13-
throw new Error('You should provide TypeComposer instance to composeWithDataLoader method');
14-
}
30+
// if (!(typeComposer instanceof TypeComposer)) {
31+
// throw new Error('You should provide TypeComposer instance to composeWithDataLoader method');
32+
// }
33+
//
34+
//
35+
/**
36+
* Set defaults
37+
*/
38+
options = {
39+
cacheExpiration: options.cacheExpiration || 300,
40+
removeProjection: options.removeProjection || true,
41+
debug: options.debug || false
42+
};
1543

1644
/**
17-
* get resolvers to add DataLoader to
45+
* Add DataLoader to FindById
1846
*/
19-
var count = typeComposer.get('$count');
20-
var findById = typeComposer.get('$findById');
21-
var findByIds = typeComposer.get('$findByIds');
22-
var findMany = typeComposer.get('$findMany');
23-
var findOne = typeComposer.get('$findOne');
24-
console.log(typeComposer.getTypeName());
25-
26-
if (!findById) throw new Error('TypeComposer(' + typeComposer.getTypeName() + ') provided to composeWithRelay ' + 'should have findById resolver.');
27-
if (!findById) throw new Error('TypeComposer(' + typeComposer.getTypeName() + ') provided to composeWithRelay ' + 'should have findById resolver.');
28-
if (!findByIds) throw new Error('TypeComposer(' + typeComposer.getTypeName() + ') provided to composeWithRelay ' + 'should have findByIds resolver.');
29-
if (!findMany) throw new Error('TypeComposer(' + typeComposer.getTypeName() + ') provided to composeWithRelay ' + 'should have findMany resolver.');
30-
if (!findOne) throw new Error('TypeComposer(' + typeComposer.getTypeName() + ') provided to composeWithRelay ' + 'should have findOne resolver.');
47+
var findByIdResolver = typeComposer.getResolver('findById');
48+
var findByIdLoader = new _dataloader2.default(function (resolveParamsArray) {
49+
if (options.debug) console.log('New db request (findById)');
50+
var params = resolveParamsArray[0];
51+
52+
return findByIdResolver.resolve(params).then(function (res) {
53+
return [res];
54+
});
55+
}, { cacheKeyFn: function cacheKeyFn(key) {
56+
return key.args._id.toString();
57+
} });
58+
59+
typeComposer.setResolver('findById', findByIdResolver.wrapResolve(function (fn) {
60+
return function (rp) {
61+
if (options.removeProjection) delete rp.projection;
62+
_singleContinous2.default.run(findByIdLoader, rp, options);
63+
return findByIdLoader.load(rp);
64+
};
65+
}));
66+
67+
/**
68+
* Add DataLoader to FindByIds
69+
*/
70+
// let findByIdsResolver = typeComposer.getResolver('findByIds')
71+
// let findByIdsLoader = new DataLoader( (resolveParamsArray) => {
72+
// if (options.debug) console.log('New db request (findByIds)')
73+
// return findByIdResolver.resolve(resolveParamsArray[0]).then(res => [res])
74+
// },
75+
// { cacheKeyFn: key => {
76+
// let hashKey = hash(key.args)
77+
// return hashKey
78+
// } })
79+
80+
// typeComposer.setResolver(
81+
// 'findByIds',
82+
// findByIdsResolver.wrapResolve(fn => rp => {
83+
// SingleContinous.run(findByIdsLoader, rp, opt)
84+
// return findByIdsLoader.load(rp)
85+
// })
86+
// )
87+
88+
89+
/**
90+
* Add DataLoader to FindMany
91+
*/
92+
// let findManyResolver = typeComposer.getResolver('findMany')
93+
// let findManyLoader = new DataLoader( (resolveParamsArray) => {
94+
// if (options.debug) console.log('New db request (findMany)')
95+
// console.log(resolveParamsArray[0])
96+
// //response
97+
// return findManyResolver.resolve(resolveParamsArray[0]).then(res => [res])
98+
// },
99+
// { cacheKeyFn: key => {
100+
// let hashKey = hash(key.args)
101+
// return hashKey
102+
// } })
103+
104+
// typeComposer.setResolver(
105+
// 'findMany',
106+
// findManyResolver.wrapResolve(fn => rp => {
107+
// if (options.removeProjection) delete rp.projection
108+
// SingleContinous.run(findManyLoader, rp, options)
109+
// return findManyLoader.load(rp)
110+
// })
111+
// )
112+
113+
114+
/**
115+
* Add DataLoader to Connection
116+
*/
117+
var connectionResolver = typeComposer.getResolver('connection');
118+
var connectionFieldNames = typeComposer.getFieldNames();
119+
var connectionLoader = new _dataloader2.default(function (resolveParamsArray) {
120+
if (options.debug) console.log('New db request (connection)');
121+
var params = resolveParamsArray[0];
122+
//response
123+
return connectionResolver.resolve(params).then(function (res) {
124+
return [res];
125+
});
126+
}, { cacheKeyFn: function cacheKeyFn(key) {
127+
var hashKey = (0, _objectHash2.default)(key.args);
128+
return hashKey;
129+
} });
130+
131+
typeComposer.setResolver('connection', connectionResolver.wrapResolve(function (fn) {
132+
return function (rp) {
133+
if (options.removeProjection) {
134+
(function () {
135+
var projection = { edges: { node: {} } };
136+
connectionFieldNames.map(function (field) {
137+
return projection.edges.node[field] = true;
138+
});
139+
rp.projection = projection;
140+
})();
141+
}
142+
_singleContinous2.default.run(connectionLoader, rp, options);
143+
return connectionLoader.load(rp);
144+
};
145+
}));
31146

32147
return typeComposer;
33148
}

lib/definitions.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"use strict";

lib/singleContinous.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
'use strict';
2+
3+
var _stringify = require('babel-runtime/core-js/json/stringify');
4+
5+
var _stringify2 = _interopRequireDefault(_stringify);
6+
7+
var _map = require('babel-runtime/core-js/map');
8+
9+
var _map2 = _interopRequireDefault(_map);
10+
11+
var _defineProperty = require('babel-runtime/core-js/object/define-property');
12+
13+
var _defineProperty2 = _interopRequireDefault(_defineProperty);
14+
15+
Object.defineProperty(exports, "__esModule", {
16+
value: true
17+
});
18+
19+
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; (0, _defineProperty2.default)(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
20+
21+
var _objectHash = require('object-hash');
22+
23+
var _objectHash2 = _interopRequireDefault(_objectHash);
24+
25+
var _stringHash = require('string-hash');
26+
27+
var _stringHash2 = _interopRequireDefault(_stringHash);
28+
29+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
30+
31+
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
32+
33+
/**
34+
* This class makes shure functions with params only run once
35+
*/
36+
exports.default = new (function () {
37+
function SingleContinous(props) {
38+
_classCallCheck(this, SingleContinous);
39+
40+
this.store = new _map2.default();
41+
this.counter = 1;
42+
}
43+
44+
_createClass(SingleContinous, [{
45+
key: 'run',
46+
value: function run(loader, rp, opt) {
47+
var _this = this;
48+
49+
var hashKey = (0, _stringHash2.default)((0, _stringify2.default)(loader) + (0, _stringify2.default)(rp));
50+
51+
if (!this.store.has(hashKey)) {
52+
this.store.set(hashKey, 'running');
53+
setTimeout(function () {
54+
var res = loader.clear(rp);
55+
_this.store.delete(hashKey);
56+
}, opt.cacheExpiration);
57+
}
58+
}
59+
}, {
60+
key: 'clearAll',
61+
value: function clearAll() {
62+
this.store.clear();
63+
return true;
64+
}
65+
}]);
66+
67+
return SingleContinous;
68+
}())();

0 commit comments

Comments
 (0)