@atscript/db-memory 0.1.136 → 0.1.137
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 +154 -66
- package/dist/index.d.cts +52 -24
- package/dist/index.d.mts +52 -24
- package/dist/index.mjs +155 -67
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -539,12 +539,19 @@ function accumulatorFactory(expr) {
|
|
|
539
539
|
//#endregion
|
|
540
540
|
//#region src/lib/memory-adapter.ts
|
|
541
541
|
/**
|
|
542
|
+
* One database per {@link DbSpace}, shared by every adapter the space builds —
|
|
543
|
+
* the administrative adapter schema sync drops tables through included. A
|
|
544
|
+
* space is the lifetime of an in-memory database: a fresh space starts empty.
|
|
545
|
+
*/
|
|
546
|
+
const databases = /* @__PURE__ */ new WeakMap();
|
|
547
|
+
/**
|
|
542
548
|
* In-memory {@link BaseDbAdapter} implementation.
|
|
543
549
|
*
|
|
544
550
|
* Runs in one of two modes:
|
|
545
|
-
* - STORED mode (default):
|
|
546
|
-
*
|
|
547
|
-
*
|
|
551
|
+
* - STORED mode (default): rows live in a `Map` of the space's in-memory
|
|
552
|
+
* database, keyed by table name (see {@link databases}), so every adapter of
|
|
553
|
+
* the space that serves a name sees the same table, and the administrative
|
|
554
|
+
* adapter can drop it by name. Documents are kept in their nested PHYSICAL
|
|
548
555
|
* shape (no flattening), which is why {@link supportsNestedObjects} is `true`.
|
|
549
556
|
* Full CRUD surface: inserts, reads, update / replace / delete with
|
|
550
557
|
* optimistic-concurrency CAS.
|
|
@@ -556,12 +563,10 @@ function accumulatorFactory(expr) {
|
|
|
556
563
|
*/
|
|
557
564
|
var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
558
565
|
/**
|
|
559
|
-
* The
|
|
560
|
-
*
|
|
566
|
+
* The in-memory database: the space's (see {@link databases}), resolved once
|
|
567
|
+
* in {@link registerSpace}; an adapter used without a space keeps this own one.
|
|
561
568
|
*/
|
|
562
|
-
|
|
563
|
-
/** Unique indexes recorded by {@link syncIndexes}. Enforced on insert. */
|
|
564
|
-
uniqueIndexes = [];
|
|
569
|
+
_db = /* @__PURE__ */ new Map();
|
|
565
570
|
/** Memoized physical PK field names — stable for the adapter's lifetime. */
|
|
566
571
|
_pkFieldsCache;
|
|
567
572
|
/**
|
|
@@ -571,14 +576,6 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
571
576
|
*/
|
|
572
577
|
_incrementFieldsCache;
|
|
573
578
|
/**
|
|
574
|
-
* Running per-field auto-increment counters (PHYSICAL name → last value
|
|
575
|
-
* handed out). Lives on the adapter INSTANCE, so it resets whenever a new
|
|
576
|
-
* DbSpace/adapter is built — correct for an in-memory store (parity with
|
|
577
|
-
* SQLite `:memory:`, whose sequence also restarts with a fresh DB). Never
|
|
578
|
-
* persisted.
|
|
579
|
-
*/
|
|
580
|
-
_incrementCounters = /* @__PURE__ */ new Map();
|
|
581
|
-
/**
|
|
582
579
|
* Provider (read-through) backing closure. When set, this adapter is
|
|
583
580
|
* PROVIDER-BACKED: reads recompute rows from this closure per request and all
|
|
584
581
|
* writes are rejected (see {@link _assertWritable}). `undefined` ⇒ stored mode.
|
|
@@ -640,6 +637,43 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
640
637
|
}
|
|
641
638
|
return String(id);
|
|
642
639
|
}
|
|
640
|
+
/** Joins the space's in-memory database (see {@link databases}), creating it on first use. */
|
|
641
|
+
registerSpace(space) {
|
|
642
|
+
let db = databases.get(space);
|
|
643
|
+
if (!db) {
|
|
644
|
+
db = /* @__PURE__ */ new Map();
|
|
645
|
+
databases.set(space, db);
|
|
646
|
+
}
|
|
647
|
+
this._db = db;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* This table's state, or `undefined` while it does not exist (never synced,
|
|
651
|
+
* or dropped) — or when no readable is registered.
|
|
652
|
+
*/
|
|
653
|
+
_peekState() {
|
|
654
|
+
const table = this._table;
|
|
655
|
+
return table && this._db.get(table.tableName);
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* This table's state, created on first use — by `ensureTable`, or by a write
|
|
659
|
+
* to a table that was never synced (implicit create, like a MongoDB
|
|
660
|
+
* collection). Reads never create it.
|
|
661
|
+
*/
|
|
662
|
+
_state() {
|
|
663
|
+
const db = this._db;
|
|
664
|
+
const name = this._table.tableName;
|
|
665
|
+
let state = db.get(name);
|
|
666
|
+
if (!state) {
|
|
667
|
+
state = {
|
|
668
|
+
kind: this._table.isView ? "view" : "table",
|
|
669
|
+
rows: /* @__PURE__ */ new Map(),
|
|
670
|
+
uniqueIndexes: [],
|
|
671
|
+
incrementCounters: /* @__PURE__ */ new Map()
|
|
672
|
+
};
|
|
673
|
+
db.set(name, state);
|
|
674
|
+
}
|
|
675
|
+
return state;
|
|
676
|
+
}
|
|
643
677
|
/**
|
|
644
678
|
* Physical names of the primary-key field(s). Single `@meta.id` resolves via
|
|
645
679
|
* {@link AtscriptDbReadable.metaIdPhysical}; a composite key maps each logical
|
|
@@ -688,7 +722,9 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
688
722
|
* are computed so an increment PRIMARY KEY produces a real `insertedId` and
|
|
689
723
|
* stores under a real key. The memory analogue of the Mongo adapter's
|
|
690
724
|
* insert-time increment (Mongo uses an atomic `__atscript_counters`
|
|
691
|
-
* collection; an in-memory store
|
|
725
|
+
* collection; an in-memory store keeps the counter in the table's state, so
|
|
726
|
+
* it restarts with a fresh space or when the table is dropped — parity with
|
|
727
|
+
* SQLite `:memory:`; never persisted):
|
|
692
728
|
*
|
|
693
729
|
* - No value for the field → assign the next counter value. First use starts
|
|
694
730
|
* at `start ?? 1` (`max(counter, (start ?? 1) - 1) + 1`); thereafter it is
|
|
@@ -698,18 +734,18 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
698
734
|
* - Explicit value present → keep it, but advance the counter to
|
|
699
735
|
* `max(counter, value)` so a later auto value can never collide with it.
|
|
700
736
|
*/
|
|
701
|
-
_applyIncrements(row) {
|
|
737
|
+
_applyIncrements(counters, row) {
|
|
702
738
|
const fields = this._incrementFields();
|
|
703
739
|
if (fields.size === 0) return;
|
|
704
740
|
for (const [physical, start] of fields) {
|
|
705
741
|
const floor = (start ?? 1) - 1;
|
|
706
|
-
const base =
|
|
742
|
+
const base = counters.get(physical) ?? floor;
|
|
707
743
|
const current = row[physical];
|
|
708
744
|
if (current === void 0 || current === null) {
|
|
709
745
|
const next = base + 1;
|
|
710
746
|
row[physical] = next;
|
|
711
|
-
|
|
712
|
-
} else if (typeof current === "number")
|
|
747
|
+
counters.set(physical, next);
|
|
748
|
+
} else if (typeof current === "number") counters.set(physical, Math.max(base, current));
|
|
713
749
|
}
|
|
714
750
|
}
|
|
715
751
|
/**
|
|
@@ -785,7 +821,8 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
785
821
|
/**
|
|
786
822
|
* Snapshot seam for reads. Returns the current rows.
|
|
787
823
|
*
|
|
788
|
-
* - Stored mode reads the
|
|
824
|
+
* - Stored mode reads the table's Map directly (insertion order preserved);
|
|
825
|
+
* a table that does not exist reads as empty.
|
|
789
826
|
* - Provider (read-through) mode calls {@link _provider} to recompute a fresh
|
|
790
827
|
* snapshot per read.
|
|
791
828
|
*
|
|
@@ -802,7 +839,7 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
802
839
|
*/
|
|
803
840
|
_loadRows() {
|
|
804
841
|
if (this._provider) return this._provider();
|
|
805
|
-
return [...this.rows.values()];
|
|
842
|
+
return [...this._peekState()?.rows.values() ?? []];
|
|
806
843
|
}
|
|
807
844
|
/**
|
|
808
845
|
* Clones the payload in, applies the version default, generates any
|
|
@@ -812,15 +849,15 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
812
849
|
* the store. Called once per item by both `insertOne` and `insertMany`, so
|
|
813
850
|
* increment values advance sequentially across a batch.
|
|
814
851
|
*/
|
|
815
|
-
_insertRow(data) {
|
|
852
|
+
_insertRow(state, data) {
|
|
816
853
|
const row = structuredClone(data);
|
|
817
854
|
const versionColumn = this._table.versionColumn;
|
|
818
855
|
if (versionColumn !== void 0 && !(versionColumn in row)) row[versionColumn] = 0;
|
|
819
|
-
this._applyIncrements(row);
|
|
856
|
+
this._applyIncrements(state.incrementCounters, row);
|
|
820
857
|
const key = this.pkKey(row);
|
|
821
|
-
if (
|
|
822
|
-
this._enforceUniqueIndexes(row);
|
|
823
|
-
|
|
858
|
+
if (state.rows.has(key)) throw this._pkConflict();
|
|
859
|
+
this._enforceUniqueIndexes(state, row);
|
|
860
|
+
state.rows.set(key, row);
|
|
824
861
|
const fallback = this._table.metaIdPhysical ? void 0 : this._compositeInsertedId(row);
|
|
825
862
|
return this._resolveInsertedId(row, fallback);
|
|
826
863
|
}
|
|
@@ -833,8 +870,8 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
833
870
|
* `excludeKey` (when given) skips the row stored under that {@link pkKey} — so
|
|
834
871
|
* a row updating its own unique value does not false-conflict with itself.
|
|
835
872
|
*/
|
|
836
|
-
_enforceUniqueIndexes(row, excludeKey) {
|
|
837
|
-
for (const index of
|
|
873
|
+
_enforceUniqueIndexes(state, row, excludeKey) {
|
|
874
|
+
for (const index of state.uniqueIndexes) {
|
|
838
875
|
const tuple = [];
|
|
839
876
|
let skip = false;
|
|
840
877
|
for (const field of index.fields) {
|
|
@@ -846,7 +883,7 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
846
883
|
tuple.push(value);
|
|
847
884
|
}
|
|
848
885
|
if (skip) continue;
|
|
849
|
-
for (const [existingKey, existing] of
|
|
886
|
+
for (const [existingKey, existing] of state.rows) {
|
|
850
887
|
if (excludeKey !== void 0 && existingKey === excludeKey) continue;
|
|
851
888
|
let equal = true;
|
|
852
889
|
for (let i = 0; i < index.fields.length; i++) if (!valuesEqual(getPath(existing, index.fields[i]), tuple[i])) {
|
|
@@ -862,11 +899,12 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
862
899
|
}
|
|
863
900
|
async insertOne(data) {
|
|
864
901
|
this._assertWritable();
|
|
865
|
-
return { insertedId: this._insertRow(data) };
|
|
902
|
+
return { insertedId: this._insertRow(this._state(), data) };
|
|
866
903
|
}
|
|
867
904
|
async insertMany(data) {
|
|
868
905
|
this._assertWritable();
|
|
869
|
-
const
|
|
906
|
+
const state = this._state();
|
|
907
|
+
const insertedIds = data.map((item) => this._insertRow(state, item));
|
|
870
908
|
return {
|
|
871
909
|
insertedCount: data.length,
|
|
872
910
|
insertedIds
|
|
@@ -874,7 +912,7 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
874
912
|
}
|
|
875
913
|
/**
|
|
876
914
|
* Selects the stored rows a write should touch, as `{ key, row }` pairs so
|
|
877
|
-
* callers can mutate in place and re-key. Stored mode scans the
|
|
915
|
+
* callers can mutate in place and re-key. Stored mode scans the table's Map
|
|
878
916
|
* directly (writes are authoritative against the store, unlike reads which go
|
|
879
917
|
* through the {@link _loadRows} snapshot seam).
|
|
880
918
|
*
|
|
@@ -885,14 +923,15 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
885
923
|
* that has no version column is a misconfiguration and throws (mirrors the
|
|
886
924
|
* Mongo adapter's `_buildCasFilter`).
|
|
887
925
|
*
|
|
888
|
-
* When `many` is `false` at most the first match is returned.
|
|
926
|
+
* When `many` is `false` at most the first match is returned. A table that
|
|
927
|
+
* does not exist (`state` undefined) matches nothing and is not created.
|
|
889
928
|
*/
|
|
890
|
-
_selectForWrite(filter, expectedVersion, many) {
|
|
929
|
+
_selectForWrite(state, filter, expectedVersion, many) {
|
|
891
930
|
const versionColumn = this._table.versionColumn;
|
|
892
931
|
if (expectedVersion !== void 0 && versionColumn === void 0) throw new Error("expectedVersion requires a versioned table");
|
|
893
932
|
const match = buildMemoryPredicate(filter);
|
|
894
933
|
const matched = [];
|
|
895
|
-
for (const [key, row] of
|
|
934
|
+
for (const [key, row] of state?.rows ?? []) {
|
|
896
935
|
if (!match(row)) continue;
|
|
897
936
|
if (expectedVersion !== void 0 && row[versionColumn] !== expectedVersion) continue;
|
|
898
937
|
matched.push({
|
|
@@ -947,11 +986,11 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
947
986
|
* NEW key (some other row already owns it) throws `CONFLICT`. Throws BEFORE
|
|
948
987
|
* touching the Map so a failed re-key leaves the store unchanged.
|
|
949
988
|
*/
|
|
950
|
-
_commitRow(oldKey, next) {
|
|
989
|
+
_commitRow(rows, oldKey, next) {
|
|
951
990
|
const newKey = this.pkKey(next);
|
|
952
|
-
if (newKey !== oldKey &&
|
|
953
|
-
if (newKey !== oldKey)
|
|
954
|
-
|
|
991
|
+
if (newKey !== oldKey && rows.has(newKey)) throw this._pkConflict();
|
|
992
|
+
if (newKey !== oldKey) rows.delete(oldKey);
|
|
993
|
+
rows.set(newKey, next);
|
|
955
994
|
}
|
|
956
995
|
/**
|
|
957
996
|
* Update-then-commit for a single matched row: clones the pristine `row`,
|
|
@@ -961,25 +1000,26 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
961
1000
|
* commits. Nothing is written to the store until both the unique and PK checks
|
|
962
1001
|
* pass, so a conflict leaves the store untouched.
|
|
963
1002
|
*/
|
|
964
|
-
_commitUpdate(oldKey, row, data, ops) {
|
|
1003
|
+
_commitUpdate(state, oldKey, row, data, ops) {
|
|
965
1004
|
const next = structuredClone(row);
|
|
966
1005
|
this._applyUpdate(next, data, ops);
|
|
967
1006
|
this._bumpVersion(next, row);
|
|
968
|
-
this._enforceUniqueIndexes(next, oldKey);
|
|
969
|
-
this._commitRow(oldKey, next);
|
|
1007
|
+
this._enforceUniqueIndexes(state, next, oldKey);
|
|
1008
|
+
this._commitRow(state.rows, oldKey, next);
|
|
970
1009
|
}
|
|
971
1010
|
async replaceOne(filter, data, expectedVersion) {
|
|
972
1011
|
this._assertWritable();
|
|
973
|
-
const
|
|
974
|
-
|
|
1012
|
+
const state = this._peekState();
|
|
1013
|
+
const matched = this._selectForWrite(state, filter, expectedVersion, false);
|
|
1014
|
+
if (!state || matched.length === 0) return {
|
|
975
1015
|
matchedCount: 0,
|
|
976
1016
|
modifiedCount: 0
|
|
977
1017
|
};
|
|
978
1018
|
const { key, row } = matched[0];
|
|
979
1019
|
const next = structuredClone(data);
|
|
980
1020
|
this._bumpVersion(next, row);
|
|
981
|
-
this._enforceUniqueIndexes(next, key);
|
|
982
|
-
this._commitRow(key, next);
|
|
1021
|
+
this._enforceUniqueIndexes(state, next, key);
|
|
1022
|
+
this._commitRow(state.rows, key, next);
|
|
983
1023
|
return {
|
|
984
1024
|
matchedCount: 1,
|
|
985
1025
|
modifiedCount: 1
|
|
@@ -987,13 +1027,14 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
987
1027
|
}
|
|
988
1028
|
async updateOne(filter, data, ops, expectedVersion) {
|
|
989
1029
|
this._assertWritable();
|
|
990
|
-
const
|
|
991
|
-
|
|
1030
|
+
const state = this._peekState();
|
|
1031
|
+
const matched = this._selectForWrite(state, filter, expectedVersion, false);
|
|
1032
|
+
if (!state || matched.length === 0) return {
|
|
992
1033
|
matchedCount: 0,
|
|
993
1034
|
modifiedCount: 0
|
|
994
1035
|
};
|
|
995
1036
|
const { key, row } = matched[0];
|
|
996
|
-
this._commitUpdate(key, row, data, ops);
|
|
1037
|
+
this._commitUpdate(state, key, row, data, ops);
|
|
997
1038
|
return {
|
|
998
1039
|
matchedCount: 1,
|
|
999
1040
|
modifiedCount: 1
|
|
@@ -1001,9 +1042,10 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
1001
1042
|
}
|
|
1002
1043
|
async deleteOne(filter) {
|
|
1003
1044
|
this._assertWritable();
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
1045
|
+
const state = this._peekState();
|
|
1046
|
+
const matched = this._selectForWrite(state, filter, void 0, false);
|
|
1047
|
+
if (!state || matched.length === 0) return { deletedCount: 0 };
|
|
1048
|
+
state.rows.delete(matched[0].key);
|
|
1007
1049
|
return { deletedCount: 1 };
|
|
1008
1050
|
}
|
|
1009
1051
|
/**
|
|
@@ -1113,8 +1155,13 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
1113
1155
|
}
|
|
1114
1156
|
async updateMany(filter, data, ops) {
|
|
1115
1157
|
this._assertWritable();
|
|
1116
|
-
const
|
|
1117
|
-
|
|
1158
|
+
const state = this._peekState();
|
|
1159
|
+
if (!state) return {
|
|
1160
|
+
matchedCount: 0,
|
|
1161
|
+
modifiedCount: 0
|
|
1162
|
+
};
|
|
1163
|
+
const matched = this._selectForWrite(state, filter, void 0, true);
|
|
1164
|
+
for (const { key, row } of matched) this._commitUpdate(state, key, row, data, ops);
|
|
1118
1165
|
return {
|
|
1119
1166
|
matchedCount: matched.length,
|
|
1120
1167
|
modifiedCount: matched.length
|
|
@@ -1122,8 +1169,13 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
1122
1169
|
}
|
|
1123
1170
|
async replaceMany(filter, data) {
|
|
1124
1171
|
this._assertWritable();
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1172
|
+
const state = this._peekState();
|
|
1173
|
+
if (!state) return {
|
|
1174
|
+
matchedCount: 0,
|
|
1175
|
+
modifiedCount: 0
|
|
1176
|
+
};
|
|
1177
|
+
const matched = this._selectForWrite(state, filter, void 0, true);
|
|
1178
|
+
for (const { key, row } of matched) this._commitUpdate(state, key, row, data);
|
|
1127
1179
|
return {
|
|
1128
1180
|
matchedCount: matched.length,
|
|
1129
1181
|
modifiedCount: matched.length
|
|
@@ -1131,8 +1183,10 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
1131
1183
|
}
|
|
1132
1184
|
async deleteMany(filter) {
|
|
1133
1185
|
this._assertWritable();
|
|
1134
|
-
const
|
|
1135
|
-
|
|
1186
|
+
const state = this._peekState();
|
|
1187
|
+
if (!state) return { deletedCount: 0 };
|
|
1188
|
+
const matched = this._selectForWrite(state, filter, void 0, true);
|
|
1189
|
+
for (const { key } of matched) state.rows.delete(key);
|
|
1136
1190
|
return { deletedCount: matched.length };
|
|
1137
1191
|
}
|
|
1138
1192
|
/**
|
|
@@ -1141,21 +1195,54 @@ var MemoryAdapter = class extends _atscript_db.BaseDbAdapter {
|
|
|
1141
1195
|
* in-memory scan needs no plain/fulltext/geo index to answer queries.
|
|
1142
1196
|
*/
|
|
1143
1197
|
async syncIndexes() {
|
|
1144
|
-
|
|
1198
|
+
const uniqueIndexes = [];
|
|
1145
1199
|
for (const index of this._table.indexes.values()) {
|
|
1146
1200
|
if (index.type !== "unique") continue;
|
|
1147
|
-
|
|
1201
|
+
uniqueIndexes.push({
|
|
1148
1202
|
name: index.name,
|
|
1149
1203
|
fields: index.fields.map((f) => f.name),
|
|
1150
1204
|
optionalFields: new Set(index.fields.filter((f) => f.optional).map((f) => f.name))
|
|
1151
1205
|
});
|
|
1152
1206
|
}
|
|
1207
|
+
this._state().uniqueIndexes = uniqueIndexes;
|
|
1208
|
+
}
|
|
1209
|
+
/** Creates the table's (empty) state when it does not exist. Idempotent. */
|
|
1210
|
+
async ensureTable() {
|
|
1211
|
+
this._state();
|
|
1212
|
+
}
|
|
1213
|
+
/**
|
|
1214
|
+
* Whether the table exists in the space's in-memory database — created by
|
|
1215
|
+
* {@link ensureTable} (or a first write) and not dropped since. Schema sync
|
|
1216
|
+
* reports a table that does not exist as `create`. An external view always
|
|
1217
|
+
* exists: nothing in memory creates one, its rows come from a provider.
|
|
1218
|
+
* @since 0.1.137
|
|
1219
|
+
*/
|
|
1220
|
+
async tableExists() {
|
|
1221
|
+
if ((0, _atscript_db.isAtscriptDbView)(this._table) && this._table.isExternal) return true;
|
|
1222
|
+
return this._peekState() !== void 0;
|
|
1153
1223
|
}
|
|
1154
1224
|
/**
|
|
1155
|
-
*
|
|
1156
|
-
*
|
|
1225
|
+
* Drops a table by name: its rows, unique indexes and increment counters go,
|
|
1226
|
+
* so the table added back starts empty. A missing table is not an error;
|
|
1227
|
+
* a view under that name is (`dropViewByName` drops views).
|
|
1228
|
+
* @since 0.1.137
|
|
1157
1229
|
*/
|
|
1158
|
-
async
|
|
1230
|
+
async dropTableByName(tableName) {
|
|
1231
|
+
this._dropByName(tableName, "table");
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Drops a view by name — its (empty) state; a view holds no rows here.
|
|
1235
|
+
* A missing view is not an error; a table under that name is.
|
|
1236
|
+
* @since 0.1.137
|
|
1237
|
+
*/
|
|
1238
|
+
async dropViewByName(viewName) {
|
|
1239
|
+
this._dropByName(viewName, "view");
|
|
1240
|
+
}
|
|
1241
|
+
_dropByName(name, kind) {
|
|
1242
|
+
const state = this._db.get(name);
|
|
1243
|
+
if (state && state.kind !== kind) throw new Error(`Cannot drop ${kind} "${name}": it is a ${state.kind}`);
|
|
1244
|
+
this._db.delete(name);
|
|
1245
|
+
}
|
|
1159
1246
|
};
|
|
1160
1247
|
/**
|
|
1161
1248
|
* Ergonomic late-binding entry point for provider (read-through) mode. Resolves
|
|
@@ -1177,7 +1264,8 @@ function setMemoryProvider(space, type, fn) {
|
|
|
1177
1264
|
/**
|
|
1178
1265
|
* Creates a {@link DbSpace} backed by an in-memory {@link MemoryAdapter}.
|
|
1179
1266
|
*
|
|
1180
|
-
* Tables default to STORED mode (
|
|
1267
|
+
* Tables default to STORED mode (a `Map` per table in the space's in-memory
|
|
1268
|
+
* database, shared by every adapter of the space). To make one table
|
|
1181
1269
|
* read-only and read-through from a runtime closure, call `setMemoryProvider`
|
|
1182
1270
|
* (re-exported from {@link ./memory-adapter}) on the space AFTER the table's
|
|
1183
1271
|
* adapter has been built.
|
package/dist/index.d.cts
CHANGED
|
@@ -12,9 +12,10 @@ type MemoryProviderFn = () => Array<Record<string, unknown>> | Promise<Array<Rec
|
|
|
12
12
|
* In-memory {@link BaseDbAdapter} implementation.
|
|
13
13
|
*
|
|
14
14
|
* Runs in one of two modes:
|
|
15
|
-
* - STORED mode (default):
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* - STORED mode (default): rows live in a `Map` of the space's in-memory
|
|
16
|
+
* database, keyed by table name (see {@link databases}), so every adapter of
|
|
17
|
+
* the space that serves a name sees the same table, and the administrative
|
|
18
|
+
* adapter can drop it by name. Documents are kept in their nested PHYSICAL
|
|
18
19
|
* shape (no flattening), which is why {@link supportsNestedObjects} is `true`.
|
|
19
20
|
* Full CRUD surface: inserts, reads, update / replace / delete with
|
|
20
21
|
* optimistic-concurrency CAS.
|
|
@@ -26,12 +27,10 @@ type MemoryProviderFn = () => Array<Record<string, unknown>> | Promise<Array<Rec
|
|
|
26
27
|
*/
|
|
27
28
|
declare class MemoryAdapter extends BaseDbAdapter {
|
|
28
29
|
/**
|
|
29
|
-
* The
|
|
30
|
-
*
|
|
30
|
+
* The in-memory database: the space's (see {@link databases}), resolved once
|
|
31
|
+
* in {@link registerSpace}; an adapter used without a space keeps this own one.
|
|
31
32
|
*/
|
|
32
|
-
private
|
|
33
|
-
/** Unique indexes recorded by {@link syncIndexes}. Enforced on insert. */
|
|
34
|
-
private uniqueIndexes;
|
|
33
|
+
private _db;
|
|
35
34
|
/** Memoized physical PK field names — stable for the adapter's lifetime. */
|
|
36
35
|
private _pkFieldsCache?;
|
|
37
36
|
/**
|
|
@@ -40,14 +39,6 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
40
39
|
* {@link _incrementFields}).
|
|
41
40
|
*/
|
|
42
41
|
private _incrementFieldsCache?;
|
|
43
|
-
/**
|
|
44
|
-
* Running per-field auto-increment counters (PHYSICAL name → last value
|
|
45
|
-
* handed out). Lives on the adapter INSTANCE, so it resets whenever a new
|
|
46
|
-
* DbSpace/adapter is built — correct for an in-memory store (parity with
|
|
47
|
-
* SQLite `:memory:`, whose sequence also restarts with a fresh DB). Never
|
|
48
|
-
* persisted.
|
|
49
|
-
*/
|
|
50
|
-
private _incrementCounters;
|
|
51
42
|
/**
|
|
52
43
|
* Provider (read-through) backing closure. When set, this adapter is
|
|
53
44
|
* PROVIDER-BACKED: reads recompute rows from this closure per request and all
|
|
@@ -100,6 +91,19 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
100
91
|
* coerces via `Number(id)`, everything else via `String(id)`.
|
|
101
92
|
*/
|
|
102
93
|
prepareId(id: unknown, _fieldType: unknown): unknown;
|
|
94
|
+
/** Joins the space's in-memory database (see {@link databases}), creating it on first use. */
|
|
95
|
+
registerSpace(space: DbSpace): void;
|
|
96
|
+
/**
|
|
97
|
+
* This table's state, or `undefined` while it does not exist (never synced,
|
|
98
|
+
* or dropped) — or when no readable is registered.
|
|
99
|
+
*/
|
|
100
|
+
private _peekState;
|
|
101
|
+
/**
|
|
102
|
+
* This table's state, created on first use — by `ensureTable`, or by a write
|
|
103
|
+
* to a table that was never synced (implicit create, like a MongoDB
|
|
104
|
+
* collection). Reads never create it.
|
|
105
|
+
*/
|
|
106
|
+
private _state;
|
|
103
107
|
/**
|
|
104
108
|
* Physical names of the primary-key field(s). Single `@meta.id` resolves via
|
|
105
109
|
* {@link AtscriptDbReadable.metaIdPhysical}; a composite key maps each logical
|
|
@@ -133,7 +137,9 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
133
137
|
* are computed so an increment PRIMARY KEY produces a real `insertedId` and
|
|
134
138
|
* stores under a real key. The memory analogue of the Mongo adapter's
|
|
135
139
|
* insert-time increment (Mongo uses an atomic `__atscript_counters`
|
|
136
|
-
* collection; an in-memory store
|
|
140
|
+
* collection; an in-memory store keeps the counter in the table's state, so
|
|
141
|
+
* it restarts with a fresh space or when the table is dropped — parity with
|
|
142
|
+
* SQLite `:memory:`; never persisted):
|
|
137
143
|
*
|
|
138
144
|
* - No value for the field → assign the next counter value. First use starts
|
|
139
145
|
* at `start ?? 1` (`max(counter, (start ?? 1) - 1) + 1`); thereafter it is
|
|
@@ -198,7 +204,8 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
198
204
|
/**
|
|
199
205
|
* Snapshot seam for reads. Returns the current rows.
|
|
200
206
|
*
|
|
201
|
-
* - Stored mode reads the
|
|
207
|
+
* - Stored mode reads the table's Map directly (insertion order preserved);
|
|
208
|
+
* a table that does not exist reads as empty.
|
|
202
209
|
* - Provider (read-through) mode calls {@link _provider} to recompute a fresh
|
|
203
210
|
* snapshot per read.
|
|
204
211
|
*
|
|
@@ -237,7 +244,7 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
237
244
|
insertMany(data: Array<Record<string, unknown>>): Promise<TDbInsertManyResult>;
|
|
238
245
|
/**
|
|
239
246
|
* Selects the stored rows a write should touch, as `{ key, row }` pairs so
|
|
240
|
-
* callers can mutate in place and re-key. Stored mode scans the
|
|
247
|
+
* callers can mutate in place and re-key. Stored mode scans the table's Map
|
|
241
248
|
* directly (writes are authoritative against the store, unlike reads which go
|
|
242
249
|
* through the {@link _loadRows} snapshot seam).
|
|
243
250
|
*
|
|
@@ -248,7 +255,8 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
248
255
|
* that has no version column is a misconfiguration and throws (mirrors the
|
|
249
256
|
* Mongo adapter's `_buildCasFilter`).
|
|
250
257
|
*
|
|
251
|
-
* When `many` is `false` at most the first match is returned.
|
|
258
|
+
* When `many` is `false` at most the first match is returned. A table that
|
|
259
|
+
* does not exist (`state` undefined) matches nothing and is not created.
|
|
252
260
|
*/
|
|
253
261
|
private _selectForWrite;
|
|
254
262
|
/**
|
|
@@ -378,11 +386,30 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
378
386
|
* in-memory scan needs no plain/fulltext/geo index to answer queries.
|
|
379
387
|
*/
|
|
380
388
|
syncIndexes(): Promise<void>;
|
|
389
|
+
/** Creates the table's (empty) state when it does not exist. Idempotent. */
|
|
390
|
+
ensureTable(): Promise<void>;
|
|
381
391
|
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
392
|
+
* Whether the table exists in the space's in-memory database — created by
|
|
393
|
+
* {@link ensureTable} (or a first write) and not dropped since. Schema sync
|
|
394
|
+
* reports a table that does not exist as `create`. An external view always
|
|
395
|
+
* exists: nothing in memory creates one, its rows come from a provider.
|
|
396
|
+
* @since 0.1.137
|
|
384
397
|
*/
|
|
385
|
-
|
|
398
|
+
tableExists(): Promise<boolean>;
|
|
399
|
+
/**
|
|
400
|
+
* Drops a table by name: its rows, unique indexes and increment counters go,
|
|
401
|
+
* so the table added back starts empty. A missing table is not an error;
|
|
402
|
+
* a view under that name is (`dropViewByName` drops views).
|
|
403
|
+
* @since 0.1.137
|
|
404
|
+
*/
|
|
405
|
+
dropTableByName(tableName: string): Promise<void>;
|
|
406
|
+
/**
|
|
407
|
+
* Drops a view by name — its (empty) state; a view holds no rows here.
|
|
408
|
+
* A missing view is not an error; a table under that name is.
|
|
409
|
+
* @since 0.1.137
|
|
410
|
+
*/
|
|
411
|
+
dropViewByName(viewName: string): Promise<void>;
|
|
412
|
+
private _dropByName;
|
|
386
413
|
}
|
|
387
414
|
/**
|
|
388
415
|
* Ergonomic late-binding entry point for provider (read-through) mode. Resolves
|
|
@@ -482,7 +509,8 @@ declare function projectRow(row: Record<string, unknown>, projection?: Record<st
|
|
|
482
509
|
/**
|
|
483
510
|
* Creates a {@link DbSpace} backed by an in-memory {@link MemoryAdapter}.
|
|
484
511
|
*
|
|
485
|
-
* Tables default to STORED mode (
|
|
512
|
+
* Tables default to STORED mode (a `Map` per table in the space's in-memory
|
|
513
|
+
* database, shared by every adapter of the space). To make one table
|
|
486
514
|
* read-only and read-through from a runtime closure, call `setMemoryProvider`
|
|
487
515
|
* (re-exported from {@link ./memory-adapter}) on the space AFTER the table's
|
|
488
516
|
* adapter has been built.
|
package/dist/index.d.mts
CHANGED
|
@@ -12,9 +12,10 @@ type MemoryProviderFn = () => Array<Record<string, unknown>> | Promise<Array<Rec
|
|
|
12
12
|
* In-memory {@link BaseDbAdapter} implementation.
|
|
13
13
|
*
|
|
14
14
|
* Runs in one of two modes:
|
|
15
|
-
* - STORED mode (default):
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* - STORED mode (default): rows live in a `Map` of the space's in-memory
|
|
16
|
+
* database, keyed by table name (see {@link databases}), so every adapter of
|
|
17
|
+
* the space that serves a name sees the same table, and the administrative
|
|
18
|
+
* adapter can drop it by name. Documents are kept in their nested PHYSICAL
|
|
18
19
|
* shape (no flattening), which is why {@link supportsNestedObjects} is `true`.
|
|
19
20
|
* Full CRUD surface: inserts, reads, update / replace / delete with
|
|
20
21
|
* optimistic-concurrency CAS.
|
|
@@ -26,12 +27,10 @@ type MemoryProviderFn = () => Array<Record<string, unknown>> | Promise<Array<Rec
|
|
|
26
27
|
*/
|
|
27
28
|
declare class MemoryAdapter extends BaseDbAdapter {
|
|
28
29
|
/**
|
|
29
|
-
* The
|
|
30
|
-
*
|
|
30
|
+
* The in-memory database: the space's (see {@link databases}), resolved once
|
|
31
|
+
* in {@link registerSpace}; an adapter used without a space keeps this own one.
|
|
31
32
|
*/
|
|
32
|
-
private
|
|
33
|
-
/** Unique indexes recorded by {@link syncIndexes}. Enforced on insert. */
|
|
34
|
-
private uniqueIndexes;
|
|
33
|
+
private _db;
|
|
35
34
|
/** Memoized physical PK field names — stable for the adapter's lifetime. */
|
|
36
35
|
private _pkFieldsCache?;
|
|
37
36
|
/**
|
|
@@ -40,14 +39,6 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
40
39
|
* {@link _incrementFields}).
|
|
41
40
|
*/
|
|
42
41
|
private _incrementFieldsCache?;
|
|
43
|
-
/**
|
|
44
|
-
* Running per-field auto-increment counters (PHYSICAL name → last value
|
|
45
|
-
* handed out). Lives on the adapter INSTANCE, so it resets whenever a new
|
|
46
|
-
* DbSpace/adapter is built — correct for an in-memory store (parity with
|
|
47
|
-
* SQLite `:memory:`, whose sequence also restarts with a fresh DB). Never
|
|
48
|
-
* persisted.
|
|
49
|
-
*/
|
|
50
|
-
private _incrementCounters;
|
|
51
42
|
/**
|
|
52
43
|
* Provider (read-through) backing closure. When set, this adapter is
|
|
53
44
|
* PROVIDER-BACKED: reads recompute rows from this closure per request and all
|
|
@@ -100,6 +91,19 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
100
91
|
* coerces via `Number(id)`, everything else via `String(id)`.
|
|
101
92
|
*/
|
|
102
93
|
prepareId(id: unknown, _fieldType: unknown): unknown;
|
|
94
|
+
/** Joins the space's in-memory database (see {@link databases}), creating it on first use. */
|
|
95
|
+
registerSpace(space: DbSpace): void;
|
|
96
|
+
/**
|
|
97
|
+
* This table's state, or `undefined` while it does not exist (never synced,
|
|
98
|
+
* or dropped) — or when no readable is registered.
|
|
99
|
+
*/
|
|
100
|
+
private _peekState;
|
|
101
|
+
/**
|
|
102
|
+
* This table's state, created on first use — by `ensureTable`, or by a write
|
|
103
|
+
* to a table that was never synced (implicit create, like a MongoDB
|
|
104
|
+
* collection). Reads never create it.
|
|
105
|
+
*/
|
|
106
|
+
private _state;
|
|
103
107
|
/**
|
|
104
108
|
* Physical names of the primary-key field(s). Single `@meta.id` resolves via
|
|
105
109
|
* {@link AtscriptDbReadable.metaIdPhysical}; a composite key maps each logical
|
|
@@ -133,7 +137,9 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
133
137
|
* are computed so an increment PRIMARY KEY produces a real `insertedId` and
|
|
134
138
|
* stores under a real key. The memory analogue of the Mongo adapter's
|
|
135
139
|
* insert-time increment (Mongo uses an atomic `__atscript_counters`
|
|
136
|
-
* collection; an in-memory store
|
|
140
|
+
* collection; an in-memory store keeps the counter in the table's state, so
|
|
141
|
+
* it restarts with a fresh space or when the table is dropped — parity with
|
|
142
|
+
* SQLite `:memory:`; never persisted):
|
|
137
143
|
*
|
|
138
144
|
* - No value for the field → assign the next counter value. First use starts
|
|
139
145
|
* at `start ?? 1` (`max(counter, (start ?? 1) - 1) + 1`); thereafter it is
|
|
@@ -198,7 +204,8 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
198
204
|
/**
|
|
199
205
|
* Snapshot seam for reads. Returns the current rows.
|
|
200
206
|
*
|
|
201
|
-
* - Stored mode reads the
|
|
207
|
+
* - Stored mode reads the table's Map directly (insertion order preserved);
|
|
208
|
+
* a table that does not exist reads as empty.
|
|
202
209
|
* - Provider (read-through) mode calls {@link _provider} to recompute a fresh
|
|
203
210
|
* snapshot per read.
|
|
204
211
|
*
|
|
@@ -237,7 +244,7 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
237
244
|
insertMany(data: Array<Record<string, unknown>>): Promise<TDbInsertManyResult>;
|
|
238
245
|
/**
|
|
239
246
|
* Selects the stored rows a write should touch, as `{ key, row }` pairs so
|
|
240
|
-
* callers can mutate in place and re-key. Stored mode scans the
|
|
247
|
+
* callers can mutate in place and re-key. Stored mode scans the table's Map
|
|
241
248
|
* directly (writes are authoritative against the store, unlike reads which go
|
|
242
249
|
* through the {@link _loadRows} snapshot seam).
|
|
243
250
|
*
|
|
@@ -248,7 +255,8 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
248
255
|
* that has no version column is a misconfiguration and throws (mirrors the
|
|
249
256
|
* Mongo adapter's `_buildCasFilter`).
|
|
250
257
|
*
|
|
251
|
-
* When `many` is `false` at most the first match is returned.
|
|
258
|
+
* When `many` is `false` at most the first match is returned. A table that
|
|
259
|
+
* does not exist (`state` undefined) matches nothing and is not created.
|
|
252
260
|
*/
|
|
253
261
|
private _selectForWrite;
|
|
254
262
|
/**
|
|
@@ -378,11 +386,30 @@ declare class MemoryAdapter extends BaseDbAdapter {
|
|
|
378
386
|
* in-memory scan needs no plain/fulltext/geo index to answer queries.
|
|
379
387
|
*/
|
|
380
388
|
syncIndexes(): Promise<void>;
|
|
389
|
+
/** Creates the table's (empty) state when it does not exist. Idempotent. */
|
|
390
|
+
ensureTable(): Promise<void>;
|
|
381
391
|
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
392
|
+
* Whether the table exists in the space's in-memory database — created by
|
|
393
|
+
* {@link ensureTable} (or a first write) and not dropped since. Schema sync
|
|
394
|
+
* reports a table that does not exist as `create`. An external view always
|
|
395
|
+
* exists: nothing in memory creates one, its rows come from a provider.
|
|
396
|
+
* @since 0.1.137
|
|
384
397
|
*/
|
|
385
|
-
|
|
398
|
+
tableExists(): Promise<boolean>;
|
|
399
|
+
/**
|
|
400
|
+
* Drops a table by name: its rows, unique indexes and increment counters go,
|
|
401
|
+
* so the table added back starts empty. A missing table is not an error;
|
|
402
|
+
* a view under that name is (`dropViewByName` drops views).
|
|
403
|
+
* @since 0.1.137
|
|
404
|
+
*/
|
|
405
|
+
dropTableByName(tableName: string): Promise<void>;
|
|
406
|
+
/**
|
|
407
|
+
* Drops a view by name — its (empty) state; a view holds no rows here.
|
|
408
|
+
* A missing view is not an error; a table under that name is.
|
|
409
|
+
* @since 0.1.137
|
|
410
|
+
*/
|
|
411
|
+
dropViewByName(viewName: string): Promise<void>;
|
|
412
|
+
private _dropByName;
|
|
386
413
|
}
|
|
387
414
|
/**
|
|
388
415
|
* Ergonomic late-binding entry point for provider (read-through) mode. Resolves
|
|
@@ -482,7 +509,8 @@ declare function projectRow(row: Record<string, unknown>, projection?: Record<st
|
|
|
482
509
|
/**
|
|
483
510
|
* Creates a {@link DbSpace} backed by an in-memory {@link MemoryAdapter}.
|
|
484
511
|
*
|
|
485
|
-
* Tables default to STORED mode (
|
|
512
|
+
* Tables default to STORED mode (a `Map` per table in the space's in-memory
|
|
513
|
+
* database, shared by every adapter of the space). To make one table
|
|
486
514
|
* read-only and read-through from a runtime closure, call `setMemoryProvider`
|
|
487
515
|
* (re-exported from {@link ./memory-adapter}) on the space AFTER the table's
|
|
488
516
|
* adapter has been built.
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ALL_AGGREGATE_FNS, ALL_BUCKET_UNITS, BaseDbAdapter, DbError, DbSpace, walkFilter } from "@atscript/db";
|
|
1
|
+
import { ALL_AGGREGATE_FNS, ALL_BUCKET_UNITS, BaseDbAdapter, DbError, DbSpace, isAtscriptDbView, walkFilter } from "@atscript/db";
|
|
2
2
|
import { assertAggregateFn, resolveAlias } from "@atscript/db/agg";
|
|
3
3
|
import { bucketer } from "@uniqu/core";
|
|
4
4
|
//#region src/lib/memory-filter.ts
|
|
@@ -538,12 +538,19 @@ function accumulatorFactory(expr) {
|
|
|
538
538
|
//#endregion
|
|
539
539
|
//#region src/lib/memory-adapter.ts
|
|
540
540
|
/**
|
|
541
|
+
* One database per {@link DbSpace}, shared by every adapter the space builds —
|
|
542
|
+
* the administrative adapter schema sync drops tables through included. A
|
|
543
|
+
* space is the lifetime of an in-memory database: a fresh space starts empty.
|
|
544
|
+
*/
|
|
545
|
+
const databases = /* @__PURE__ */ new WeakMap();
|
|
546
|
+
/**
|
|
541
547
|
* In-memory {@link BaseDbAdapter} implementation.
|
|
542
548
|
*
|
|
543
549
|
* Runs in one of two modes:
|
|
544
|
-
* - STORED mode (default):
|
|
545
|
-
*
|
|
546
|
-
*
|
|
550
|
+
* - STORED mode (default): rows live in a `Map` of the space's in-memory
|
|
551
|
+
* database, keyed by table name (see {@link databases}), so every adapter of
|
|
552
|
+
* the space that serves a name sees the same table, and the administrative
|
|
553
|
+
* adapter can drop it by name. Documents are kept in their nested PHYSICAL
|
|
547
554
|
* shape (no flattening), which is why {@link supportsNestedObjects} is `true`.
|
|
548
555
|
* Full CRUD surface: inserts, reads, update / replace / delete with
|
|
549
556
|
* optimistic-concurrency CAS.
|
|
@@ -555,12 +562,10 @@ function accumulatorFactory(expr) {
|
|
|
555
562
|
*/
|
|
556
563
|
var MemoryAdapter = class extends BaseDbAdapter {
|
|
557
564
|
/**
|
|
558
|
-
* The
|
|
559
|
-
*
|
|
565
|
+
* The in-memory database: the space's (see {@link databases}), resolved once
|
|
566
|
+
* in {@link registerSpace}; an adapter used without a space keeps this own one.
|
|
560
567
|
*/
|
|
561
|
-
|
|
562
|
-
/** Unique indexes recorded by {@link syncIndexes}. Enforced on insert. */
|
|
563
|
-
uniqueIndexes = [];
|
|
568
|
+
_db = /* @__PURE__ */ new Map();
|
|
564
569
|
/** Memoized physical PK field names — stable for the adapter's lifetime. */
|
|
565
570
|
_pkFieldsCache;
|
|
566
571
|
/**
|
|
@@ -570,14 +575,6 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
570
575
|
*/
|
|
571
576
|
_incrementFieldsCache;
|
|
572
577
|
/**
|
|
573
|
-
* Running per-field auto-increment counters (PHYSICAL name → last value
|
|
574
|
-
* handed out). Lives on the adapter INSTANCE, so it resets whenever a new
|
|
575
|
-
* DbSpace/adapter is built — correct for an in-memory store (parity with
|
|
576
|
-
* SQLite `:memory:`, whose sequence also restarts with a fresh DB). Never
|
|
577
|
-
* persisted.
|
|
578
|
-
*/
|
|
579
|
-
_incrementCounters = /* @__PURE__ */ new Map();
|
|
580
|
-
/**
|
|
581
578
|
* Provider (read-through) backing closure. When set, this adapter is
|
|
582
579
|
* PROVIDER-BACKED: reads recompute rows from this closure per request and all
|
|
583
580
|
* writes are rejected (see {@link _assertWritable}). `undefined` ⇒ stored mode.
|
|
@@ -639,6 +636,43 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
639
636
|
}
|
|
640
637
|
return String(id);
|
|
641
638
|
}
|
|
639
|
+
/** Joins the space's in-memory database (see {@link databases}), creating it on first use. */
|
|
640
|
+
registerSpace(space) {
|
|
641
|
+
let db = databases.get(space);
|
|
642
|
+
if (!db) {
|
|
643
|
+
db = /* @__PURE__ */ new Map();
|
|
644
|
+
databases.set(space, db);
|
|
645
|
+
}
|
|
646
|
+
this._db = db;
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* This table's state, or `undefined` while it does not exist (never synced,
|
|
650
|
+
* or dropped) — or when no readable is registered.
|
|
651
|
+
*/
|
|
652
|
+
_peekState() {
|
|
653
|
+
const table = this._table;
|
|
654
|
+
return table && this._db.get(table.tableName);
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* This table's state, created on first use — by `ensureTable`, or by a write
|
|
658
|
+
* to a table that was never synced (implicit create, like a MongoDB
|
|
659
|
+
* collection). Reads never create it.
|
|
660
|
+
*/
|
|
661
|
+
_state() {
|
|
662
|
+
const db = this._db;
|
|
663
|
+
const name = this._table.tableName;
|
|
664
|
+
let state = db.get(name);
|
|
665
|
+
if (!state) {
|
|
666
|
+
state = {
|
|
667
|
+
kind: this._table.isView ? "view" : "table",
|
|
668
|
+
rows: /* @__PURE__ */ new Map(),
|
|
669
|
+
uniqueIndexes: [],
|
|
670
|
+
incrementCounters: /* @__PURE__ */ new Map()
|
|
671
|
+
};
|
|
672
|
+
db.set(name, state);
|
|
673
|
+
}
|
|
674
|
+
return state;
|
|
675
|
+
}
|
|
642
676
|
/**
|
|
643
677
|
* Physical names of the primary-key field(s). Single `@meta.id` resolves via
|
|
644
678
|
* {@link AtscriptDbReadable.metaIdPhysical}; a composite key maps each logical
|
|
@@ -687,7 +721,9 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
687
721
|
* are computed so an increment PRIMARY KEY produces a real `insertedId` and
|
|
688
722
|
* stores under a real key. The memory analogue of the Mongo adapter's
|
|
689
723
|
* insert-time increment (Mongo uses an atomic `__atscript_counters`
|
|
690
|
-
* collection; an in-memory store
|
|
724
|
+
* collection; an in-memory store keeps the counter in the table's state, so
|
|
725
|
+
* it restarts with a fresh space or when the table is dropped — parity with
|
|
726
|
+
* SQLite `:memory:`; never persisted):
|
|
691
727
|
*
|
|
692
728
|
* - No value for the field → assign the next counter value. First use starts
|
|
693
729
|
* at `start ?? 1` (`max(counter, (start ?? 1) - 1) + 1`); thereafter it is
|
|
@@ -697,18 +733,18 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
697
733
|
* - Explicit value present → keep it, but advance the counter to
|
|
698
734
|
* `max(counter, value)` so a later auto value can never collide with it.
|
|
699
735
|
*/
|
|
700
|
-
_applyIncrements(row) {
|
|
736
|
+
_applyIncrements(counters, row) {
|
|
701
737
|
const fields = this._incrementFields();
|
|
702
738
|
if (fields.size === 0) return;
|
|
703
739
|
for (const [physical, start] of fields) {
|
|
704
740
|
const floor = (start ?? 1) - 1;
|
|
705
|
-
const base =
|
|
741
|
+
const base = counters.get(physical) ?? floor;
|
|
706
742
|
const current = row[physical];
|
|
707
743
|
if (current === void 0 || current === null) {
|
|
708
744
|
const next = base + 1;
|
|
709
745
|
row[physical] = next;
|
|
710
|
-
|
|
711
|
-
} else if (typeof current === "number")
|
|
746
|
+
counters.set(physical, next);
|
|
747
|
+
} else if (typeof current === "number") counters.set(physical, Math.max(base, current));
|
|
712
748
|
}
|
|
713
749
|
}
|
|
714
750
|
/**
|
|
@@ -784,7 +820,8 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
784
820
|
/**
|
|
785
821
|
* Snapshot seam for reads. Returns the current rows.
|
|
786
822
|
*
|
|
787
|
-
* - Stored mode reads the
|
|
823
|
+
* - Stored mode reads the table's Map directly (insertion order preserved);
|
|
824
|
+
* a table that does not exist reads as empty.
|
|
788
825
|
* - Provider (read-through) mode calls {@link _provider} to recompute a fresh
|
|
789
826
|
* snapshot per read.
|
|
790
827
|
*
|
|
@@ -801,7 +838,7 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
801
838
|
*/
|
|
802
839
|
_loadRows() {
|
|
803
840
|
if (this._provider) return this._provider();
|
|
804
|
-
return [...this.rows.values()];
|
|
841
|
+
return [...this._peekState()?.rows.values() ?? []];
|
|
805
842
|
}
|
|
806
843
|
/**
|
|
807
844
|
* Clones the payload in, applies the version default, generates any
|
|
@@ -811,15 +848,15 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
811
848
|
* the store. Called once per item by both `insertOne` and `insertMany`, so
|
|
812
849
|
* increment values advance sequentially across a batch.
|
|
813
850
|
*/
|
|
814
|
-
_insertRow(data) {
|
|
851
|
+
_insertRow(state, data) {
|
|
815
852
|
const row = structuredClone(data);
|
|
816
853
|
const versionColumn = this._table.versionColumn;
|
|
817
854
|
if (versionColumn !== void 0 && !(versionColumn in row)) row[versionColumn] = 0;
|
|
818
|
-
this._applyIncrements(row);
|
|
855
|
+
this._applyIncrements(state.incrementCounters, row);
|
|
819
856
|
const key = this.pkKey(row);
|
|
820
|
-
if (
|
|
821
|
-
this._enforceUniqueIndexes(row);
|
|
822
|
-
|
|
857
|
+
if (state.rows.has(key)) throw this._pkConflict();
|
|
858
|
+
this._enforceUniqueIndexes(state, row);
|
|
859
|
+
state.rows.set(key, row);
|
|
823
860
|
const fallback = this._table.metaIdPhysical ? void 0 : this._compositeInsertedId(row);
|
|
824
861
|
return this._resolveInsertedId(row, fallback);
|
|
825
862
|
}
|
|
@@ -832,8 +869,8 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
832
869
|
* `excludeKey` (when given) skips the row stored under that {@link pkKey} — so
|
|
833
870
|
* a row updating its own unique value does not false-conflict with itself.
|
|
834
871
|
*/
|
|
835
|
-
_enforceUniqueIndexes(row, excludeKey) {
|
|
836
|
-
for (const index of
|
|
872
|
+
_enforceUniqueIndexes(state, row, excludeKey) {
|
|
873
|
+
for (const index of state.uniqueIndexes) {
|
|
837
874
|
const tuple = [];
|
|
838
875
|
let skip = false;
|
|
839
876
|
for (const field of index.fields) {
|
|
@@ -845,7 +882,7 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
845
882
|
tuple.push(value);
|
|
846
883
|
}
|
|
847
884
|
if (skip) continue;
|
|
848
|
-
for (const [existingKey, existing] of
|
|
885
|
+
for (const [existingKey, existing] of state.rows) {
|
|
849
886
|
if (excludeKey !== void 0 && existingKey === excludeKey) continue;
|
|
850
887
|
let equal = true;
|
|
851
888
|
for (let i = 0; i < index.fields.length; i++) if (!valuesEqual(getPath(existing, index.fields[i]), tuple[i])) {
|
|
@@ -861,11 +898,12 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
861
898
|
}
|
|
862
899
|
async insertOne(data) {
|
|
863
900
|
this._assertWritable();
|
|
864
|
-
return { insertedId: this._insertRow(data) };
|
|
901
|
+
return { insertedId: this._insertRow(this._state(), data) };
|
|
865
902
|
}
|
|
866
903
|
async insertMany(data) {
|
|
867
904
|
this._assertWritable();
|
|
868
|
-
const
|
|
905
|
+
const state = this._state();
|
|
906
|
+
const insertedIds = data.map((item) => this._insertRow(state, item));
|
|
869
907
|
return {
|
|
870
908
|
insertedCount: data.length,
|
|
871
909
|
insertedIds
|
|
@@ -873,7 +911,7 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
873
911
|
}
|
|
874
912
|
/**
|
|
875
913
|
* Selects the stored rows a write should touch, as `{ key, row }` pairs so
|
|
876
|
-
* callers can mutate in place and re-key. Stored mode scans the
|
|
914
|
+
* callers can mutate in place and re-key. Stored mode scans the table's Map
|
|
877
915
|
* directly (writes are authoritative against the store, unlike reads which go
|
|
878
916
|
* through the {@link _loadRows} snapshot seam).
|
|
879
917
|
*
|
|
@@ -884,14 +922,15 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
884
922
|
* that has no version column is a misconfiguration and throws (mirrors the
|
|
885
923
|
* Mongo adapter's `_buildCasFilter`).
|
|
886
924
|
*
|
|
887
|
-
* When `many` is `false` at most the first match is returned.
|
|
925
|
+
* When `many` is `false` at most the first match is returned. A table that
|
|
926
|
+
* does not exist (`state` undefined) matches nothing and is not created.
|
|
888
927
|
*/
|
|
889
|
-
_selectForWrite(filter, expectedVersion, many) {
|
|
928
|
+
_selectForWrite(state, filter, expectedVersion, many) {
|
|
890
929
|
const versionColumn = this._table.versionColumn;
|
|
891
930
|
if (expectedVersion !== void 0 && versionColumn === void 0) throw new Error("expectedVersion requires a versioned table");
|
|
892
931
|
const match = buildMemoryPredicate(filter);
|
|
893
932
|
const matched = [];
|
|
894
|
-
for (const [key, row] of
|
|
933
|
+
for (const [key, row] of state?.rows ?? []) {
|
|
895
934
|
if (!match(row)) continue;
|
|
896
935
|
if (expectedVersion !== void 0 && row[versionColumn] !== expectedVersion) continue;
|
|
897
936
|
matched.push({
|
|
@@ -946,11 +985,11 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
946
985
|
* NEW key (some other row already owns it) throws `CONFLICT`. Throws BEFORE
|
|
947
986
|
* touching the Map so a failed re-key leaves the store unchanged.
|
|
948
987
|
*/
|
|
949
|
-
_commitRow(oldKey, next) {
|
|
988
|
+
_commitRow(rows, oldKey, next) {
|
|
950
989
|
const newKey = this.pkKey(next);
|
|
951
|
-
if (newKey !== oldKey &&
|
|
952
|
-
if (newKey !== oldKey)
|
|
953
|
-
|
|
990
|
+
if (newKey !== oldKey && rows.has(newKey)) throw this._pkConflict();
|
|
991
|
+
if (newKey !== oldKey) rows.delete(oldKey);
|
|
992
|
+
rows.set(newKey, next);
|
|
954
993
|
}
|
|
955
994
|
/**
|
|
956
995
|
* Update-then-commit for a single matched row: clones the pristine `row`,
|
|
@@ -960,25 +999,26 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
960
999
|
* commits. Nothing is written to the store until both the unique and PK checks
|
|
961
1000
|
* pass, so a conflict leaves the store untouched.
|
|
962
1001
|
*/
|
|
963
|
-
_commitUpdate(oldKey, row, data, ops) {
|
|
1002
|
+
_commitUpdate(state, oldKey, row, data, ops) {
|
|
964
1003
|
const next = structuredClone(row);
|
|
965
1004
|
this._applyUpdate(next, data, ops);
|
|
966
1005
|
this._bumpVersion(next, row);
|
|
967
|
-
this._enforceUniqueIndexes(next, oldKey);
|
|
968
|
-
this._commitRow(oldKey, next);
|
|
1006
|
+
this._enforceUniqueIndexes(state, next, oldKey);
|
|
1007
|
+
this._commitRow(state.rows, oldKey, next);
|
|
969
1008
|
}
|
|
970
1009
|
async replaceOne(filter, data, expectedVersion) {
|
|
971
1010
|
this._assertWritable();
|
|
972
|
-
const
|
|
973
|
-
|
|
1011
|
+
const state = this._peekState();
|
|
1012
|
+
const matched = this._selectForWrite(state, filter, expectedVersion, false);
|
|
1013
|
+
if (!state || matched.length === 0) return {
|
|
974
1014
|
matchedCount: 0,
|
|
975
1015
|
modifiedCount: 0
|
|
976
1016
|
};
|
|
977
1017
|
const { key, row } = matched[0];
|
|
978
1018
|
const next = structuredClone(data);
|
|
979
1019
|
this._bumpVersion(next, row);
|
|
980
|
-
this._enforceUniqueIndexes(next, key);
|
|
981
|
-
this._commitRow(key, next);
|
|
1020
|
+
this._enforceUniqueIndexes(state, next, key);
|
|
1021
|
+
this._commitRow(state.rows, key, next);
|
|
982
1022
|
return {
|
|
983
1023
|
matchedCount: 1,
|
|
984
1024
|
modifiedCount: 1
|
|
@@ -986,13 +1026,14 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
986
1026
|
}
|
|
987
1027
|
async updateOne(filter, data, ops, expectedVersion) {
|
|
988
1028
|
this._assertWritable();
|
|
989
|
-
const
|
|
990
|
-
|
|
1029
|
+
const state = this._peekState();
|
|
1030
|
+
const matched = this._selectForWrite(state, filter, expectedVersion, false);
|
|
1031
|
+
if (!state || matched.length === 0) return {
|
|
991
1032
|
matchedCount: 0,
|
|
992
1033
|
modifiedCount: 0
|
|
993
1034
|
};
|
|
994
1035
|
const { key, row } = matched[0];
|
|
995
|
-
this._commitUpdate(key, row, data, ops);
|
|
1036
|
+
this._commitUpdate(state, key, row, data, ops);
|
|
996
1037
|
return {
|
|
997
1038
|
matchedCount: 1,
|
|
998
1039
|
modifiedCount: 1
|
|
@@ -1000,9 +1041,10 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
1000
1041
|
}
|
|
1001
1042
|
async deleteOne(filter) {
|
|
1002
1043
|
this._assertWritable();
|
|
1003
|
-
const
|
|
1004
|
-
|
|
1005
|
-
|
|
1044
|
+
const state = this._peekState();
|
|
1045
|
+
const matched = this._selectForWrite(state, filter, void 0, false);
|
|
1046
|
+
if (!state || matched.length === 0) return { deletedCount: 0 };
|
|
1047
|
+
state.rows.delete(matched[0].key);
|
|
1006
1048
|
return { deletedCount: 1 };
|
|
1007
1049
|
}
|
|
1008
1050
|
/**
|
|
@@ -1112,8 +1154,13 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
1112
1154
|
}
|
|
1113
1155
|
async updateMany(filter, data, ops) {
|
|
1114
1156
|
this._assertWritable();
|
|
1115
|
-
const
|
|
1116
|
-
|
|
1157
|
+
const state = this._peekState();
|
|
1158
|
+
if (!state) return {
|
|
1159
|
+
matchedCount: 0,
|
|
1160
|
+
modifiedCount: 0
|
|
1161
|
+
};
|
|
1162
|
+
const matched = this._selectForWrite(state, filter, void 0, true);
|
|
1163
|
+
for (const { key, row } of matched) this._commitUpdate(state, key, row, data, ops);
|
|
1117
1164
|
return {
|
|
1118
1165
|
matchedCount: matched.length,
|
|
1119
1166
|
modifiedCount: matched.length
|
|
@@ -1121,8 +1168,13 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
1121
1168
|
}
|
|
1122
1169
|
async replaceMany(filter, data) {
|
|
1123
1170
|
this._assertWritable();
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1171
|
+
const state = this._peekState();
|
|
1172
|
+
if (!state) return {
|
|
1173
|
+
matchedCount: 0,
|
|
1174
|
+
modifiedCount: 0
|
|
1175
|
+
};
|
|
1176
|
+
const matched = this._selectForWrite(state, filter, void 0, true);
|
|
1177
|
+
for (const { key, row } of matched) this._commitUpdate(state, key, row, data);
|
|
1126
1178
|
return {
|
|
1127
1179
|
matchedCount: matched.length,
|
|
1128
1180
|
modifiedCount: matched.length
|
|
@@ -1130,8 +1182,10 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
1130
1182
|
}
|
|
1131
1183
|
async deleteMany(filter) {
|
|
1132
1184
|
this._assertWritable();
|
|
1133
|
-
const
|
|
1134
|
-
|
|
1185
|
+
const state = this._peekState();
|
|
1186
|
+
if (!state) return { deletedCount: 0 };
|
|
1187
|
+
const matched = this._selectForWrite(state, filter, void 0, true);
|
|
1188
|
+
for (const { key } of matched) state.rows.delete(key);
|
|
1135
1189
|
return { deletedCount: matched.length };
|
|
1136
1190
|
}
|
|
1137
1191
|
/**
|
|
@@ -1140,21 +1194,54 @@ var MemoryAdapter = class extends BaseDbAdapter {
|
|
|
1140
1194
|
* in-memory scan needs no plain/fulltext/geo index to answer queries.
|
|
1141
1195
|
*/
|
|
1142
1196
|
async syncIndexes() {
|
|
1143
|
-
|
|
1197
|
+
const uniqueIndexes = [];
|
|
1144
1198
|
for (const index of this._table.indexes.values()) {
|
|
1145
1199
|
if (index.type !== "unique") continue;
|
|
1146
|
-
|
|
1200
|
+
uniqueIndexes.push({
|
|
1147
1201
|
name: index.name,
|
|
1148
1202
|
fields: index.fields.map((f) => f.name),
|
|
1149
1203
|
optionalFields: new Set(index.fields.filter((f) => f.optional).map((f) => f.name))
|
|
1150
1204
|
});
|
|
1151
1205
|
}
|
|
1206
|
+
this._state().uniqueIndexes = uniqueIndexes;
|
|
1207
|
+
}
|
|
1208
|
+
/** Creates the table's (empty) state when it does not exist. Idempotent. */
|
|
1209
|
+
async ensureTable() {
|
|
1210
|
+
this._state();
|
|
1211
|
+
}
|
|
1212
|
+
/**
|
|
1213
|
+
* Whether the table exists in the space's in-memory database — created by
|
|
1214
|
+
* {@link ensureTable} (or a first write) and not dropped since. Schema sync
|
|
1215
|
+
* reports a table that does not exist as `create`. An external view always
|
|
1216
|
+
* exists: nothing in memory creates one, its rows come from a provider.
|
|
1217
|
+
* @since 0.1.137
|
|
1218
|
+
*/
|
|
1219
|
+
async tableExists() {
|
|
1220
|
+
if (isAtscriptDbView(this._table) && this._table.isExternal) return true;
|
|
1221
|
+
return this._peekState() !== void 0;
|
|
1152
1222
|
}
|
|
1153
1223
|
/**
|
|
1154
|
-
*
|
|
1155
|
-
*
|
|
1224
|
+
* Drops a table by name: its rows, unique indexes and increment counters go,
|
|
1225
|
+
* so the table added back starts empty. A missing table is not an error;
|
|
1226
|
+
* a view under that name is (`dropViewByName` drops views).
|
|
1227
|
+
* @since 0.1.137
|
|
1156
1228
|
*/
|
|
1157
|
-
async
|
|
1229
|
+
async dropTableByName(tableName) {
|
|
1230
|
+
this._dropByName(tableName, "table");
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* Drops a view by name — its (empty) state; a view holds no rows here.
|
|
1234
|
+
* A missing view is not an error; a table under that name is.
|
|
1235
|
+
* @since 0.1.137
|
|
1236
|
+
*/
|
|
1237
|
+
async dropViewByName(viewName) {
|
|
1238
|
+
this._dropByName(viewName, "view");
|
|
1239
|
+
}
|
|
1240
|
+
_dropByName(name, kind) {
|
|
1241
|
+
const state = this._db.get(name);
|
|
1242
|
+
if (state && state.kind !== kind) throw new Error(`Cannot drop ${kind} "${name}": it is a ${state.kind}`);
|
|
1243
|
+
this._db.delete(name);
|
|
1244
|
+
}
|
|
1158
1245
|
};
|
|
1159
1246
|
/**
|
|
1160
1247
|
* Ergonomic late-binding entry point for provider (read-through) mode. Resolves
|
|
@@ -1176,7 +1263,8 @@ function setMemoryProvider(space, type, fn) {
|
|
|
1176
1263
|
/**
|
|
1177
1264
|
* Creates a {@link DbSpace} backed by an in-memory {@link MemoryAdapter}.
|
|
1178
1265
|
*
|
|
1179
|
-
* Tables default to STORED mode (
|
|
1266
|
+
* Tables default to STORED mode (a `Map` per table in the space's in-memory
|
|
1267
|
+
* database, shared by every adapter of the space). To make one table
|
|
1180
1268
|
* read-only and read-through from a runtime closure, call `setMemoryProvider`
|
|
1181
1269
|
* (re-exported from {@link ./memory-adapter}) on the space AFTER the table's
|
|
1182
1270
|
* adapter has been built.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/db-memory",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.137",
|
|
4
4
|
"description": "In-memory adapter for atscript-db.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"atscript",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"@atscript/core": "^0.1.92",
|
|
46
46
|
"@atscript/typescript": "^0.1.92",
|
|
47
47
|
"@uniqu/core": "^0.1.11",
|
|
48
|
-
"@atscript/db": "^0.1.
|
|
48
|
+
"@atscript/db": "^0.1.137"
|
|
49
49
|
},
|
|
50
50
|
"scripts": {
|
|
51
51
|
"postinstall": "asc -f dts",
|