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

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