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