@travetto/model-memory 8.0.0-alpha.24 → 8.0.0-alpha.25

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
@@ -14,7 +14,7 @@ yarn add @travetto/model-memory
14
14
  ```
15
15
 
16
16
  This module provides a memory-based implementation for the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations."). Supported features:
17
- * [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/types/crud.ts#L11)
18
- * [Expiry](https://github.com/travetto/travetto/tree/main/module/model/src/types/expiry.ts#L10)
19
17
  * [Blob](https://github.com/travetto/travetto/tree/main/module/model/src/types/blob.ts#L8)
20
- * [Indexed](https://github.com/travetto/travetto/tree/main/module/model-indexed/src/types/service.ts#L16)
18
+ * [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/types/crud.ts#L10)
19
+ * [Expiry](https://github.com/travetto/travetto/tree/main/module/model/src/types/expiry.ts#L10)
20
+ * [Indexed](https://github.com/travetto/travetto/tree/main/module/model-indexed/src/types/service.ts#L21)
package/__index__.ts CHANGED
@@ -1 +1 @@
1
- export * from './src/service.ts';
1
+ export * from './src/service.ts';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/model-memory",
3
- "version": "8.0.0-alpha.24",
3
+ "version": "8.0.0-alpha.25",
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.21",
30
- "@travetto/di": "^8.0.0-alpha.19",
31
- "@travetto/model": "^8.0.0-alpha.22",
32
- "@travetto/model-indexed": "^8.0.0-alpha.24",
33
- "@travetto/schema": "^8.0.0-alpha.21"
29
+ "@travetto/config": "^8.0.0-alpha.22",
30
+ "@travetto/di": "^8.0.0-alpha.20",
31
+ "@travetto/model": "^8.0.0-alpha.23",
32
+ "@travetto/model-indexed": "^8.0.0-alpha.25",
33
+ "@travetto/schema": "^8.0.0-alpha.22"
34
34
  },
35
35
  "peerDependencies": {
36
- "@travetto/cli": "^8.0.0-alpha.27",
37
- "@travetto/test": "^8.0.0-alpha.20"
36
+ "@travetto/cli": "^8.0.0-alpha.28",
37
+ "@travetto/test": "^8.0.0-alpha.21"
38
38
  },
39
39
  "peerDependenciesMeta": {
40
40
  "@travetto/cli": {
package/src/service.ts CHANGED
@@ -1,21 +1,51 @@
1
- import {
2
- type Class, type TimeSpan, castTo, type BinaryMetadata,
3
- type ByteRange, type BinaryType, BinaryUtil, type BinaryArray, JSONUtil, BinaryMetadataUtil,
4
- } from '@travetto/runtime';
5
- import { Injectable, PostConstruct } from '@travetto/di';
6
1
  import { Config } from '@travetto/config';
2
+ import { Injectable, PostConstruct } from '@travetto/di';
7
3
  import {
8
- type ModelType, type ModelCrudSupport, type ModelExpirySupport, type ModelStorageSupport, ModelRegistryIndex,
9
- NotFoundError, ExistsError, type OptionalId, type ModelBlobSupport, ModelCrudUtil, ModelExpiryUtil, ModelStorageUtil,
4
+ ExistsError,
10
5
  IndexNotSupported,
6
+ type ModelBlobSupport,
7
+ type ModelCrudSupport,
8
+ ModelCrudUtil,
9
+ type ModelExpirySupport,
10
+ ModelExpiryUtil,
11
11
  type ModelListOptions,
12
+ ModelRegistryIndex,
13
+ type ModelStorageSupport,
14
+ ModelStorageUtil,
15
+ type ModelType,
16
+ NotFoundError,
17
+ type OptionalId
12
18
  } from '@travetto/model';
13
19
  import {
14
- type ModelIndexedSupport, type KeyedIndexSelection, type KeyedIndexBody, type ModelPageOptions, ModelIndexedUtil,
15
- type SingleItemIndex, type SortedIndexSelection, type ModelPageResult, type SortedIndex,
16
- type AllIndexes, isModelIndexedIndex, type FullKeyedIndexBody, type FullKeyedIndexWithPartialBody, ModelIndexedComputedIndex,
17
- type ModelIndexedSearchOptions, type SortedIndexSelectionType,
20
+ type AllIndexes,
21
+ type FullKeyedIndexBody,
22
+ type FullKeyedIndexWithPartialBody,
23
+ isModelIndexedIndex,
24
+ type KeyedIndexBody,
25
+ type KeyedIndexSelection,
26
+ ModelIndexedComputedIndex,
27
+ type ModelIndexedSearchOptions,
28
+ type ModelIndexedSupport,
29
+ ModelIndexedUtil,
30
+ type ModelPageOptions,
31
+ type ModelPageResult,
32
+ type SingleItemIndex,
33
+ type SortedIndex,
34
+ type SortedIndexSelection,
35
+ type SortedIndexSelectionType
18
36
  } from '@travetto/model-indexed';
37
+ import {
38
+ type BinaryArray,
39
+ type BinaryMetadata,
40
+ BinaryMetadataUtil,
41
+ type BinaryType,
42
+ BinaryUtil,
43
+ type ByteRange,
44
+ type Class,
45
+ castTo,
46
+ JSONUtil,
47
+ type TimeSpan
48
+ } from '@travetto/runtime';
19
49
 
20
50
  const ModelBlobNamespace = '__blobs';
21
51
  const ModelBlobMetaNamespace = `${ModelBlobNamespace}_meta`;
@@ -23,8 +53,7 @@ const ModelBlobMetaNamespace = `${ModelBlobNamespace}_meta`;
23
53
  type StoreType = Map<string, BinaryArray>;
24
54
 
25
55
  const sortValue = (a: string | number, b: string | number): number =>
26
- (typeof a === 'number' && typeof b === 'number') ?
27
- a - b : (typeof a === 'string' && typeof b === 'string') ? a.localeCompare(b) : 0;
56
+ typeof a === 'number' && typeof b === 'number' ? a - b : typeof a === 'string' && typeof b === 'string' ? a.localeCompare(b) : 0;
28
57
 
29
58
  @Config('model.memory')
30
59
  export class MemoryModelConfig {
@@ -51,23 +80,25 @@ function getFirstId(data: Map<string, unknown> | Set<string>, value?: string | n
51
80
  * Standard in-memory support
52
81
  */
53
82
  @Injectable()
54
- export class MemoryModelService implements
55
- ModelCrudSupport, ModelBlobSupport,
56
- ModelExpirySupport, ModelStorageSupport,
57
- ModelIndexedSupport {
58
-
83
+ export class MemoryModelService
84
+ implements ModelCrudSupport, ModelBlobSupport, ModelExpirySupport, ModelStorageSupport, ModelIndexedSupport
85
+ {
59
86
  #store = new Map<string, StoreType>();
60
87
  #indices = {
61
88
  'indexed:sorted': new Map<string, Map<string, Map<string, number | string>>>(),
62
- 'indexed:keyed': new Map<string, Map<string, Set<string>>>(),
89
+ 'indexed:keyed': new Map<string, Map<string, Set<string>>>()
63
90
  } as const;
64
91
 
65
92
  idSource = ModelCrudUtil.uuidSource();
66
93
  config: MemoryModelConfig;
67
94
 
68
- constructor(config: MemoryModelConfig) { this.config = config; }
95
+ constructor(config: MemoryModelConfig) {
96
+ this.config = config;
97
+ }
69
98
 
70
- get client(): Map<string, StoreType> { return this.#store; }
99
+ get client(): Map<string, StoreType> {
100
+ return this.#store;
101
+ }
71
102
 
72
103
  #getStore<T extends ModelType>(cls: Class<T> | string): StoreType {
73
104
  const key = typeof cls === 'string' ? cls : ModelRegistryIndex.getStoreName(cls);
@@ -95,7 +126,9 @@ export class MemoryModelService implements
95
126
  const computed = ModelIndexedComputedIndex.get(idx, item).validate({ sort: true });
96
127
  switch (idx.type) {
97
128
  case 'indexed:sorted':
98
- case 'indexed:keyed': this.#indices[idx.type].get(idxName)?.get(computed.getKey())?.delete(id); break;
129
+ case 'indexed:keyed':
130
+ this.#indices[idx.type].get(idxName)?.get(computed.getKey())?.delete(id);
131
+ break;
99
132
  }
100
133
  }
101
134
  } catch (error) {
@@ -146,11 +179,11 @@ export class MemoryModelService implements
146
179
  }
147
180
  }
148
181
 
149
- async #getIdByIndex<
150
- T extends ModelType,
151
- K extends KeyedIndexSelection<T>,
152
- S extends SortedIndexSelection<T>
153
- >(cls: Class<T>, idx: SingleItemIndex<T, K, S>, body: FullKeyedIndexBody<T, K, S>): Promise<string> {
182
+ async #getIdByIndex<T extends ModelType, K extends KeyedIndexSelection<T>, S extends SortedIndexSelection<T>>(
183
+ cls: Class<T>,
184
+ idx: SingleItemIndex<T, K, S>,
185
+ body: FullKeyedIndexBody<T, K, S>
186
+ ): Promise<string> {
154
187
  const computed = ModelIndexedComputedIndex.get(idx, body).validate({ sort: true });
155
188
 
156
189
  const index = this.#indices[idx.type].get(indexName(cls, idx))?.get(computed.getKey());
@@ -176,11 +209,8 @@ export class MemoryModelService implements
176
209
  throw new NotFoundError(cls, computed.getKey({ sort: true }));
177
210
  }
178
211
 
179
- async * #iterateIds(
180
- ids: string[],
181
- options?: ModelListOptions & ModelPageOptions<number>,
182
- ): AsyncIterable<string[]> {
183
- let offset = options && 'offset' in options ? options.offset ?? 0 : 0;
212
+ async *#iterateIds(ids: string[], options?: ModelListOptions & ModelPageOptions<number>): AsyncIterable<string[]> {
213
+ let offset = options && 'offset' in options ? (options.offset ?? 0) : 0;
184
214
  const batchSize = options?.batchSizeHint ?? 100;
185
215
  let produced = 0;
186
216
  const maxCount = options?.limit ?? Number.MAX_SAFE_INTEGER;
@@ -198,9 +228,7 @@ export class MemoryModelService implements
198
228
  }
199
229
  }
200
230
 
201
- async * #getIndexIds<
202
- T extends ModelType,
203
- >(
231
+ async *#getIndexIds<T extends ModelType>(
204
232
  cls: Class<T>,
205
233
  idx: AllIndexes<T>,
206
234
  body: KeyedIndexBody<T>,
@@ -219,9 +247,9 @@ export class MemoryModelService implements
219
247
  ids = [];
220
248
  } else if (index instanceof Map) {
221
249
  ids = [...index.entries()]
222
- .filter(([, sort]) => filterIndex ? filterIndex(sort) : true)
250
+ .filter(([, sort]) => (filterIndex ? filterIndex(sort) : true))
223
251
  .sort((a, b) => sortValue(a[1], b[1]))
224
- .map(([id,]) => id);
252
+ .map(([id]) => id);
225
253
  } else {
226
254
  ids = [...index];
227
255
  }
@@ -299,7 +327,7 @@ export class MemoryModelService implements
299
327
  await this.#persist(cls, where, 'remove');
300
328
  }
301
329
 
302
- async * list<T extends ModelType>(cls: Class<T>, options?: ModelListOptions): AsyncIterable<T[]> {
330
+ async *list<T extends ModelType>(cls: Class<T>, options?: ModelListOptions): AsyncIterable<T[]> {
303
331
  for await (const batch of this.#iterateIds([...this.#getStore(cls).keys()], options)) {
304
332
  yield ModelCrudUtil.filterOutNotFound(batch.map(id => this.get(cls, id)));
305
333
  }
@@ -307,7 +335,13 @@ export class MemoryModelService implements
307
335
 
308
336
  // Blob Support
309
337
  async upsertBlob(location: string, input: BinaryType, metadata?: BinaryMetadata, overwrite = true): Promise<void> {
310
- if (!overwrite && await this.getBlobMetadata(location).then(() => true, () => false)) {
338
+ if (
339
+ !overwrite &&
340
+ (await this.getBlobMetadata(location).then(
341
+ () => true,
342
+ () => false
343
+ ))
344
+ ) {
311
345
  return;
312
346
  }
313
347
  const resolved = await BinaryMetadataUtil.compute(input, metadata);
@@ -318,7 +352,6 @@ export class MemoryModelService implements
318
352
  }
319
353
 
320
354
  async getBlob(location: string, range?: ByteRange): Promise<Blob> {
321
-
322
355
  const blobs = this.#find(ModelBlobNamespace, location, 'notfound');
323
356
 
324
357
  let data = blobs.get(location)!;
@@ -364,14 +397,13 @@ export class MemoryModelService implements
364
397
  store.delete(key);
365
398
  deleted += 1;
366
399
  }
367
- } catch { } // Do not let a single error stop the process
400
+ } catch {} // Do not let a single error stop the process
368
401
  }
369
402
  return deleted;
370
403
  }
371
404
 
372
405
  // Storage Support
373
- async createStorage(): Promise<void> {
374
- }
406
+ async createStorage(): Promise<void> {}
375
407
 
376
408
  async deleteStorage(): Promise<void> {
377
409
  this.#store.clear();
@@ -398,53 +430,48 @@ export class MemoryModelService implements
398
430
  }
399
431
 
400
432
  // Indexed
401
- async getByIndex<
402
- T extends ModelType,
403
- K extends KeyedIndexSelection<T>,
404
- S extends SortedIndexSelection<T>
405
- >(cls: Class<T>, idx: SingleItemIndex<T, K, S>, body: FullKeyedIndexBody<T, K, S>): Promise<T> {
433
+ async getByIndex<T extends ModelType, K extends KeyedIndexSelection<T>, S extends SortedIndexSelection<T>>(
434
+ cls: Class<T>,
435
+ idx: SingleItemIndex<T, K, S>,
436
+ body: FullKeyedIndexBody<T, K, S>
437
+ ): Promise<T> {
406
438
  return this.get(cls, await this.#getIdByIndex(cls, idx, body));
407
-
408
439
  }
409
440
 
410
- async deleteByIndex<
411
- T extends ModelType,
412
- K extends KeyedIndexSelection<T>,
413
- S extends SortedIndexSelection<T>
414
- >(cls: Class<T>, idx: SingleItemIndex<T, K, S>, body: FullKeyedIndexBody<T, K, S>): Promise<void> {
441
+ async deleteByIndex<T extends ModelType, K extends KeyedIndexSelection<T>, S extends SortedIndexSelection<T>>(
442
+ cls: Class<T>,
443
+ idx: SingleItemIndex<T, K, S>,
444
+ body: FullKeyedIndexBody<T, K, S>
445
+ ): Promise<void> {
415
446
  await this.delete(cls, await this.#getIdByIndex(cls, idx, body));
416
447
  }
417
448
 
418
- upsertByIndex<
419
- T extends ModelType,
420
- K extends KeyedIndexSelection<T>,
421
- S extends SortedIndexSelection<T>
422
- >(cls: Class<T>, idx: SingleItemIndex<T, K, S>, body: OptionalId<T>): Promise<T> {
449
+ upsertByIndex<T extends ModelType, K extends KeyedIndexSelection<T>, S extends SortedIndexSelection<T>>(
450
+ cls: Class<T>,
451
+ idx: SingleItemIndex<T, K, S>,
452
+ body: OptionalId<T>
453
+ ): Promise<T> {
423
454
  return ModelIndexedUtil.naiveUpsert(this, cls, idx, body);
424
455
  }
425
456
 
426
- updateByIndex<
427
- T extends ModelType,
428
- K extends KeyedIndexSelection<T>,
429
- S extends SortedIndexSelection<T>
430
- >(cls: Class<T>, idx: SingleItemIndex<T, K, S>, body: T): Promise<T> {
457
+ updateByIndex<T extends ModelType, K extends KeyedIndexSelection<T>, S extends SortedIndexSelection<T>>(
458
+ cls: Class<T>,
459
+ idx: SingleItemIndex<T, K, S>,
460
+ body: T
461
+ ): Promise<T> {
431
462
  return ModelIndexedUtil.naiveUpdate(this, cls, idx, body);
432
463
  }
433
464
 
434
- async updatePartialByIndex<
435
- T extends ModelType,
436
- K extends KeyedIndexSelection<T>,
437
- S extends SortedIndexSelection<T>
438
- >(cls: Class<T>, idx: SingleItemIndex<T, K, S>, body: FullKeyedIndexWithPartialBody<T, K, S>): Promise<T> {
465
+ async updatePartialByIndex<T extends ModelType, K extends KeyedIndexSelection<T>, S extends SortedIndexSelection<T>>(
466
+ cls: Class<T>,
467
+ idx: SingleItemIndex<T, K, S>,
468
+ body: FullKeyedIndexWithPartialBody<T, K, S>
469
+ ): Promise<T> {
439
470
  const item = await ModelCrudUtil.naivePartialUpdate(cls, () => this.getByIndex(cls, idx, castTo(body)), castTo(body));
440
471
  return this.update(cls, item);
441
472
  }
442
473
 
443
- async pageByIndex<
444
- T extends ModelType,
445
- K extends KeyedIndexSelection<T>,
446
- S extends SortedIndexSelection<T>
447
- >(
474
+ async pageByIndex<T extends ModelType, K extends KeyedIndexSelection<T>, S extends SortedIndexSelection<T>>(
448
475
  cls: Class<T>,
449
476
  idx: SortedIndex<T, K, S>,
450
477
  body: KeyedIndexBody<T, K>,
@@ -456,16 +483,12 @@ export class MemoryModelService implements
456
483
  const items: T[] = [];
457
484
  for await (const batch of this.#getIndexIds(cls, idx, body, { limit: 100, ...options, offset })) {
458
485
  produced += batch.length;
459
- items.push(...await ModelCrudUtil.filterOutNotFound(batch.map(id => this.get(cls, id))));
486
+ items.push(...(await ModelCrudUtil.filterOutNotFound(batch.map(id => this.get(cls, id)))));
460
487
  }
461
488
  return { items, nextOffset: items.length ? JSONUtil.toBase64(offset + produced) : undefined };
462
489
  }
463
490
 
464
- async * listByIndex<
465
- T extends ModelType,
466
- K extends KeyedIndexSelection<T>,
467
- S extends SortedIndexSelection<T>
468
- >(
491
+ async *listByIndex<T extends ModelType, K extends KeyedIndexSelection<T>, S extends SortedIndexSelection<T>>(
469
492
  cls: Class<T>,
470
493
  idx: SortedIndex<T, K, S>,
471
494
  body: KeyedIndexBody<T, K>,
@@ -483,12 +506,9 @@ export class MemoryModelService implements
483
506
  B extends SortedIndexSelectionType<T, S> & string
484
507
  >(cls: Class<T>, idx: SortedIndex<T, K, S>, body: KeyedIndexBody<T, K>, prefix: B, options?: ModelIndexedSearchOptions): Promise<T[]> {
485
508
  const items: T[] = [];
486
- for await (const batch of this.#getIndexIds(
487
- cls, idx, body, options,
488
- id => (typeof id === 'string' && id.startsWith(prefix))
489
- )) {
490
- items.push(...await ModelCrudUtil.filterOutNotFound(batch.map(id => this.get(cls, id))));
509
+ for await (const batch of this.#getIndexIds(cls, idx, body, options, id => typeof id === 'string' && id.startsWith(prefix))) {
510
+ items.push(...(await ModelCrudUtil.filterOutNotFound(batch.map(id => this.get(cls, id)))));
491
511
  }
492
512
  return items;
493
513
  }
494
- }
514
+ }