@karmaniverous/entity-manager 4.4.3 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -373,7 +373,7 @@ Query an entity across shards.
|
|
|
373
373
|
| options.shardQuery | <code>ShardQueryFunction</code> | Sharded query function. |
|
|
374
374
|
| [options.limit] | <code>number</code> | Request limit. |
|
|
375
375
|
| [options.pageKeys] | <code>object</code> | Map of shard page keys. |
|
|
376
|
-
| [options.
|
|
376
|
+
| [options.pageSize] | <code>number</code> | Request page size. |
|
|
377
377
|
|
|
378
378
|
<a name="module_entity-manager.EntityManager+rehydrateIndex"></a>
|
|
379
379
|
|
|
@@ -435,8 +435,8 @@ Shard query function
|
|
|
435
435
|
| Param | Type | Description |
|
|
436
436
|
| --- | --- | --- |
|
|
437
437
|
| shardedKey | <code>string</code> | Sharded key. |
|
|
438
|
-
| [limit] | <code>number</code> | Request limit. |
|
|
439
438
|
| [pageKey] | <code>\*</code> | Page key. |
|
|
439
|
+
| [limit] | <code>number</code> | Request limit. |
|
|
440
440
|
|
|
441
441
|
<a name="module_entity-manager..ShardedQueryResult"></a>
|
|
442
442
|
|
|
@@ -6,11 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.EntityManager = void 0;
|
|
7
7
|
var _zipObject2 = _interopRequireDefault(require("lodash/zipObject"));
|
|
8
8
|
var _map2 = _interopRequireDefault(require("lodash/map"));
|
|
9
|
-
var _size2 = _interopRequireDefault(require("lodash/size"));
|
|
10
9
|
var _isEmpty2 = _interopRequireDefault(require("lodash/isEmpty"));
|
|
11
10
|
var _fromPairs2 = _interopRequireDefault(require("lodash/fromPairs"));
|
|
12
|
-
var _parseInt2 = _interopRequireDefault(require("lodash/parseInt"));
|
|
13
|
-
var _isString2 = _interopRequireDefault(require("lodash/isString"));
|
|
14
11
|
var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject"));
|
|
15
12
|
var _isInteger2 = _interopRequireDefault(require("lodash/isInteger"));
|
|
16
13
|
var _isUndefined2 = _interopRequireDefault(require("lodash/isUndefined"));
|
|
@@ -213,8 +210,8 @@ class EntityManager {
|
|
|
213
210
|
*
|
|
214
211
|
* @callback ShardQueryFunction
|
|
215
212
|
* @param {string} shardedKey - Sharded key.
|
|
216
|
-
* @param {number} [limit] - Request limit.
|
|
217
213
|
* @param {*} [pageKey] - Page key.
|
|
214
|
+
* @param {number} [limit] - Request limit.
|
|
218
215
|
* @returns {Promise<ShardQueryResult>} Sharded query result.
|
|
219
216
|
*/
|
|
220
217
|
|
|
@@ -234,7 +231,7 @@ class EntityManager {
|
|
|
234
231
|
* @param {ShardQueryFunction} options.shardQuery - Sharded query function.
|
|
235
232
|
* @param {number} [options.limit] - Request limit.
|
|
236
233
|
* @param {object} [options.pageKeys] - Map of shard page keys.
|
|
237
|
-
* @param {number
|
|
234
|
+
* @param {number} [options.pageSize] - Request page size.
|
|
238
235
|
* @returns {Promise<ShardedQueryResult>} Sharded query result.
|
|
239
236
|
*/
|
|
240
237
|
async query() {
|
|
@@ -245,21 +242,21 @@ class EntityManager {
|
|
|
245
242
|
shardQuery,
|
|
246
243
|
limit,
|
|
247
244
|
pageKeys,
|
|
248
|
-
|
|
245
|
+
pageSize
|
|
249
246
|
} = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
250
247
|
// Validate params.
|
|
251
248
|
this.#entityManager.validateKeyToken(entityToken, keyToken);
|
|
252
249
|
this.#entityManager.validateItem(item);
|
|
253
250
|
if (!(0, _isFunction2.default)(shardQuery)) throw new Error('shardQuery must be a function');
|
|
254
|
-
if (!(0, _isUndefined2.default)(limit) && !((0, _isInteger2.default)(limit) && limit >= 1)) throw new Error('limit must be a positive integer');
|
|
251
|
+
if (!(0, _isUndefined2.default)(limit) && !(limit === Infinity || (0, _isInteger2.default)(limit) && limit >= 1)) throw new Error('limit must be a positive integer or Infinity.');
|
|
255
252
|
if (!(0, _isUndefined2.default)(pageKeys) && !(0, _isPlainObject2.default)(pageKeys)) throw new Error('pageKeys must be an object');
|
|
256
|
-
if (!(0, _isUndefined2.default)(
|
|
253
|
+
if (!(0, _isUndefined2.default)(pageSize) && !((0, _isInteger2.default)(pageSize) && pageSize >= 1)) throw new Error('pageSize must be a positive integer');
|
|
257
254
|
|
|
258
255
|
// Apply default limit.
|
|
259
256
|
limit ??= this.#entityManager.getEntityConfig(entityToken).defaultLimit;
|
|
260
257
|
|
|
261
|
-
//
|
|
262
|
-
|
|
258
|
+
// Apply default pageSize.
|
|
259
|
+
pageSize ??= this.#entityManager.getEntityConfig(entityToken).defaultPageSize;
|
|
263
260
|
|
|
264
261
|
// Generate default pageKeys if not provided
|
|
265
262
|
pageKeys ??= (0, _fromPairs2.default)(this.getKeySpace(entityToken, keyToken, item).map(shardedKey => [shardedKey, undefined]));
|
|
@@ -270,7 +267,7 @@ class EntityManager {
|
|
|
270
267
|
shardQuery,
|
|
271
268
|
limit,
|
|
272
269
|
pageKeys,
|
|
273
|
-
|
|
270
|
+
pageSize
|
|
274
271
|
});
|
|
275
272
|
|
|
276
273
|
// Return empty result if no pageKeys.
|
|
@@ -280,9 +277,6 @@ class EntityManager {
|
|
|
280
277
|
pageKeys: {}
|
|
281
278
|
};
|
|
282
279
|
|
|
283
|
-
// Calculate shard limit.
|
|
284
|
-
const shardLimit = (0, _isUndefined2.default)(limit) ? undefined : Math.ceil(limit / (0, _size2.default)(pageKeys));
|
|
285
|
-
|
|
286
280
|
// Iterate search over pages.
|
|
287
281
|
let page = 0;
|
|
288
282
|
const result = {
|
|
@@ -291,8 +285,12 @@ class EntityManager {
|
|
|
291
285
|
pageKeys
|
|
292
286
|
};
|
|
293
287
|
do {
|
|
288
|
+
// TODO: This loop will blow up as shards scale, since at a minimum it will return shardCount x pageSize
|
|
289
|
+
// items, which may be >> limit. Probably the way to fix this is to limit the number of shards queried per
|
|
290
|
+
// iteration in order to keep shardsQueried * pageSize > (limit - items.length) but only just.
|
|
291
|
+
|
|
294
292
|
// Query every shard in pageKeys.
|
|
295
|
-
const shardQueryResults = await Promise.all((0, _map2.default)(result.pageKeys, (pageKey, shardedKey) => new Promise(resolve => shardQuery(shardedKey, pageKey,
|
|
293
|
+
const shardQueryResults = await Promise.all((0, _map2.default)(result.pageKeys, (pageKey, shardedKey) => new Promise(resolve => shardQuery(shardedKey, pageKey, pageSize).then(_ref6 => {
|
|
296
294
|
let {
|
|
297
295
|
count,
|
|
298
296
|
items,
|
|
@@ -334,7 +332,7 @@ class EntityManager {
|
|
|
334
332
|
result.items = [...result.items, ...pageResult.items];
|
|
335
333
|
result.pageKeys = pageResult.pageKeys;
|
|
336
334
|
page++;
|
|
337
|
-
} while (
|
|
335
|
+
} while (result.items.length < limit && !(0, _isEmpty2.default)(result.pageKeys));
|
|
338
336
|
return result;
|
|
339
337
|
}
|
|
340
338
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.PrivateEntityManager = exports.DEFAULT_LIMIT = void 0;
|
|
6
|
+
exports.PrivateEntityManager = exports.DEFAULT_PAGE_SIZE = exports.DEFAULT_LIMIT = void 0;
|
|
7
7
|
var _isInteger2 = _interopRequireDefault(require("lodash/isInteger"));
|
|
8
8
|
var _isPlainObject2 = _interopRequireDefault(require("lodash/isPlainObject"));
|
|
9
9
|
var _range2 = _interopRequireDefault(require("lodash/range"));
|
|
@@ -26,7 +26,8 @@ var _mapValues2 = _interopRequireDefault(require("lodash/mapValues"));
|
|
|
26
26
|
var _jsonschema = require("jsonschema");
|
|
27
27
|
var _stringHash = _interopRequireDefault(require("string-hash"));
|
|
28
28
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
29
|
-
const DEFAULT_LIMIT = exports.DEFAULT_LIMIT =
|
|
29
|
+
const DEFAULT_LIMIT = exports.DEFAULT_LIMIT = 10;
|
|
30
|
+
const DEFAULT_PAGE_SIZE = exports.DEFAULT_PAGE_SIZE = 10;
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* EntityManager config validation schema.
|
|
@@ -45,6 +46,9 @@ const configSchema = {
|
|
|
45
46
|
defaultLimit: {
|
|
46
47
|
type: 'integer'
|
|
47
48
|
},
|
|
49
|
+
defaultPageSize: {
|
|
50
|
+
type: 'integer'
|
|
51
|
+
},
|
|
48
52
|
indexes: {
|
|
49
53
|
type: 'object',
|
|
50
54
|
additionalProperties: {
|
|
@@ -175,6 +179,7 @@ class PrivateEntityManager {
|
|
|
175
179
|
entities: (0, _mapValues2.default)(entities, _ref => {
|
|
176
180
|
let {
|
|
177
181
|
defaultLimit = DEFAULT_LIMIT,
|
|
182
|
+
defaultPageSize = DEFAULT_PAGE_SIZE,
|
|
178
183
|
indexes = {},
|
|
179
184
|
keys = {},
|
|
180
185
|
sharding: {
|
|
@@ -187,6 +192,7 @@ class PrivateEntityManager {
|
|
|
187
192
|
} = _ref;
|
|
188
193
|
return {
|
|
189
194
|
defaultLimit,
|
|
195
|
+
defaultPageSize,
|
|
190
196
|
indexes,
|
|
191
197
|
keys,
|
|
192
198
|
sharding: {
|
|
@@ -196,8 +196,8 @@ export class EntityManager {
|
|
|
196
196
|
*
|
|
197
197
|
* @callback ShardQueryFunction
|
|
198
198
|
* @param {string} shardedKey - Sharded key.
|
|
199
|
-
* @param {number} [limit] - Request limit.
|
|
200
199
|
* @param {*} [pageKey] - Page key.
|
|
200
|
+
* @param {number} [limit] - Request limit.
|
|
201
201
|
* @returns {Promise<ShardQueryResult>} Sharded query result.
|
|
202
202
|
*/
|
|
203
203
|
|
|
@@ -217,7 +217,7 @@ export class EntityManager {
|
|
|
217
217
|
* @param {ShardQueryFunction} options.shardQuery - Sharded query function.
|
|
218
218
|
* @param {number} [options.limit] - Request limit.
|
|
219
219
|
* @param {object} [options.pageKeys] - Map of shard page keys.
|
|
220
|
-
* @param {number
|
|
220
|
+
* @param {number} [options.pageSize] - Request page size.
|
|
221
221
|
* @returns {Promise<ShardedQueryResult>} Sharded query result.
|
|
222
222
|
*/
|
|
223
223
|
async query({
|
|
@@ -227,26 +227,33 @@ export class EntityManager {
|
|
|
227
227
|
shardQuery,
|
|
228
228
|
limit,
|
|
229
229
|
pageKeys,
|
|
230
|
-
|
|
230
|
+
pageSize,
|
|
231
231
|
} = {}) {
|
|
232
232
|
// Validate params.
|
|
233
233
|
this.#entityManager.validateKeyToken(entityToken, keyToken);
|
|
234
234
|
this.#entityManager.validateItem(item);
|
|
235
|
+
|
|
235
236
|
if (!_.isFunction(shardQuery))
|
|
236
237
|
throw new Error('shardQuery must be a function');
|
|
237
|
-
|
|
238
|
-
|
|
238
|
+
|
|
239
|
+
if (
|
|
240
|
+
!_.isUndefined(limit) &&
|
|
241
|
+
!(limit === Infinity || (_.isInteger(limit) && limit >= 1))
|
|
242
|
+
)
|
|
243
|
+
throw new Error('limit must be a positive integer or Infinity.');
|
|
244
|
+
|
|
239
245
|
if (!_.isUndefined(pageKeys) && !_.isPlainObject(pageKeys))
|
|
240
246
|
throw new Error('pageKeys must be an object');
|
|
241
|
-
|
|
242
|
-
|
|
247
|
+
|
|
248
|
+
if (!_.isUndefined(pageSize) && !(_.isInteger(pageSize) && pageSize >= 1))
|
|
249
|
+
throw new Error('pageSize must be a positive integer');
|
|
243
250
|
|
|
244
251
|
// Apply default limit.
|
|
245
252
|
limit ??= this.#entityManager.getEntityConfig(entityToken).defaultLimit;
|
|
246
253
|
|
|
247
|
-
//
|
|
248
|
-
|
|
249
|
-
|
|
254
|
+
// Apply default pageSize.
|
|
255
|
+
pageSize ??=
|
|
256
|
+
this.#entityManager.getEntityConfig(entityToken).defaultPageSize;
|
|
250
257
|
|
|
251
258
|
// Generate default pageKeys if not provided
|
|
252
259
|
pageKeys ??= _.fromPairs(
|
|
@@ -263,29 +270,28 @@ export class EntityManager {
|
|
|
263
270
|
shardQuery,
|
|
264
271
|
limit,
|
|
265
272
|
pageKeys,
|
|
266
|
-
|
|
273
|
+
pageSize,
|
|
267
274
|
});
|
|
268
275
|
|
|
269
276
|
// Return empty result if no pageKeys.
|
|
270
277
|
if (_.isEmpty(pageKeys)) return { count: 0, items: [], pageKeys: {} };
|
|
271
278
|
|
|
272
|
-
// Calculate shard limit.
|
|
273
|
-
const shardLimit = _.isUndefined(limit)
|
|
274
|
-
? undefined
|
|
275
|
-
: Math.ceil(limit / _.size(pageKeys));
|
|
276
|
-
|
|
277
279
|
// Iterate search over pages.
|
|
278
280
|
let page = 0;
|
|
279
281
|
const result = { count: 0, items: [], pageKeys };
|
|
280
282
|
|
|
281
283
|
do {
|
|
284
|
+
// TODO: This loop will blow up as shards scale, since at a minimum it will return shardCount x pageSize
|
|
285
|
+
// items, which may be >> limit. Probably the way to fix this is to limit the number of shards queried per
|
|
286
|
+
// iteration in order to keep shardsQueried * pageSize > (limit - items.length) but only just.
|
|
287
|
+
|
|
282
288
|
// Query every shard in pageKeys.
|
|
283
289
|
const shardQueryResults = await Promise.all(
|
|
284
290
|
_.map(
|
|
285
291
|
result.pageKeys,
|
|
286
292
|
(pageKey, shardedKey) =>
|
|
287
293
|
new Promise((resolve) =>
|
|
288
|
-
shardQuery(shardedKey, pageKey,
|
|
294
|
+
shardQuery(shardedKey, pageKey, pageSize).then(
|
|
289
295
|
({ count, items, pageKey }) =>
|
|
290
296
|
resolve({ count, items, pageKey, shardedKey })
|
|
291
297
|
)
|
|
@@ -315,11 +321,7 @@ export class EntityManager {
|
|
|
315
321
|
result.items = [...result.items, ...pageResult.items];
|
|
316
322
|
result.pageKeys = pageResult.pageKeys;
|
|
317
323
|
page++;
|
|
318
|
-
} while (
|
|
319
|
-
page < pages &&
|
|
320
|
-
result.items.length < limit * pages &&
|
|
321
|
-
!_.isEmpty(result.pageKeys)
|
|
322
|
-
);
|
|
324
|
+
} while (result.items.length < limit && !_.isEmpty(result.pageKeys));
|
|
323
325
|
|
|
324
326
|
return result;
|
|
325
327
|
}
|
|
@@ -2,7 +2,8 @@ import { validate } from 'jsonschema';
|
|
|
2
2
|
import _ from 'lodash';
|
|
3
3
|
import stringHash from 'string-hash';
|
|
4
4
|
|
|
5
|
-
export const DEFAULT_LIMIT =
|
|
5
|
+
export const DEFAULT_LIMIT = 10;
|
|
6
|
+
export const DEFAULT_PAGE_SIZE = 10;
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* EntityManager config validation schema.
|
|
@@ -21,6 +22,9 @@ const configSchema = {
|
|
|
21
22
|
defaultLimit: {
|
|
22
23
|
type: 'integer',
|
|
23
24
|
},
|
|
25
|
+
defaultPageSize: {
|
|
26
|
+
type: 'integer',
|
|
27
|
+
},
|
|
24
28
|
indexes: {
|
|
25
29
|
type: 'object',
|
|
26
30
|
additionalProperties: {
|
|
@@ -141,6 +145,7 @@ export class PrivateEntityManager {
|
|
|
141
145
|
entities,
|
|
142
146
|
({
|
|
143
147
|
defaultLimit = DEFAULT_LIMIT,
|
|
148
|
+
defaultPageSize = DEFAULT_PAGE_SIZE,
|
|
144
149
|
indexes = {},
|
|
145
150
|
keys = {},
|
|
146
151
|
sharding: {
|
|
@@ -152,6 +157,7 @@ export class PrivateEntityManager {
|
|
|
152
157
|
} = {},
|
|
153
158
|
}) => ({
|
|
154
159
|
defaultLimit,
|
|
160
|
+
defaultPageSize,
|
|
155
161
|
indexes,
|
|
156
162
|
keys,
|
|
157
163
|
sharding: {
|