@travetto/model-indexed 8.0.0-alpha.11 → 8.0.0-alpha.13
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 +13 -6
- package/package.json +6 -6
- package/src/types/list.ts +9 -4
- package/src/types/service.ts +11 -4
- package/support/test/indexed.ts +26 -1
package/README.md
CHANGED
|
@@ -205,6 +205,9 @@ export interface ModelIndexedSupport extends ModelBasicSupport {
|
|
|
205
205
|
|
|
206
206
|
/**
|
|
207
207
|
* Page through entities by ranged index as defined by fields of idx
|
|
208
|
+
*
|
|
209
|
+
* Note: Limit is generally honored, but can vary depending on the underlying storage implementation.
|
|
210
|
+
*
|
|
208
211
|
* @param cls The type to search by
|
|
209
212
|
* @param idx The index to search against
|
|
210
213
|
* @param body The payload of fields needed to search
|
|
@@ -214,10 +217,14 @@ export interface ModelIndexedSupport extends ModelBasicSupport {
|
|
|
214
217
|
T extends ModelType,
|
|
215
218
|
S extends SortedIndexSelection<T>,
|
|
216
219
|
K extends KeyedIndexSelection<T>
|
|
217
|
-
>(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>, options?:
|
|
220
|
+
>(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>, options?: ModelPageOptions): Promise<ModelPageResult<T>>;
|
|
218
221
|
|
|
219
222
|
/**
|
|
220
223
|
* List all entities by ranged index as defined by fields of idx
|
|
224
|
+
*
|
|
225
|
+
* Note: Limit is generally honored, but can vary depending on the underlying storage implementation.
|
|
226
|
+
* Batch size hint can be used to optimize batch size, but is not guaranteed.
|
|
227
|
+
*
|
|
221
228
|
* @param cls The type to search by
|
|
222
229
|
* @param idx The index to search against
|
|
223
230
|
* @param body The payload of fields needed to search
|
|
@@ -226,7 +233,7 @@ export interface ModelIndexedSupport extends ModelBasicSupport {
|
|
|
226
233
|
T extends ModelType,
|
|
227
234
|
S extends SortedIndexSelection<T>,
|
|
228
235
|
K extends KeyedIndexSelection<T>
|
|
229
|
-
>(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>,): AsyncIterable<T>;
|
|
236
|
+
>(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>, options?: ModelListOptions): AsyncIterable<T[]>;
|
|
230
237
|
}
|
|
231
238
|
```
|
|
232
239
|
|
|
@@ -237,7 +244,7 @@ The service provides these operations:
|
|
|
237
244
|
* `updateByIndex` — Update an existing item by index
|
|
238
245
|
* `updatePartialByIndex` — Partially update an item by index
|
|
239
246
|
* `pageByIndex` — Fetch a page of items with pagination metadata
|
|
240
|
-
* `listByIndex` — Stream
|
|
247
|
+
* `listByIndex` — Stream matching items from a sorted index in batches, optionally capped by `limit`
|
|
241
248
|
|
|
242
249
|
### Getting Items
|
|
243
250
|
Use `getByIndex` to fetch a single item by providing all required key fields.
|
|
@@ -345,15 +352,15 @@ export async function listExample(modelService: ModelIndexedSupport) {
|
|
|
345
352
|
}
|
|
346
353
|
```
|
|
347
354
|
|
|
348
|
-
Use `listByIndex` when you want to iterate through
|
|
355
|
+
Use `listByIndex` when you want to iterate through matching items as an async stream of batches. The same list options used by `list` are supported here, including `limit` when you want to stop after a fixed number of records.
|
|
349
356
|
|
|
350
357
|
**Code: Streaming by Sorted Index**
|
|
351
358
|
```typescript
|
|
352
359
|
export async function listStreamExample(modelService: ModelIndexedSupport) {
|
|
353
360
|
const items: User[] = [];
|
|
354
361
|
|
|
355
|
-
for await (const
|
|
356
|
-
items.push(
|
|
362
|
+
for await (const batch of modelService.listByIndex(User, recentUsers, {}, { limit: 25 })) {
|
|
363
|
+
items.push(...batch);
|
|
357
364
|
}
|
|
358
365
|
|
|
359
366
|
return items;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-indexed",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Basic indexing support for model sources that support it.",
|
|
6
6
|
"keywords": [
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"directory": "module/model-indexed"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@travetto/model": "^8.0.0-alpha.
|
|
30
|
-
"@travetto/registry": "^8.0.0-alpha.
|
|
31
|
-
"@travetto/schema": "^8.0.0-alpha.
|
|
29
|
+
"@travetto/model": "^8.0.0-alpha.12",
|
|
30
|
+
"@travetto/registry": "^8.0.0-alpha.11",
|
|
31
|
+
"@travetto/schema": "^8.0.0-alpha.12"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@travetto/cli": "^8.0.0-alpha.
|
|
35
|
-
"@travetto/test": "^8.0.0-alpha.
|
|
34
|
+
"@travetto/cli": "^8.0.0-alpha.17",
|
|
35
|
+
"@travetto/test": "^8.0.0-alpha.11"
|
|
36
36
|
},
|
|
37
37
|
"peerDependenciesMeta": {
|
|
38
38
|
"@travetto/cli": {
|
package/src/types/list.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { ModelType } from '@travetto/model';
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export interface ModelPageOptions<O = string> {
|
|
4
|
+
batchSizeHint?: number;
|
|
4
5
|
limit?: number;
|
|
5
6
|
offset?: O;
|
|
6
|
-
}
|
|
7
|
+
}
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Result of a page request.
|
|
11
|
+
* @virtual true
|
|
12
|
+
*/
|
|
13
|
+
export interface ModelPageResult<T extends ModelType> {
|
|
9
14
|
items: T[];
|
|
10
15
|
nextOffset?: string;
|
|
11
|
-
}
|
|
16
|
+
}
|
package/src/types/service.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import type { ModelType, ModelBasicSupport, OptionalId } from '@travetto/model';
|
|
1
|
+
import type { ModelType, ModelBasicSupport, OptionalId, ModelListOptions } from '@travetto/model';
|
|
2
2
|
import type { Class } from '@travetto/runtime';
|
|
3
3
|
|
|
4
4
|
import type {
|
|
5
5
|
KeyedIndexSelection, KeyedIndexBody, SortedIndexSelection, SortedIndex,
|
|
6
6
|
SingleItemIndex, FullKeyedIndexBody, FullKeyedIndexWithPartialBody
|
|
7
7
|
} from './indexes.ts';
|
|
8
|
-
import type {
|
|
8
|
+
import type { ModelPageOptions, ModelPageResult } from './list.ts';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Support for simple indexed activity
|
|
@@ -75,6 +75,9 @@ export interface ModelIndexedSupport extends ModelBasicSupport {
|
|
|
75
75
|
|
|
76
76
|
/**
|
|
77
77
|
* Page through entities by ranged index as defined by fields of idx
|
|
78
|
+
*
|
|
79
|
+
* Note: Limit is generally honored, but can vary depending on the underlying storage implementation.
|
|
80
|
+
*
|
|
78
81
|
* @param cls The type to search by
|
|
79
82
|
* @param idx The index to search against
|
|
80
83
|
* @param body The payload of fields needed to search
|
|
@@ -84,10 +87,14 @@ export interface ModelIndexedSupport extends ModelBasicSupport {
|
|
|
84
87
|
T extends ModelType,
|
|
85
88
|
S extends SortedIndexSelection<T>,
|
|
86
89
|
K extends KeyedIndexSelection<T>
|
|
87
|
-
>(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>, options?:
|
|
90
|
+
>(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>, options?: ModelPageOptions): Promise<ModelPageResult<T>>;
|
|
88
91
|
|
|
89
92
|
/**
|
|
90
93
|
* List all entities by ranged index as defined by fields of idx
|
|
94
|
+
*
|
|
95
|
+
* Note: Limit is generally honored, but can vary depending on the underlying storage implementation.
|
|
96
|
+
* Batch size hint can be used to optimize batch size, but is not guaranteed.
|
|
97
|
+
*
|
|
91
98
|
* @param cls The type to search by
|
|
92
99
|
* @param idx The index to search against
|
|
93
100
|
* @param body The payload of fields needed to search
|
|
@@ -96,5 +103,5 @@ export interface ModelIndexedSupport extends ModelBasicSupport {
|
|
|
96
103
|
T extends ModelType,
|
|
97
104
|
S extends SortedIndexSelection<T>,
|
|
98
105
|
K extends KeyedIndexSelection<T>
|
|
99
|
-
>(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>,): AsyncIterable<T>;
|
|
106
|
+
>(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>, options?: ModelListOptions): AsyncIterable<T[]>;
|
|
100
107
|
}
|
package/support/test/indexed.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
|
+
import timers from 'node:timers/promises';
|
|
2
3
|
|
|
3
4
|
import { Suite, Test } from '@travetto/test';
|
|
4
5
|
import { Schema } from '@travetto/schema';
|
|
@@ -8,7 +9,7 @@ import { BaseModelSuite } from '@travetto/model/support/test/base.ts';
|
|
|
8
9
|
|
|
9
10
|
import type { ModelIndexedSupport } from '../../src/types/service.ts';
|
|
10
11
|
import { keyedIndex, sortedIndex } from '../../src/indexes.ts';
|
|
11
|
-
import { IndexedFieldError } from '../../
|
|
12
|
+
import { IndexedFieldError } from '../../src/types/error.ts';
|
|
12
13
|
|
|
13
14
|
@Model('index_user')
|
|
14
15
|
class User {
|
|
@@ -371,4 +372,28 @@ export abstract class ModelIndexedSuite extends BaseModelSuite<ModelIndexedSuppo
|
|
|
371
372
|
assert(items.length === allColors.length);
|
|
372
373
|
assert.deepEqual(items, allColors.toReversed());
|
|
373
374
|
}
|
|
375
|
+
|
|
376
|
+
@Test()
|
|
377
|
+
async listByIndexAbortSignal() {
|
|
378
|
+
const service = await this.service;
|
|
379
|
+
|
|
380
|
+
await Promise.all(
|
|
381
|
+
[20, 30, 40].map(age => service.create(User3, User3.from({ name: 'page', age, color: `${age}` })))
|
|
382
|
+
);
|
|
383
|
+
|
|
384
|
+
const controller = new AbortController();
|
|
385
|
+
const found: User3[] = [];
|
|
386
|
+
|
|
387
|
+
for await (const items of service.listByIndex(User3, userAgeIndex, { name: 'page' }, { abort: controller.signal, batchSizeHint: 1 })) {
|
|
388
|
+
found.push(...items);
|
|
389
|
+
controller.abort();
|
|
390
|
+
await timers.setTimeout(10);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (this.indexLimitSkew) {
|
|
394
|
+
assert(found.length < this.indexLimitSkew && found.length > 0);
|
|
395
|
+
} else {
|
|
396
|
+
assert(found.length === 1);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
374
399
|
}
|