@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
@@ -21,7 +21,7 @@ var __rest = (this && this.__rest) || function (s, e) {
21
21
  // @ts-check
22
22
  import weakHash from "./utils/weakHash.js";
23
23
  import instaql from "./instaql.js";
24
- import * as instaml from './instaml.js';
24
+ import * as instaml from "./instaml.js";
25
25
  import * as s from "./store.js";
26
26
  import uuid from "./utils/uuid.js";
27
27
  import IndexedDBStorage from "./IndexedDBStorage.js";
@@ -49,6 +49,8 @@ import { SyncTable } from "./SyncTable.js";
49
49
  /** @typedef {import('./Connection.ts').Connection} Connection */
50
50
  /** @typedef {import('./Connection.ts').TransportType} TransportType */
51
51
  /** @typedef {import('./Connection.ts').EventSourceConstructor} EventSourceConstructor */
52
+ /** @typedef {import('./reactorTypes.ts').QuerySub} QuerySub */
53
+ /** @typedef {import('./reactorTypes.ts').QuerySubInStorage} QuerySubInStorage */
52
54
  const STATUS = {
53
55
  CONNECTING: 'connecting',
54
56
  OPENED: 'opened',
@@ -101,20 +103,37 @@ const ignoreLogging = {
101
103
  'refresh-presence': true,
102
104
  'patch-presence': true,
103
105
  };
106
+ /**
107
+ * @param {QuerySubInStorage} x
108
+ * @param {boolean | null} useDateObjects
109
+ * @returns {QuerySub}
110
+ */
104
111
  function querySubFromStorage(x, useDateObjects) {
105
112
  var _a;
106
113
  const v = typeof x === 'string' ? JSON.parse(x) : x;
107
114
  if ((_a = v === null || v === void 0 ? void 0 : v.result) === null || _a === void 0 ? void 0 : _a.store) {
108
- const storeJSON = v.result.store;
109
- v.result.store = s.fromJSON(Object.assign(Object.assign({}, storeJSON), { useDateObjects: useDateObjects }));
115
+ const attrsStore = s.attrsStoreFromJSON(v.result.attrsStore, v.result.store);
116
+ if (attrsStore) {
117
+ const storeJSON = v.result.store;
118
+ v.result.store = s.fromJSON(attrsStore, Object.assign(Object.assign({}, storeJSON), { useDateObjects: useDateObjects }));
119
+ v.result.attrsStore = attrsStore;
120
+ }
110
121
  }
111
122
  return v;
112
123
  }
124
+ /**
125
+ *
126
+ * @param {string} _key
127
+ * @param {QuerySub} sub
128
+ * @returns QuerySubInStorage
129
+ */
113
130
  function querySubToStorage(_key, sub) {
114
- var _a;
115
- const jsonSub = Object.assign({}, sub);
116
- if ((_a = sub.result) === null || _a === void 0 ? void 0 : _a.store) {
117
- jsonSub.result = Object.assign(Object.assign({}, sub.result), { store: s.toJSON(sub.result.store) });
131
+ const { result } = sub, rest = __rest(sub, ["result"]);
132
+ const jsonSub = /** @type {import('./reactorTypes.ts').QuerySubInStorage} */ (rest);
133
+ if (result) {
134
+ /** @type {import('./reactorTypes.ts').QuerySubResultInStorage} */
135
+ const jsonResult = Object.assign(Object.assign({}, result), { store: s.toJSON(result.store), attrsStore: result.attrsStore.toJSON() });
136
+ jsonSub.result = jsonResult;
118
137
  }
119
138
  return jsonSub;
120
139
  }
@@ -259,7 +278,7 @@ export default class Reactor {
259
278
  }
260
279
  try {
261
280
  const txSteps = instaml.transform({
262
- attrs: this.optimisticAttrs(),
281
+ attrsStore: this.optimisticAttrs(),
263
282
  schema: this.config.schema,
264
283
  stores: Object.values(this.querySubs.currentValue).map((sub) => { var _a; return (_a = sub === null || sub === void 0 ? void 0 : sub.result) === null || _a === void 0 ? void 0 : _a.store; }),
265
284
  useDateObjects: this.config.useDateObjects,
@@ -425,7 +444,9 @@ export default class Reactor {
425
444
  this._initStorage(Storage);
426
445
  this._syncTable = new SyncTable(this._trySendAuthed.bind(this), new Storage(this.config.appId, 'syncSubs'), {
427
446
  useDateObjects: this.config.useDateObjects,
428
- }, this._log, (triples) => s.createStore(this.attrs, triples, this.config.enableCardinalityInference, this._linkIndex, this.config.useDateObjects));
447
+ }, this._log, (triples) => {
448
+ return s.createStore(this.ensureAttrs(), triples, this.config.enableCardinalityInference, this.config.useDateObjects);
449
+ }, () => this.ensureAttrs());
429
450
  this._oauthCallbackResponse = this._oauthLoginInit();
430
451
  // kick off a request to cache it
431
452
  this.getCurrentUser();
@@ -455,6 +476,12 @@ export default class Reactor {
455
476
  addEventListener('beforeunload', this._beforeUnload);
456
477
  }
457
478
  }
479
+ ensureAttrs() {
480
+ if (!this.attrs) {
481
+ throw new Error('attrs have not loaded.');
482
+ }
483
+ return this.attrs;
484
+ }
458
485
  updateSchema(schema) {
459
486
  this.config = Object.assign(Object.assign({}, this.config), { schema: schema, cardinalityInference: Boolean(schema) });
460
487
  this._linkIndex = schema ? createLinkIndex(this.config.schema) : null;
@@ -478,7 +505,7 @@ export default class Reactor {
478
505
  serialize: querySubToStorage,
479
506
  parse: (_key, x) => querySubFromStorage(x, this.config.useDateObjects),
480
507
  // objectSize
481
- objectSize: (x) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = x.result) === null || _a === void 0 ? void 0 : _a.store) === null || _b === void 0 ? void 0 : _b.triples) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0; },
508
+ objectSize: (x) => { var _a, _b, _c, _d; return (_d = (_c = (_b = (_a = x === null || x === void 0 ? void 0 : x.result) === null || _a === void 0 ? void 0 : _a.store) === null || _b === void 0 ? void 0 : _b.triples) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0; },
482
509
  logger: this._log,
483
510
  preloadEntryCount: 10,
484
511
  gc: {
@@ -612,7 +639,8 @@ export default class Reactor {
612
639
  const pageInfo = (_d = (_c = result === null || result === void 0 ? void 0 : result[0]) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d['page-info'];
613
640
  const aggregate = (_f = (_e = result === null || result === void 0 ? void 0 : result[0]) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f['aggregate'];
614
641
  const triples = extractTriples(result);
615
- const store = s.createStore(this.attrs, triples, enableCardinalityInference, this._linkIndex, this.config.useDateObjects);
642
+ const attrsStore = this.ensureAttrs();
643
+ const store = s.createStore(attrsStore, triples, enableCardinalityInference, this.config.useDateObjects);
616
644
  this.querySubs.updateInPlace((prev) => {
617
645
  if (!prev[hash]) {
618
646
  this._log.info('Missing value in querySubs', { hash, q });
@@ -620,6 +648,7 @@ export default class Reactor {
620
648
  }
621
649
  prev[hash].result = {
622
650
  store,
651
+ attrsStore,
623
652
  pageInfo,
624
653
  aggregate,
625
654
  processedTxId: msg['processed-tx-id'],
@@ -654,7 +683,7 @@ export default class Reactor {
654
683
  this._setAttrs(attrs);
655
684
  }
656
685
  this._cleanupPendingMutationsTimeout();
657
- const rewrittenMutations = this._rewriteMutations(this.attrs, this._pendingMutations(), processedTxId);
686
+ const rewrittenMutations = this._rewriteMutations(this.ensureAttrs(), this._pendingMutations(), processedTxId);
658
687
  if (rewrittenMutations !== this._pendingMutations()) {
659
688
  // We know we've changed the mutations to fix the attr ids and removed
660
689
  // processed attrs, so we'll persist those changes to prevent optimisticAttrs
@@ -670,19 +699,33 @@ export default class Reactor {
670
699
  const result = x['instaql-result'];
671
700
  const hash = weakHash(q);
672
701
  const triples = extractTriples(result);
673
- const store = s.createStore(this.attrs, triples, enableCardinalityInference, this._linkIndex, this.config.useDateObjects);
674
- const newStore = this._applyOptimisticUpdates(store, mutations, processedTxId);
702
+ const attrsStore = this.ensureAttrs();
703
+ const store = s.createStore(attrsStore, triples, enableCardinalityInference, this.config.useDateObjects);
704
+ const { store: newStore, attrsStore: newAttrsStore } = this._applyOptimisticUpdates(store, attrsStore, mutations, processedTxId);
675
705
  const pageInfo = (_b = (_a = result === null || result === void 0 ? void 0 : result[0]) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b['page-info'];
676
706
  const aggregate = (_d = (_c = result === null || result === void 0 ? void 0 : result[0]) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d['aggregate'];
677
- return { q, hash, store: newStore, pageInfo, aggregate };
707
+ return {
708
+ q,
709
+ hash,
710
+ store: newStore,
711
+ attrsStore: newAttrsStore,
712
+ pageInfo,
713
+ aggregate,
714
+ };
678
715
  });
679
- updates.forEach(({ hash, q, store, pageInfo, aggregate }) => {
716
+ updates.forEach(({ hash, q, store, attrsStore, pageInfo, aggregate }) => {
680
717
  this.querySubs.updateInPlace((prev) => {
681
718
  if (!prev[hash]) {
682
719
  this._log.error('Missing value in querySubs', { hash, q });
683
720
  return;
684
721
  }
685
- prev[hash].result = { store, pageInfo, aggregate, processedTxId };
722
+ prev[hash].result = {
723
+ store,
724
+ attrsStore,
725
+ pageInfo,
726
+ aggregate,
727
+ processedTxId,
728
+ };
686
729
  });
687
730
  });
688
731
  this._cleanupPendingMutationsQueries();
@@ -694,7 +737,7 @@ export default class Reactor {
694
737
  case 'transact-ok': {
695
738
  const { 'client-event-id': eventId, 'tx-id': txId } = msg;
696
739
  this._inFlightMutationEventIds.delete(eventId);
697
- const muts = this._rewriteMutations(this.attrs, this._pendingMutations());
740
+ const muts = this._rewriteMutations(this.ensureAttrs(), this._pendingMutations());
698
741
  const prevMutation = muts.get(eventId);
699
742
  if (!prevMutation) {
700
743
  break;
@@ -703,11 +746,17 @@ export default class Reactor {
703
746
  this._updatePendingMutations((prev) => {
704
747
  prev.set(eventId, Object.assign(Object.assign({}, prev.get(eventId)), { 'tx-id': txId, confirmed: Date.now() }));
705
748
  });
706
- const newAttrs = prevMutation['tx-steps']
707
- .filter(([action, ..._args]) => action === 'add-attr')
708
- .map(([_action, attr]) => attr)
709
- .concat(Object.values(this.attrs));
710
- this._setAttrs(newAttrs);
749
+ const newAttrs = [];
750
+ for (const step of prevMutation['tx-steps']) {
751
+ if (step[0] === 'add-attr') {
752
+ const attr = step[1];
753
+ newAttrs.push(attr);
754
+ }
755
+ }
756
+ if (newAttrs.length) {
757
+ const existingAttrs = Object.values(this.ensureAttrs().attrs);
758
+ this._setAttrs([...existingAttrs, ...newAttrs]);
759
+ }
711
760
  this._finishTransaction('synced', eventId);
712
761
  this._cleanupPendingMutationsTimeout();
713
762
  break;
@@ -868,10 +917,10 @@ export default class Reactor {
868
917
  this._completeQueryOnce(q, hash, r.dfd);
869
918
  }
870
919
  _setAttrs(attrs) {
871
- this.attrs = attrs.reduce((acc, attr) => {
920
+ this.attrs = new s.AttrsStoreClass(attrs.reduce((acc, attr) => {
872
921
  acc[attr.id] = attr;
873
922
  return acc;
874
- }, {});
923
+ }, {}), this._linkIndex);
875
924
  this.notifyAttrsSubs();
876
925
  }
877
926
  _startQuerySub(q, hash) {
@@ -977,6 +1026,12 @@ export default class Reactor {
977
1026
  // We remove `add-attr` commands for attrs that already exist.
978
1027
  // We update `add-triple` and `retract-triple` commands to use the
979
1028
  // server attr-ids.
1029
+ /**
1030
+ *
1031
+ * @param {s.AttrsStore} attrs
1032
+ * @param {any} muts
1033
+ * @param {number} [processedTxId]
1034
+ */
980
1035
  _rewriteMutations(attrs, muts, processedTxId) {
981
1036
  if (!attrs)
982
1037
  return muts;
@@ -984,12 +1039,12 @@ export default class Reactor {
984
1039
  return new Map();
985
1040
  const findExistingAttr = (attr) => {
986
1041
  const [_, etype, label] = attr['forward-identity'];
987
- const existing = instaml.getAttrByFwdIdentName(attrs, etype, label);
1042
+ const existing = s.getAttrByFwdIdentName(attrs, etype, label);
988
1043
  return existing;
989
1044
  };
990
1045
  const findReverseAttr = (attr) => {
991
1046
  const [_, etype, label] = attr['forward-identity'];
992
- const revAttr = instaml.getAttrByReverseIdentName(attrs, etype, label);
1047
+ const revAttr = s.getAttrByReverseIdentName(attrs, etype, label);
993
1048
  return revAttr;
994
1049
  };
995
1050
  const mapping = { attrIdMap: {}, refSwapAttrIds: new Set() };
@@ -1052,8 +1107,11 @@ export default class Reactor {
1052
1107
  }
1053
1108
  // ---------------------------
1054
1109
  // Transact
1110
+ /**
1111
+ * @returns {s.AttrsStore}
1112
+ */
1055
1113
  optimisticAttrs() {
1056
- var _a;
1114
+ var _a, _b;
1057
1115
  const pendingMutationSteps = [...this._pendingMutations().values()] // hack due to Map()
1058
1116
  .flatMap((x) => x['tx-steps']);
1059
1117
  const deletedAttrIds = new Set(pendingMutationSteps
@@ -1066,17 +1124,22 @@ export default class Reactor {
1066
1124
  }
1067
1125
  else if (_action === 'update-attr' &&
1068
1126
  attr.id &&
1069
- ((_a = this.attrs) === null || _a === void 0 ? void 0 : _a[attr.id])) {
1070
- const fullAttr = Object.assign(Object.assign({}, this.attrs[attr.id]), attr);
1127
+ ((_a = this.attrs) === null || _a === void 0 ? void 0 : _a.getAttr(attr.id))) {
1128
+ const fullAttr = Object.assign(Object.assign({}, this.attrs.getAttr(attr.id)), attr);
1071
1129
  pendingAttrs.push(fullAttr);
1072
1130
  }
1073
1131
  }
1074
- const attrsWithoutDeleted = [
1075
- ...Object.values(this.attrs || {}),
1076
- ...pendingAttrs,
1077
- ].filter((a) => !deletedAttrIds.has(a.id));
1078
- const attrsRecord = Object.fromEntries(attrsWithoutDeleted.map((a) => [a.id, a]));
1079
- return attrsRecord;
1132
+ if (!deletedAttrIds.size && !pendingAttrs.length) {
1133
+ return this.attrs || new s.AttrsStoreClass({}, this._linkIndex);
1134
+ }
1135
+ const attrs = Object.assign({}, (((_b = this.attrs) === null || _b === void 0 ? void 0 : _b.attrs) || {}));
1136
+ for (const attr of pendingAttrs) {
1137
+ attrs[attr.id] = attr;
1138
+ }
1139
+ for (const id of deletedAttrIds) {
1140
+ delete attrs[id];
1141
+ }
1142
+ return new s.AttrsStoreClass(attrs, this._linkIndex);
1080
1143
  }
1081
1144
  /** Runs instaql on a query and a store */
1082
1145
  dataForQuery(hash) {
@@ -1101,19 +1164,21 @@ export default class Reactor {
1101
1164
  pendingMutationsVersion === cached.pendingMutationsVersion) {
1102
1165
  return cached;
1103
1166
  }
1104
- const { store, pageInfo, aggregate, processedTxId } = result;
1105
- const mutations = this._rewriteMutationsSorted(store.attrs, pendingMutations);
1106
- const newStore = this._applyOptimisticUpdates(store, mutations, processedTxId);
1107
- const resp = instaql({ store: newStore, pageInfo, aggregate }, q);
1167
+ const { store, attrsStore, pageInfo, aggregate, processedTxId } = result;
1168
+ const mutations = this._rewriteMutationsSorted(attrsStore, pendingMutations);
1169
+ const { store: newStore, attrsStore: newAttrsStore } = this._applyOptimisticUpdates(store, attrsStore, mutations, processedTxId);
1170
+ const resp = instaql({ store: newStore, attrsStore: newAttrsStore, pageInfo, aggregate }, q);
1108
1171
  return { data: resp, querySubVersion, pendingMutationsVersion };
1109
1172
  }
1110
- _applyOptimisticUpdates(store, mutations, processedTxId) {
1173
+ _applyOptimisticUpdates(store, attrsStore, mutations, processedTxId) {
1111
1174
  for (const [_, mut] of mutations) {
1112
1175
  if (!mut['tx-id'] || (processedTxId && mut['tx-id'] > processedTxId)) {
1113
- store = s.transact(store, mut['tx-steps']);
1176
+ const result = s.transact(store, attrsStore, mut['tx-steps']);
1177
+ store = result.store;
1178
+ attrsStore = result.attrsStore;
1114
1179
  }
1115
1180
  }
1116
- return store;
1181
+ return { store, attrsStore };
1117
1182
  }
1118
1183
  /** Re-compute all subscriptions */
1119
1184
  notifyAll() {
@@ -1193,7 +1258,7 @@ export default class Reactor {
1193
1258
  .forEach(({ eventId, q }) => {
1194
1259
  this._trySendAuthed(eventId, { op: 'add-query', q });
1195
1260
  });
1196
- const muts = this._rewriteMutationsSorted(this.attrs, this._pendingMutations());
1261
+ const muts = this._rewriteMutationsSorted(this.ensureAttrs(), this._pendingMutations());
1197
1262
  muts.forEach(([eventId, mut]) => {
1198
1263
  if (!mut['tx-id']) {
1199
1264
  this._sendMutation(eventId, mut);
@@ -1480,7 +1545,7 @@ export default class Reactor {
1480
1545
  subscribeAttrs(cb) {
1481
1546
  this.attrsCbs.push(cb);
1482
1547
  if (this.attrs) {
1483
- cb(this.attrs);
1548
+ cb(this.attrs.attrs);
1484
1549
  }
1485
1550
  return () => {
1486
1551
  this.attrsCbs = this.attrsCbs.filter((x) => x !== cb);
@@ -1496,7 +1561,7 @@ export default class Reactor {
1496
1561
  if (!this.attrs)
1497
1562
  return;
1498
1563
  const oas = this.optimisticAttrs();
1499
- this.attrsCbs.forEach((cb) => cb(oas));
1564
+ this.attrsCbs.forEach((cb) => cb(oas.attrs));
1500
1565
  }
1501
1566
  notifyConnectionStatusSubs(status) {
1502
1567
  this.connectionStatusCbs.forEach((cb) => cb(status));