@travetto/model-memory 8.0.0-alpha.11 → 8.0.0-alpha.12
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/package.json +8 -8
- package/src/service.ts +52 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-memory",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Memory backing for the travetto model module.",
|
|
6
6
|
"keywords": [
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
"directory": "module/model-memory"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@travetto/config": "^8.0.0-alpha.
|
|
30
|
-
"@travetto/di": "^8.0.0-alpha.
|
|
31
|
-
"@travetto/model": "^8.0.0-alpha.
|
|
32
|
-
"@travetto/model-indexed": "^8.0.0-alpha.
|
|
33
|
-
"@travetto/schema": "^8.0.0-alpha.
|
|
29
|
+
"@travetto/config": "^8.0.0-alpha.11",
|
|
30
|
+
"@travetto/di": "^8.0.0-alpha.11",
|
|
31
|
+
"@travetto/model": "^8.0.0-alpha.11",
|
|
32
|
+
"@travetto/model-indexed": "^8.0.0-alpha.12",
|
|
33
|
+
"@travetto/schema": "^8.0.0-alpha.11"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@travetto/cli": "^8.0.0-alpha.
|
|
37
|
-
"@travetto/test": "^8.0.0-alpha.
|
|
36
|
+
"@travetto/cli": "^8.0.0-alpha.16",
|
|
37
|
+
"@travetto/test": "^8.0.0-alpha.11"
|
|
38
38
|
},
|
|
39
39
|
"peerDependenciesMeta": {
|
|
40
40
|
"@travetto/cli": {
|
package/src/service.ts
CHANGED
|
@@ -8,10 +8,11 @@ import {
|
|
|
8
8
|
type ModelType, type ModelCrudSupport, type ModelExpirySupport, type ModelStorageSupport, ModelRegistryIndex,
|
|
9
9
|
NotFoundError, ExistsError, type OptionalId, type ModelBlobSupport, ModelCrudUtil, ModelExpiryUtil, ModelStorageUtil,
|
|
10
10
|
IndexNotSupported,
|
|
11
|
+
type ModelListOptions,
|
|
11
12
|
} from '@travetto/model';
|
|
12
13
|
import {
|
|
13
|
-
type ModelIndexedSupport, type KeyedIndexSelection, type KeyedIndexBody, type
|
|
14
|
-
type SingleItemIndex, type SortedIndexSelection, type
|
|
14
|
+
type ModelIndexedSupport, type KeyedIndexSelection, type KeyedIndexBody, type ModelPageOptions, ModelIndexedUtil,
|
|
15
|
+
type SingleItemIndex, type SortedIndexSelection, type ModelPageResult, type SortedIndex,
|
|
15
16
|
type AllIndexes, isModelIndexedIndex, type FullKeyedIndexBody, type FullKeyedIndexWithPartialBody, ModelIndexedComputedIndex,
|
|
16
17
|
} from '@travetto/model-indexed';
|
|
17
18
|
|
|
@@ -170,11 +171,39 @@ export class MemoryModelService implements
|
|
|
170
171
|
throw new NotFoundError(cls, computed.getKey({ sort: true }));
|
|
171
172
|
}
|
|
172
173
|
|
|
173
|
-
#
|
|
174
|
+
async * #iterateIds<T extends ModelType>(
|
|
175
|
+
ids: string[],
|
|
176
|
+
options?: ModelListOptions & ModelPageOptions<number>
|
|
177
|
+
|
|
178
|
+
): AsyncIterable<string[]> {
|
|
179
|
+
let offset = options && 'offset' in options ? options.offset ?? 0 : 0;
|
|
180
|
+
const batchSize = options?.batchSizeHint ?? 100;
|
|
181
|
+
let produced = 0;
|
|
182
|
+
const maxCount = options?.limit ?? Number.MAX_SAFE_INTEGER;
|
|
183
|
+
while (offset < ids.length && produced < maxCount) {
|
|
184
|
+
if (options?.abort?.aborted) {
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
const end = Math.min(offset + batchSize, ids.length, maxCount - produced + offset);
|
|
188
|
+
const batch = ids.slice(offset, end);
|
|
189
|
+
if (batch.length) {
|
|
190
|
+
yield batch;
|
|
191
|
+
}
|
|
192
|
+
offset += batchSize;
|
|
193
|
+
produced += batch.length;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async * #getIndexIds<
|
|
174
198
|
T extends ModelType,
|
|
175
199
|
K extends KeyedIndexSelection<T>,
|
|
176
200
|
S extends SortedIndexSelection<T>
|
|
177
|
-
>(
|
|
201
|
+
>(
|
|
202
|
+
cls: Class<T>,
|
|
203
|
+
idx: AllIndexes<T, K, S>,
|
|
204
|
+
body: KeyedIndexBody<T, K>,
|
|
205
|
+
options?: ModelListOptions & ModelPageOptions<number>
|
|
206
|
+
): AsyncIterable<string[]> {
|
|
178
207
|
const computed = ModelIndexedComputedIndex.get(idx, body).validate();
|
|
179
208
|
if (!isModelIndexedIndex(idx)) {
|
|
180
209
|
throw new IndexNotSupported(cls, idx, 'Only ModelIndexed indices can be used with MemoryModelService');
|
|
@@ -182,13 +211,15 @@ export class MemoryModelService implements
|
|
|
182
211
|
|
|
183
212
|
const base = this.#indices[idx.type].get(indexName(cls, idx));
|
|
184
213
|
const index = base?.get(computed.getKey());
|
|
214
|
+
let ids: string[];
|
|
185
215
|
if (!index) {
|
|
186
|
-
|
|
216
|
+
ids = [];
|
|
187
217
|
} else if (index instanceof Map) {
|
|
188
|
-
|
|
218
|
+
ids = [...index.entries()].toSorted((a, b) => a[1] - b[1]).map(([id,]) => id);
|
|
189
219
|
} else {
|
|
190
|
-
|
|
220
|
+
ids = [...index];
|
|
191
221
|
}
|
|
222
|
+
yield* this.#iterateIds(ids, options);
|
|
192
223
|
}
|
|
193
224
|
|
|
194
225
|
@PostConstruct()
|
|
@@ -261,15 +292,9 @@ export class MemoryModelService implements
|
|
|
261
292
|
await this.#persist(cls, where, 'remove');
|
|
262
293
|
}
|
|
263
294
|
|
|
264
|
-
async * list<T extends ModelType>(cls: Class<T
|
|
265
|
-
for (const
|
|
266
|
-
|
|
267
|
-
yield await this.get(cls, id);
|
|
268
|
-
} catch (error) {
|
|
269
|
-
if (!(error instanceof NotFoundError)) {
|
|
270
|
-
throw error;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
295
|
+
async * list<T extends ModelType>(cls: Class<T>, options?: ModelListOptions): AsyncIterable<T[]> {
|
|
296
|
+
for await (const batch of this.#iterateIds([...this.#getStore(cls).keys()], options)) {
|
|
297
|
+
yield ModelCrudUtil.filterOutNotFound(batch.map(id => this.get(cls, id)));
|
|
273
298
|
}
|
|
274
299
|
}
|
|
275
300
|
|
|
@@ -416,17 +441,17 @@ export class MemoryModelService implements
|
|
|
416
441
|
cls: Class<T>,
|
|
417
442
|
idx: SortedIndex<T, K, S>,
|
|
418
443
|
body: KeyedIndexBody<T, K>,
|
|
419
|
-
options?:
|
|
420
|
-
): Promise<
|
|
421
|
-
const ids = this.#getIndexIds(cls, idx, body);
|
|
444
|
+
options?: ModelPageOptions
|
|
445
|
+
): Promise<ModelPageResult<T>> {
|
|
422
446
|
const offset = options?.offset ? JSONUtil.fromBase64<number>(options.offset) : 0;
|
|
423
|
-
|
|
447
|
+
let produced = 0;
|
|
424
448
|
|
|
425
449
|
const items: T[] = [];
|
|
426
|
-
for (const
|
|
427
|
-
|
|
450
|
+
for await (const batch of this.#getIndexIds(cls, idx, body, { limit: 100, ...options, offset })) {
|
|
451
|
+
produced += batch.length;
|
|
452
|
+
items.push(...await ModelCrudUtil.filterOutNotFound(batch.map(id => this.get(cls, id))));
|
|
428
453
|
}
|
|
429
|
-
return { items, nextOffset: items.length ? JSONUtil.toBase64(offset +
|
|
454
|
+
return { items, nextOffset: items.length ? JSONUtil.toBase64(offset + produced) : undefined };
|
|
430
455
|
}
|
|
431
456
|
|
|
432
457
|
async * listByIndex<
|
|
@@ -437,10 +462,10 @@ export class MemoryModelService implements
|
|
|
437
462
|
cls: Class<T>,
|
|
438
463
|
idx: SortedIndex<T, K, S>,
|
|
439
464
|
body: KeyedIndexBody<T, K>,
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
for (const
|
|
443
|
-
yield
|
|
465
|
+
options?: ModelListOptions
|
|
466
|
+
): AsyncIterable<T[]> {
|
|
467
|
+
for await (const batch of this.#getIndexIds(cls, idx, body, options)) {
|
|
468
|
+
yield ModelCrudUtil.filterOutNotFound(batch.map(id => this.get(cls, id)));
|
|
444
469
|
}
|
|
445
470
|
}
|
|
446
471
|
}
|