@instantdb/core 0.22.86-experimental.split-store.20178922132.1 → 0.22.87-experimental.drewh-explorer-component.20180358679.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.
- package/dist/commonjs/Reactor.d.ts +6 -20
- package/dist/commonjs/Reactor.d.ts.map +1 -1
- package/dist/commonjs/Reactor.js +42 -97
- package/dist/commonjs/Reactor.js.map +1 -1
- package/dist/commonjs/SyncTable.d.ts +1 -4
- package/dist/commonjs/SyncTable.d.ts.map +1 -1
- package/dist/commonjs/SyncTable.js +37 -35
- package/dist/commonjs/SyncTable.js.map +1 -1
- package/dist/commonjs/instaml.d.ts +4 -17
- package/dist/commonjs/instaml.d.ts.map +1 -1
- package/dist/commonjs/instaml.js +76 -105
- package/dist/commonjs/instaml.js.map +1 -1
- package/dist/commonjs/instaql.d.ts +1 -2
- package/dist/commonjs/instaql.d.ts.map +1 -1
- package/dist/commonjs/instaql.js +63 -65
- package/dist/commonjs/instaql.js.map +1 -1
- package/dist/commonjs/store.d.ts +21 -44
- package/dist/commonjs/store.d.ts.map +1 -1
- package/dist/commonjs/store.js +69 -164
- package/dist/commonjs/store.js.map +1 -1
- package/dist/esm/Reactor.d.ts +6 -20
- package/dist/esm/Reactor.d.ts.map +1 -1
- package/dist/esm/Reactor.js +43 -98
- package/dist/esm/Reactor.js.map +1 -1
- package/dist/esm/SyncTable.d.ts +1 -4
- package/dist/esm/SyncTable.d.ts.map +1 -1
- package/dist/esm/SyncTable.js +37 -35
- package/dist/esm/SyncTable.js.map +1 -1
- package/dist/esm/instaml.d.ts +4 -17
- package/dist/esm/instaml.d.ts.map +1 -1
- package/dist/esm/instaml.js +71 -102
- package/dist/esm/instaml.js.map +1 -1
- package/dist/esm/instaql.d.ts +1 -2
- package/dist/esm/instaql.d.ts.map +1 -1
- package/dist/esm/instaql.js +63 -65
- package/dist/esm/instaql.js.map +1 -1
- package/dist/esm/store.d.ts +21 -44
- package/dist/esm/store.d.ts.map +1 -1
- package/dist/esm/store.js +69 -161
- package/dist/esm/store.js.map +1 -1
- package/dist/standalone/index.js +1364 -1536
- package/dist/standalone/index.umd.cjs +3 -3
- package/package.json +2 -2
- package/src/Reactor.js +58 -126
- package/src/SyncTable.ts +45 -85
- package/src/{instaml.ts → instaml.js} +95 -195
- package/src/instaql.ts +60 -86
- package/src/store.ts +79 -209
- package/dist/commonjs/reactorTypes.d.ts +0 -29
- package/dist/commonjs/reactorTypes.d.ts.map +0 -1
- package/dist/commonjs/reactorTypes.js +0 -3
- package/dist/commonjs/reactorTypes.js.map +0 -1
- package/dist/esm/reactorTypes.d.ts +0 -29
- package/dist/esm/reactorTypes.d.ts.map +0 -1
- package/dist/esm/reactorTypes.js +0 -2
- package/dist/esm/reactorTypes.js.map +0 -1
- package/src/reactorTypes.ts +0 -32
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instantdb/core",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.87-experimental.drewh-explorer-component.20180358679.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.
|
|
56
|
+
"@instantdb/version": "0.22.87-experimental.drewh-explorer-component.20180358679.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.
|
|
5
|
-
import * as
|
|
4
|
+
import * as instaml from './instaml.js';
|
|
5
|
+
import * as s 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,8 +36,6 @@ 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 */
|
|
41
39
|
|
|
42
40
|
const STATUS = {
|
|
43
41
|
CONNECTING: 'connecting',
|
|
@@ -109,52 +107,27 @@ const ignoreLogging = {
|
|
|
109
107
|
'patch-presence': true,
|
|
110
108
|
};
|
|
111
109
|
|
|
112
|
-
/**
|
|
113
|
-
* @param {QuerySubInStorage} x
|
|
114
|
-
* @param {boolean | null} useDateObjects
|
|
115
|
-
* @returns {QuerySub}
|
|
116
|
-
*/
|
|
117
110
|
function querySubFromStorage(x, useDateObjects) {
|
|
118
111
|
const v = typeof x === 'string' ? JSON.parse(x) : x;
|
|
119
112
|
|
|
120
113
|
if (v?.result?.store) {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
}
|
|
114
|
+
const storeJSON = v.result.store;
|
|
115
|
+
v.result.store = s.fromJSON({
|
|
116
|
+
...storeJSON,
|
|
117
|
+
useDateObjects: useDateObjects,
|
|
118
|
+
});
|
|
133
119
|
}
|
|
134
120
|
|
|
135
121
|
return v;
|
|
136
122
|
}
|
|
137
123
|
|
|
138
|
-
/**
|
|
139
|
-
*
|
|
140
|
-
* @param {string} _key
|
|
141
|
-
* @param {QuerySub} sub
|
|
142
|
-
* @returns QuerySubInStorage
|
|
143
|
-
*/
|
|
144
124
|
function querySubToStorage(_key, sub) {
|
|
145
|
-
const {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
/** @type {import('./reactorTypes.ts').QuerySubResultInStorage} */
|
|
151
|
-
const jsonResult = {
|
|
152
|
-
...result,
|
|
153
|
-
store: sts.toJSON(result.store),
|
|
154
|
-
attrsStore: result.attrsStore.toJSON(),
|
|
125
|
+
const jsonSub = { ...sub };
|
|
126
|
+
if (sub.result?.store) {
|
|
127
|
+
jsonSub.result = {
|
|
128
|
+
...sub.result,
|
|
129
|
+
store: s.toJSON(sub.result.store),
|
|
155
130
|
};
|
|
156
|
-
|
|
157
|
-
jsonSub.result = jsonResult;
|
|
158
131
|
}
|
|
159
132
|
return jsonSub;
|
|
160
133
|
}
|
|
@@ -203,13 +176,12 @@ function sortedMutationEntries(entries) {
|
|
|
203
176
|
* @template {import('./presence.ts').RoomSchemaShape} [RoomSchema = {}]
|
|
204
177
|
*/
|
|
205
178
|
export default class Reactor {
|
|
206
|
-
/** @type {sts.AttrsStore | undefined} */
|
|
207
179
|
attrs;
|
|
208
180
|
_isOnline = true;
|
|
209
181
|
_isShutdown = false;
|
|
210
182
|
status = STATUS.CONNECTING;
|
|
211
183
|
|
|
212
|
-
/** @type {PersistedObject
|
|
184
|
+
/** @type {PersistedObject} */
|
|
213
185
|
querySubs;
|
|
214
186
|
|
|
215
187
|
/** @type {PersistedObject} */
|
|
@@ -334,15 +306,14 @@ export default class Reactor {
|
|
|
334
306
|
useDateObjects: this.config.useDateObjects,
|
|
335
307
|
},
|
|
336
308
|
this._log,
|
|
337
|
-
(triples) =>
|
|
338
|
-
|
|
339
|
-
this.
|
|
309
|
+
(triples) =>
|
|
310
|
+
s.createStore(
|
|
311
|
+
this.attrs,
|
|
340
312
|
triples,
|
|
341
313
|
this.config.enableCardinalityInference,
|
|
314
|
+
this._linkIndex,
|
|
342
315
|
this.config.useDateObjects,
|
|
343
|
-
)
|
|
344
|
-
},
|
|
345
|
-
() => this.ensureAttrs(),
|
|
316
|
+
),
|
|
346
317
|
);
|
|
347
318
|
|
|
348
319
|
this._oauthCallbackResponse = this._oauthLoginInit();
|
|
@@ -382,13 +353,6 @@ export default class Reactor {
|
|
|
382
353
|
}
|
|
383
354
|
}
|
|
384
355
|
|
|
385
|
-
ensureAttrs() {
|
|
386
|
-
if (!this.attrs) {
|
|
387
|
-
throw new Error('attrs have not loaded.');
|
|
388
|
-
}
|
|
389
|
-
return this.attrs;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
356
|
updateSchema(schema) {
|
|
393
357
|
this.config = {
|
|
394
358
|
...this.config,
|
|
@@ -419,7 +383,7 @@ export default class Reactor {
|
|
|
419
383
|
serialize: querySubToStorage,
|
|
420
384
|
parse: (_key, x) => querySubFromStorage(x, this.config.useDateObjects),
|
|
421
385
|
// objectSize
|
|
422
|
-
objectSize: (x) => x
|
|
386
|
+
objectSize: (x) => x.result?.store?.triples?.length ?? 0,
|
|
423
387
|
logger: this._log,
|
|
424
388
|
preloadEntryCount: 10,
|
|
425
389
|
gc: {
|
|
@@ -588,13 +552,13 @@ export default class Reactor {
|
|
|
588
552
|
const pageInfo = result?.[0]?.data?.['page-info'];
|
|
589
553
|
const aggregate = result?.[0]?.data?.['aggregate'];
|
|
590
554
|
const triples = extractTriples(result);
|
|
591
|
-
const store =
|
|
592
|
-
this.
|
|
555
|
+
const store = s.createStore(
|
|
556
|
+
this.attrs,
|
|
593
557
|
triples,
|
|
594
558
|
enableCardinalityInference,
|
|
559
|
+
this._linkIndex,
|
|
595
560
|
this.config.useDateObjects,
|
|
596
561
|
);
|
|
597
|
-
|
|
598
562
|
this.querySubs.updateInPlace((prev) => {
|
|
599
563
|
if (!prev[hash]) {
|
|
600
564
|
this._log.info('Missing value in querySubs', { hash, q });
|
|
@@ -602,7 +566,6 @@ export default class Reactor {
|
|
|
602
566
|
}
|
|
603
567
|
prev[hash].result = {
|
|
604
568
|
store,
|
|
605
|
-
attrsStore: this.ensureAttrs(),
|
|
606
569
|
pageInfo,
|
|
607
570
|
aggregate,
|
|
608
571
|
processedTxId: msg['processed-tx-id'],
|
|
@@ -640,7 +603,7 @@ export default class Reactor {
|
|
|
640
603
|
this._cleanupPendingMutationsTimeout();
|
|
641
604
|
|
|
642
605
|
const rewrittenMutations = this._rewriteMutations(
|
|
643
|
-
this.
|
|
606
|
+
this.attrs,
|
|
644
607
|
this._pendingMutations(),
|
|
645
608
|
processedTxId,
|
|
646
609
|
);
|
|
@@ -661,15 +624,15 @@ export default class Reactor {
|
|
|
661
624
|
const result = x['instaql-result'];
|
|
662
625
|
const hash = weakHash(q);
|
|
663
626
|
const triples = extractTriples(result);
|
|
664
|
-
const store =
|
|
665
|
-
this.
|
|
627
|
+
const store = s.createStore(
|
|
628
|
+
this.attrs,
|
|
666
629
|
triples,
|
|
667
630
|
enableCardinalityInference,
|
|
631
|
+
this._linkIndex,
|
|
668
632
|
this.config.useDateObjects,
|
|
669
633
|
);
|
|
670
634
|
const newStore = this._applyOptimisticUpdates(
|
|
671
635
|
store,
|
|
672
|
-
this.ensureAttrs(),
|
|
673
636
|
mutations,
|
|
674
637
|
processedTxId,
|
|
675
638
|
);
|
|
@@ -684,13 +647,7 @@ export default class Reactor {
|
|
|
684
647
|
this._log.error('Missing value in querySubs', { hash, q });
|
|
685
648
|
return;
|
|
686
649
|
}
|
|
687
|
-
prev[hash].result = {
|
|
688
|
-
store,
|
|
689
|
-
attrsStore: this.ensureAttrs(),
|
|
690
|
-
pageInfo,
|
|
691
|
-
aggregate,
|
|
692
|
-
processedTxId,
|
|
693
|
-
};
|
|
650
|
+
prev[hash].result = { store, pageInfo, aggregate, processedTxId };
|
|
694
651
|
});
|
|
695
652
|
});
|
|
696
653
|
|
|
@@ -707,7 +664,7 @@ export default class Reactor {
|
|
|
707
664
|
this._inFlightMutationEventIds.delete(eventId);
|
|
708
665
|
|
|
709
666
|
const muts = this._rewriteMutations(
|
|
710
|
-
this.
|
|
667
|
+
this.attrs,
|
|
711
668
|
this._pendingMutations(),
|
|
712
669
|
);
|
|
713
670
|
const prevMutation = muts.get(eventId);
|
|
@@ -724,18 +681,12 @@ export default class Reactor {
|
|
|
724
681
|
});
|
|
725
682
|
});
|
|
726
683
|
|
|
727
|
-
const newAttrs = []
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
}
|
|
734
|
-
if (newAttrs.length) {
|
|
735
|
-
const existingAttrs = Object.values(this.ensureAttrs());
|
|
736
|
-
this._setAttrs([...existingAttrs, ...newAttrs]);
|
|
737
|
-
this._setAttrs(newAttrs);
|
|
738
|
-
}
|
|
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);
|
|
739
690
|
|
|
740
691
|
this._finishTransaction('synced', eventId);
|
|
741
692
|
|
|
@@ -919,13 +870,10 @@ export default class Reactor {
|
|
|
919
870
|
}
|
|
920
871
|
|
|
921
872
|
_setAttrs(attrs) {
|
|
922
|
-
this.attrs =
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
}, {}),
|
|
927
|
-
this._linkIndex,
|
|
928
|
-
);
|
|
873
|
+
this.attrs = attrs.reduce((acc, attr) => {
|
|
874
|
+
acc[attr.id] = attr;
|
|
875
|
+
return acc;
|
|
876
|
+
}, {});
|
|
929
877
|
|
|
930
878
|
this.notifyAttrsSubs();
|
|
931
879
|
}
|
|
@@ -1074,23 +1022,17 @@ export default class Reactor {
|
|
|
1074
1022
|
// We remove `add-attr` commands for attrs that already exist.
|
|
1075
1023
|
// We update `add-triple` and `retract-triple` commands to use the
|
|
1076
1024
|
// server attr-ids.
|
|
1077
|
-
/**
|
|
1078
|
-
*
|
|
1079
|
-
* @param {sts.AttrsStore} attrs
|
|
1080
|
-
* @param {any} muts
|
|
1081
|
-
* @param {number} [processedTxId]
|
|
1082
|
-
*/
|
|
1083
1025
|
_rewriteMutations(attrs, muts, processedTxId) {
|
|
1084
1026
|
if (!attrs) return muts;
|
|
1085
1027
|
if (!muts) return new Map();
|
|
1086
1028
|
const findExistingAttr = (attr) => {
|
|
1087
1029
|
const [_, etype, label] = attr['forward-identity'];
|
|
1088
|
-
const existing =
|
|
1030
|
+
const existing = instaml.getAttrByFwdIdentName(attrs, etype, label);
|
|
1089
1031
|
return existing;
|
|
1090
1032
|
};
|
|
1091
1033
|
const findReverseAttr = (attr) => {
|
|
1092
1034
|
const [_, etype, label] = attr['forward-identity'];
|
|
1093
|
-
const revAttr =
|
|
1035
|
+
const revAttr = instaml.getAttrByReverseIdentName(attrs, etype, label);
|
|
1094
1036
|
return revAttr;
|
|
1095
1037
|
};
|
|
1096
1038
|
const mapping = { attrIdMap: {}, refSwapAttrIds: new Set() };
|
|
@@ -1167,9 +1109,6 @@ export default class Reactor {
|
|
|
1167
1109
|
// ---------------------------
|
|
1168
1110
|
// Transact
|
|
1169
1111
|
|
|
1170
|
-
/**
|
|
1171
|
-
* @returns {sts.AttrsStore}
|
|
1172
|
-
*/
|
|
1173
1112
|
optimisticAttrs() {
|
|
1174
1113
|
const pendingMutationSteps = [...this._pendingMutations().values()] // hack due to Map()
|
|
1175
1114
|
.flatMap((x) => x['tx-steps']);
|
|
@@ -1187,26 +1126,23 @@ export default class Reactor {
|
|
|
1187
1126
|
} else if (
|
|
1188
1127
|
_action === 'update-attr' &&
|
|
1189
1128
|
attr.id &&
|
|
1190
|
-
this.attrs?.
|
|
1129
|
+
this.attrs?.[attr.id]
|
|
1191
1130
|
) {
|
|
1192
|
-
const fullAttr = { ...this.attrs
|
|
1131
|
+
const fullAttr = { ...this.attrs[attr.id], ...attr };
|
|
1193
1132
|
pendingAttrs.push(fullAttr);
|
|
1194
1133
|
}
|
|
1195
1134
|
}
|
|
1196
1135
|
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1136
|
+
const attrsWithoutDeleted = [
|
|
1137
|
+
...Object.values(this.attrs || {}),
|
|
1138
|
+
...pendingAttrs,
|
|
1139
|
+
].filter((a) => !deletedAttrIds.has(a.id));
|
|
1200
1140
|
|
|
1201
|
-
const
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
}
|
|
1205
|
-
for (const id of deletedAttrIds) {
|
|
1206
|
-
delete attrs[id];
|
|
1207
|
-
}
|
|
1141
|
+
const attrsRecord = Object.fromEntries(
|
|
1142
|
+
attrsWithoutDeleted.map((a) => [a.id, a]),
|
|
1143
|
+
);
|
|
1208
1144
|
|
|
1209
|
-
return
|
|
1145
|
+
return attrsRecord;
|
|
1210
1146
|
}
|
|
1211
1147
|
|
|
1212
1148
|
/** Runs instaql on a query and a store */
|
|
@@ -1234,29 +1170,25 @@ export default class Reactor {
|
|
|
1234
1170
|
return cached;
|
|
1235
1171
|
}
|
|
1236
1172
|
|
|
1237
|
-
const { store,
|
|
1173
|
+
const { store, pageInfo, aggregate, processedTxId } = result;
|
|
1238
1174
|
const mutations = this._rewriteMutationsSorted(
|
|
1239
|
-
|
|
1175
|
+
store.attrs,
|
|
1240
1176
|
pendingMutations,
|
|
1241
1177
|
);
|
|
1242
1178
|
const newStore = this._applyOptimisticUpdates(
|
|
1243
1179
|
store,
|
|
1244
|
-
attrsStore,
|
|
1245
1180
|
mutations,
|
|
1246
1181
|
processedTxId,
|
|
1247
1182
|
);
|
|
1248
|
-
const resp = instaql(
|
|
1249
|
-
{ store: newStore, attrsStore, pageInfo, aggregate },
|
|
1250
|
-
q,
|
|
1251
|
-
);
|
|
1183
|
+
const resp = instaql({ store: newStore, pageInfo, aggregate }, q);
|
|
1252
1184
|
|
|
1253
1185
|
return { data: resp, querySubVersion, pendingMutationsVersion };
|
|
1254
1186
|
}
|
|
1255
1187
|
|
|
1256
|
-
_applyOptimisticUpdates(store,
|
|
1188
|
+
_applyOptimisticUpdates(store, mutations, processedTxId) {
|
|
1257
1189
|
for (const [_, mut] of mutations) {
|
|
1258
1190
|
if (!mut['tx-id'] || (processedTxId && mut['tx-id'] > processedTxId)) {
|
|
1259
|
-
store =
|
|
1191
|
+
store = s.transact(store, mut['tx-steps']);
|
|
1260
1192
|
}
|
|
1261
1193
|
}
|
|
1262
1194
|
return store;
|
|
@@ -1316,7 +1248,7 @@ export default class Reactor {
|
|
|
1316
1248
|
try {
|
|
1317
1249
|
const txSteps = instaml.transform(
|
|
1318
1250
|
{
|
|
1319
|
-
|
|
1251
|
+
attrs: this.optimisticAttrs(),
|
|
1320
1252
|
schema: this.config.schema,
|
|
1321
1253
|
stores: Object.values(this.querySubs.currentValue).map(
|
|
1322
1254
|
(sub) => sub?.result?.store,
|
|
@@ -1434,7 +1366,7 @@ export default class Reactor {
|
|
|
1434
1366
|
});
|
|
1435
1367
|
|
|
1436
1368
|
const muts = this._rewriteMutationsSorted(
|
|
1437
|
-
this.
|
|
1369
|
+
this.attrs,
|
|
1438
1370
|
this._pendingMutations(),
|
|
1439
1371
|
);
|
|
1440
1372
|
muts.forEach(([eventId, mut]) => {
|
|
@@ -1890,7 +1822,7 @@ export default class Reactor {
|
|
|
1890
1822
|
this.attrsCbs.push(cb);
|
|
1891
1823
|
|
|
1892
1824
|
if (this.attrs) {
|
|
1893
|
-
cb(this.attrs
|
|
1825
|
+
cb(this.attrs);
|
|
1894
1826
|
}
|
|
1895
1827
|
|
|
1896
1828
|
return () => {
|
package/src/SyncTable.ts
CHANGED
|
@@ -16,12 +16,12 @@ type SubState = {
|
|
|
16
16
|
|
|
17
17
|
type SubEntity = {
|
|
18
18
|
entity: any;
|
|
19
|
-
store:
|
|
19
|
+
store: any;
|
|
20
20
|
serverCreatedAt: number;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
type SubValues = {
|
|
24
|
-
|
|
24
|
+
attrs: Record<string, any>;
|
|
25
25
|
entities: Array<SubEntity>;
|
|
26
26
|
};
|
|
27
27
|
|
|
@@ -38,21 +38,8 @@ type Sub = {
|
|
|
38
38
|
updatedAt: number;
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
type SubEntityInStorage = {
|
|
42
|
-
entity: any;
|
|
43
|
-
store: s.StoreJson;
|
|
44
|
-
serverCreatedAt: number;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
type SubValuesInStorage = {
|
|
48
|
-
attrsStore: s.AttrsStoreJson;
|
|
49
|
-
entities: Array<SubEntityInStorage>;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
41
|
// We could make a better type for this if we had a return type for s.toJSON
|
|
53
|
-
type SubInStorage =
|
|
54
|
-
values: SubValuesInStorage;
|
|
55
|
-
};
|
|
42
|
+
type SubInStorage = Sub;
|
|
56
43
|
|
|
57
44
|
type StartMsg = {
|
|
58
45
|
op: 'start-sync';
|
|
@@ -109,38 +96,36 @@ type Config = { useDateObjects: boolean };
|
|
|
109
96
|
function syncSubFromStorage(sub: SubInStorage, useDateObjects: boolean): Sub {
|
|
110
97
|
const values = sub.values;
|
|
111
98
|
if (values) {
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
(e as unknown as SubEntity).store = s.fromJSON(attrsStore, e.store);
|
|
117
|
-
}
|
|
118
|
-
(values as unknown as SubValues).attrsStore = attrsStore;
|
|
99
|
+
for (const e of values.entities || []) {
|
|
100
|
+
e.store.useDateObjects = useDateObjects;
|
|
101
|
+
e.store.attrs = values.attrs;
|
|
102
|
+
e.store = s.fromJSON(e.store);
|
|
119
103
|
}
|
|
120
104
|
}
|
|
121
105
|
|
|
122
|
-
return sub
|
|
106
|
+
return sub;
|
|
123
107
|
}
|
|
124
108
|
|
|
125
109
|
function syncSubToStorage(_k: string, sub: Sub): SubInStorage {
|
|
126
|
-
if (sub.values) {
|
|
127
|
-
const entities:
|
|
110
|
+
if (sub.values?.entities) {
|
|
111
|
+
const entities: SubEntity[] = [];
|
|
128
112
|
for (const e of sub.values?.entities) {
|
|
129
113
|
const store = s.toJSON(e.store);
|
|
114
|
+
// We'll store the attrs once on values, and put the
|
|
115
|
+
// attrs back into the store on hydration
|
|
116
|
+
// @ts-ignore: ts doesn't want us to delete a non-optional
|
|
117
|
+
delete store['attrs'];
|
|
130
118
|
entities.push({ ...e, store });
|
|
131
119
|
}
|
|
132
|
-
return {
|
|
133
|
-
...sub,
|
|
134
|
-
values: { attrsStore: sub.values.attrsStore.toJSON(), entities },
|
|
135
|
-
};
|
|
120
|
+
return { ...sub, values: { ...sub.values, entities } };
|
|
136
121
|
} else {
|
|
137
|
-
return sub
|
|
122
|
+
return sub;
|
|
138
123
|
}
|
|
139
124
|
}
|
|
140
125
|
|
|
141
126
|
function onMergeSub(
|
|
142
127
|
_key: string,
|
|
143
|
-
storageSub:
|
|
128
|
+
storageSub: SubInStorage,
|
|
144
129
|
inMemorySub: Sub | null,
|
|
145
130
|
): Sub {
|
|
146
131
|
const storageTxId = storageSub?.state?.txId;
|
|
@@ -157,21 +142,13 @@ function onMergeSub(
|
|
|
157
142
|
return storageSub || inMemorySub;
|
|
158
143
|
}
|
|
159
144
|
|
|
160
|
-
function queryEntity(sub: Sub, store:
|
|
161
|
-
const res = instaql(
|
|
162
|
-
{ store, attrsStore, pageInfo: null, aggregate: null },
|
|
163
|
-
sub.query,
|
|
164
|
-
);
|
|
145
|
+
function queryEntity(sub: Sub, store: any) {
|
|
146
|
+
const res = instaql({ store, pageInfo: null, aggregate: null }, sub.query);
|
|
165
147
|
return res.data[sub.table][0];
|
|
166
148
|
}
|
|
167
149
|
|
|
168
|
-
function getServerCreatedAt(
|
|
169
|
-
sub
|
|
170
|
-
store: s.Store,
|
|
171
|
-
attrsStore: s.AttrsStore,
|
|
172
|
-
entityId: string,
|
|
173
|
-
): number {
|
|
174
|
-
const aid = s.getAttrByFwdIdentName(attrsStore, sub.table, 'id')?.id;
|
|
150
|
+
function getServerCreatedAt(sub: Sub, store: any, entityId: string): number {
|
|
151
|
+
const aid = s.getAttrByFwdIdentName(store, sub.table, 'id')?.id;
|
|
175
152
|
if (!aid) {
|
|
176
153
|
return -1;
|
|
177
154
|
}
|
|
@@ -183,25 +160,23 @@ function getServerCreatedAt(
|
|
|
183
160
|
}
|
|
184
161
|
|
|
185
162
|
function applyChangesToStore(
|
|
186
|
-
store:
|
|
187
|
-
attrsStore: s.AttrsStore,
|
|
163
|
+
store: any,
|
|
188
164
|
changes: SyncUpdateTriplesMsg['txes'][number]['changes'],
|
|
189
165
|
): void {
|
|
190
166
|
for (const { action, triple } of changes) {
|
|
191
167
|
switch (action) {
|
|
192
168
|
case 'added':
|
|
193
|
-
s.addTriple(store,
|
|
169
|
+
s.addTriple(store, triple);
|
|
194
170
|
break;
|
|
195
171
|
case 'removed':
|
|
196
|
-
s.retractTriple(store,
|
|
172
|
+
s.retractTriple(store, triple);
|
|
197
173
|
break;
|
|
198
174
|
}
|
|
199
175
|
}
|
|
200
176
|
}
|
|
201
177
|
|
|
202
178
|
function changedFieldsOfChanges(
|
|
203
|
-
store:
|
|
204
|
-
attrsStore: s.AttrsStore,
|
|
179
|
+
store: any,
|
|
205
180
|
changes: SyncUpdateTriplesMsg['txes'][number]['changes'],
|
|
206
181
|
): {
|
|
207
182
|
[eid: string]: SyncTransaction<
|
|
@@ -215,7 +190,7 @@ function changedFieldsOfChanges(
|
|
|
215
190
|
const changedFields = {};
|
|
216
191
|
for (const { action, triple } of changes) {
|
|
217
192
|
const [e, a, v] = triple;
|
|
218
|
-
const field =
|
|
193
|
+
const field = store.attrs[a]?.['forward-identity']?.[2];
|
|
219
194
|
if (!field) continue;
|
|
220
195
|
|
|
221
196
|
const fields = changedFields[e] ?? {};
|
|
@@ -250,19 +225,17 @@ function subData(sub: Sub, entities: NonNullable<Sub['values']>['entities']) {
|
|
|
250
225
|
return { [sub.table]: entities.map((e) => e.entity) };
|
|
251
226
|
}
|
|
252
227
|
|
|
253
|
-
type CreateStore = (triples: Triple[]) => s.Store;
|
|
254
|
-
|
|
255
228
|
// Updates the sub order field type if it hasn't been set
|
|
256
229
|
// and returns the type. We have to wait until the attrs
|
|
257
230
|
// are loaded before we can determine the type.
|
|
258
|
-
function orderFieldTypeMutative(sub: Sub,
|
|
231
|
+
function orderFieldTypeMutative(sub: Sub, createStore) {
|
|
259
232
|
if (sub.orderFieldType) {
|
|
260
233
|
return sub.orderFieldType;
|
|
261
234
|
}
|
|
262
235
|
const orderFieldType =
|
|
263
236
|
sub.orderField === 'serverCreatedAt'
|
|
264
237
|
? 'number'
|
|
265
|
-
: s.getAttrByFwdIdentName(
|
|
238
|
+
: s.getAttrByFwdIdentName(createStore([]), sub.table, sub.orderField)?.[
|
|
266
239
|
'checked-data-type'
|
|
267
240
|
];
|
|
268
241
|
|
|
@@ -441,22 +414,19 @@ export class SyncTable {
|
|
|
441
414
|
private config: Config;
|
|
442
415
|
private idToHash: { [subscriptionId: string]: string } = {};
|
|
443
416
|
private log: Logger;
|
|
444
|
-
private createStore:
|
|
445
|
-
private getAttrs: () => s.AttrsStore;
|
|
417
|
+
private createStore: (triples: Triple[]) => any;
|
|
446
418
|
|
|
447
419
|
constructor(
|
|
448
420
|
trySend: TrySend,
|
|
449
421
|
storage: StorageInterface,
|
|
450
422
|
config: Config,
|
|
451
423
|
log: Logger,
|
|
452
|
-
createStore:
|
|
453
|
-
getAttrs: () => s.AttrsStore,
|
|
424
|
+
createStore: (triples: Triple[]) => any,
|
|
454
425
|
) {
|
|
455
426
|
this.trySend = trySend;
|
|
456
427
|
this.config = config;
|
|
457
428
|
this.log = log;
|
|
458
429
|
this.createStore = createStore;
|
|
459
|
-
this.getAttrs = getAttrs;
|
|
460
430
|
|
|
461
431
|
this.subs = new PersistedObject<string, Sub, SubInStorage>({
|
|
462
432
|
persister: storage,
|
|
@@ -654,23 +624,19 @@ export class SyncTable {
|
|
|
654
624
|
|
|
655
625
|
const values: SubValues = sub.values ?? {
|
|
656
626
|
entities: [],
|
|
657
|
-
|
|
627
|
+
attrs: this.createStore([]).attrs,
|
|
658
628
|
};
|
|
659
629
|
sub.values = values;
|
|
660
630
|
const entities = values.entities;
|
|
661
631
|
|
|
662
632
|
for (const entRows of joinRows) {
|
|
663
633
|
const store = this.createStore(entRows);
|
|
664
|
-
|
|
634
|
+
values.attrs = store.attrs;
|
|
635
|
+
const entity = queryEntity(sub, store);
|
|
665
636
|
entities.push({
|
|
666
637
|
store,
|
|
667
638
|
entity,
|
|
668
|
-
serverCreatedAt: getServerCreatedAt(
|
|
669
|
-
sub,
|
|
670
|
-
store,
|
|
671
|
-
values.attrsStore,
|
|
672
|
-
entity.id,
|
|
673
|
-
),
|
|
639
|
+
serverCreatedAt: getServerCreatedAt(sub, store, entity.id),
|
|
674
640
|
});
|
|
675
641
|
batch.push(entity);
|
|
676
642
|
}
|
|
@@ -761,7 +727,7 @@ export class SyncTable {
|
|
|
761
727
|
|
|
762
728
|
const values: SubValues = sub.values ?? {
|
|
763
729
|
entities: [],
|
|
764
|
-
|
|
730
|
+
attrs: this.createStore([]).attrs,
|
|
765
731
|
};
|
|
766
732
|
const entities = values.entities;
|
|
767
733
|
sub.values = values;
|
|
@@ -772,13 +738,11 @@ export class SyncTable {
|
|
|
772
738
|
for (let i = 0; i < entities.length; i++) {
|
|
773
739
|
const ent = entities[i];
|
|
774
740
|
if (s.hasEntity(ent.store, eid)) {
|
|
775
|
-
applyChangesToStore(ent.store,
|
|
776
|
-
const entity = queryEntity(sub, ent.store
|
|
777
|
-
const changedFields = changedFieldsOfChanges(
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
changes,
|
|
781
|
-
)[eid];
|
|
741
|
+
applyChangesToStore(ent.store, changes);
|
|
742
|
+
const entity = queryEntity(sub, ent.store);
|
|
743
|
+
const changedFields = changedFieldsOfChanges(ent.store, changes)[
|
|
744
|
+
eid
|
|
745
|
+
];
|
|
782
746
|
if (entity) {
|
|
783
747
|
updated.push({
|
|
784
748
|
oldEntity: ent.entity,
|
|
@@ -799,8 +763,9 @@ export class SyncTable {
|
|
|
799
763
|
// If we have anything left in byEid, then this must be a new entity we don't know about
|
|
800
764
|
for (const [_eid, changes] of Object.entries(byEid)) {
|
|
801
765
|
const store = this.createStore([]);
|
|
802
|
-
|
|
803
|
-
|
|
766
|
+
values.attrs = store.attrs;
|
|
767
|
+
applyChangesToStore(store, changes);
|
|
768
|
+
const entity = queryEntity(sub, store);
|
|
804
769
|
if (!entity) {
|
|
805
770
|
this.log.error('No entity found after applying change', {
|
|
806
771
|
sub,
|
|
@@ -812,12 +777,7 @@ export class SyncTable {
|
|
|
812
777
|
entities.push({
|
|
813
778
|
store,
|
|
814
779
|
entity,
|
|
815
|
-
serverCreatedAt: getServerCreatedAt(
|
|
816
|
-
sub,
|
|
817
|
-
store,
|
|
818
|
-
values.attrsStore,
|
|
819
|
-
entity.id,
|
|
820
|
-
),
|
|
780
|
+
serverCreatedAt: getServerCreatedAt(sub, store, entity.id),
|
|
821
781
|
});
|
|
822
782
|
added.push(entity);
|
|
823
783
|
}
|
|
@@ -829,7 +789,7 @@ export class SyncTable {
|
|
|
829
789
|
entities.splice(idx, 1);
|
|
830
790
|
}
|
|
831
791
|
|
|
832
|
-
const orderFieldType = orderFieldTypeMutative(sub, this.
|
|
792
|
+
const orderFieldType = orderFieldTypeMutative(sub, this.createStore);
|
|
833
793
|
|
|
834
794
|
sortEntitiesInPlace(sub, orderFieldType!, entities);
|
|
835
795
|
this.notifyCbs(hash, {
|