@instantdb/core 0.22.57 → 0.22.58
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/__tests__/src/Reactor.test.js +97 -21
- package/__tests__/src/utils/PersistedObject.test.ts +383 -0
- package/dist/commonjs/InMemoryStorage.d.ts +11 -0
- package/dist/commonjs/InMemoryStorage.d.ts.map +1 -0
- package/dist/commonjs/InMemoryStorage.js +48 -0
- package/dist/commonjs/InMemoryStorage.js.map +1 -0
- package/dist/commonjs/IndexedDBStorage.d.ts +10 -3
- package/dist/commonjs/IndexedDBStorage.d.ts.map +1 -1
- package/dist/commonjs/IndexedDBStorage.js +254 -8
- package/dist/commonjs/IndexedDBStorage.js.map +1 -1
- package/dist/commonjs/Reactor.d.ts +7 -16
- package/dist/commonjs/Reactor.d.ts.map +1 -1
- package/dist/commonjs/Reactor.js +199 -149
- package/dist/commonjs/Reactor.js.map +1 -1
- package/dist/commonjs/SyncTable.d.ts +3 -1
- package/dist/commonjs/SyncTable.d.ts.map +1 -1
- package/dist/commonjs/SyncTable.js +194 -168
- package/dist/commonjs/SyncTable.js.map +1 -1
- package/dist/commonjs/index.d.ts +2 -1
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +3 -1
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/utils/PersistedObject.d.ts +73 -29
- package/dist/commonjs/utils/PersistedObject.d.ts.map +1 -1
- package/dist/commonjs/utils/PersistedObject.js +366 -77
- package/dist/commonjs/utils/PersistedObject.js.map +1 -1
- package/dist/esm/InMemoryStorage.d.ts +11 -0
- package/dist/esm/InMemoryStorage.d.ts.map +1 -0
- package/dist/esm/InMemoryStorage.js +45 -0
- package/dist/esm/InMemoryStorage.js.map +1 -0
- package/dist/esm/IndexedDBStorage.d.ts +10 -3
- package/dist/esm/IndexedDBStorage.d.ts.map +1 -1
- package/dist/esm/IndexedDBStorage.js +254 -8
- package/dist/esm/IndexedDBStorage.js.map +1 -1
- package/dist/esm/Reactor.d.ts +7 -16
- package/dist/esm/Reactor.d.ts.map +1 -1
- package/dist/esm/Reactor.js +199 -149
- package/dist/esm/Reactor.js.map +1 -1
- package/dist/esm/SyncTable.d.ts +3 -1
- package/dist/esm/SyncTable.d.ts.map +1 -1
- package/dist/esm/SyncTable.js +194 -168
- package/dist/esm/SyncTable.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +4 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/utils/PersistedObject.d.ts +73 -29
- package/dist/esm/utils/PersistedObject.d.ts.map +1 -1
- package/dist/esm/utils/PersistedObject.js +364 -76
- package/dist/esm/utils/PersistedObject.js.map +1 -1
- package/dist/standalone/index.js +1978 -1567
- package/dist/standalone/index.umd.cjs +3 -3
- package/package.json +2 -2
- package/src/InMemoryStorage.ts +34 -0
- package/src/IndexedDBStorage.ts +281 -9
- package/src/Reactor.js +212 -184
- package/src/SyncTable.ts +220 -191
- package/src/index.ts +8 -0
- package/src/utils/PersistedObject.ts +480 -109
- package/src/InMemoryStorage.js +0 -14
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Logger } from './Reactor.js';
|
|
2
2
|
import { InstaQLResponse, ValidQuery } from './queryTypes.ts';
|
|
3
3
|
import { EntitiesDef, IContainEntitiesAndLinks } from './schemaTypes.ts';
|
|
4
|
+
import { StorageInterface } from './index.ts';
|
|
4
5
|
type StartMsg = {
|
|
5
6
|
op: 'start-sync';
|
|
6
7
|
q: string;
|
|
@@ -8,6 +9,7 @@ type StartMsg = {
|
|
|
8
9
|
type EndMsg = {
|
|
9
10
|
op: 'remove-sync';
|
|
10
11
|
'subscription-id': string;
|
|
12
|
+
'keep-subscription': boolean;
|
|
11
13
|
};
|
|
12
14
|
type ResyncMsg = {
|
|
13
15
|
op: 'resync-table';
|
|
@@ -103,7 +105,7 @@ export declare class SyncTable {
|
|
|
103
105
|
private idToHash;
|
|
104
106
|
private log;
|
|
105
107
|
private createStore;
|
|
106
|
-
constructor(trySend: TrySend,
|
|
108
|
+
constructor(trySend: TrySend, storage: StorageInterface, config: Config, log: Logger, createStore: (triples: Triple[]) => any);
|
|
107
109
|
beforeUnload(): void;
|
|
108
110
|
subscribe(q: any, cb: SyncTableCallback<any, any, any>): (opts?: {
|
|
109
111
|
keepSubscription?: boolean | null | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SyncTable.d.ts","sourceRoot":"","sources":["../../src/SyncTable.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"SyncTable.d.ts","sourceRoot":"","sources":["../../src/SyncTable.ts"],"names":[],"mappings":"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"}
|
|
@@ -52,44 +52,44 @@ const weakHash_ts_1 = __importDefault(require("./utils/weakHash.js"));
|
|
|
52
52
|
const uuid_ts_1 = __importDefault(require("./utils/uuid.js"));
|
|
53
53
|
const instaql_js_1 = __importStar(require("./instaql.js"));
|
|
54
54
|
// Modifies the data in place because it comes directly from storage
|
|
55
|
-
function
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
for (const e of
|
|
55
|
+
function syncSubFromStorage(sub, useDateObjects) {
|
|
56
|
+
const values = sub.values;
|
|
57
|
+
if (values) {
|
|
58
|
+
for (const e of values.entities || []) {
|
|
59
59
|
e.store.useDateObjects = useDateObjects;
|
|
60
|
+
e.store.attrs = values.attrs;
|
|
60
61
|
e.store = s.fromJSON(e.store);
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
|
-
return
|
|
64
|
+
return sub;
|
|
64
65
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
jsonSubs[key] = sub;
|
|
66
|
+
function syncSubToStorage(_k, sub) {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
if ((_a = sub.values) === null || _a === void 0 ? void 0 : _a.entities) {
|
|
69
|
+
const entities = [];
|
|
70
|
+
for (const e of (_b = sub.values) === null || _b === void 0 ? void 0 : _b.entities) {
|
|
71
|
+
const store = s.toJSON(e.store);
|
|
72
|
+
// We'll store the attrs once on values, and put the
|
|
73
|
+
// attrs back into the store on hydration
|
|
74
|
+
delete store['attrs'];
|
|
75
|
+
entities.push(Object.assign(Object.assign({}, e), { store }));
|
|
78
76
|
}
|
|
77
|
+
return Object.assign(Object.assign({}, sub), { values: Object.assign(Object.assign({}, sub.values), { entities }) });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
return sub;
|
|
79
81
|
}
|
|
80
|
-
return jsonSubs;
|
|
81
82
|
}
|
|
82
|
-
function
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
function onMergeSub(_key, storageSub, inMemorySub) {
|
|
84
|
+
const storageTxId = storageSub === null || storageSub === void 0 ? void 0 : storageSub.state.txId;
|
|
85
|
+
const memoryTxId = inMemorySub === null || inMemorySub === void 0 ? void 0 : inMemorySub.state.txId;
|
|
86
|
+
if (storageTxId && (!memoryTxId || storageTxId > memoryTxId)) {
|
|
87
|
+
return storageSub;
|
|
86
88
|
}
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
subs[k] = v;
|
|
90
|
-
}
|
|
89
|
+
if (memoryTxId && (!storageTxId || memoryTxId > storageTxId)) {
|
|
90
|
+
return inMemorySub;
|
|
91
91
|
}
|
|
92
|
-
return
|
|
92
|
+
return storageSub || inMemorySub;
|
|
93
93
|
}
|
|
94
94
|
function queryEntity(sub, store) {
|
|
95
95
|
const res = (0, instaql_js_1.default)({ store, pageInfo: null, aggregate: null }, sub.query);
|
|
@@ -180,7 +180,7 @@ var CallbackEventType;
|
|
|
180
180
|
CallbackEventType["Error"] = "Error";
|
|
181
181
|
})(CallbackEventType || (exports.CallbackEventType = CallbackEventType = {}));
|
|
182
182
|
class SyncTable {
|
|
183
|
-
constructor(trySend,
|
|
183
|
+
constructor(trySend, storage, config, log, createStore) {
|
|
184
184
|
// Using any for the SyncCallback because we'd need Reactor to be typed
|
|
185
185
|
this.callbacks = {};
|
|
186
186
|
this.idToHash = {};
|
|
@@ -188,7 +188,20 @@ class SyncTable {
|
|
|
188
188
|
this.config = config;
|
|
189
189
|
this.log = log;
|
|
190
190
|
this.createStore = createStore;
|
|
191
|
-
this.subs = new PersistedObject_ts_1.PersistedObject(
|
|
191
|
+
this.subs = new PersistedObject_ts_1.PersistedObject({
|
|
192
|
+
persister: storage,
|
|
193
|
+
merge: onMergeSub,
|
|
194
|
+
serialize: syncSubToStorage,
|
|
195
|
+
parse: (_key, x) => syncSubFromStorage(x, this.config.useDateObjects),
|
|
196
|
+
objectSize: (sub) => { var _a; return ((_a = sub.values) === null || _a === void 0 ? void 0 : _a.entities.length) || 0; },
|
|
197
|
+
logger: log,
|
|
198
|
+
gc: {
|
|
199
|
+
maxAgeMs: 1000 * 60 * 60 * 24 * 7 * 52, // 1 year
|
|
200
|
+
maxEntries: 1000,
|
|
201
|
+
// Size of each sub is the number of entity
|
|
202
|
+
maxSize: 1000000, // 1 million entities
|
|
203
|
+
},
|
|
204
|
+
});
|
|
192
205
|
}
|
|
193
206
|
beforeUnload() {
|
|
194
207
|
this.subs.flush();
|
|
@@ -207,17 +220,15 @@ class SyncTable {
|
|
|
207
220
|
this.callbacks[hash] = cbs;
|
|
208
221
|
if (!cbs.length) {
|
|
209
222
|
delete this.callbacks[hash];
|
|
210
|
-
if (keepSubscription) {
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
223
|
const sub = this.subs.currentValue[hash];
|
|
214
224
|
if (sub === null || sub === void 0 ? void 0 : sub.state) {
|
|
215
|
-
this.clearSubscriptionData(sub.state.subscriptionId);
|
|
225
|
+
this.clearSubscriptionData(sub.state.subscriptionId, keepSubscription);
|
|
226
|
+
}
|
|
227
|
+
if (!keepSubscription) {
|
|
228
|
+
this.subs.updateInPlace((prev) => {
|
|
229
|
+
delete prev[hash];
|
|
230
|
+
});
|
|
216
231
|
}
|
|
217
|
-
this.subs.set((prev) => {
|
|
218
|
-
delete prev[hash];
|
|
219
|
-
return prev;
|
|
220
|
-
});
|
|
221
232
|
}
|
|
222
233
|
}
|
|
223
234
|
sendStart(query) {
|
|
@@ -236,36 +247,37 @@ class SyncTable {
|
|
|
236
247
|
token: state.token,
|
|
237
248
|
});
|
|
238
249
|
}
|
|
239
|
-
sendRemove(state) {
|
|
250
|
+
sendRemove(state, keepSubscription) {
|
|
240
251
|
this.trySend((0, uuid_ts_1.default)(), {
|
|
241
252
|
op: 'remove-sync',
|
|
242
253
|
'subscription-id': state.subscriptionId,
|
|
254
|
+
'keep-subscription': keepSubscription,
|
|
243
255
|
});
|
|
244
256
|
}
|
|
245
257
|
initSubscription(query, hash, cb) {
|
|
246
258
|
return __awaiter(this, void 0, void 0, function* () {
|
|
247
|
-
var _a, _b, _c;
|
|
259
|
+
var _a, _b, _c, _d, _e;
|
|
248
260
|
// Wait for storage to load so that we know if we already have an existing subscription
|
|
249
|
-
yield this.subs.
|
|
261
|
+
yield this.subs.waitForKeyToLoad(hash);
|
|
250
262
|
const existingSub = this.subs.currentValue[hash];
|
|
251
263
|
if (existingSub && existingSub.state && existingSub.state.txId) {
|
|
252
264
|
this.sendResync(existingSub, existingSub.state);
|
|
253
|
-
if (existingSub.entities && cb) {
|
|
265
|
+
if (((_a = existingSub.values) === null || _a === void 0 ? void 0 : _a.entities) && cb) {
|
|
254
266
|
const k = Object.keys(query)[0];
|
|
255
267
|
cb({
|
|
256
268
|
type: CallbackEventType.LoadFromStorage,
|
|
257
|
-
data: subData(existingSub, existingSub.entities),
|
|
269
|
+
data: subData(existingSub, (_b = existingSub.values) === null || _b === void 0 ? void 0 : _b.entities),
|
|
258
270
|
});
|
|
259
271
|
}
|
|
260
272
|
return;
|
|
261
273
|
}
|
|
262
274
|
const table = Object.keys(query)[0];
|
|
263
|
-
const orderBy = ((
|
|
275
|
+
const orderBy = ((_d = (_c = query[table]) === null || _c === void 0 ? void 0 : _c.$) === null || _d === void 0 ? void 0 : _d.order) || { serverCreatedAt: 'asc' };
|
|
264
276
|
const [orderField, orderDirection] = Object.entries(orderBy)[0];
|
|
265
277
|
const orderFieldType = orderField === 'serverCreatedAt'
|
|
266
278
|
? 'number'
|
|
267
|
-
: (
|
|
268
|
-
this.subs.
|
|
279
|
+
: (_e = s.getAttrByFwdIdentName(this.createStore([]), table, orderField)) === null || _e === void 0 ? void 0 : _e['checked-data-type'];
|
|
280
|
+
this.subs.updateInPlace((prev) => {
|
|
269
281
|
prev[hash] = {
|
|
270
282
|
query,
|
|
271
283
|
hash: hash,
|
|
@@ -276,15 +288,14 @@ class SyncTable {
|
|
|
276
288
|
createdAt: Date.now(),
|
|
277
289
|
updatedAt: Date.now(),
|
|
278
290
|
};
|
|
279
|
-
return prev;
|
|
280
291
|
});
|
|
281
292
|
this.sendStart(query);
|
|
282
293
|
});
|
|
283
294
|
}
|
|
284
295
|
flushPending() {
|
|
285
296
|
return __awaiter(this, void 0, void 0, function* () {
|
|
286
|
-
yield this.subs.waitForLoaded();
|
|
287
297
|
for (const hash of Object.keys(this.callbacks)) {
|
|
298
|
+
yield this.subs.waitForKeyToLoad(hash);
|
|
288
299
|
const sub = this.subs.currentValue[hash];
|
|
289
300
|
if (sub) {
|
|
290
301
|
yield this.initSubscription(sub.query, sub.hash);
|
|
@@ -300,7 +311,7 @@ class SyncTable {
|
|
|
300
311
|
const q = msg.q;
|
|
301
312
|
const hash = (0, weakHash_ts_1.default)(q);
|
|
302
313
|
this.idToHash[subscriptionId] = hash;
|
|
303
|
-
this.subs.
|
|
314
|
+
this.subs.updateInPlace((prev) => {
|
|
304
315
|
const sub = prev[hash];
|
|
305
316
|
if (!sub) {
|
|
306
317
|
this.log.error('Missing sub for hash', hash, 'subscription-id', subscriptionId, 'query', q);
|
|
@@ -310,7 +321,6 @@ class SyncTable {
|
|
|
310
321
|
subscriptionId: subscriptionId,
|
|
311
322
|
token: msg.token,
|
|
312
323
|
};
|
|
313
|
-
return prev;
|
|
314
324
|
});
|
|
315
325
|
}
|
|
316
326
|
notifyCbs(hash, event) {
|
|
@@ -319,6 +329,7 @@ class SyncTable {
|
|
|
319
329
|
}
|
|
320
330
|
}
|
|
321
331
|
onSyncLoadBatch(msg) {
|
|
332
|
+
var _a;
|
|
322
333
|
const subscriptionId = msg['subscription-id'];
|
|
323
334
|
const joinRows = msg['join-rows'];
|
|
324
335
|
const hash = this.idToHash[subscriptionId];
|
|
@@ -327,49 +338,55 @@ class SyncTable {
|
|
|
327
338
|
return;
|
|
328
339
|
}
|
|
329
340
|
const batch = [];
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
341
|
+
const sub = this.subs.currentValue[hash];
|
|
342
|
+
if (!sub) {
|
|
343
|
+
this.log.error('Missing sub for hash', hash, msg);
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
const values = (_a = sub.values) !== null && _a !== void 0 ? _a : {
|
|
347
|
+
entities: [],
|
|
348
|
+
attrs: this.createStore([]).attrs,
|
|
349
|
+
};
|
|
350
|
+
sub.values = values;
|
|
351
|
+
const entities = values.entities;
|
|
352
|
+
for (const entRows of joinRows) {
|
|
353
|
+
const store = this.createStore(entRows);
|
|
354
|
+
values.attrs = store.attrs;
|
|
355
|
+
const entity = queryEntity(sub, store);
|
|
356
|
+
entities.push({
|
|
357
|
+
store,
|
|
358
|
+
entity,
|
|
359
|
+
serverCreatedAt: getServerCreatedAt(sub, store, entity.id),
|
|
360
|
+
});
|
|
361
|
+
batch.push(entity);
|
|
362
|
+
}
|
|
363
|
+
this.subs.updateInPlace((prev) => {
|
|
364
|
+
prev[hash] = sub;
|
|
365
|
+
// Make sure we write a field or mutative won't
|
|
366
|
+
// see the change because sub === prev[hash]
|
|
367
|
+
prev[hash].updatedAt = Date.now();
|
|
351
368
|
});
|
|
352
|
-
|
|
353
|
-
if (sub.entities) {
|
|
369
|
+
if (sub.values) {
|
|
354
370
|
this.notifyCbs(hash, {
|
|
355
371
|
type: CallbackEventType.InitialSyncBatch,
|
|
356
|
-
data: subData(sub, sub.entities),
|
|
372
|
+
data: subData(sub, sub.values.entities),
|
|
357
373
|
batch,
|
|
358
374
|
});
|
|
359
375
|
}
|
|
360
376
|
}
|
|
361
377
|
onSyncInitFinish(msg) {
|
|
378
|
+
var _a;
|
|
362
379
|
const subscriptionId = msg['subscription-id'];
|
|
363
380
|
const hash = this.idToHash[subscriptionId];
|
|
364
381
|
if (!hash) {
|
|
365
382
|
this.log.error('Missing hash for subscription', msg);
|
|
366
383
|
return;
|
|
367
384
|
}
|
|
368
|
-
this.subs.
|
|
385
|
+
this.subs.updateInPlace((prev) => {
|
|
369
386
|
const sub = prev[hash];
|
|
370
387
|
if (!sub) {
|
|
371
388
|
this.log.error('Missing sub for hash', hash, msg);
|
|
372
|
-
return
|
|
389
|
+
return;
|
|
373
390
|
}
|
|
374
391
|
const state = sub.state;
|
|
375
392
|
if (!state) {
|
|
@@ -378,131 +395,140 @@ class SyncTable {
|
|
|
378
395
|
}
|
|
379
396
|
state.txId = msg['tx-id'];
|
|
380
397
|
sub.updatedAt = Date.now();
|
|
381
|
-
return prev;
|
|
382
398
|
});
|
|
383
399
|
const sub = this.subs.currentValue[hash];
|
|
384
400
|
if (sub) {
|
|
385
401
|
this.notifyCbs(hash, {
|
|
386
402
|
type: CallbackEventType.InitialSyncComplete,
|
|
387
|
-
data: subData(sub, sub.entities || []),
|
|
403
|
+
data: subData(sub, ((_a = sub.values) === null || _a === void 0 ? void 0 : _a.entities) || []),
|
|
388
404
|
});
|
|
389
405
|
}
|
|
390
406
|
}
|
|
391
407
|
onSyncUpdateTriples(msg) {
|
|
408
|
+
var _a, _b, _c;
|
|
392
409
|
const subscriptionId = msg['subscription-id'];
|
|
393
410
|
const hash = this.idToHash[subscriptionId];
|
|
394
411
|
if (!hash) {
|
|
395
412
|
this.log.error('Missing hash for subscription', msg);
|
|
396
413
|
return;
|
|
397
414
|
}
|
|
398
|
-
this.subs.
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
415
|
+
const sub = this.subs.currentValue[hash];
|
|
416
|
+
if (!sub) {
|
|
417
|
+
this.log.error('Missing sub for hash', hash, msg);
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
const state = sub.state;
|
|
421
|
+
if (!state) {
|
|
422
|
+
this.log.error('Missing state for sub', sub, msg);
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
for (const tx of msg.txes) {
|
|
426
|
+
if (state.txId >= tx['tx-id']) {
|
|
427
|
+
continue;
|
|
404
428
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
429
|
+
state.txId = tx['tx-id'];
|
|
430
|
+
const idxesToDelete = [];
|
|
431
|
+
// Note: this won't work as well when links are involved
|
|
432
|
+
const byEid = {};
|
|
433
|
+
for (const change of tx.changes) {
|
|
434
|
+
const eidChanges = (_a = byEid[change.triple[0]]) !== null && _a !== void 0 ? _a : [];
|
|
435
|
+
byEid[change.triple[0]] = eidChanges;
|
|
436
|
+
eidChanges.push(change);
|
|
409
437
|
}
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
eidLoop: for (const [eid, changes] of Object.entries(byEid)) {
|
|
428
|
-
for (const [entIdx, ent] of Object.entries(entities)) {
|
|
429
|
-
if (s.hasEntity(ent.store, eid)) {
|
|
430
|
-
applyChangesToStore(ent.store, changes);
|
|
431
|
-
const entity = queryEntity(sub, ent.store);
|
|
432
|
-
const changedFields = changedFieldsOfChanges(ent.store, changes)[eid];
|
|
433
|
-
for (const [k, { oldValue, newValue }] of Object.entries(changedFields || {})) {
|
|
434
|
-
if (oldValue === newValue) {
|
|
435
|
-
delete changedFields[k];
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
if (entity) {
|
|
439
|
-
updated.push({
|
|
440
|
-
oldEntity: ent.entity,
|
|
441
|
-
newEntity: entity,
|
|
442
|
-
changedFields: changedFields || {},
|
|
443
|
-
});
|
|
444
|
-
ent.entity = entity;
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
idxesToDelete.push(entIdx);
|
|
438
|
+
const values = (_b = sub.values) !== null && _b !== void 0 ? _b : {
|
|
439
|
+
entities: [],
|
|
440
|
+
attrs: this.createStore([]).attrs,
|
|
441
|
+
};
|
|
442
|
+
const entities = values.entities;
|
|
443
|
+
sub.values = values;
|
|
444
|
+
const updated = [];
|
|
445
|
+
// Update the existing stores, if we already know about this entity
|
|
446
|
+
eidLoop: for (const [eid, changes] of Object.entries(byEid)) {
|
|
447
|
+
for (const [entIdx, ent] of Object.entries(entities)) {
|
|
448
|
+
if (s.hasEntity(ent.store, eid)) {
|
|
449
|
+
applyChangesToStore(ent.store, changes);
|
|
450
|
+
const entity = queryEntity(sub, ent.store);
|
|
451
|
+
const changedFields = changedFieldsOfChanges(ent.store, changes)[eid];
|
|
452
|
+
for (const [k, { oldValue, newValue }] of Object.entries(changedFields || {})) {
|
|
453
|
+
if (oldValue === newValue) {
|
|
454
|
+
delete changedFields[k];
|
|
448
455
|
}
|
|
449
|
-
delete byEid[eid];
|
|
450
|
-
continue eidLoop;
|
|
451
456
|
}
|
|
457
|
+
if (entity) {
|
|
458
|
+
updated.push({
|
|
459
|
+
oldEntity: ent.entity,
|
|
460
|
+
newEntity: entity,
|
|
461
|
+
changedFields: changedFields || {},
|
|
462
|
+
});
|
|
463
|
+
ent.entity = entity;
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
idxesToDelete.push(entIdx);
|
|
467
|
+
}
|
|
468
|
+
delete byEid[eid];
|
|
469
|
+
continue eidLoop;
|
|
452
470
|
}
|
|
453
471
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
1;
|
|
467
|
-
continue;
|
|
468
|
-
}
|
|
469
|
-
entities.push({
|
|
472
|
+
}
|
|
473
|
+
const added = [];
|
|
474
|
+
// If we have anything left in byEid, then this must be a new entity we don't know about
|
|
475
|
+
for (const [_eid, changes] of Object.entries(byEid)) {
|
|
476
|
+
const store = this.createStore([]);
|
|
477
|
+
values.attrs = store.attrs;
|
|
478
|
+
applyChangesToStore(store, changes);
|
|
479
|
+
const entity = queryEntity(sub, store);
|
|
480
|
+
if (!entity) {
|
|
481
|
+
this.log.error('No entity found after applying change', {
|
|
482
|
+
sub,
|
|
483
|
+
changes,
|
|
470
484
|
store,
|
|
471
|
-
entity,
|
|
472
|
-
serverCreatedAt: getServerCreatedAt(sub, store, entity.id),
|
|
473
485
|
});
|
|
474
|
-
|
|
475
|
-
}
|
|
476
|
-
const removed = [];
|
|
477
|
-
for (const idx of idxesToDelete.sort().reverse()) {
|
|
478
|
-
removed.push(entities[idx].entity);
|
|
479
|
-
entities.splice(idx, 1);
|
|
486
|
+
continue;
|
|
480
487
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
added,
|
|
486
|
-
removed,
|
|
487
|
-
updated,
|
|
488
|
+
entities.push({
|
|
489
|
+
store,
|
|
490
|
+
entity,
|
|
491
|
+
serverCreatedAt: getServerCreatedAt(sub, store, entity.id),
|
|
488
492
|
});
|
|
489
|
-
|
|
493
|
+
added.push(entity);
|
|
494
|
+
}
|
|
495
|
+
const removed = [];
|
|
496
|
+
for (const idx of idxesToDelete.sort().reverse()) {
|
|
497
|
+
removed.push(entities[idx].entity);
|
|
498
|
+
entities.splice(idx, 1);
|
|
490
499
|
}
|
|
491
|
-
|
|
500
|
+
sortEntitiesInPlace(sub, entities);
|
|
501
|
+
this.notifyCbs(hash, {
|
|
502
|
+
type: CallbackEventType.SyncTransaction,
|
|
503
|
+
data: subData(sub, (_c = sub.values) === null || _c === void 0 ? void 0 : _c.entities),
|
|
504
|
+
added,
|
|
505
|
+
removed,
|
|
506
|
+
updated,
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
this.subs.updateInPlace((prev) => {
|
|
510
|
+
prev[hash] = sub;
|
|
511
|
+
// Make sure we write a field or mutative won't
|
|
512
|
+
// see the change because sub === prev[hash]
|
|
513
|
+
prev[hash].updatedAt = Date.now();
|
|
492
514
|
});
|
|
493
515
|
}
|
|
494
|
-
clearSubscriptionData(subscriptionId) {
|
|
516
|
+
clearSubscriptionData(subscriptionId, keepSubscription) {
|
|
495
517
|
const hash = this.idToHash[subscriptionId];
|
|
496
518
|
if (hash) {
|
|
497
519
|
delete this.idToHash[subscriptionId];
|
|
498
520
|
const sub = this.subs.currentValue[hash];
|
|
499
521
|
if (sub.state) {
|
|
500
|
-
this.sendRemove(sub.state);
|
|
522
|
+
this.sendRemove(sub.state, keepSubscription);
|
|
523
|
+
}
|
|
524
|
+
if (keepSubscription) {
|
|
525
|
+
this.subs.unloadKey(hash);
|
|
526
|
+
}
|
|
527
|
+
else {
|
|
528
|
+
this.subs.updateInPlace((prev) => {
|
|
529
|
+
delete prev[hash];
|
|
530
|
+
});
|
|
501
531
|
}
|
|
502
|
-
this.subs.set((prev) => {
|
|
503
|
-
delete prev[hash];
|
|
504
|
-
return prev;
|
|
505
|
-
});
|
|
506
532
|
if (sub) {
|
|
507
533
|
return sub;
|
|
508
534
|
}
|
|
@@ -528,7 +554,7 @@ class SyncTable {
|
|
|
528
554
|
// This can happen if the auth changed and we need to refetch with the
|
|
529
555
|
// new auth or if the subscription is too far behind.
|
|
530
556
|
const subscriptionId = msg['original-event']['subscription-id'];
|
|
531
|
-
const removedSub = this.clearSubscriptionData(subscriptionId);
|
|
557
|
+
const removedSub = this.clearSubscriptionData(subscriptionId, false);
|
|
532
558
|
if (removedSub) {
|
|
533
559
|
this.initSubscription(removedSub.query, removedSub.hash);
|
|
534
560
|
}
|