@atscript/db-memory 0.1.146 → 0.1.148
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/dist/index.cjs +372 -81
- package/dist/index.d.cts +55 -5
- package/dist/index.d.mts +55 -5
- package/dist/index.mjs +373 -82
- package/package.json +9 -9
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AggregateFn, BaseDbAdapter, BucketUnit, DbQuery, DbSpace, FilterExpr, TDbDeleteResult, TDbFieldMeta, TDbInsertManyResult, TDbInsertResult, TDbObjectKind, TDbUpdateResult, TFieldOps } from "@atscript/db";
|
|
1
|
+
import { AggregateFn, BaseDbAdapter, BucketUnit, DbQuery, DbSpace, FilterExpr, ResolvedRelationFilter, TDbDeleteResult, TDbFieldMeta, TDbInsertIgnoreSlot, TDbInsertManyResult, TDbInsertResult, TDbObjectKind, TDbUpdateResult, TFieldOps, TViewCapability } from "@atscript/db";
|
|
2
2
|
import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
|
|
3
3
|
|
|
4
4
|
//#region src/lib/memory-adapter.d.ts
|
|
@@ -76,6 +76,17 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
76
76
|
* decomposes patches into dot-path `$set`s and loads relations app-level.
|
|
77
77
|
*/
|
|
78
78
|
canFilterField(fd: TDbFieldMeta): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Relational predicates (`{ nav: { $some | $none: … } }`) are evaluated in
|
|
81
|
+
* reads AND mutation filters. Before a filter holding them is compiled, every
|
|
82
|
+
* related table (and junction) is loaded ONCE for that operation — through
|
|
83
|
+
* its own adapter's snapshot seam, so a provider-backed related table works
|
|
84
|
+
* too — and each predicate becomes a set of matching correlation keys
|
|
85
|
+
* (see {@link _relationSets}). Predicate-free filters take the plain path.
|
|
86
|
+
*
|
|
87
|
+
* @since 0.1.147
|
|
88
|
+
*/
|
|
89
|
+
supportsRelationFilters(_mode: "read" | "write"): boolean;
|
|
79
90
|
/**
|
|
80
91
|
* Coerces a by-id value to the id field's declared leaf type. The framework
|
|
81
92
|
* calls `adapter.prepareId(value, fieldType)` when building by-id filters, so a
|
|
@@ -107,7 +118,7 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
107
118
|
/**
|
|
108
119
|
* Physical names of the primary-key field(s). Single `@meta.id` resolves via
|
|
109
120
|
* {@link AtscriptDbReadable.metaIdPhysical}; a composite key maps each logical
|
|
110
|
-
* PK path through `
|
|
121
|
+
* PK path through `physicalPath` (`@db.column` renames included). Memoized
|
|
111
122
|
* because it is stable per adapter (1:1 with a fixed table) yet read on every
|
|
112
123
|
* `pkKey`/projection — recomputing would re-read `this._table.*` and re-allocate.
|
|
113
124
|
*/
|
|
@@ -221,6 +232,22 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
221
232
|
* AND single-snapshot-per-`findManyWithCount` both fall out for free.
|
|
222
233
|
*/
|
|
223
234
|
protected _loadRows(): Record<string, unknown>[] | Promise<Record<string, unknown>[]>;
|
|
235
|
+
/**
|
|
236
|
+
* A per-operation row loader for relational predicates: each related table
|
|
237
|
+
* is snapshotted at most once per operation (the first predicate that needs
|
|
238
|
+
* it loads it; later ones — and nested ones — reuse that snapshot), so a
|
|
239
|
+
* provider-backed related table is invoked once per read. `own` seeds this
|
|
240
|
+
* table's snapshot so a self relation reads the same rows as the outer scan.
|
|
241
|
+
*/
|
|
242
|
+
private _snapshotLoader;
|
|
243
|
+
/**
|
|
244
|
+
* The prepared correlation sets for `filter`'s relational predicates.
|
|
245
|
+
* Callers only await it when `containsRelationFilter(filter)` — a
|
|
246
|
+
* predicate-free filter keeps its fully synchronous path. Write methods call
|
|
247
|
+
* it BEFORE reading the table state, so the related tables (a self relation
|
|
248
|
+
* included) are snapshotted before any row changes, like SQL.
|
|
249
|
+
*/
|
|
250
|
+
private _relationSets;
|
|
224
251
|
/**
|
|
225
252
|
* Clones the payload in, applies the version default, generates any
|
|
226
253
|
* `@db.default.increment` values, enforces PK + unique constraints, stores
|
|
@@ -242,6 +269,9 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
242
269
|
private _enforceUniqueIndexes;
|
|
243
270
|
insertOne(data: Record<string, unknown>): Promise<TDbInsertResult>;
|
|
244
271
|
insertMany(data: Array<Record<string, unknown>>): Promise<TDbInsertManyResult>;
|
|
272
|
+
supportsInsertIgnore(): boolean;
|
|
273
|
+
/** A row colliding on the primary key or a unique index (`CONFLICT`) becomes a skipped slot. */
|
|
274
|
+
insertManyIgnore(data: Array<Record<string, unknown>>): Promise<TDbInsertIgnoreSlot[]>;
|
|
245
275
|
/**
|
|
246
276
|
* Selects the stored rows a write should touch, as `{ key, row }` pairs so
|
|
247
277
|
* callers can mutate in place and re-key. Stored mode scans the table's Map
|
|
@@ -257,6 +287,9 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
257
287
|
*
|
|
258
288
|
* When `many` is `false` at most the first match is returned. A table that
|
|
259
289
|
* does not exist (`state` undefined) matches nothing and is not created.
|
|
290
|
+
*
|
|
291
|
+
* A filter with relational predicates needs `relationSets`, prepared by the
|
|
292
|
+
* caller BEFORE it reads `state` (see {@link _relationSets}).
|
|
260
293
|
*/
|
|
261
294
|
private _selectForWrite;
|
|
262
295
|
/**
|
|
@@ -376,8 +409,12 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
376
409
|
* there is no zone this adapter cannot resolve).
|
|
377
410
|
*/
|
|
378
411
|
calendarBucketUnits(): ReadonlySet<BucketUnit>;
|
|
379
|
-
/** Every aggregate function
|
|
412
|
+
/** Every aggregate function: `countDistinct`, `first` and `last` included. */
|
|
380
413
|
aggregateFns(): ReadonlySet<AggregateFn>;
|
|
414
|
+
/** Arithmetic in an aggregate `$select` (`{ $expr }`, `{ $fn, $expr }`). */
|
|
415
|
+
supportsAggregateExpressions(): boolean;
|
|
416
|
+
/** Managed views render nothing (non-goal) — both are accepted like `aggregateFns()`. */
|
|
417
|
+
viewCapabilities(): ReadonlySet<TViewCapability>;
|
|
381
418
|
updateMany(filter: FilterExpr, data: Record<string, unknown>, ops?: TFieldOps): Promise<TDbUpdateResult>;
|
|
382
419
|
replaceMany(filter: FilterExpr, data: Record<string, unknown>): Promise<TDbUpdateResult>;
|
|
383
420
|
deleteMany(filter: FilterExpr): Promise<TDbDeleteResult>;
|
|
@@ -449,6 +486,14 @@ type Predicate = (row: Record<string, unknown>) => boolean;
|
|
|
449
486
|
* later concern; the SQL/Mongo adapters flatten differently and we do not want
|
|
450
487
|
* to fake a semantic the store can't back yet.
|
|
451
488
|
*/
|
|
489
|
+
/**
|
|
490
|
+
* Per-predicate correlation sets: for every {@link ResolvedRelationFilter} of
|
|
491
|
+
* a filter, the SOURCE correlation tuples (see {@link correlationKey}) that
|
|
492
|
+
* have at least one related row matching the predicate's inner filter.
|
|
493
|
+
* Built asynchronously by {@link prepareRelationSets}; consumed synchronously
|
|
494
|
+
* by {@link buildMemoryPredicate}.
|
|
495
|
+
*/
|
|
496
|
+
type RelationSets = ReadonlyMap<ResolvedRelationFilter, ReadonlySet<string>>;
|
|
452
497
|
/**
|
|
453
498
|
* Compiles a {@link FilterExpr} into an in-memory row predicate
|
|
454
499
|
* `(row) => boolean`, reusing the shared {@link walkFilter} walker so filter
|
|
@@ -456,8 +501,13 @@ type Predicate = (row: Record<string, unknown>) => boolean;
|
|
|
456
501
|
*
|
|
457
502
|
* An empty/absent filter (for which `walkFilter` returns `undefined`) compiles
|
|
458
503
|
* to a match-everything predicate.
|
|
504
|
+
*
|
|
505
|
+
* A filter holding relational predicates (`ResolvedRelationFilter` operands,
|
|
506
|
+
* since 0.1.147) needs `relationSets` — prepared internally by
|
|
507
|
+
* `MemoryAdapter` from the related tables; a standalone call on such a
|
|
508
|
+
* filter throws `REL_FILTER_NOT_SUPPORTED`.
|
|
459
509
|
*/
|
|
460
|
-
declare function buildMemoryPredicate(filter: FilterExpr): Predicate;
|
|
510
|
+
declare function buildMemoryPredicate(filter: FilterExpr, relationSets?: RelationSets): Predicate;
|
|
461
511
|
//#endregion
|
|
462
512
|
//#region src/lib/memory-engine.d.ts
|
|
463
513
|
/**
|
|
@@ -525,4 +575,4 @@ declare function projectRow(row: Record<string, unknown>, projection?: Record<st
|
|
|
525
575
|
*/
|
|
526
576
|
declare function createAdapter(): DbSpace;
|
|
527
577
|
//#endregion
|
|
528
|
-
export { MemoryAdapter, MemoryProviderFn, buildMemoryPredicate, createAdapter, projectRow, setMemoryProvider, sortRows };
|
|
578
|
+
export { MemoryAdapter, type MemoryProviderFn, buildMemoryPredicate, createAdapter, projectRow, setMemoryProvider, sortRows };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AggregateFn, BaseDbAdapter, BucketUnit, DbQuery, DbSpace, FilterExpr, TDbDeleteResult, TDbFieldMeta, TDbInsertManyResult, TDbInsertResult, TDbObjectKind, TDbUpdateResult, TFieldOps } from "@atscript/db";
|
|
1
|
+
import { AggregateFn, BaseDbAdapter, BucketUnit, DbQuery, DbSpace, FilterExpr, ResolvedRelationFilter, TDbDeleteResult, TDbFieldMeta, TDbInsertIgnoreSlot, TDbInsertManyResult, TDbInsertResult, TDbObjectKind, TDbUpdateResult, TFieldOps, TViewCapability } from "@atscript/db";
|
|
2
2
|
import { TAtscriptAnnotatedType } from "@atscript/typescript/utils";
|
|
3
3
|
|
|
4
4
|
//#region src/lib/memory-adapter.d.ts
|
|
@@ -76,6 +76,17 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
76
76
|
* decomposes patches into dot-path `$set`s and loads relations app-level.
|
|
77
77
|
*/
|
|
78
78
|
canFilterField(fd: TDbFieldMeta): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Relational predicates (`{ nav: { $some | $none: … } }`) are evaluated in
|
|
81
|
+
* reads AND mutation filters. Before a filter holding them is compiled, every
|
|
82
|
+
* related table (and junction) is loaded ONCE for that operation — through
|
|
83
|
+
* its own adapter's snapshot seam, so a provider-backed related table works
|
|
84
|
+
* too — and each predicate becomes a set of matching correlation keys
|
|
85
|
+
* (see {@link _relationSets}). Predicate-free filters take the plain path.
|
|
86
|
+
*
|
|
87
|
+
* @since 0.1.147
|
|
88
|
+
*/
|
|
89
|
+
supportsRelationFilters(_mode: "read" | "write"): boolean;
|
|
79
90
|
/**
|
|
80
91
|
* Coerces a by-id value to the id field's declared leaf type. The framework
|
|
81
92
|
* calls `adapter.prepareId(value, fieldType)` when building by-id filters, so a
|
|
@@ -107,7 +118,7 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
107
118
|
/**
|
|
108
119
|
* Physical names of the primary-key field(s). Single `@meta.id` resolves via
|
|
109
120
|
* {@link AtscriptDbReadable.metaIdPhysical}; a composite key maps each logical
|
|
110
|
-
* PK path through `
|
|
121
|
+
* PK path through `physicalPath` (`@db.column` renames included). Memoized
|
|
111
122
|
* because it is stable per adapter (1:1 with a fixed table) yet read on every
|
|
112
123
|
* `pkKey`/projection — recomputing would re-read `this._table.*` and re-allocate.
|
|
113
124
|
*/
|
|
@@ -221,6 +232,22 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
221
232
|
* AND single-snapshot-per-`findManyWithCount` both fall out for free.
|
|
222
233
|
*/
|
|
223
234
|
protected _loadRows(): Record<string, unknown>[] | Promise<Record<string, unknown>[]>;
|
|
235
|
+
/**
|
|
236
|
+
* A per-operation row loader for relational predicates: each related table
|
|
237
|
+
* is snapshotted at most once per operation (the first predicate that needs
|
|
238
|
+
* it loads it; later ones — and nested ones — reuse that snapshot), so a
|
|
239
|
+
* provider-backed related table is invoked once per read. `own` seeds this
|
|
240
|
+
* table's snapshot so a self relation reads the same rows as the outer scan.
|
|
241
|
+
*/
|
|
242
|
+
private _snapshotLoader;
|
|
243
|
+
/**
|
|
244
|
+
* The prepared correlation sets for `filter`'s relational predicates.
|
|
245
|
+
* Callers only await it when `containsRelationFilter(filter)` — a
|
|
246
|
+
* predicate-free filter keeps its fully synchronous path. Write methods call
|
|
247
|
+
* it BEFORE reading the table state, so the related tables (a self relation
|
|
248
|
+
* included) are snapshotted before any row changes, like SQL.
|
|
249
|
+
*/
|
|
250
|
+
private _relationSets;
|
|
224
251
|
/**
|
|
225
252
|
* Clones the payload in, applies the version default, generates any
|
|
226
253
|
* `@db.default.increment` values, enforces PK + unique constraints, stores
|
|
@@ -242,6 +269,9 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
242
269
|
private _enforceUniqueIndexes;
|
|
243
270
|
insertOne(data: Record<string, unknown>): Promise<TDbInsertResult>;
|
|
244
271
|
insertMany(data: Array<Record<string, unknown>>): Promise<TDbInsertManyResult>;
|
|
272
|
+
supportsInsertIgnore(): boolean;
|
|
273
|
+
/** A row colliding on the primary key or a unique index (`CONFLICT`) becomes a skipped slot. */
|
|
274
|
+
insertManyIgnore(data: Array<Record<string, unknown>>): Promise<TDbInsertIgnoreSlot[]>;
|
|
245
275
|
/**
|
|
246
276
|
* Selects the stored rows a write should touch, as `{ key, row }` pairs so
|
|
247
277
|
* callers can mutate in place and re-key. Stored mode scans the table's Map
|
|
@@ -257,6 +287,9 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
257
287
|
*
|
|
258
288
|
* When `many` is `false` at most the first match is returned. A table that
|
|
259
289
|
* does not exist (`state` undefined) matches nothing and is not created.
|
|
290
|
+
*
|
|
291
|
+
* A filter with relational predicates needs `relationSets`, prepared by the
|
|
292
|
+
* caller BEFORE it reads `state` (see {@link _relationSets}).
|
|
260
293
|
*/
|
|
261
294
|
private _selectForWrite;
|
|
262
295
|
/**
|
|
@@ -376,8 +409,12 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
376
409
|
* there is no zone this adapter cannot resolve).
|
|
377
410
|
*/
|
|
378
411
|
calendarBucketUnits(): ReadonlySet<BucketUnit>;
|
|
379
|
-
/** Every aggregate function
|
|
412
|
+
/** Every aggregate function: `countDistinct`, `first` and `last` included. */
|
|
380
413
|
aggregateFns(): ReadonlySet<AggregateFn>;
|
|
414
|
+
/** Arithmetic in an aggregate `$select` (`{ $expr }`, `{ $fn, $expr }`). */
|
|
415
|
+
supportsAggregateExpressions(): boolean;
|
|
416
|
+
/** Managed views render nothing (non-goal) — both are accepted like `aggregateFns()`. */
|
|
417
|
+
viewCapabilities(): ReadonlySet<TViewCapability>;
|
|
381
418
|
updateMany(filter: FilterExpr, data: Record<string, unknown>, ops?: TFieldOps): Promise<TDbUpdateResult>;
|
|
382
419
|
replaceMany(filter: FilterExpr, data: Record<string, unknown>): Promise<TDbUpdateResult>;
|
|
383
420
|
deleteMany(filter: FilterExpr): Promise<TDbDeleteResult>;
|
|
@@ -449,6 +486,14 @@ type Predicate = (row: Record<string, unknown>) => boolean;
|
|
|
449
486
|
* later concern; the SQL/Mongo adapters flatten differently and we do not want
|
|
450
487
|
* to fake a semantic the store can't back yet.
|
|
451
488
|
*/
|
|
489
|
+
/**
|
|
490
|
+
* Per-predicate correlation sets: for every {@link ResolvedRelationFilter} of
|
|
491
|
+
* a filter, the SOURCE correlation tuples (see {@link correlationKey}) that
|
|
492
|
+
* have at least one related row matching the predicate's inner filter.
|
|
493
|
+
* Built asynchronously by {@link prepareRelationSets}; consumed synchronously
|
|
494
|
+
* by {@link buildMemoryPredicate}.
|
|
495
|
+
*/
|
|
496
|
+
type RelationSets = ReadonlyMap<ResolvedRelationFilter, ReadonlySet<string>>;
|
|
452
497
|
/**
|
|
453
498
|
* Compiles a {@link FilterExpr} into an in-memory row predicate
|
|
454
499
|
* `(row) => boolean`, reusing the shared {@link walkFilter} walker so filter
|
|
@@ -456,8 +501,13 @@ type Predicate = (row: Record<string, unknown>) => boolean;
|
|
|
456
501
|
*
|
|
457
502
|
* An empty/absent filter (for which `walkFilter` returns `undefined`) compiles
|
|
458
503
|
* to a match-everything predicate.
|
|
504
|
+
*
|
|
505
|
+
* A filter holding relational predicates (`ResolvedRelationFilter` operands,
|
|
506
|
+
* since 0.1.147) needs `relationSets` — prepared internally by
|
|
507
|
+
* `MemoryAdapter` from the related tables; a standalone call on such a
|
|
508
|
+
* filter throws `REL_FILTER_NOT_SUPPORTED`.
|
|
459
509
|
*/
|
|
460
|
-
declare function buildMemoryPredicate(filter: FilterExpr): Predicate;
|
|
510
|
+
declare function buildMemoryPredicate(filter: FilterExpr, relationSets?: RelationSets): Predicate;
|
|
461
511
|
//#endregion
|
|
462
512
|
//#region src/lib/memory-engine.d.ts
|
|
463
513
|
/**
|
|
@@ -525,4 +575,4 @@ declare function projectRow(row: Record<string, unknown>, projection?: Record<st
|
|
|
525
575
|
*/
|
|
526
576
|
declare function createAdapter(): DbSpace;
|
|
527
577
|
//#endregion
|
|
528
|
-
export { MemoryAdapter, MemoryProviderFn, buildMemoryPredicate, createAdapter, projectRow, setMemoryProvider, sortRows };
|
|
578
|
+
export { MemoryAdapter, type MemoryProviderFn, buildMemoryPredicate, createAdapter, projectRow, setMemoryProvider, sortRows };
|