@instantdb/core 0.22.88-experimental.drewh-ssr.20251523170.1 → 0.22.88-experimental.split-store.20252005043.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 (102) 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 +24 -19
  9. package/dist/commonjs/Reactor.d.ts.map +1 -1
  10. package/dist/commonjs/Reactor.js +112 -106
  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/index.d.ts +1 -5
  17. package/dist/commonjs/index.d.ts.map +1 -1
  18. package/dist/commonjs/index.js +1 -7
  19. package/dist/commonjs/index.js.map +1 -1
  20. package/dist/commonjs/instaml.d.ts +17 -4
  21. package/dist/commonjs/instaml.d.ts.map +1 -1
  22. package/dist/commonjs/instaml.js +115 -82
  23. package/dist/commonjs/instaml.js.map +1 -1
  24. package/dist/commonjs/instaql.d.ts +4 -3
  25. package/dist/commonjs/instaql.d.ts.map +1 -1
  26. package/dist/commonjs/instaql.js +65 -63
  27. package/dist/commonjs/instaql.js.map +1 -1
  28. package/dist/commonjs/reactorTypes.d.ts +29 -0
  29. package/dist/commonjs/reactorTypes.d.ts.map +1 -0
  30. package/dist/commonjs/reactorTypes.js +3 -0
  31. package/dist/commonjs/reactorTypes.js.map +1 -0
  32. package/dist/commonjs/store.d.ts +67 -25
  33. package/dist/commonjs/store.d.ts.map +1 -1
  34. package/dist/commonjs/store.js +177 -81
  35. package/dist/commonjs/store.js.map +1 -1
  36. package/dist/esm/Reactor.d.ts +24 -19
  37. package/dist/esm/Reactor.d.ts.map +1 -1
  38. package/dist/esm/Reactor.js +113 -107
  39. package/dist/esm/Reactor.js.map +1 -1
  40. package/dist/esm/SyncTable.d.ts +4 -1
  41. package/dist/esm/SyncTable.d.ts.map +1 -1
  42. package/dist/esm/SyncTable.js +35 -37
  43. package/dist/esm/SyncTable.js.map +1 -1
  44. package/dist/esm/index.d.ts +1 -5
  45. package/dist/esm/index.d.ts.map +1 -1
  46. package/dist/esm/index.js +2 -5
  47. package/dist/esm/index.js.map +1 -1
  48. package/dist/esm/instaml.d.ts +17 -4
  49. package/dist/esm/instaml.d.ts.map +1 -1
  50. package/dist/esm/instaml.js +112 -77
  51. package/dist/esm/instaml.js.map +1 -1
  52. package/dist/esm/instaql.d.ts +4 -3
  53. package/dist/esm/instaql.d.ts.map +1 -1
  54. package/dist/esm/instaql.js +65 -63
  55. package/dist/esm/instaql.js.map +1 -1
  56. package/dist/esm/reactorTypes.d.ts +29 -0
  57. package/dist/esm/reactorTypes.d.ts.map +1 -0
  58. package/dist/esm/reactorTypes.js +2 -0
  59. package/dist/esm/reactorTypes.js.map +1 -0
  60. package/dist/esm/store.d.ts +67 -25
  61. package/dist/esm/store.d.ts.map +1 -1
  62. package/dist/esm/store.js +174 -81
  63. package/dist/esm/store.js.map +1 -1
  64. package/dist/standalone/index.js +1851 -1961
  65. package/dist/standalone/index.umd.cjs +3 -3
  66. package/package.json +2 -2
  67. package/src/Reactor.js +155 -143
  68. package/src/SyncTable.ts +85 -45
  69. package/src/index.ts +0 -9
  70. package/src/{instaml.js → instaml.ts} +201 -96
  71. package/src/instaql.ts +88 -62
  72. package/src/reactorTypes.ts +32 -0
  73. package/src/store.ts +257 -101
  74. package/__tests__/src/instaql.bench.js +0 -29
  75. package/__tests__/src/serializeSchema.test.ts +0 -123
  76. package/dist/commonjs/createRouteHandler.d.ts +0 -8
  77. package/dist/commonjs/createRouteHandler.d.ts.map +0 -1
  78. package/dist/commonjs/createRouteHandler.js +0 -57
  79. package/dist/commonjs/createRouteHandler.js.map +0 -1
  80. package/dist/commonjs/framework.d.ts +0 -77
  81. package/dist/commonjs/framework.d.ts.map +0 -1
  82. package/dist/commonjs/framework.js +0 -199
  83. package/dist/commonjs/framework.js.map +0 -1
  84. package/dist/commonjs/parseSchemaFromJSON.d.ts +0 -3
  85. package/dist/commonjs/parseSchemaFromJSON.d.ts.map +0 -1
  86. package/dist/commonjs/parseSchemaFromJSON.js +0 -148
  87. package/dist/commonjs/parseSchemaFromJSON.js.map +0 -1
  88. package/dist/esm/createRouteHandler.d.ts +0 -8
  89. package/dist/esm/createRouteHandler.d.ts.map +0 -1
  90. package/dist/esm/createRouteHandler.js +0 -53
  91. package/dist/esm/createRouteHandler.js.map +0 -1
  92. package/dist/esm/framework.d.ts +0 -77
  93. package/dist/esm/framework.d.ts.map +0 -1
  94. package/dist/esm/framework.js +0 -159
  95. package/dist/esm/framework.js.map +0 -1
  96. package/dist/esm/parseSchemaFromJSON.d.ts +0 -3
  97. package/dist/esm/parseSchemaFromJSON.d.ts.map +0 -1
  98. package/dist/esm/parseSchemaFromJSON.js +0 -144
  99. package/dist/esm/parseSchemaFromJSON.js.map +0 -1
  100. package/src/createRouteHandler.ts +0 -44
  101. package/src/framework.ts +0 -281
  102. package/src/parseSchemaFromJSON.ts +0 -176
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instantdb/core",
3
- "version": "0.22.88-experimental.drewh-ssr.20251523170.1",
3
+ "version": "0.22.88-experimental.split-store.20252005043.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.88-experimental.drewh-ssr.20251523170.1"
56
+ "@instantdb/version": "0.22.88-experimental.split-store.20252005043.1"
57
57
  },
58
58
  "scripts": {
59
59
  "test": "vitest",
package/src/Reactor.js CHANGED
@@ -1,7 +1,7 @@
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';
4
+ import * as instaml from './instaml.ts';
5
5
  import * as s from './store.ts';
6
6
  import uuid from './utils/uuid.ts';
7
7
  import IndexedDBStorage from './IndexedDBStorage.ts';
@@ -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 = s.attrsStoreFromJSON(
122
+ v.result.attrsStore,
123
+ v.result.store,
124
+ );
125
+ if (attrsStore) {
126
+ const storeJSON = v.result.store;
127
+ v.result.store = s.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: s.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 {s.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,30 +334,21 @@ 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 s.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();
320
349
 
321
350
  // kick off a request to cache it
322
- this.getCurrentUser().then((userInfo) => {
323
- this.syncUserToEndpoint(userInfo.user);
324
- });
325
-
326
- setInterval(
327
- async () => {
328
- const currentUser = await this.getCurrentUser();
329
- this.syncUserToEndpoint(currentUser.user);
330
- },
331
- 1000 * 60 * 20,
332
- );
351
+ this.getCurrentUser();
333
352
 
334
353
  NetworkListener.getIsOnline().then((isOnline) => {
335
354
  this._isOnline = isOnline;
@@ -363,6 +382,13 @@ export default class Reactor {
363
382
  }
364
383
  }
365
384
 
385
+ ensureAttrs() {
386
+ if (!this.attrs) {
387
+ throw new Error('attrs have not loaded.');
388
+ }
389
+ return this.attrs;
390
+ }
391
+
366
392
  updateSchema(schema) {
367
393
  this.config = {
368
394
  ...this.config,
@@ -393,7 +419,7 @@ export default class Reactor {
393
419
  serialize: querySubToStorage,
394
420
  parse: (_key, x) => querySubFromStorage(x, this.config.useDateObjects),
395
421
  // objectSize
396
- objectSize: (x) => x.result?.store?.triples?.length ?? 0,
422
+ objectSize: (x) => x?.result?.store?.triples?.length ?? 0,
397
423
  logger: this._log,
398
424
  preloadEntryCount: 10,
399
425
  gc: {
@@ -523,42 +549,6 @@ export default class Reactor {
523
549
  }
524
550
  }
525
551
 
526
- /**
527
- * Does the same thing as add-query-ok
528
- * but called as a result of receiving query info from ssr
529
- * @param {any} q
530
- * @param {{ triples: any; pageInfo: any; }} result
531
- * @param {boolean} enableCardinalityInference
532
- */
533
- _addQueryData(q, result, enableCardinalityInference) {
534
- if (!this.attrs) {
535
- throw new Error('Attrs in reactor have not been set');
536
- }
537
- const queryHash = weakHash(q);
538
- const store = s.createStore(
539
- this.attrs,
540
- result.triples,
541
- enableCardinalityInference,
542
- this._linkIndex,
543
- this.config.useDateObjects,
544
- );
545
- this.querySubs.updateInPlace((prev) => {
546
- prev[queryHash] = {
547
- result: {
548
- store,
549
- pageInfo: result.pageInfo,
550
- processedTxId: undefined,
551
- isExternal: true,
552
- },
553
- q,
554
- };
555
- });
556
- this._cleanupPendingMutationsQueries();
557
- this.notifyOne(queryHash);
558
- this.notifyOneQueryOnce(queryHash);
559
- this._cleanupPendingMutationsTimeout();
560
- }
561
-
562
552
  _handleReceive(connId, msg) {
563
553
  // opt-out, enabled by default if schema
564
554
  const enableCardinalityInference =
@@ -598,13 +588,14 @@ export default class Reactor {
598
588
  const pageInfo = result?.[0]?.data?.['page-info'];
599
589
  const aggregate = result?.[0]?.data?.['aggregate'];
600
590
  const triples = extractTriples(result);
591
+ const attrsStore = this.ensureAttrs();
601
592
  const store = s.createStore(
602
- this.attrs,
593
+ attrsStore,
603
594
  triples,
604
595
  enableCardinalityInference,
605
- this._linkIndex,
606
596
  this.config.useDateObjects,
607
597
  );
598
+
608
599
  this.querySubs.updateInPlace((prev) => {
609
600
  if (!prev[hash]) {
610
601
  this._log.info('Missing value in querySubs', { hash, q });
@@ -612,6 +603,7 @@ export default class Reactor {
612
603
  }
613
604
  prev[hash].result = {
614
605
  store,
606
+ attrsStore,
615
607
  pageInfo,
616
608
  aggregate,
617
609
  processedTxId: msg['processed-tx-id'],
@@ -649,7 +641,7 @@ export default class Reactor {
649
641
  this._cleanupPendingMutationsTimeout();
650
642
 
651
643
  const rewrittenMutations = this._rewriteMutations(
652
- this.attrs,
644
+ this.ensureAttrs(),
653
645
  this._pendingMutations(),
654
646
  processedTxId,
655
647
  );
@@ -670,32 +662,49 @@ export default class Reactor {
670
662
  const result = x['instaql-result'];
671
663
  const hash = weakHash(q);
672
664
  const triples = extractTriples(result);
665
+ const attrsStore = this.ensureAttrs();
673
666
  const store = s.createStore(
674
- this.attrs,
667
+ attrsStore,
675
668
  triples,
676
669
  enableCardinalityInference,
677
- this._linkIndex,
678
670
  this.config.useDateObjects,
679
671
  );
680
- const newStore = this._applyOptimisticUpdates(
681
- store,
682
- mutations,
683
- processedTxId,
684
- );
672
+ const { store: newStore, attrsStore: newAttrsStore } =
673
+ this._applyOptimisticUpdates(
674
+ store,
675
+ attrsStore,
676
+ mutations,
677
+ processedTxId,
678
+ );
685
679
  const pageInfo = result?.[0]?.data?.['page-info'];
686
680
  const aggregate = result?.[0]?.data?.['aggregate'];
687
- return { q, hash, store: newStore, pageInfo, aggregate };
681
+ return {
682
+ q,
683
+ hash,
684
+ store: newStore,
685
+ attrsStore: newAttrsStore,
686
+ pageInfo,
687
+ aggregate,
688
+ };
688
689
  });
689
690
 
690
- updates.forEach(({ hash, q, store, pageInfo, aggregate }) => {
691
- this.querySubs.updateInPlace((prev) => {
692
- if (!prev[hash]) {
693
- this._log.error('Missing value in querySubs', { hash, q });
694
- return;
695
- }
696
- prev[hash].result = { store, pageInfo, aggregate, processedTxId };
697
- });
698
- });
691
+ updates.forEach(
692
+ ({ hash, q, store, attrsStore, pageInfo, aggregate }) => {
693
+ this.querySubs.updateInPlace((prev) => {
694
+ if (!prev[hash]) {
695
+ this._log.error('Missing value in querySubs', { hash, q });
696
+ return;
697
+ }
698
+ prev[hash].result = {
699
+ store,
700
+ attrsStore,
701
+ pageInfo,
702
+ aggregate,
703
+ processedTxId,
704
+ };
705
+ });
706
+ },
707
+ );
699
708
 
700
709
  this._cleanupPendingMutationsQueries();
701
710
 
@@ -710,7 +719,7 @@ export default class Reactor {
710
719
  this._inFlightMutationEventIds.delete(eventId);
711
720
 
712
721
  const muts = this._rewriteMutations(
713
- this.attrs,
722
+ this.ensureAttrs(),
714
723
  this._pendingMutations(),
715
724
  );
716
725
  const prevMutation = muts.get(eventId);
@@ -727,12 +736,17 @@ export default class Reactor {
727
736
  });
728
737
  });
729
738
 
730
- const newAttrs = prevMutation['tx-steps']
731
- .filter(([action, ..._args]) => action === 'add-attr')
732
- .map(([_action, attr]) => attr)
733
- .concat(Object.values(this.attrs));
734
-
735
- this._setAttrs(newAttrs);
739
+ const newAttrs = [];
740
+ for (const step of prevMutation['tx-steps']) {
741
+ if (step[0] === 'add-attr') {
742
+ const attr = step[1];
743
+ newAttrs.push(attr);
744
+ }
745
+ }
746
+ if (newAttrs.length) {
747
+ const existingAttrs = Object.values(this.ensureAttrs().attrs);
748
+ this._setAttrs([...existingAttrs, ...newAttrs]);
749
+ }
736
750
 
737
751
  this._finishTransaction('synced', eventId);
738
752
 
@@ -916,10 +930,13 @@ export default class Reactor {
916
930
  }
917
931
 
918
932
  _setAttrs(attrs) {
919
- this.attrs = attrs.reduce((acc, attr) => {
920
- acc[attr.id] = attr;
921
- return acc;
922
- }, {});
933
+ this.attrs = new s.AttrsStoreClass(
934
+ attrs.reduce((acc, attr) => {
935
+ acc[attr.id] = attr;
936
+ return acc;
937
+ }, {}),
938
+ this._linkIndex,
939
+ );
923
940
 
924
941
  this.notifyAttrsSubs();
925
942
  }
@@ -1068,17 +1085,23 @@ export default class Reactor {
1068
1085
  // We remove `add-attr` commands for attrs that already exist.
1069
1086
  // We update `add-triple` and `retract-triple` commands to use the
1070
1087
  // server attr-ids.
1088
+ /**
1089
+ *
1090
+ * @param {s.AttrsStore} attrs
1091
+ * @param {any} muts
1092
+ * @param {number} [processedTxId]
1093
+ */
1071
1094
  _rewriteMutations(attrs, muts, processedTxId) {
1072
1095
  if (!attrs) return muts;
1073
1096
  if (!muts) return new Map();
1074
1097
  const findExistingAttr = (attr) => {
1075
1098
  const [_, etype, label] = attr['forward-identity'];
1076
- const existing = instaml.getAttrByFwdIdentName(attrs, etype, label);
1099
+ const existing = s.getAttrByFwdIdentName(attrs, etype, label);
1077
1100
  return existing;
1078
1101
  };
1079
1102
  const findReverseAttr = (attr) => {
1080
1103
  const [_, etype, label] = attr['forward-identity'];
1081
- const revAttr = instaml.getAttrByReverseIdentName(attrs, etype, label);
1104
+ const revAttr = s.getAttrByReverseIdentName(attrs, etype, label);
1082
1105
  return revAttr;
1083
1106
  };
1084
1107
  const mapping = { attrIdMap: {}, refSwapAttrIds: new Set() };
@@ -1155,6 +1178,9 @@ export default class Reactor {
1155
1178
  // ---------------------------
1156
1179
  // Transact
1157
1180
 
1181
+ /**
1182
+ * @returns {s.AttrsStore}
1183
+ */
1158
1184
  optimisticAttrs() {
1159
1185
  const pendingMutationSteps = [...this._pendingMutations().values()] // hack due to Map()
1160
1186
  .flatMap((x) => x['tx-steps']);
@@ -1172,27 +1198,30 @@ export default class Reactor {
1172
1198
  } else if (
1173
1199
  _action === 'update-attr' &&
1174
1200
  attr.id &&
1175
- this.attrs?.[attr.id]
1201
+ this.attrs?.getAttr(attr.id)
1176
1202
  ) {
1177
- const fullAttr = { ...this.attrs[attr.id], ...attr };
1203
+ const fullAttr = { ...this.attrs.getAttr(attr.id), ...attr };
1178
1204
  pendingAttrs.push(fullAttr);
1179
1205
  }
1180
1206
  }
1181
1207
 
1182
- const attrsWithoutDeleted = [
1183
- ...Object.values(this.attrs || {}),
1184
- ...pendingAttrs,
1185
- ].filter((a) => !deletedAttrIds.has(a.id));
1208
+ if (!deletedAttrIds.size && !pendingAttrs.length) {
1209
+ return this.attrs || new s.AttrsStoreClass({}, this._linkIndex);
1210
+ }
1186
1211
 
1187
- const attrsRecord = Object.fromEntries(
1188
- attrsWithoutDeleted.map((a) => [a.id, a]),
1189
- );
1212
+ const attrs = { ...(this.attrs?.attrs || {}) };
1213
+ for (const attr of pendingAttrs) {
1214
+ attrs[attr.id] = attr;
1215
+ }
1216
+ for (const id of deletedAttrIds) {
1217
+ delete attrs[id];
1218
+ }
1190
1219
 
1191
- return attrsRecord;
1220
+ return new s.AttrsStoreClass(attrs, this._linkIndex);
1192
1221
  }
1193
1222
 
1194
1223
  /** Runs instaql on a query and a store */
1195
- dataForQuery(hash, applyOptimistic = true) {
1224
+ dataForQuery(hash) {
1196
1225
  const errorMessage = this._errorMessage;
1197
1226
  if (errorMessage) {
1198
1227
  return { error: errorMessage };
@@ -1216,27 +1245,30 @@ export default class Reactor {
1216
1245
  return cached;
1217
1246
  }
1218
1247
 
1219
- let store = result.store;
1220
- const { pageInfo, aggregate, processedTxId } = result;
1248
+ const { store, attrsStore, pageInfo, aggregate, processedTxId } = result;
1221
1249
  const mutations = this._rewriteMutationsSorted(
1222
- store.attrs,
1250
+ attrsStore,
1223
1251
  pendingMutations,
1224
1252
  );
1225
- if (applyOptimistic) {
1226
- store = this._applyOptimisticUpdates(store, mutations, processedTxId);
1227
- }
1228
- const resp = instaql({ store: store, pageInfo, aggregate }, q);
1253
+ const { store: newStore, attrsStore: newAttrsStore } =
1254
+ this._applyOptimisticUpdates(store, attrsStore, mutations, processedTxId);
1255
+ const resp = instaql(
1256
+ { store: newStore, attrsStore: newAttrsStore, pageInfo, aggregate },
1257
+ q,
1258
+ );
1229
1259
 
1230
1260
  return { data: resp, querySubVersion, pendingMutationsVersion };
1231
1261
  }
1232
1262
 
1233
- _applyOptimisticUpdates(store, mutations, processedTxId) {
1263
+ _applyOptimisticUpdates(store, attrsStore, mutations, processedTxId) {
1234
1264
  for (const [_, mut] of mutations) {
1235
1265
  if (!mut['tx-id'] || (processedTxId && mut['tx-id'] > processedTxId)) {
1236
- store = s.transact(store, mut['tx-steps']);
1266
+ const result = s.transact(store, attrsStore, mut['tx-steps']);
1267
+ store = result.store;
1268
+ attrsStore = result.attrsStore;
1237
1269
  }
1238
1270
  }
1239
- return store;
1271
+ return { store, attrsStore };
1240
1272
  }
1241
1273
 
1242
1274
  /** Re-run instaql and call all callbacks with new data */
@@ -1293,7 +1325,7 @@ export default class Reactor {
1293
1325
  try {
1294
1326
  const txSteps = instaml.transform(
1295
1327
  {
1296
- attrs: this.optimisticAttrs(),
1328
+ attrsStore: this.optimisticAttrs(),
1297
1329
  schema: this.config.schema,
1298
1330
  stores: Object.values(this.querySubs.currentValue).map(
1299
1331
  (sub) => sub?.result?.store,
@@ -1411,7 +1443,7 @@ export default class Reactor {
1411
1443
  });
1412
1444
 
1413
1445
  const muts = this._rewriteMutationsSorted(
1414
- this.attrs,
1446
+ this.ensureAttrs(),
1415
1447
  this._pendingMutations(),
1416
1448
  );
1417
1449
  muts.forEach(([eventId, mut]) => {
@@ -1867,7 +1899,7 @@ export default class Reactor {
1867
1899
  this.attrsCbs.push(cb);
1868
1900
 
1869
1901
  if (this.attrs) {
1870
- cb(this.attrs);
1902
+ cb(this.attrs.attrs);
1871
1903
  }
1872
1904
 
1873
1905
  return () => {
@@ -1886,7 +1918,7 @@ export default class Reactor {
1886
1918
  notifyAttrsSubs() {
1887
1919
  if (!this.attrs) return;
1888
1920
  const oas = this.optimisticAttrs();
1889
- this.attrsCbs.forEach((cb) => cb(oas));
1921
+ this.attrsCbs.forEach((cb) => cb(oas.attrs));
1890
1922
  }
1891
1923
 
1892
1924
  notifyConnectionStatusSubs(status) {
@@ -1957,27 +1989,7 @@ export default class Reactor {
1957
1989
  }
1958
1990
  }
1959
1991
 
1960
- async syncUserToEndpoint(user) {
1961
- if (this.config.cookieEndpoint) {
1962
- try {
1963
- fetch(this.config.cookieEndpoint + '/sync-auth', {
1964
- method: 'POST',
1965
- body: JSON.stringify({
1966
- user: user,
1967
- }),
1968
- headers: {
1969
- 'Content-Type': 'application/json',
1970
- },
1971
- });
1972
- } catch (error) {
1973
- console.error('Error syncing user with external endpoint', error);
1974
- }
1975
- }
1976
- }
1977
-
1978
1992
  updateUser(newUser) {
1979
- this.syncUserToEndpoint(newUser);
1980
-
1981
1993
  const newV = { error: undefined, user: newUser };
1982
1994
  this._currentUserCached = { isLoading: false, ...newV };
1983
1995
  this._dataForQueryCache = {};