@instantdb/core 0.22.86-experimental.split-store.20178922132.1 → 0.22.86-experimental.split-store.20243647937.1
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/__tests__/src/Reactor.test.js +18 -11
- package/__tests__/src/{datalog.test.js → datalog.test.ts} +17 -5
- package/__tests__/src/{instaml.test.js → instaml.test.ts} +183 -119
- package/__tests__/src/instaql.bench.ts +34 -0
- package/__tests__/src/{instaql.test.js → instaql.test.ts} +342 -455
- package/__tests__/src/instaqlInference.test.js +13 -9
- package/__tests__/src/{store.test.js → store.test.ts} +188 -210
- package/dist/commonjs/Reactor.d.ts +4 -1
- package/dist/commonjs/Reactor.d.ts.map +1 -1
- package/dist/commonjs/Reactor.js +22 -12
- package/dist/commonjs/Reactor.js.map +1 -1
- package/dist/commonjs/instaml.d.ts +3 -3
- package/dist/commonjs/instaml.d.ts.map +1 -1
- package/dist/commonjs/instaml.js +2 -2
- package/dist/commonjs/instaml.js.map +1 -1
- package/dist/commonjs/instaql.d.ts +2 -2
- package/dist/commonjs/instaql.d.ts.map +1 -1
- package/dist/commonjs/instaql.js.map +1 -1
- package/dist/commonjs/store.d.ts +28 -9
- package/dist/commonjs/store.d.ts.map +1 -1
- package/dist/commonjs/store.js +25 -19
- package/dist/commonjs/store.js.map +1 -1
- package/dist/esm/Reactor.d.ts +4 -1
- package/dist/esm/Reactor.d.ts.map +1 -1
- package/dist/esm/Reactor.js +22 -12
- package/dist/esm/Reactor.js.map +1 -1
- package/dist/esm/instaml.d.ts +3 -3
- package/dist/esm/instaml.d.ts.map +1 -1
- package/dist/esm/instaml.js +3 -3
- package/dist/esm/instaml.js.map +1 -1
- package/dist/esm/instaql.d.ts +2 -2
- package/dist/esm/instaql.d.ts.map +1 -1
- package/dist/esm/instaql.js.map +1 -1
- package/dist/esm/store.d.ts +28 -9
- package/dist/esm/store.d.ts.map +1 -1
- package/dist/esm/store.js +23 -17
- package/dist/esm/store.js.map +1 -1
- package/dist/standalone/index.js +580 -564
- package/dist/standalone/index.umd.cjs +2 -2
- package/package.json +2 -2
- package/src/Reactor.js +44 -35
- package/src/instaml.ts +8 -7
- package/src/instaql.ts +2 -2
- package/src/store.ts +61 -30
- package/__tests__/src/instaql.bench.js +0 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instantdb/core",
|
|
3
|
-
"version": "0.22.86-experimental.split-store.
|
|
3
|
+
"version": "0.22.86-experimental.split-store.20243647937.1",
|
|
4
4
|
"description": "Instant's core local abstraction",
|
|
5
5
|
"homepage": "https://github.com/instantdb/instant/tree/main/client/packages/core",
|
|
6
6
|
"repository": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"mutative": "^1.0.10",
|
|
55
55
|
"uuid": "^11.1.0",
|
|
56
|
-
"@instantdb/version": "0.22.86-experimental.split-store.
|
|
56
|
+
"@instantdb/version": "0.22.86-experimental.split-store.20243647937.1"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
59
|
"test": "vitest",
|
package/src/Reactor.js
CHANGED
|
@@ -661,38 +661,49 @@ export default class Reactor {
|
|
|
661
661
|
const result = x['instaql-result'];
|
|
662
662
|
const hash = weakHash(q);
|
|
663
663
|
const triples = extractTriples(result);
|
|
664
|
+
const attrsStore = this.ensureAttrs();
|
|
664
665
|
const store = sts.createStore(
|
|
665
|
-
|
|
666
|
+
attrsStore,
|
|
666
667
|
triples,
|
|
667
668
|
enableCardinalityInference,
|
|
668
669
|
this.config.useDateObjects,
|
|
669
670
|
);
|
|
670
|
-
const newStore =
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
671
|
+
const { store: newStore, attrsStore: newAttrsStore } =
|
|
672
|
+
this._applyOptimisticUpdates(
|
|
673
|
+
store,
|
|
674
|
+
attrsStore,
|
|
675
|
+
mutations,
|
|
676
|
+
processedTxId,
|
|
677
|
+
);
|
|
676
678
|
const pageInfo = result?.[0]?.data?.['page-info'];
|
|
677
679
|
const aggregate = result?.[0]?.data?.['aggregate'];
|
|
678
|
-
return {
|
|
680
|
+
return {
|
|
681
|
+
q,
|
|
682
|
+
hash,
|
|
683
|
+
store: newStore,
|
|
684
|
+
attrsStore: newAttrsStore,
|
|
685
|
+
pageInfo,
|
|
686
|
+
aggregate,
|
|
687
|
+
};
|
|
679
688
|
});
|
|
680
689
|
|
|
681
|
-
updates.forEach(
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
690
|
+
updates.forEach(
|
|
691
|
+
({ hash, q, store, attrsStore, pageInfo, aggregate }) => {
|
|
692
|
+
this.querySubs.updateInPlace((prev) => {
|
|
693
|
+
if (!prev[hash]) {
|
|
694
|
+
this._log.error('Missing value in querySubs', { hash, q });
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
prev[hash].result = {
|
|
698
|
+
store,
|
|
699
|
+
attrsStore,
|
|
700
|
+
pageInfo,
|
|
701
|
+
aggregate,
|
|
702
|
+
processedTxId,
|
|
703
|
+
};
|
|
704
|
+
});
|
|
705
|
+
},
|
|
706
|
+
);
|
|
696
707
|
|
|
697
708
|
this._cleanupPendingMutationsQueries();
|
|
698
709
|
|
|
@@ -919,7 +930,7 @@ export default class Reactor {
|
|
|
919
930
|
}
|
|
920
931
|
|
|
921
932
|
_setAttrs(attrs) {
|
|
922
|
-
this.attrs = new sts.
|
|
933
|
+
this.attrs = new sts.AttrsStoreClass(
|
|
923
934
|
attrs.reduce((acc, attr) => {
|
|
924
935
|
acc[attr.id] = attr;
|
|
925
936
|
return acc;
|
|
@@ -1195,7 +1206,7 @@ export default class Reactor {
|
|
|
1195
1206
|
}
|
|
1196
1207
|
|
|
1197
1208
|
if (!deletedAttrIds.size && !pendingAttrs.length) {
|
|
1198
|
-
return this.attrs || new sts.
|
|
1209
|
+
return this.attrs || new sts.AttrsStoreClass({}, this._linkIndex);
|
|
1199
1210
|
}
|
|
1200
1211
|
|
|
1201
1212
|
const attrs = { ...(this.attrs?.attrs || {}) };
|
|
@@ -1206,7 +1217,7 @@ export default class Reactor {
|
|
|
1206
1217
|
delete attrs[id];
|
|
1207
1218
|
}
|
|
1208
1219
|
|
|
1209
|
-
return new sts.
|
|
1220
|
+
return new sts.AttrsStoreClass(attrs, this._linkIndex);
|
|
1210
1221
|
}
|
|
1211
1222
|
|
|
1212
1223
|
/** Runs instaql on a query and a store */
|
|
@@ -1239,14 +1250,10 @@ export default class Reactor {
|
|
|
1239
1250
|
attrsStore,
|
|
1240
1251
|
pendingMutations,
|
|
1241
1252
|
);
|
|
1242
|
-
const newStore =
|
|
1243
|
-
store,
|
|
1244
|
-
attrsStore,
|
|
1245
|
-
mutations,
|
|
1246
|
-
processedTxId,
|
|
1247
|
-
);
|
|
1253
|
+
const { store: newStore, attrsStore: newAttrsStore } =
|
|
1254
|
+
this._applyOptimisticUpdates(store, attrsStore, mutations, processedTxId);
|
|
1248
1255
|
const resp = instaql(
|
|
1249
|
-
{ store: newStore, attrsStore, pageInfo, aggregate },
|
|
1256
|
+
{ store: newStore, attrsStore: newAttrsStore, pageInfo, aggregate },
|
|
1250
1257
|
q,
|
|
1251
1258
|
);
|
|
1252
1259
|
|
|
@@ -1256,10 +1263,12 @@ export default class Reactor {
|
|
|
1256
1263
|
_applyOptimisticUpdates(store, attrsStore, mutations, processedTxId) {
|
|
1257
1264
|
for (const [_, mut] of mutations) {
|
|
1258
1265
|
if (!mut['tx-id'] || (processedTxId && mut['tx-id'] > processedTxId)) {
|
|
1259
|
-
|
|
1266
|
+
const result = sts.transact(store, attrsStore, mut['tx-steps']);
|
|
1267
|
+
store = result.store;
|
|
1268
|
+
attrsStore = result.attrsStore;
|
|
1260
1269
|
}
|
|
1261
1270
|
}
|
|
1262
|
-
return store;
|
|
1271
|
+
return { store, attrsStore };
|
|
1263
1272
|
}
|
|
1264
1273
|
|
|
1265
1274
|
/** Re-run instaql and call all callbacks with new data */
|
package/src/instaml.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
allMapValues,
|
|
3
3
|
AttrsStore,
|
|
4
|
+
AttrsStoreClass,
|
|
4
5
|
getAttrByFwdIdentName,
|
|
5
6
|
getAttrByReverseIdentName,
|
|
6
7
|
Store,
|
|
@@ -205,7 +206,7 @@ function expandUnlink({ attrsStore }: Ctx, [etype, eidA, obj]) {
|
|
|
205
206
|
}
|
|
206
207
|
|
|
207
208
|
function checkEntityExists(
|
|
208
|
-
stores: (Store | undefined)[],
|
|
209
|
+
stores: (Store | undefined)[] | undefined,
|
|
209
210
|
attrsStore: AttrsStore,
|
|
210
211
|
etype: string,
|
|
211
212
|
eid: string,
|
|
@@ -241,10 +242,10 @@ function checkEntityExists(
|
|
|
241
242
|
}
|
|
242
243
|
|
|
243
244
|
type Ctx = {
|
|
244
|
-
stores
|
|
245
|
+
stores?: (Store | undefined)[];
|
|
245
246
|
attrsStore: AttrsStore;
|
|
246
|
-
schema
|
|
247
|
-
useDateObjects
|
|
247
|
+
schema?: Schema;
|
|
248
|
+
useDateObjects?: boolean | null;
|
|
248
249
|
};
|
|
249
250
|
|
|
250
251
|
function convertOpts({ stores, attrsStore }: Ctx, [etype, eid, obj_, opts]) {
|
|
@@ -458,7 +459,7 @@ function refPropsFromSchema(schema: Schema, etype, label) {
|
|
|
458
459
|
}
|
|
459
460
|
|
|
460
461
|
function createRefAttr(
|
|
461
|
-
schema: Schema,
|
|
462
|
+
schema: Schema | undefined,
|
|
462
463
|
etype: string,
|
|
463
464
|
label: string,
|
|
464
465
|
props?: Partial<InstantDBAttr> | undefined,
|
|
@@ -593,7 +594,7 @@ function createMissingAttrs(
|
|
|
593
594
|
identName.indexOf('.') !== -1 &&
|
|
594
595
|
// attr names can have `.` in them, so use the attr we find with a `.`
|
|
595
596
|
// before assuming it's a ref lookup.
|
|
596
|
-
!
|
|
597
|
+
!attrByFwdIdent(etype, identName)
|
|
597
598
|
);
|
|
598
599
|
}
|
|
599
600
|
|
|
@@ -694,7 +695,7 @@ function createMissingAttrs(
|
|
|
694
695
|
for (const attr of localAttrs) {
|
|
695
696
|
nextAttrs[attr.id] = attr;
|
|
696
697
|
}
|
|
697
|
-
return [new
|
|
698
|
+
return [new AttrsStoreClass(nextAttrs, attrsStore.linkIndex), addOps];
|
|
698
699
|
}
|
|
699
700
|
return [attrsStore, addOps];
|
|
700
701
|
}
|
package/src/instaql.ts
CHANGED
package/src/store.ts
CHANGED
|
@@ -18,23 +18,23 @@ export type Store = {
|
|
|
18
18
|
eav: Map<string, Map<string, Map<any, Triple>>>;
|
|
19
19
|
aev: Map<string, Map<string, Map<any, Triple>>>;
|
|
20
20
|
vae: Map<any, Map<string, Map<string, Triple>>>;
|
|
21
|
-
useDateObjects: boolean | null;
|
|
22
|
-
cardinalityInference: boolean | null;
|
|
21
|
+
useDateObjects: boolean | null | undefined;
|
|
22
|
+
cardinalityInference: boolean | null | undefined;
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
type StoreJsonVersion0 = {
|
|
26
26
|
__type: 'store';
|
|
27
27
|
attrs: Attrs;
|
|
28
28
|
triples: Triple[];
|
|
29
|
-
cardinalityInference: boolean | null;
|
|
29
|
+
cardinalityInference: boolean | null | undefined;
|
|
30
30
|
linkIndex: LinkIndex | null;
|
|
31
|
-
useDateObjects: boolean | null;
|
|
31
|
+
useDateObjects: boolean | null | undefined;
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
type StoreJsonVersion1 = {
|
|
35
35
|
triples: Triple[];
|
|
36
|
-
cardinalityInference: boolean | null;
|
|
37
|
-
useDateObjects: boolean | null;
|
|
36
|
+
cardinalityInference: boolean | null | undefined;
|
|
37
|
+
useDateObjects: boolean | null | undefined;
|
|
38
38
|
version: 1;
|
|
39
39
|
};
|
|
40
40
|
|
|
@@ -45,7 +45,22 @@ export type AttrsStoreJson = {
|
|
|
45
45
|
linkIndex: LinkIndex | null;
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
-
export
|
|
48
|
+
export interface AttrsStore {
|
|
49
|
+
attrs: Attrs;
|
|
50
|
+
linkIndex: LinkIndex | null;
|
|
51
|
+
resetAttrIndexes(): void;
|
|
52
|
+
addAttr(attr: InstantDBAttr): void;
|
|
53
|
+
deleteAttr(attrId: string): void;
|
|
54
|
+
updateAttr(partialAttr: Partial<InstantDBAttr> & { id: string }): void;
|
|
55
|
+
getAttr(id: string): InstantDBAttr | undefined;
|
|
56
|
+
blobAttrs: Map<string, Map<string, InstantDBAttr>>;
|
|
57
|
+
primaryKeys: Map<string, InstantDBAttr>;
|
|
58
|
+
forwardIdents: Map<string, Map<string, InstantDBAttr>>;
|
|
59
|
+
revIdents: Map<string, Map<string, InstantDBAttr>>;
|
|
60
|
+
toJSON(): AttrsStoreJson;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class AttrsStoreClass implements AttrsStore {
|
|
49
64
|
public attrs: Attrs;
|
|
50
65
|
public linkIndex: LinkIndex | null;
|
|
51
66
|
private _blobAttrs: Map<string, Map<string, InstantDBAttr>> | null = null;
|
|
@@ -53,7 +68,6 @@ export class AttrsStore {
|
|
|
53
68
|
private _forwardIdents: Map<string, Map<string, InstantDBAttr>> | null = null;
|
|
54
69
|
private _revIdents: Map<string, Map<string, InstantDBAttr>> | null = null;
|
|
55
70
|
constructor(attrs: Attrs, linkIndex: LinkIndex | null) {
|
|
56
|
-
console.log('attrs init', new Error('trace'));
|
|
57
71
|
this.attrs = attrs;
|
|
58
72
|
this.linkIndex = linkIndex;
|
|
59
73
|
}
|
|
@@ -187,19 +201,22 @@ function deleteInMap(m, path) {
|
|
|
187
201
|
deleteInMap(m.get(head), tail);
|
|
188
202
|
}
|
|
189
203
|
|
|
190
|
-
function setInMap(m, path, value) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
204
|
+
function setInMap(m: Map<any, any>, path: any[], value: any) {
|
|
205
|
+
let current = m;
|
|
206
|
+
const lastI = path.length - 1;
|
|
207
|
+
for (let i = 0; i < lastI; i++) {
|
|
208
|
+
const part = path[i];
|
|
209
|
+
|
|
210
|
+
let nextMap = current.get(part);
|
|
211
|
+
if (nextMap === undefined) {
|
|
212
|
+
nextMap = new Map();
|
|
213
|
+
current.set(part, nextMap);
|
|
214
|
+
}
|
|
215
|
+
current = nextMap;
|
|
195
216
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
if (!nextM) {
|
|
199
|
-
nextM = new Map();
|
|
200
|
-
m.set(head, nextM);
|
|
217
|
+
if (lastI > -1) {
|
|
218
|
+
current.set(path[lastI], value);
|
|
201
219
|
}
|
|
202
|
-
setInMap(nextM, tail, value);
|
|
203
220
|
}
|
|
204
221
|
|
|
205
222
|
function isDateAttr(attr: InstantDBAttr) {
|
|
@@ -209,7 +226,7 @@ function isDateAttr(attr: InstantDBAttr) {
|
|
|
209
226
|
function createTripleIndexes(
|
|
210
227
|
attrsStore: AttrsStore,
|
|
211
228
|
triples: Triple[],
|
|
212
|
-
useDateObjects: boolean | null,
|
|
229
|
+
useDateObjects: boolean | null | undefined,
|
|
213
230
|
): Pick<Store, 'eav' | 'aev' | 'vae'> {
|
|
214
231
|
const eav = new Map();
|
|
215
232
|
const aev = new Map();
|
|
@@ -286,10 +303,10 @@ export function attrsStoreFromJSON(
|
|
|
286
303
|
storeJSON: StoreJson | null,
|
|
287
304
|
): AttrsStore | undefined {
|
|
288
305
|
if (attrsStoreJSON) {
|
|
289
|
-
return new
|
|
306
|
+
return new AttrsStoreClass(attrsStoreJSON.attrs, attrsStoreJSON.linkIndex);
|
|
290
307
|
}
|
|
291
308
|
if (storeJSON && '__type' in storeJSON) {
|
|
292
|
-
return new
|
|
309
|
+
return new AttrsStoreClass(storeJSON.attrs, storeJSON.linkIndex);
|
|
293
310
|
}
|
|
294
311
|
}
|
|
295
312
|
|
|
@@ -304,8 +321,8 @@ export function hasEntity(store: Store, e: string) {
|
|
|
304
321
|
export function createStore(
|
|
305
322
|
attrsStore: AttrsStore,
|
|
306
323
|
triples: Triple[],
|
|
307
|
-
enableCardinalityInference
|
|
308
|
-
useDateObjects
|
|
324
|
+
enableCardinalityInference?: boolean | null,
|
|
325
|
+
useDateObjects?: boolean | null,
|
|
309
326
|
): Store {
|
|
310
327
|
const store = createTripleIndexes(
|
|
311
328
|
attrsStore,
|
|
@@ -876,7 +893,11 @@ function findTriple(
|
|
|
876
893
|
return getInMap(store.eav, [eid, aid]);
|
|
877
894
|
}
|
|
878
895
|
|
|
879
|
-
export function transact(
|
|
896
|
+
export function transact(
|
|
897
|
+
store: Store,
|
|
898
|
+
attrsStore: AttrsStore,
|
|
899
|
+
txSteps,
|
|
900
|
+
): { store: Store; attrsStore: AttrsStore } {
|
|
880
901
|
const txStepsFiltered = txSteps.filter(
|
|
881
902
|
([action, eid, attrId, value, opts]) => {
|
|
882
903
|
if (action !== 'add-triple' && action !== 'deep-merge-triple') {
|
|
@@ -915,9 +936,19 @@ export function transact(store: Store, attrsStore: AttrsStore, txSteps) {
|
|
|
915
936
|
},
|
|
916
937
|
);
|
|
917
938
|
|
|
918
|
-
return create(
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
939
|
+
return create(
|
|
940
|
+
{ store, attrsStore },
|
|
941
|
+
(draft) => {
|
|
942
|
+
txStepsFiltered.forEach((txStep) => {
|
|
943
|
+
applyTxStep(draft.store, draft.attrsStore, txStep);
|
|
944
|
+
});
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
mark: (target) => {
|
|
948
|
+
if (target instanceof AttrsStoreClass) {
|
|
949
|
+
return 'immutable';
|
|
950
|
+
}
|
|
951
|
+
},
|
|
952
|
+
},
|
|
953
|
+
);
|
|
923
954
|
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { bench } from 'vitest';
|
|
2
|
-
|
|
3
|
-
import zenecaAttrs from './data/zeneca/attrs.json';
|
|
4
|
-
import zenecaTriples from './data/zeneca/triples.json';
|
|
5
|
-
import { createStore } from '../../src/store';
|
|
6
|
-
import query from '../../src/instaql';
|
|
7
|
-
|
|
8
|
-
const zenecaIdToAttr = zenecaAttrs.reduce((res, x) => {
|
|
9
|
-
res[x.id] = x;
|
|
10
|
-
return res;
|
|
11
|
-
}, {});
|
|
12
|
-
|
|
13
|
-
const store = createStore(zenecaIdToAttr, zenecaTriples);
|
|
14
|
-
|
|
15
|
-
bench('big query', () => {
|
|
16
|
-
query(
|
|
17
|
-
{ store },
|
|
18
|
-
{
|
|
19
|
-
users: {
|
|
20
|
-
bookshelves: {
|
|
21
|
-
books: {},
|
|
22
|
-
users: {
|
|
23
|
-
bookshelves: {},
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
);
|
|
29
|
-
});
|