@instantdb/core 0.22.88 → 0.22.89-experimental.drewh-fix-export.20277749804.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.
Files changed (65) hide show
  1. package/__tests__/src/Reactor.test.js +18 -11
  2. package/__tests__/src/{datalog.test.js → datalog.test.ts} +17 -5
  3. package/__tests__/src/{instaml.test.js → instaml.test.ts} +183 -119
  4. package/__tests__/src/instaql.bench.ts +34 -0
  5. package/__tests__/src/{instaql.test.js → instaql.test.ts} +342 -455
  6. package/__tests__/src/instaqlInference.test.js +13 -9
  7. package/__tests__/src/{store.test.js → store.test.ts} +215 -212
  8. package/dist/commonjs/Reactor.d.ts +23 -6
  9. package/dist/commonjs/Reactor.d.ts.map +1 -1
  10. package/dist/commonjs/Reactor.js +110 -45
  11. package/dist/commonjs/Reactor.js.map +1 -1
  12. package/dist/commonjs/SyncTable.d.ts +4 -1
  13. package/dist/commonjs/SyncTable.d.ts.map +1 -1
  14. package/dist/commonjs/SyncTable.js +35 -37
  15. package/dist/commonjs/SyncTable.js.map +1 -1
  16. package/dist/commonjs/instaml.d.ts +17 -4
  17. package/dist/commonjs/instaml.d.ts.map +1 -1
  18. package/dist/commonjs/instaml.js +115 -82
  19. package/dist/commonjs/instaml.js.map +1 -1
  20. package/dist/commonjs/instaql.d.ts +4 -3
  21. package/dist/commonjs/instaql.d.ts.map +1 -1
  22. package/dist/commonjs/instaql.js +65 -63
  23. package/dist/commonjs/instaql.js.map +1 -1
  24. package/dist/commonjs/reactorTypes.d.ts +29 -0
  25. package/dist/commonjs/reactorTypes.d.ts.map +1 -0
  26. package/dist/commonjs/reactorTypes.js +3 -0
  27. package/dist/commonjs/reactorTypes.js.map +1 -0
  28. package/dist/commonjs/store.d.ts +67 -25
  29. package/dist/commonjs/store.d.ts.map +1 -1
  30. package/dist/commonjs/store.js +177 -81
  31. package/dist/commonjs/store.js.map +1 -1
  32. package/dist/esm/Reactor.d.ts +23 -6
  33. package/dist/esm/Reactor.d.ts.map +1 -1
  34. package/dist/esm/Reactor.js +111 -46
  35. package/dist/esm/Reactor.js.map +1 -1
  36. package/dist/esm/SyncTable.d.ts +4 -1
  37. package/dist/esm/SyncTable.d.ts.map +1 -1
  38. package/dist/esm/SyncTable.js +35 -37
  39. package/dist/esm/SyncTable.js.map +1 -1
  40. package/dist/esm/instaml.d.ts +17 -4
  41. package/dist/esm/instaml.d.ts.map +1 -1
  42. package/dist/esm/instaml.js +112 -77
  43. package/dist/esm/instaml.js.map +1 -1
  44. package/dist/esm/instaql.d.ts +4 -3
  45. package/dist/esm/instaql.d.ts.map +1 -1
  46. package/dist/esm/instaql.js +65 -63
  47. package/dist/esm/instaql.js.map +1 -1
  48. package/dist/esm/reactorTypes.d.ts +29 -0
  49. package/dist/esm/reactorTypes.d.ts.map +1 -0
  50. package/dist/esm/reactorTypes.js +2 -0
  51. package/dist/esm/reactorTypes.js.map +1 -0
  52. package/dist/esm/store.d.ts +67 -25
  53. package/dist/esm/store.d.ts.map +1 -1
  54. package/dist/esm/store.js +174 -81
  55. package/dist/esm/store.js.map +1 -1
  56. package/dist/standalone/index.js +1605 -1415
  57. package/dist/standalone/index.umd.cjs +3 -3
  58. package/package.json +2 -2
  59. package/src/Reactor.js +152 -75
  60. package/src/SyncTable.ts +85 -45
  61. package/src/{instaml.js → instaml.ts} +201 -96
  62. package/src/instaql.ts +88 -62
  63. package/src/reactorTypes.ts +32 -0
  64. package/src/store.ts +257 -101
  65. package/__tests__/src/instaql.bench.js +0 -29
package/src/store.ts CHANGED
@@ -7,34 +7,163 @@ import { LinkIndex } from './utils/linkIndex.ts';
7
7
  type Triple = [string, string, any, number];
8
8
  type Attrs = Record<string, InstantDBAttr>;
9
9
 
10
- type AttrIndexes = {
10
+ interface AttrIndexes {
11
11
  blobAttrs: Map<string, Map<string, InstantDBAttr>>;
12
12
  primaryKeys: Map<string, InstantDBAttr>;
13
13
  forwardIdents: Map<string, Map<string, InstantDBAttr>>;
14
14
  revIdents: Map<string, Map<string, InstantDBAttr>>;
15
- };
15
+ }
16
16
 
17
17
  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
- attrs: Attrs;
23
- attrIndexes: AttrIndexes;
24
- cardinalityInference: boolean | null;
25
- linkIndex: LinkIndex | null;
26
- __type: 'store';
21
+ useDateObjects: boolean | null | undefined;
22
+ cardinalityInference: boolean | null | undefined;
27
23
  };
28
24
 
29
- export type StoreJson = {
25
+ type StoreJsonVersion0 = {
30
26
  __type: 'store';
31
27
  attrs: Attrs;
32
28
  triples: Triple[];
33
- cardinalityInference: boolean | null;
29
+ cardinalityInference: boolean | null | undefined;
30
+ linkIndex: LinkIndex | null;
31
+ useDateObjects: boolean | null | undefined;
32
+ };
33
+
34
+ type StoreJsonVersion1 = {
35
+ triples: Triple[];
36
+ cardinalityInference: boolean | null | undefined;
37
+ useDateObjects: boolean | null | undefined;
38
+ version: 1;
39
+ };
40
+
41
+ export type StoreJson = StoreJsonVersion0 | StoreJsonVersion1;
42
+
43
+ export type AttrsStoreJson = {
44
+ attrs: Attrs;
34
45
  linkIndex: LinkIndex | null;
35
- useDateObjects: boolean | null;
36
46
  };
37
47
 
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 {
64
+ public attrs: Attrs;
65
+ public linkIndex: LinkIndex | null;
66
+ private _blobAttrs: Map<string, Map<string, InstantDBAttr>> | null = null;
67
+ private _primaryKeys: Map<string, InstantDBAttr> | null = null;
68
+ private _forwardIdents: Map<string, Map<string, InstantDBAttr>> | null = null;
69
+ private _revIdents: Map<string, Map<string, InstantDBAttr>> | null = null;
70
+ constructor(attrs: Attrs, linkIndex: LinkIndex | null) {
71
+ this.attrs = attrs;
72
+ this.linkIndex = linkIndex;
73
+ }
74
+
75
+ public resetAttrIndexes() {
76
+ this._blobAttrs = null;
77
+ this._primaryKeys = null;
78
+ this._forwardIdents = null;
79
+ this._revIdents = null;
80
+ }
81
+
82
+ public addAttr(attr: InstantDBAttr) {
83
+ this.attrs[attr.id] = attr;
84
+ this.resetAttrIndexes();
85
+ }
86
+
87
+ public deleteAttr(attrId: string) {
88
+ delete this.attrs[attrId];
89
+ this.resetAttrIndexes();
90
+ }
91
+
92
+ public updateAttr(partialAttr: Partial<InstantDBAttr> & { id: string }) {
93
+ const attr = this.attrs[partialAttr.id];
94
+ if (!attr) return;
95
+ this.attrs[partialAttr.id] = { ...attr, ...partialAttr };
96
+ this.resetAttrIndexes();
97
+ }
98
+
99
+ public getAttr(id: string): InstantDBAttr | undefined {
100
+ return this.attrs[id];
101
+ }
102
+
103
+ get blobAttrs(): Map<string, Map<string, InstantDBAttr>> {
104
+ if (this._blobAttrs) {
105
+ return this._blobAttrs;
106
+ }
107
+ this._blobAttrs = new Map();
108
+ for (const attr of Object.values(this.attrs)) {
109
+ if (isBlob(attr)) {
110
+ const [_, fwdEtype, fwdLabel] = attr['forward-identity'];
111
+ setInMap(this.blobAttrs, [fwdEtype, fwdLabel], attr);
112
+ }
113
+ }
114
+ return this._blobAttrs;
115
+ }
116
+
117
+ get primaryKeys(): Map<string, InstantDBAttr> {
118
+ if (this._primaryKeys) {
119
+ return this._primaryKeys;
120
+ }
121
+ this._primaryKeys = new Map();
122
+
123
+ for (const attr of Object.values(this.attrs)) {
124
+ if (attr['primary?']) {
125
+ const [_, fwdEtype] = attr['forward-identity'];
126
+ setInMap(this._primaryKeys, [fwdEtype], attr);
127
+ }
128
+ }
129
+ return this._primaryKeys;
130
+ }
131
+
132
+ get forwardIdents(): Map<string, Map<string, InstantDBAttr>> {
133
+ if (this._forwardIdents) {
134
+ return this._forwardIdents;
135
+ }
136
+ this._forwardIdents = new Map();
137
+
138
+ for (const attr of Object.values(this.attrs)) {
139
+ const fwdIdent = attr['forward-identity'];
140
+ const [_, fwdEtype, fwdLabel] = fwdIdent;
141
+ setInMap(this._forwardIdents, [fwdEtype, fwdLabel], attr);
142
+ }
143
+ return this._forwardIdents;
144
+ }
145
+
146
+ get revIdents(): Map<string, Map<string, InstantDBAttr>> {
147
+ if (this._revIdents) {
148
+ return this._revIdents;
149
+ }
150
+ this._revIdents = new Map();
151
+
152
+ for (const attr of Object.values(this.attrs)) {
153
+ const revIdent = attr['reverse-identity'];
154
+ if (revIdent) {
155
+ const [_, revEtype, revLabel] = revIdent;
156
+ setInMap(this._revIdents, [revEtype, revLabel], attr);
157
+ }
158
+ }
159
+ return this._revIdents;
160
+ }
161
+
162
+ public toJSON(): AttrsStoreJson {
163
+ return { attrs: this.attrs, linkIndex: this.linkIndex };
164
+ }
165
+ }
166
+
38
167
  function hasEA(attr: InstantDBAttr) {
39
168
  return attr['cardinality'] === 'one';
40
169
  }
@@ -66,19 +195,22 @@ function deleteInMap(m, path) {
66
195
  deleteInMap(m.get(head), tail);
67
196
  }
68
197
 
69
- function setInMap(m, path, value) {
70
- if (path.length === 0) throw new Error('path must have at least one element');
71
- if (path.length === 1) {
72
- m.set(path[0], value);
73
- return;
198
+ function setInMap(m: Map<any, any>, path: any[], value: any) {
199
+ let current = m;
200
+ const lastI = path.length - 1;
201
+ for (let i = 0; i < lastI; i++) {
202
+ const part = path[i];
203
+
204
+ let nextMap = current.get(part);
205
+ if (nextMap === undefined) {
206
+ nextMap = new Map();
207
+ current.set(part, nextMap);
208
+ }
209
+ current = nextMap;
74
210
  }
75
- const [head, ...tail] = path;
76
- let nextM = m.get(head);
77
- if (!nextM) {
78
- nextM = new Map();
79
- m.set(head, nextM);
211
+ if (lastI > -1) {
212
+ current.set(path[lastI], value);
80
213
  }
81
- setInMap(nextM, tail, value);
82
214
  }
83
215
 
84
216
  function isDateAttr(attr: InstantDBAttr) {
@@ -86,18 +218,18 @@ function isDateAttr(attr: InstantDBAttr) {
86
218
  }
87
219
 
88
220
  function createTripleIndexes(
89
- attrs: Record<string, InstantDBAttr>,
221
+ attrsStore: AttrsStore,
90
222
  triples: Triple[],
91
- useDateObjects: boolean | null,
223
+ useDateObjects: boolean | null | undefined,
92
224
  ): Pick<Store, 'eav' | 'aev' | 'vae'> {
93
225
  const eav = new Map();
94
226
  const aev = new Map();
95
227
  const vae = new Map();
96
228
  for (const triple of triples) {
97
- let [eid, aid, v, t] = triple;
98
- const attr = getAttr(attrs, aid);
229
+ let [eid, aid, v] = triple;
230
+ const attr = attrsStore.getAttr(aid);
99
231
  if (!attr) {
100
- console.warn('no such attr', eid, attrs);
232
+ console.warn('no such attr', aid, eid);
101
233
  continue;
102
234
  }
103
235
 
@@ -142,27 +274,36 @@ function createAttrIndexes(attrs: Record<string, InstantDBAttr>): AttrIndexes {
142
274
  return { blobAttrs, primaryKeys, forwardIdents, revIdents };
143
275
  }
144
276
 
145
- export function toJSON(store: Store): StoreJson {
277
+ export function toJSON(store: Store): StoreJsonVersion1 {
146
278
  return {
147
- __type: store.__type,
148
- attrs: store.attrs,
149
279
  triples: allMapValues(store.eav, 3),
150
280
  cardinalityInference: store.cardinalityInference,
151
- linkIndex: store.linkIndex,
152
281
  useDateObjects: store.useDateObjects,
282
+ version: 1,
153
283
  };
154
284
  }
155
285
 
156
- export function fromJSON(storeJSON: StoreJson): Store {
286
+ export function fromJSON(attrsStore: AttrsStore, storeJSON: StoreJson): Store {
157
287
  return createStore(
158
- storeJSON.attrs,
288
+ attrsStore,
159
289
  storeJSON.triples,
160
290
  storeJSON.cardinalityInference,
161
- storeJSON.linkIndex,
162
291
  storeJSON.useDateObjects,
163
292
  );
164
293
  }
165
294
 
295
+ export function attrsStoreFromJSON(
296
+ attrsStoreJSON: AttrsStoreJson | null,
297
+ storeJSON: StoreJson | null,
298
+ ): AttrsStore | undefined {
299
+ if (attrsStoreJSON) {
300
+ return new AttrsStoreClass(attrsStoreJSON.attrs, attrsStoreJSON.linkIndex);
301
+ }
302
+ if (storeJSON && '__type' in storeJSON) {
303
+ return new AttrsStoreClass(storeJSON.attrs, storeJSON.linkIndex);
304
+ }
305
+ }
306
+
166
307
  export function hasTriple(store: Store, [e, a, v]: [string, string, any]) {
167
308
  return getInMap(store.eav, [e, a, v]) !== undefined;
168
309
  }
@@ -171,29 +312,19 @@ export function hasEntity(store: Store, e: string) {
171
312
  return getInMap(store.eav, [e]) !== undefined;
172
313
  }
173
314
 
174
- function resetAttrIndexes(store: Store) {
175
- store.attrIndexes = createAttrIndexes(store.attrs);
176
- }
177
-
178
315
  export function createStore(
179
- attrs: Record<string, InstantDBAttr>,
316
+ attrsStore: AttrsStore,
180
317
  triples: Triple[],
181
- enableCardinalityInference: boolean | null,
182
- linkIndex: LinkIndex | null,
183
- useDateObjects: boolean | null,
318
+ enableCardinalityInference?: boolean | null,
319
+ useDateObjects?: boolean | null,
184
320
  ): Store {
185
321
  const store = createTripleIndexes(
186
- attrs,
322
+ attrsStore,
187
323
  triples,
188
324
  useDateObjects,
189
325
  ) as unknown as Store;
190
- store.useDateObjects = useDateObjects;
191
- store.attrs = attrs;
192
- store.attrIndexes = createAttrIndexes(attrs);
193
326
  store.cardinalityInference = enableCardinalityInference;
194
- store.linkIndex = linkIndex;
195
- store.__type = 'store';
196
-
327
+ store.useDateObjects = useDateObjects;
197
328
  return store;
198
329
  }
199
330
 
@@ -254,13 +385,17 @@ function resolveLookupRefs(store: Store, triple: Triple): Triple | null {
254
385
  }
255
386
  }
256
387
 
257
- export function retractTriple(store: Store, rawTriple: Triple): void {
388
+ export function retractTriple(
389
+ store: Store,
390
+ attrsStore: AttrsStore,
391
+ rawTriple: Triple,
392
+ ): void {
258
393
  const triple = resolveLookupRefs(store, rawTriple);
259
394
  if (!triple) {
260
395
  return;
261
396
  }
262
397
  const [eid, aid, v] = triple;
263
- const attr = getAttr(store.attrs, aid);
398
+ const attr = attrsStore.getAttr(aid);
264
399
  if (!attr) {
265
400
  return;
266
401
  }
@@ -310,13 +445,17 @@ function getCreatedAt(
310
445
  return createdAt || Date.now() * 10 + _seed++;
311
446
  }
312
447
 
313
- export function addTriple(store: Store, rawTriple: Triple) {
448
+ export function addTriple(
449
+ store: Store,
450
+ attrsStore: AttrsStore,
451
+ rawTriple: Triple,
452
+ ) {
314
453
  const triple = resolveLookupRefs(store, rawTriple);
315
454
  if (!triple) {
316
455
  return;
317
456
  }
318
457
  let [eid, aid, v] = triple;
319
- const attr = getAttr(store.attrs, aid);
458
+ const attr = attrsStore.getAttr(aid);
320
459
  if (!attr) {
321
460
  // (XXX): Due to the way we're handling attrs, it's
322
461
  // possible to enter a state where we receive a triple without an attr.
@@ -349,14 +488,14 @@ export function addTriple(store: Store, rawTriple: Triple) {
349
488
  }
350
489
  }
351
490
 
352
- function mergeTriple(store: Store, rawTriple: Triple) {
491
+ function mergeTriple(store: Store, attrsStore: AttrsStore, rawTriple: Triple) {
353
492
  const triple = resolveLookupRefs(store, rawTriple);
354
493
  if (!triple) {
355
494
  return;
356
495
  }
357
496
 
358
497
  const [eid, aid, update] = triple;
359
- const attr = getAttr(store.attrs, aid);
498
+ const attr = attrsStore.getAttr(aid);
360
499
 
361
500
  if (!attr) return;
362
501
 
@@ -380,9 +519,10 @@ function mergeTriple(store: Store, rawTriple: Triple) {
380
519
  ];
381
520
 
382
521
  setInMap(store.eav, [eid, aid], new Map([[updatedValue, enhancedTriple]]));
522
+ setInMap(store.aev, [aid, eid], new Map([[updatedValue, enhancedTriple]]));
383
523
  }
384
524
 
385
- function deleteEntity(store: Store, args: any[]) {
525
+ function deleteEntity(store: Store, attrsStore: AttrsStore, args: any[]) {
386
526
  const [lookup, etype] = args;
387
527
  const triple = resolveLookupRefs(store, [lookup] as unknown as Triple);
388
528
 
@@ -395,13 +535,13 @@ function deleteEntity(store: Store, args: any[]) {
395
535
  const eMap = store.eav.get(id);
396
536
  if (eMap) {
397
537
  for (const a of eMap.keys()) {
398
- const attr = store.attrs[a];
538
+ const attr = attrsStore.getAttr(a);
399
539
 
400
540
  // delete cascade refs
401
541
  if (attr && attr['on-delete-reverse'] === 'cascade') {
402
542
  allMapValues(eMap.get(a), 1).forEach(
403
543
  ([e, a, v]: [string, string, any]) =>
404
- deleteEntity(store, [v, attr['reverse-identity']?.[1]]),
544
+ deleteEntity(store, attrsStore, [v, attr['reverse-identity']?.[1]]),
405
545
  );
406
546
  }
407
547
 
@@ -430,7 +570,7 @@ function deleteEntity(store: Store, args: any[]) {
430
570
  if (vaeTriples) {
431
571
  vaeTriples.forEach((triple: Triple) => {
432
572
  const [e, a, v] = triple;
433
- const attr = store.attrs[a];
573
+ const attr = attrsStore.getAttr(a);
434
574
  if (!etype || !attr || attr['reverse-identity']?.[1] === etype) {
435
575
  deleteInMap(store.eav, [e, a, v]);
436
576
  deleteInMap(store.aev, [a, e, v]);
@@ -441,7 +581,7 @@ function deleteEntity(store: Store, args: any[]) {
441
581
  attr['on-delete'] === 'cascade' &&
442
582
  attr['reverse-identity']?.[1] === etype
443
583
  ) {
444
- deleteEntity(store, [e, attr['forward-identity']?.[1]]);
584
+ deleteEntity(store, attrsStore, [e, attr['forward-identity']?.[1]]);
445
585
  }
446
586
  });
447
587
  }
@@ -458,9 +598,9 @@ function deleteEntity(store: Store, args: any[]) {
458
598
  // * We could batch this reset at the end
459
599
  // * We could add an ave index for all triples, so removing the
460
600
  // right triples is easy and fast.
461
- function resetIndexMap(store: Store, newTriples: Triple[]) {
601
+ function resetIndexMap(store: Store, attrsStore, newTriples: Triple[]) {
462
602
  const newIndexMap = createTripleIndexes(
463
- store.attrs,
603
+ attrsStore,
464
604
  newTriples,
465
605
  store.useDateObjects,
466
606
  );
@@ -469,57 +609,55 @@ function resetIndexMap(store: Store, newTriples: Triple[]) {
469
609
  });
470
610
  }
471
611
 
472
- function addAttr(store: Store, [attr]: [InstantDBAttr]) {
473
- store.attrs[attr.id] = attr;
474
- resetAttrIndexes(store);
612
+ function addAttr(attrsStore: AttrsStore, [attr]: [InstantDBAttr]) {
613
+ attrsStore.addAttr(attr);
475
614
  }
476
615
 
477
616
  function getAllTriples(store: Store): Triple[] {
478
617
  return allMapValues(store.eav, 3);
479
618
  }
480
619
 
481
- function deleteAttr(store: Store, [id]: [string]) {
482
- if (!store.attrs[id]) return;
620
+ function deleteAttr(store: Store, attrsStore: AttrsStore, [id]: [string]) {
621
+ if (!attrsStore.getAttr(id)) return;
483
622
  const newTriples = getAllTriples(store).filter(([_, aid]) => aid !== id);
484
- delete store.attrs[id];
485
- resetAttrIndexes(store);
486
- resetIndexMap(store, newTriples);
623
+ attrsStore.deleteAttr(id);
624
+ resetIndexMap(store, attrsStore, newTriples);
487
625
  }
488
626
 
489
627
  function updateAttr(
490
628
  store: Store,
629
+ attrsStore: AttrsStore,
491
630
  [partialAttr]: [Partial<InstantDBAttr> & { id: string }],
492
631
  ) {
493
- const attr = store.attrs[partialAttr.id];
632
+ const attr = attrsStore.getAttr(partialAttr.id);
494
633
  if (!attr) return;
495
- store.attrs[partialAttr.id] = { ...attr, ...partialAttr };
496
- resetAttrIndexes(store);
497
- resetIndexMap(store, getAllTriples(store));
634
+ attrsStore.updateAttr(partialAttr);
635
+ resetIndexMap(store, attrsStore, getAllTriples(store));
498
636
  }
499
637
 
500
- function applyTxStep(store: Store, txStep) {
638
+ function applyTxStep(store: Store, attrsStore: AttrsStore, txStep) {
501
639
  const [action, ...args] = txStep;
502
640
  switch (action) {
503
641
  case 'add-triple':
504
- addTriple(store, args);
642
+ addTriple(store, attrsStore, args);
505
643
  break;
506
644
  case 'deep-merge-triple':
507
- mergeTriple(store, args);
645
+ mergeTriple(store, attrsStore, args);
508
646
  break;
509
647
  case 'retract-triple':
510
- retractTriple(store, args);
648
+ retractTriple(store, attrsStore, args);
511
649
  break;
512
650
  case 'delete-entity':
513
- deleteEntity(store, args);
651
+ deleteEntity(store, attrsStore, args);
514
652
  break;
515
653
  case 'add-attr':
516
- addAttr(store, args);
654
+ addAttr(attrsStore, args);
517
655
  break;
518
656
  case 'delete-attr':
519
- deleteAttr(store, args);
657
+ deleteAttr(store, attrsStore, args);
520
658
  break;
521
659
  case 'update-attr':
522
- updateAttr(store, args);
660
+ updateAttr(store, attrsStore, args);
523
661
  break;
524
662
  case 'restore-attr':
525
663
  break;
@@ -700,35 +838,36 @@ export function getAsObject(
700
838
  }
701
839
 
702
840
  export function getAttrByFwdIdentName(
703
- store: Store,
841
+ attrsStore: AttrsStore,
704
842
  inputEtype: string,
705
843
  inputLabel: string,
706
844
  ) {
707
- return store.attrIndexes.forwardIdents.get(inputEtype)?.get(inputLabel);
845
+ return attrsStore.forwardIdents.get(inputEtype)?.get(inputLabel);
708
846
  }
709
847
 
710
848
  export function getAttrByReverseIdentName(
711
- store: Store,
849
+ attrsStore: AttrsStore,
712
850
  inputEtype: string,
713
851
  inputLabel: string,
714
852
  ) {
715
- return store.attrIndexes.revIdents.get(inputEtype)?.get(inputLabel);
853
+ return attrsStore.revIdents.get(inputEtype)?.get(inputLabel);
716
854
  }
717
855
 
718
- export function getBlobAttrs(store: Store, etype: string) {
719
- return store.attrIndexes.blobAttrs.get(etype);
856
+ export function getBlobAttrs(attrsStore: AttrsStore, etype: string) {
857
+ return attrsStore.blobAttrs.get(etype);
720
858
  }
721
859
 
722
- export function getPrimaryKeyAttr(store: Store, etype: string) {
723
- const fromPrimary = store.attrIndexes.primaryKeys.get(etype);
860
+ export function getPrimaryKeyAttr(attrsStore: AttrsStore, etype: string) {
861
+ const fromPrimary = attrsStore.primaryKeys.get(etype);
724
862
  if (fromPrimary) {
725
863
  return fromPrimary;
726
864
  }
727
- return store.attrIndexes.forwardIdents.get(etype)?.get('id');
865
+ return attrsStore.forwardIdents.get(etype)?.get('id');
728
866
  }
729
867
 
730
868
  function findTriple(
731
869
  store: Store,
870
+ attrsStore: AttrsStore,
732
871
  rawTriple: [string, string, any] | Triple,
733
872
  ): Triple | undefined {
734
873
  const triple = resolveLookupRefs(store, rawTriple as Triple);
@@ -737,7 +876,7 @@ function findTriple(
737
876
  }
738
877
 
739
878
  const [eid, aid, v] = triple;
740
- const attr = getAttr(store.attrs, aid);
879
+ const attr = attrsStore.getAttr(aid);
741
880
  if (!attr) {
742
881
  // (XXX): Due to the way we're handling attrs, it's
743
882
  // possible to enter a state where we receive a triple without an attr.
@@ -749,7 +888,11 @@ function findTriple(
749
888
  return getInMap(store.eav, [eid, aid]);
750
889
  }
751
890
 
752
- export function transact(store: Store, txSteps) {
891
+ export function transact(
892
+ store: Store,
893
+ attrsStore: AttrsStore,
894
+ txSteps,
895
+ ): { store: Store; attrsStore: AttrsStore } {
753
896
  const txStepsFiltered = txSteps.filter(
754
897
  ([action, eid, attrId, value, opts]) => {
755
898
  if (action !== 'add-triple' && action !== 'deep-merge-triple') {
@@ -763,10 +906,13 @@ export function transact(store: Store, txSteps) {
763
906
 
764
907
  let exists = false;
765
908
 
766
- const attr = getAttr(store.attrs, attrId);
909
+ const attr = attrsStore.getAttr(attrId);
767
910
  if (attr) {
768
- const idAttr = getPrimaryKeyAttr(store, attr['forward-identity'][1]);
769
- exists = !!findTriple(store, [
911
+ const idAttr = getPrimaryKeyAttr(
912
+ attrsStore,
913
+ attr['forward-identity'][1],
914
+ );
915
+ exists = !!findTriple(store, attrsStore, [
770
916
  eid as string,
771
917
  idAttr?.id as string,
772
918
  eid,
@@ -785,9 +931,19 @@ export function transact(store: Store, txSteps) {
785
931
  },
786
932
  );
787
933
 
788
- return create(store, (draft) => {
789
- txStepsFiltered.forEach((txStep) => {
790
- applyTxStep(draft, txStep);
791
- });
792
- });
934
+ return create(
935
+ { store, attrsStore },
936
+ (draft) => {
937
+ txStepsFiltered.forEach((txStep) => {
938
+ applyTxStep(draft.store, draft.attrsStore, txStep);
939
+ });
940
+ },
941
+ {
942
+ mark: (target) => {
943
+ if (target instanceof AttrsStoreClass) {
944
+ return 'immutable';
945
+ }
946
+ },
947
+ },
948
+ );
793
949
  }
@@ -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
- });