@instantdb/core 0.22.86-experimental.drewh-explorer-component.20178667850.1 → 0.22.86-experimental.split-store.20178922132.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 (57) hide show
  1. package/dist/commonjs/Reactor.d.ts +20 -6
  2. package/dist/commonjs/Reactor.d.ts.map +1 -1
  3. package/dist/commonjs/Reactor.js +97 -42
  4. package/dist/commonjs/Reactor.js.map +1 -1
  5. package/dist/commonjs/SyncTable.d.ts +4 -1
  6. package/dist/commonjs/SyncTable.d.ts.map +1 -1
  7. package/dist/commonjs/SyncTable.js +35 -37
  8. package/dist/commonjs/SyncTable.js.map +1 -1
  9. package/dist/commonjs/instaml.d.ts +17 -4
  10. package/dist/commonjs/instaml.d.ts.map +1 -1
  11. package/dist/commonjs/instaml.js +105 -76
  12. package/dist/commonjs/instaml.js.map +1 -1
  13. package/dist/commonjs/instaql.d.ts +2 -1
  14. package/dist/commonjs/instaql.d.ts.map +1 -1
  15. package/dist/commonjs/instaql.js +65 -63
  16. package/dist/commonjs/instaql.js.map +1 -1
  17. package/dist/commonjs/reactorTypes.d.ts +29 -0
  18. package/dist/commonjs/reactorTypes.d.ts.map +1 -0
  19. package/dist/commonjs/reactorTypes.js +3 -0
  20. package/dist/commonjs/reactorTypes.js.map +1 -0
  21. package/dist/commonjs/store.d.ts +44 -21
  22. package/dist/commonjs/store.d.ts.map +1 -1
  23. package/dist/commonjs/store.js +164 -69
  24. package/dist/commonjs/store.js.map +1 -1
  25. package/dist/esm/Reactor.d.ts +20 -6
  26. package/dist/esm/Reactor.d.ts.map +1 -1
  27. package/dist/esm/Reactor.js +98 -43
  28. package/dist/esm/Reactor.js.map +1 -1
  29. package/dist/esm/SyncTable.d.ts +4 -1
  30. package/dist/esm/SyncTable.d.ts.map +1 -1
  31. package/dist/esm/SyncTable.js +35 -37
  32. package/dist/esm/SyncTable.js.map +1 -1
  33. package/dist/esm/instaml.d.ts +17 -4
  34. package/dist/esm/instaml.d.ts.map +1 -1
  35. package/dist/esm/instaml.js +102 -71
  36. package/dist/esm/instaml.js.map +1 -1
  37. package/dist/esm/instaql.d.ts +2 -1
  38. package/dist/esm/instaql.d.ts.map +1 -1
  39. package/dist/esm/instaql.js +65 -63
  40. package/dist/esm/instaql.js.map +1 -1
  41. package/dist/esm/reactorTypes.d.ts +29 -0
  42. package/dist/esm/reactorTypes.d.ts.map +1 -0
  43. package/dist/esm/reactorTypes.js +2 -0
  44. package/dist/esm/reactorTypes.js.map +1 -0
  45. package/dist/esm/store.d.ts +44 -21
  46. package/dist/esm/store.d.ts.map +1 -1
  47. package/dist/esm/store.js +161 -69
  48. package/dist/esm/store.js.map +1 -1
  49. package/dist/standalone/index.js +1536 -1364
  50. package/dist/standalone/index.umd.cjs +3 -3
  51. package/package.json +2 -2
  52. package/src/Reactor.js +126 -58
  53. package/src/SyncTable.ts +85 -45
  54. package/src/{instaml.js → instaml.ts} +195 -95
  55. package/src/instaql.ts +86 -60
  56. package/src/reactorTypes.ts +32 -0
  57. package/src/store.ts +209 -79
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instantdb/core",
3
- "version": "0.22.86-experimental.drewh-explorer-component.20178667850.1",
3
+ "version": "0.22.86-experimental.split-store.20178922132.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.drewh-explorer-component.20178667850.1"
56
+ "@instantdb/version": "0.22.86-experimental.split-store.20178922132.1"
57
57
  },
58
58
  "scripts": {
59
59
  "test": "vitest",
package/src/Reactor.js CHANGED
@@ -1,8 +1,8 @@
1
1
  // @ts-check
2
2
  import weakHash from './utils/weakHash.ts';
3
3
  import instaql from './instaql.ts';
4
- import * as instaml from './instaml.js';
5
- import * as s from './store.ts';
4
+ import * as instaml from './instaml.ts';
5
+ import * as sts from './store.ts';
6
6
  import uuid from './utils/uuid.ts';
7
7
  import IndexedDBStorage from './IndexedDBStorage.ts';
8
8
  import WindowNetworkListener from './WindowNetworkListener.js';
@@ -36,6 +36,8 @@ import { SyncTable } from './SyncTable.ts';
36
36
  /** @typedef {import('./Connection.ts').Connection} Connection */
37
37
  /** @typedef {import('./Connection.ts').TransportType} TransportType */
38
38
  /** @typedef {import('./Connection.ts').EventSourceConstructor} EventSourceConstructor */
39
+ /** @typedef {import('./reactorTypes.ts').QuerySub} QuerySub */
40
+ /** @typedef {import('./reactorTypes.ts').QuerySubInStorage} QuerySubInStorage */
39
41
 
40
42
  const STATUS = {
41
43
  CONNECTING: 'connecting',
@@ -107,27 +109,52 @@ const ignoreLogging = {
107
109
  'patch-presence': true,
108
110
  };
109
111
 
112
+ /**
113
+ * @param {QuerySubInStorage} x
114
+ * @param {boolean | null} useDateObjects
115
+ * @returns {QuerySub}
116
+ */
110
117
  function querySubFromStorage(x, useDateObjects) {
111
118
  const v = typeof x === 'string' ? JSON.parse(x) : x;
112
119
 
113
120
  if (v?.result?.store) {
114
- const storeJSON = v.result.store;
115
- v.result.store = s.fromJSON({
116
- ...storeJSON,
117
- useDateObjects: useDateObjects,
118
- });
121
+ const attrsStore = sts.attrsStoreFromJSON(
122
+ v.result.attrsStore,
123
+ v.result.store,
124
+ );
125
+ if (attrsStore) {
126
+ const storeJSON = v.result.store;
127
+ v.result.store = sts.fromJSON(attrsStore, {
128
+ ...storeJSON,
129
+ useDateObjects: useDateObjects,
130
+ });
131
+ v.result.attrsStore = attrsStore;
132
+ }
119
133
  }
120
134
 
121
135
  return v;
122
136
  }
123
137
 
138
+ /**
139
+ *
140
+ * @param {string} _key
141
+ * @param {QuerySub} sub
142
+ * @returns QuerySubInStorage
143
+ */
124
144
  function querySubToStorage(_key, sub) {
125
- const jsonSub = { ...sub };
126
- if (sub.result?.store) {
127
- jsonSub.result = {
128
- ...sub.result,
129
- store: s.toJSON(sub.result.store),
145
+ const { result, ...rest } = sub;
146
+ const jsonSub = /** @type {import('./reactorTypes.ts').QuerySubInStorage} */ (
147
+ rest
148
+ );
149
+ if (result) {
150
+ /** @type {import('./reactorTypes.ts').QuerySubResultInStorage} */
151
+ const jsonResult = {
152
+ ...result,
153
+ store: sts.toJSON(result.store),
154
+ attrsStore: result.attrsStore.toJSON(),
130
155
  };
156
+
157
+ jsonSub.result = jsonResult;
131
158
  }
132
159
  return jsonSub;
133
160
  }
@@ -176,12 +203,13 @@ function sortedMutationEntries(entries) {
176
203
  * @template {import('./presence.ts').RoomSchemaShape} [RoomSchema = {}]
177
204
  */
178
205
  export default class Reactor {
206
+ /** @type {sts.AttrsStore | undefined} */
179
207
  attrs;
180
208
  _isOnline = true;
181
209
  _isShutdown = false;
182
210
  status = STATUS.CONNECTING;
183
211
 
184
- /** @type {PersistedObject} */
212
+ /** @type {PersistedObject<string, QuerySub, QuerySubInStorage>} */
185
213
  querySubs;
186
214
 
187
215
  /** @type {PersistedObject} */
@@ -306,14 +334,15 @@ export default class Reactor {
306
334
  useDateObjects: this.config.useDateObjects,
307
335
  },
308
336
  this._log,
309
- (triples) =>
310
- s.createStore(
311
- this.attrs,
337
+ (triples) => {
338
+ return sts.createStore(
339
+ this.ensureAttrs(),
312
340
  triples,
313
341
  this.config.enableCardinalityInference,
314
- this._linkIndex,
315
342
  this.config.useDateObjects,
316
- ),
343
+ );
344
+ },
345
+ () => this.ensureAttrs(),
317
346
  );
318
347
 
319
348
  this._oauthCallbackResponse = this._oauthLoginInit();
@@ -353,6 +382,13 @@ export default class Reactor {
353
382
  }
354
383
  }
355
384
 
385
+ ensureAttrs() {
386
+ if (!this.attrs) {
387
+ throw new Error('attrs have not loaded.');
388
+ }
389
+ return this.attrs;
390
+ }
391
+
356
392
  updateSchema(schema) {
357
393
  this.config = {
358
394
  ...this.config,
@@ -383,7 +419,7 @@ export default class Reactor {
383
419
  serialize: querySubToStorage,
384
420
  parse: (_key, x) => querySubFromStorage(x, this.config.useDateObjects),
385
421
  // objectSize
386
- objectSize: (x) => x.result?.store?.triples?.length ?? 0,
422
+ objectSize: (x) => x?.result?.store?.triples?.length ?? 0,
387
423
  logger: this._log,
388
424
  preloadEntryCount: 10,
389
425
  gc: {
@@ -552,13 +588,13 @@ export default class Reactor {
552
588
  const pageInfo = result?.[0]?.data?.['page-info'];
553
589
  const aggregate = result?.[0]?.data?.['aggregate'];
554
590
  const triples = extractTriples(result);
555
- const store = s.createStore(
556
- this.attrs,
591
+ const store = sts.createStore(
592
+ this.ensureAttrs(),
557
593
  triples,
558
594
  enableCardinalityInference,
559
- this._linkIndex,
560
595
  this.config.useDateObjects,
561
596
  );
597
+
562
598
  this.querySubs.updateInPlace((prev) => {
563
599
  if (!prev[hash]) {
564
600
  this._log.info('Missing value in querySubs', { hash, q });
@@ -566,6 +602,7 @@ export default class Reactor {
566
602
  }
567
603
  prev[hash].result = {
568
604
  store,
605
+ attrsStore: this.ensureAttrs(),
569
606
  pageInfo,
570
607
  aggregate,
571
608
  processedTxId: msg['processed-tx-id'],
@@ -603,7 +640,7 @@ export default class Reactor {
603
640
  this._cleanupPendingMutationsTimeout();
604
641
 
605
642
  const rewrittenMutations = this._rewriteMutations(
606
- this.attrs,
643
+ this.ensureAttrs(),
607
644
  this._pendingMutations(),
608
645
  processedTxId,
609
646
  );
@@ -624,15 +661,15 @@ export default class Reactor {
624
661
  const result = x['instaql-result'];
625
662
  const hash = weakHash(q);
626
663
  const triples = extractTriples(result);
627
- const store = s.createStore(
628
- this.attrs,
664
+ const store = sts.createStore(
665
+ this.ensureAttrs(),
629
666
  triples,
630
667
  enableCardinalityInference,
631
- this._linkIndex,
632
668
  this.config.useDateObjects,
633
669
  );
634
670
  const newStore = this._applyOptimisticUpdates(
635
671
  store,
672
+ this.ensureAttrs(),
636
673
  mutations,
637
674
  processedTxId,
638
675
  );
@@ -647,7 +684,13 @@ export default class Reactor {
647
684
  this._log.error('Missing value in querySubs', { hash, q });
648
685
  return;
649
686
  }
650
- prev[hash].result = { store, pageInfo, aggregate, processedTxId };
687
+ prev[hash].result = {
688
+ store,
689
+ attrsStore: this.ensureAttrs(),
690
+ pageInfo,
691
+ aggregate,
692
+ processedTxId,
693
+ };
651
694
  });
652
695
  });
653
696
 
@@ -664,7 +707,7 @@ export default class Reactor {
664
707
  this._inFlightMutationEventIds.delete(eventId);
665
708
 
666
709
  const muts = this._rewriteMutations(
667
- this.attrs,
710
+ this.ensureAttrs(),
668
711
  this._pendingMutations(),
669
712
  );
670
713
  const prevMutation = muts.get(eventId);
@@ -681,12 +724,18 @@ export default class Reactor {
681
724
  });
682
725
  });
683
726
 
684
- const newAttrs = prevMutation['tx-steps']
685
- .filter(([action, ..._args]) => action === 'add-attr')
686
- .map(([_action, attr]) => attr)
687
- .concat(Object.values(this.attrs));
688
-
689
- this._setAttrs(newAttrs);
727
+ const newAttrs = [];
728
+ for (const step of prevMutation['tx-steps']) {
729
+ if (step[0] === 'add-attr') {
730
+ const attr = step[1];
731
+ newAttrs.push(attr);
732
+ }
733
+ }
734
+ if (newAttrs.length) {
735
+ const existingAttrs = Object.values(this.ensureAttrs());
736
+ this._setAttrs([...existingAttrs, ...newAttrs]);
737
+ this._setAttrs(newAttrs);
738
+ }
690
739
 
691
740
  this._finishTransaction('synced', eventId);
692
741
 
@@ -870,10 +919,13 @@ export default class Reactor {
870
919
  }
871
920
 
872
921
  _setAttrs(attrs) {
873
- this.attrs = attrs.reduce((acc, attr) => {
874
- acc[attr.id] = attr;
875
- return acc;
876
- }, {});
922
+ this.attrs = new sts.AttrsStore(
923
+ attrs.reduce((acc, attr) => {
924
+ acc[attr.id] = attr;
925
+ return acc;
926
+ }, {}),
927
+ this._linkIndex,
928
+ );
877
929
 
878
930
  this.notifyAttrsSubs();
879
931
  }
@@ -1022,17 +1074,23 @@ export default class Reactor {
1022
1074
  // We remove `add-attr` commands for attrs that already exist.
1023
1075
  // We update `add-triple` and `retract-triple` commands to use the
1024
1076
  // server attr-ids.
1077
+ /**
1078
+ *
1079
+ * @param {sts.AttrsStore} attrs
1080
+ * @param {any} muts
1081
+ * @param {number} [processedTxId]
1082
+ */
1025
1083
  _rewriteMutations(attrs, muts, processedTxId) {
1026
1084
  if (!attrs) return muts;
1027
1085
  if (!muts) return new Map();
1028
1086
  const findExistingAttr = (attr) => {
1029
1087
  const [_, etype, label] = attr['forward-identity'];
1030
- const existing = instaml.getAttrByFwdIdentName(attrs, etype, label);
1088
+ const existing = sts.getAttrByFwdIdentName(attrs, etype, label);
1031
1089
  return existing;
1032
1090
  };
1033
1091
  const findReverseAttr = (attr) => {
1034
1092
  const [_, etype, label] = attr['forward-identity'];
1035
- const revAttr = instaml.getAttrByReverseIdentName(attrs, etype, label);
1093
+ const revAttr = sts.getAttrByReverseIdentName(attrs, etype, label);
1036
1094
  return revAttr;
1037
1095
  };
1038
1096
  const mapping = { attrIdMap: {}, refSwapAttrIds: new Set() };
@@ -1109,6 +1167,9 @@ export default class Reactor {
1109
1167
  // ---------------------------
1110
1168
  // Transact
1111
1169
 
1170
+ /**
1171
+ * @returns {sts.AttrsStore}
1172
+ */
1112
1173
  optimisticAttrs() {
1113
1174
  const pendingMutationSteps = [...this._pendingMutations().values()] // hack due to Map()
1114
1175
  .flatMap((x) => x['tx-steps']);
@@ -1126,23 +1187,26 @@ export default class Reactor {
1126
1187
  } else if (
1127
1188
  _action === 'update-attr' &&
1128
1189
  attr.id &&
1129
- this.attrs?.[attr.id]
1190
+ this.attrs?.getAttr(attr.id)
1130
1191
  ) {
1131
- const fullAttr = { ...this.attrs[attr.id], ...attr };
1192
+ const fullAttr = { ...this.attrs.getAttr(attr.id), ...attr };
1132
1193
  pendingAttrs.push(fullAttr);
1133
1194
  }
1134
1195
  }
1135
1196
 
1136
- const attrsWithoutDeleted = [
1137
- ...Object.values(this.attrs || {}),
1138
- ...pendingAttrs,
1139
- ].filter((a) => !deletedAttrIds.has(a.id));
1197
+ if (!deletedAttrIds.size && !pendingAttrs.length) {
1198
+ return this.attrs || new sts.AttrsStore({}, this._linkIndex);
1199
+ }
1140
1200
 
1141
- const attrsRecord = Object.fromEntries(
1142
- attrsWithoutDeleted.map((a) => [a.id, a]),
1143
- );
1201
+ const attrs = { ...(this.attrs?.attrs || {}) };
1202
+ for (const attr of pendingAttrs) {
1203
+ attrs[attr.id] = attr;
1204
+ }
1205
+ for (const id of deletedAttrIds) {
1206
+ delete attrs[id];
1207
+ }
1144
1208
 
1145
- return attrsRecord;
1209
+ return new sts.AttrsStore(attrs, this._linkIndex);
1146
1210
  }
1147
1211
 
1148
1212
  /** Runs instaql on a query and a store */
@@ -1170,25 +1234,29 @@ export default class Reactor {
1170
1234
  return cached;
1171
1235
  }
1172
1236
 
1173
- const { store, pageInfo, aggregate, processedTxId } = result;
1237
+ const { store, attrsStore, pageInfo, aggregate, processedTxId } = result;
1174
1238
  const mutations = this._rewriteMutationsSorted(
1175
- store.attrs,
1239
+ attrsStore,
1176
1240
  pendingMutations,
1177
1241
  );
1178
1242
  const newStore = this._applyOptimisticUpdates(
1179
1243
  store,
1244
+ attrsStore,
1180
1245
  mutations,
1181
1246
  processedTxId,
1182
1247
  );
1183
- const resp = instaql({ store: newStore, pageInfo, aggregate }, q);
1248
+ const resp = instaql(
1249
+ { store: newStore, attrsStore, pageInfo, aggregate },
1250
+ q,
1251
+ );
1184
1252
 
1185
1253
  return { data: resp, querySubVersion, pendingMutationsVersion };
1186
1254
  }
1187
1255
 
1188
- _applyOptimisticUpdates(store, mutations, processedTxId) {
1256
+ _applyOptimisticUpdates(store, attrsStore, mutations, processedTxId) {
1189
1257
  for (const [_, mut] of mutations) {
1190
1258
  if (!mut['tx-id'] || (processedTxId && mut['tx-id'] > processedTxId)) {
1191
- store = s.transact(store, mut['tx-steps']);
1259
+ store = sts.transact(store, attrsStore, mut['tx-steps']);
1192
1260
  }
1193
1261
  }
1194
1262
  return store;
@@ -1248,7 +1316,7 @@ export default class Reactor {
1248
1316
  try {
1249
1317
  const txSteps = instaml.transform(
1250
1318
  {
1251
- attrs: this.optimisticAttrs(),
1319
+ attrsStore: this.optimisticAttrs(),
1252
1320
  schema: this.config.schema,
1253
1321
  stores: Object.values(this.querySubs.currentValue).map(
1254
1322
  (sub) => sub?.result?.store,
@@ -1366,7 +1434,7 @@ export default class Reactor {
1366
1434
  });
1367
1435
 
1368
1436
  const muts = this._rewriteMutationsSorted(
1369
- this.attrs,
1437
+ this.ensureAttrs(),
1370
1438
  this._pendingMutations(),
1371
1439
  );
1372
1440
  muts.forEach(([eventId, mut]) => {
@@ -1822,7 +1890,7 @@ export default class Reactor {
1822
1890
  this.attrsCbs.push(cb);
1823
1891
 
1824
1892
  if (this.attrs) {
1825
- cb(this.attrs);
1893
+ cb(this.attrs.attrs);
1826
1894
  }
1827
1895
 
1828
1896
  return () => {