@instantdb/core 0.22.88 → 0.22.89-experimental.drewh-ssr.20277611943.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/__tests__/src/Reactor.test.js +18 -11
- package/__tests__/src/{datalog.test.js → datalog.test.ts} +17 -5
- package/__tests__/src/{instaml.test.js → instaml.test.ts} +183 -119
- package/__tests__/src/instaql.bench.ts +34 -0
- package/__tests__/src/{instaql.test.js → instaql.test.ts} +342 -455
- package/__tests__/src/instaqlInference.test.js +13 -9
- package/__tests__/src/serializeSchema.test.ts +123 -0
- package/__tests__/src/{store.test.js → store.test.ts} +215 -212
- package/dist/commonjs/Reactor.d.ts +36 -7
- package/dist/commonjs/Reactor.d.ts.map +1 -1
- package/dist/commonjs/Reactor.js +176 -47
- package/dist/commonjs/Reactor.js.map +1 -1
- package/dist/commonjs/SyncTable.d.ts +4 -1
- package/dist/commonjs/SyncTable.d.ts.map +1 -1
- package/dist/commonjs/SyncTable.js +35 -37
- package/dist/commonjs/SyncTable.js.map +1 -1
- package/dist/commonjs/createRouteHandler.d.ts +8 -0
- package/dist/commonjs/createRouteHandler.d.ts.map +1 -0
- package/dist/commonjs/createRouteHandler.js +57 -0
- package/dist/commonjs/createRouteHandler.js.map +1 -0
- package/dist/commonjs/framework.d.ts +77 -0
- package/dist/commonjs/framework.d.ts.map +1 -0
- package/dist/commonjs/framework.js +209 -0
- package/dist/commonjs/framework.js.map +1 -0
- package/dist/commonjs/index.d.ts +5 -1
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +7 -1
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/instaml.d.ts +17 -4
- package/dist/commonjs/instaml.d.ts.map +1 -1
- package/dist/commonjs/instaml.js +115 -82
- package/dist/commonjs/instaml.js.map +1 -1
- package/dist/commonjs/instaql.d.ts +4 -3
- package/dist/commonjs/instaql.d.ts.map +1 -1
- package/dist/commonjs/instaql.js +65 -63
- package/dist/commonjs/instaql.js.map +1 -1
- package/dist/commonjs/parseSchemaFromJSON.d.ts +3 -0
- package/dist/commonjs/parseSchemaFromJSON.d.ts.map +1 -0
- package/dist/commonjs/parseSchemaFromJSON.js +148 -0
- package/dist/commonjs/parseSchemaFromJSON.js.map +1 -0
- package/dist/commonjs/reactorTypes.d.ts +30 -0
- package/dist/commonjs/reactorTypes.d.ts.map +1 -0
- package/dist/commonjs/reactorTypes.js +3 -0
- package/dist/commonjs/reactorTypes.js.map +1 -0
- package/dist/commonjs/store.d.ts +67 -25
- package/dist/commonjs/store.d.ts.map +1 -1
- package/dist/commonjs/store.js +177 -81
- package/dist/commonjs/store.js.map +1 -1
- package/dist/esm/Reactor.d.ts +36 -7
- package/dist/esm/Reactor.d.ts.map +1 -1
- package/dist/esm/Reactor.js +177 -48
- package/dist/esm/Reactor.js.map +1 -1
- package/dist/esm/SyncTable.d.ts +4 -1
- package/dist/esm/SyncTable.d.ts.map +1 -1
- package/dist/esm/SyncTable.js +35 -37
- package/dist/esm/SyncTable.js.map +1 -1
- package/dist/esm/createRouteHandler.d.ts +8 -0
- package/dist/esm/createRouteHandler.d.ts.map +1 -0
- package/dist/esm/createRouteHandler.js +53 -0
- package/dist/esm/createRouteHandler.js.map +1 -0
- package/dist/esm/framework.d.ts +77 -0
- package/dist/esm/framework.d.ts.map +1 -0
- package/dist/esm/framework.js +169 -0
- package/dist/esm/framework.js.map +1 -0
- package/dist/esm/index.d.ts +5 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +5 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/instaml.d.ts +17 -4
- package/dist/esm/instaml.d.ts.map +1 -1
- package/dist/esm/instaml.js +112 -77
- package/dist/esm/instaml.js.map +1 -1
- package/dist/esm/instaql.d.ts +4 -3
- package/dist/esm/instaql.d.ts.map +1 -1
- package/dist/esm/instaql.js +65 -63
- package/dist/esm/instaql.js.map +1 -1
- package/dist/esm/parseSchemaFromJSON.d.ts +3 -0
- package/dist/esm/parseSchemaFromJSON.d.ts.map +1 -0
- package/dist/esm/parseSchemaFromJSON.js +144 -0
- package/dist/esm/parseSchemaFromJSON.js.map +1 -0
- package/dist/esm/reactorTypes.d.ts +30 -0
- package/dist/esm/reactorTypes.d.ts.map +1 -0
- package/dist/esm/reactorTypes.js +2 -0
- package/dist/esm/reactorTypes.js.map +1 -0
- package/dist/esm/store.d.ts +67 -25
- package/dist/esm/store.d.ts.map +1 -1
- package/dist/esm/store.js +174 -81
- package/dist/esm/store.js.map +1 -1
- package/dist/standalone/index.js +2899 -2389
- package/dist/standalone/index.umd.cjs +3 -3
- package/package.json +2 -2
- package/src/Reactor.js +232 -77
- package/src/SyncTable.ts +85 -45
- package/src/createRouteHandler.ts +44 -0
- package/src/framework.ts +294 -0
- package/src/index.ts +9 -0
- package/src/{instaml.js → instaml.ts} +201 -96
- package/src/instaql.ts +88 -62
- package/src/parseSchemaFromJSON.ts +176 -0
- package/src/reactorTypes.ts +33 -0
- package/src/store.ts +257 -101
- package/__tests__/src/instaql.bench.js +0 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instantdb/core",
|
|
3
|
-
"version": "0.22.
|
|
3
|
+
"version": "0.22.89-experimental.drewh-ssr.20277611943.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.89-experimental.drewh-ssr.20277611943.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.
|
|
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
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
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
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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,20 +334,31 @@ export default class Reactor {
|
|
|
306
334
|
useDateObjects: this.config.useDateObjects,
|
|
307
335
|
},
|
|
308
336
|
this._log,
|
|
309
|
-
(triples) =>
|
|
310
|
-
s.createStore(
|
|
311
|
-
this.
|
|
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()
|
|
351
|
+
this.getCurrentUser().then((userInfo) => {
|
|
352
|
+
this.syncUserToEndpoint(userInfo.user);
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
setInterval(
|
|
356
|
+
async () => {
|
|
357
|
+
const currentUser = await this.getCurrentUser();
|
|
358
|
+
this.syncUserToEndpoint(currentUser.user);
|
|
359
|
+
},
|
|
360
|
+
1000 * 60 * 20,
|
|
361
|
+
);
|
|
323
362
|
|
|
324
363
|
NetworkListener.getIsOnline().then((isOnline) => {
|
|
325
364
|
this._isOnline = isOnline;
|
|
@@ -353,6 +392,13 @@ export default class Reactor {
|
|
|
353
392
|
}
|
|
354
393
|
}
|
|
355
394
|
|
|
395
|
+
ensureAttrs() {
|
|
396
|
+
if (!this.attrs) {
|
|
397
|
+
throw new Error('attrs have not loaded.');
|
|
398
|
+
}
|
|
399
|
+
return this.attrs;
|
|
400
|
+
}
|
|
401
|
+
|
|
356
402
|
updateSchema(schema) {
|
|
357
403
|
this.config = {
|
|
358
404
|
...this.config,
|
|
@@ -383,7 +429,7 @@ export default class Reactor {
|
|
|
383
429
|
serialize: querySubToStorage,
|
|
384
430
|
parse: (_key, x) => querySubFromStorage(x, this.config.useDateObjects),
|
|
385
431
|
// objectSize
|
|
386
|
-
objectSize: (x) => x
|
|
432
|
+
objectSize: (x) => x?.result?.store?.triples?.length ?? 0,
|
|
387
433
|
logger: this._log,
|
|
388
434
|
preloadEntryCount: 10,
|
|
389
435
|
gc: {
|
|
@@ -513,6 +559,43 @@ export default class Reactor {
|
|
|
513
559
|
}
|
|
514
560
|
}
|
|
515
561
|
|
|
562
|
+
/**
|
|
563
|
+
* Does the same thing as add-query-ok
|
|
564
|
+
* but called as a result of receiving query info from ssr
|
|
565
|
+
* @param {any} q
|
|
566
|
+
* @param {{ triples: any; pageInfo: any; }} result
|
|
567
|
+
* @param {boolean} enableCardinalityInference
|
|
568
|
+
*/
|
|
569
|
+
_addQueryData(q, result, enableCardinalityInference) {
|
|
570
|
+
if (!this.attrs) {
|
|
571
|
+
throw new Error('Attrs in reactor have not been set');
|
|
572
|
+
}
|
|
573
|
+
const queryHash = weakHash(q);
|
|
574
|
+
const attrsStore = this.ensureAttrs();
|
|
575
|
+
const store = s.createStore(
|
|
576
|
+
this.attrs,
|
|
577
|
+
result.triples,
|
|
578
|
+
enableCardinalityInference,
|
|
579
|
+
this.config.useDateObjects,
|
|
580
|
+
);
|
|
581
|
+
this.querySubs.updateInPlace((prev) => {
|
|
582
|
+
prev[queryHash] = {
|
|
583
|
+
result: {
|
|
584
|
+
store,
|
|
585
|
+
attrsStore,
|
|
586
|
+
pageInfo: result.pageInfo,
|
|
587
|
+
processedTxId: undefined,
|
|
588
|
+
isExternal: true,
|
|
589
|
+
},
|
|
590
|
+
q,
|
|
591
|
+
};
|
|
592
|
+
});
|
|
593
|
+
this._cleanupPendingMutationsQueries();
|
|
594
|
+
this.notifyOne(queryHash);
|
|
595
|
+
this.notifyOneQueryOnce(queryHash);
|
|
596
|
+
this._cleanupPendingMutationsTimeout();
|
|
597
|
+
}
|
|
598
|
+
|
|
516
599
|
_handleReceive(connId, msg) {
|
|
517
600
|
// opt-out, enabled by default if schema
|
|
518
601
|
const enableCardinalityInference =
|
|
@@ -552,13 +635,14 @@ export default class Reactor {
|
|
|
552
635
|
const pageInfo = result?.[0]?.data?.['page-info'];
|
|
553
636
|
const aggregate = result?.[0]?.data?.['aggregate'];
|
|
554
637
|
const triples = extractTriples(result);
|
|
638
|
+
const attrsStore = this.ensureAttrs();
|
|
555
639
|
const store = s.createStore(
|
|
556
|
-
|
|
640
|
+
attrsStore,
|
|
557
641
|
triples,
|
|
558
642
|
enableCardinalityInference,
|
|
559
|
-
this._linkIndex,
|
|
560
643
|
this.config.useDateObjects,
|
|
561
644
|
);
|
|
645
|
+
|
|
562
646
|
this.querySubs.updateInPlace((prev) => {
|
|
563
647
|
if (!prev[hash]) {
|
|
564
648
|
this._log.info('Missing value in querySubs', { hash, q });
|
|
@@ -566,6 +650,7 @@ export default class Reactor {
|
|
|
566
650
|
}
|
|
567
651
|
prev[hash].result = {
|
|
568
652
|
store,
|
|
653
|
+
attrsStore,
|
|
569
654
|
pageInfo,
|
|
570
655
|
aggregate,
|
|
571
656
|
processedTxId: msg['processed-tx-id'],
|
|
@@ -603,7 +688,7 @@ export default class Reactor {
|
|
|
603
688
|
this._cleanupPendingMutationsTimeout();
|
|
604
689
|
|
|
605
690
|
const rewrittenMutations = this._rewriteMutations(
|
|
606
|
-
this.
|
|
691
|
+
this.ensureAttrs(),
|
|
607
692
|
this._pendingMutations(),
|
|
608
693
|
processedTxId,
|
|
609
694
|
);
|
|
@@ -624,32 +709,49 @@ export default class Reactor {
|
|
|
624
709
|
const result = x['instaql-result'];
|
|
625
710
|
const hash = weakHash(q);
|
|
626
711
|
const triples = extractTriples(result);
|
|
712
|
+
const attrsStore = this.ensureAttrs();
|
|
627
713
|
const store = s.createStore(
|
|
628
|
-
|
|
714
|
+
attrsStore,
|
|
629
715
|
triples,
|
|
630
716
|
enableCardinalityInference,
|
|
631
|
-
this._linkIndex,
|
|
632
717
|
this.config.useDateObjects,
|
|
633
718
|
);
|
|
634
|
-
const newStore =
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
719
|
+
const { store: newStore, attrsStore: newAttrsStore } =
|
|
720
|
+
this._applyOptimisticUpdates(
|
|
721
|
+
store,
|
|
722
|
+
attrsStore,
|
|
723
|
+
mutations,
|
|
724
|
+
processedTxId,
|
|
725
|
+
);
|
|
639
726
|
const pageInfo = result?.[0]?.data?.['page-info'];
|
|
640
727
|
const aggregate = result?.[0]?.data?.['aggregate'];
|
|
641
|
-
return {
|
|
728
|
+
return {
|
|
729
|
+
q,
|
|
730
|
+
hash,
|
|
731
|
+
store: newStore,
|
|
732
|
+
attrsStore: newAttrsStore,
|
|
733
|
+
pageInfo,
|
|
734
|
+
aggregate,
|
|
735
|
+
};
|
|
642
736
|
});
|
|
643
737
|
|
|
644
|
-
updates.forEach(
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
738
|
+
updates.forEach(
|
|
739
|
+
({ hash, q, store, attrsStore, pageInfo, aggregate }) => {
|
|
740
|
+
this.querySubs.updateInPlace((prev) => {
|
|
741
|
+
if (!prev[hash]) {
|
|
742
|
+
this._log.error('Missing value in querySubs', { hash, q });
|
|
743
|
+
return;
|
|
744
|
+
}
|
|
745
|
+
prev[hash].result = {
|
|
746
|
+
store,
|
|
747
|
+
attrsStore,
|
|
748
|
+
pageInfo,
|
|
749
|
+
aggregate,
|
|
750
|
+
processedTxId,
|
|
751
|
+
};
|
|
752
|
+
});
|
|
753
|
+
},
|
|
754
|
+
);
|
|
653
755
|
|
|
654
756
|
this._cleanupPendingMutationsQueries();
|
|
655
757
|
|
|
@@ -664,7 +766,7 @@ export default class Reactor {
|
|
|
664
766
|
this._inFlightMutationEventIds.delete(eventId);
|
|
665
767
|
|
|
666
768
|
const muts = this._rewriteMutations(
|
|
667
|
-
this.
|
|
769
|
+
this.ensureAttrs(),
|
|
668
770
|
this._pendingMutations(),
|
|
669
771
|
);
|
|
670
772
|
const prevMutation = muts.get(eventId);
|
|
@@ -681,12 +783,17 @@ export default class Reactor {
|
|
|
681
783
|
});
|
|
682
784
|
});
|
|
683
785
|
|
|
684
|
-
const newAttrs =
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
786
|
+
const newAttrs = [];
|
|
787
|
+
for (const step of prevMutation['tx-steps']) {
|
|
788
|
+
if (step[0] === 'add-attr') {
|
|
789
|
+
const attr = step[1];
|
|
790
|
+
newAttrs.push(attr);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
if (newAttrs.length) {
|
|
794
|
+
const existingAttrs = Object.values(this.ensureAttrs().attrs);
|
|
795
|
+
this._setAttrs([...existingAttrs, ...newAttrs]);
|
|
796
|
+
}
|
|
690
797
|
|
|
691
798
|
this._finishTransaction('synced', eventId);
|
|
692
799
|
|
|
@@ -870,10 +977,13 @@ export default class Reactor {
|
|
|
870
977
|
}
|
|
871
978
|
|
|
872
979
|
_setAttrs(attrs) {
|
|
873
|
-
this.attrs =
|
|
874
|
-
acc
|
|
875
|
-
|
|
876
|
-
|
|
980
|
+
this.attrs = new s.AttrsStoreClass(
|
|
981
|
+
attrs.reduce((acc, attr) => {
|
|
982
|
+
acc[attr.id] = attr;
|
|
983
|
+
return acc;
|
|
984
|
+
}, {}),
|
|
985
|
+
this._linkIndex,
|
|
986
|
+
);
|
|
877
987
|
|
|
878
988
|
this.notifyAttrsSubs();
|
|
879
989
|
}
|
|
@@ -1022,17 +1132,23 @@ export default class Reactor {
|
|
|
1022
1132
|
// We remove `add-attr` commands for attrs that already exist.
|
|
1023
1133
|
// We update `add-triple` and `retract-triple` commands to use the
|
|
1024
1134
|
// server attr-ids.
|
|
1135
|
+
/**
|
|
1136
|
+
*
|
|
1137
|
+
* @param {s.AttrsStore} attrs
|
|
1138
|
+
* @param {any} muts
|
|
1139
|
+
* @param {number} [processedTxId]
|
|
1140
|
+
*/
|
|
1025
1141
|
_rewriteMutations(attrs, muts, processedTxId) {
|
|
1026
1142
|
if (!attrs) return muts;
|
|
1027
1143
|
if (!muts) return new Map();
|
|
1028
1144
|
const findExistingAttr = (attr) => {
|
|
1029
1145
|
const [_, etype, label] = attr['forward-identity'];
|
|
1030
|
-
const existing =
|
|
1146
|
+
const existing = s.getAttrByFwdIdentName(attrs, etype, label);
|
|
1031
1147
|
return existing;
|
|
1032
1148
|
};
|
|
1033
1149
|
const findReverseAttr = (attr) => {
|
|
1034
1150
|
const [_, etype, label] = attr['forward-identity'];
|
|
1035
|
-
const revAttr =
|
|
1151
|
+
const revAttr = s.getAttrByReverseIdentName(attrs, etype, label);
|
|
1036
1152
|
return revAttr;
|
|
1037
1153
|
};
|
|
1038
1154
|
const mapping = { attrIdMap: {}, refSwapAttrIds: new Set() };
|
|
@@ -1109,6 +1225,9 @@ export default class Reactor {
|
|
|
1109
1225
|
// ---------------------------
|
|
1110
1226
|
// Transact
|
|
1111
1227
|
|
|
1228
|
+
/**
|
|
1229
|
+
* @returns {s.AttrsStore}
|
|
1230
|
+
*/
|
|
1112
1231
|
optimisticAttrs() {
|
|
1113
1232
|
const pendingMutationSteps = [...this._pendingMutations().values()] // hack due to Map()
|
|
1114
1233
|
.flatMap((x) => x['tx-steps']);
|
|
@@ -1126,27 +1245,30 @@ export default class Reactor {
|
|
|
1126
1245
|
} else if (
|
|
1127
1246
|
_action === 'update-attr' &&
|
|
1128
1247
|
attr.id &&
|
|
1129
|
-
this.attrs?.
|
|
1248
|
+
this.attrs?.getAttr(attr.id)
|
|
1130
1249
|
) {
|
|
1131
|
-
const fullAttr = { ...this.attrs
|
|
1250
|
+
const fullAttr = { ...this.attrs.getAttr(attr.id), ...attr };
|
|
1132
1251
|
pendingAttrs.push(fullAttr);
|
|
1133
1252
|
}
|
|
1134
1253
|
}
|
|
1135
1254
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
].filter((a) => !deletedAttrIds.has(a.id));
|
|
1255
|
+
if (!deletedAttrIds.size && !pendingAttrs.length) {
|
|
1256
|
+
return this.attrs || new s.AttrsStoreClass({}, this._linkIndex);
|
|
1257
|
+
}
|
|
1140
1258
|
|
|
1141
|
-
const
|
|
1142
|
-
|
|
1143
|
-
|
|
1259
|
+
const attrs = { ...(this.attrs?.attrs || {}) };
|
|
1260
|
+
for (const attr of pendingAttrs) {
|
|
1261
|
+
attrs[attr.id] = attr;
|
|
1262
|
+
}
|
|
1263
|
+
for (const id of deletedAttrIds) {
|
|
1264
|
+
delete attrs[id];
|
|
1265
|
+
}
|
|
1144
1266
|
|
|
1145
|
-
return
|
|
1267
|
+
return new s.AttrsStoreClass(attrs, this._linkIndex);
|
|
1146
1268
|
}
|
|
1147
1269
|
|
|
1148
1270
|
/** Runs instaql on a query and a store */
|
|
1149
|
-
dataForQuery(hash) {
|
|
1271
|
+
dataForQuery(hash, applyOptimistic = true) {
|
|
1150
1272
|
const errorMessage = this._errorMessage;
|
|
1151
1273
|
if (errorMessage) {
|
|
1152
1274
|
return { error: errorMessage };
|
|
@@ -1170,28 +1292,41 @@ export default class Reactor {
|
|
|
1170
1292
|
return cached;
|
|
1171
1293
|
}
|
|
1172
1294
|
|
|
1173
|
-
|
|
1295
|
+
let store = result.store;
|
|
1296
|
+
let attrsStore = result.attrsStore;
|
|
1297
|
+
const { pageInfo, aggregate, processedTxId } = result;
|
|
1174
1298
|
const mutations = this._rewriteMutationsSorted(
|
|
1175
|
-
|
|
1299
|
+
attrsStore,
|
|
1176
1300
|
pendingMutations,
|
|
1177
1301
|
);
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1302
|
+
if (applyOptimistic) {
|
|
1303
|
+
const optimisticResult = this._applyOptimisticUpdates(
|
|
1304
|
+
store,
|
|
1305
|
+
attrsStore,
|
|
1306
|
+
mutations,
|
|
1307
|
+
processedTxId,
|
|
1308
|
+
);
|
|
1309
|
+
|
|
1310
|
+
store = optimisticResult.store;
|
|
1311
|
+
attrsStore = optimisticResult.attrsStore;
|
|
1312
|
+
}
|
|
1313
|
+
const resp = instaql(
|
|
1314
|
+
{ store: store, attrsStore: attrsStore, pageInfo, aggregate },
|
|
1315
|
+
q,
|
|
1182
1316
|
);
|
|
1183
|
-
const resp = instaql({ store: newStore, pageInfo, aggregate }, q);
|
|
1184
1317
|
|
|
1185
1318
|
return { data: resp, querySubVersion, pendingMutationsVersion };
|
|
1186
1319
|
}
|
|
1187
1320
|
|
|
1188
|
-
_applyOptimisticUpdates(store, mutations, processedTxId) {
|
|
1321
|
+
_applyOptimisticUpdates(store, attrsStore, mutations, processedTxId) {
|
|
1189
1322
|
for (const [_, mut] of mutations) {
|
|
1190
1323
|
if (!mut['tx-id'] || (processedTxId && mut['tx-id'] > processedTxId)) {
|
|
1191
|
-
|
|
1324
|
+
const result = s.transact(store, attrsStore, mut['tx-steps']);
|
|
1325
|
+
store = result.store;
|
|
1326
|
+
attrsStore = result.attrsStore;
|
|
1192
1327
|
}
|
|
1193
1328
|
}
|
|
1194
|
-
return store;
|
|
1329
|
+
return { store, attrsStore };
|
|
1195
1330
|
}
|
|
1196
1331
|
|
|
1197
1332
|
/** Re-run instaql and call all callbacks with new data */
|
|
@@ -1248,7 +1383,7 @@ export default class Reactor {
|
|
|
1248
1383
|
try {
|
|
1249
1384
|
const txSteps = instaml.transform(
|
|
1250
1385
|
{
|
|
1251
|
-
|
|
1386
|
+
attrsStore: this.optimisticAttrs(),
|
|
1252
1387
|
schema: this.config.schema,
|
|
1253
1388
|
stores: Object.values(this.querySubs.currentValue).map(
|
|
1254
1389
|
(sub) => sub?.result?.store,
|
|
@@ -1366,7 +1501,7 @@ export default class Reactor {
|
|
|
1366
1501
|
});
|
|
1367
1502
|
|
|
1368
1503
|
const muts = this._rewriteMutationsSorted(
|
|
1369
|
-
this.
|
|
1504
|
+
this.ensureAttrs(),
|
|
1370
1505
|
this._pendingMutations(),
|
|
1371
1506
|
);
|
|
1372
1507
|
muts.forEach(([eventId, mut]) => {
|
|
@@ -1822,7 +1957,7 @@ export default class Reactor {
|
|
|
1822
1957
|
this.attrsCbs.push(cb);
|
|
1823
1958
|
|
|
1824
1959
|
if (this.attrs) {
|
|
1825
|
-
cb(this.attrs);
|
|
1960
|
+
cb(this.attrs.attrs);
|
|
1826
1961
|
}
|
|
1827
1962
|
|
|
1828
1963
|
return () => {
|
|
@@ -1841,7 +1976,7 @@ export default class Reactor {
|
|
|
1841
1976
|
notifyAttrsSubs() {
|
|
1842
1977
|
if (!this.attrs) return;
|
|
1843
1978
|
const oas = this.optimisticAttrs();
|
|
1844
|
-
this.attrsCbs.forEach((cb) => cb(oas));
|
|
1979
|
+
this.attrsCbs.forEach((cb) => cb(oas.attrs));
|
|
1845
1980
|
}
|
|
1846
1981
|
|
|
1847
1982
|
notifyConnectionStatusSubs(status) {
|
|
@@ -1912,7 +2047,27 @@ export default class Reactor {
|
|
|
1912
2047
|
}
|
|
1913
2048
|
}
|
|
1914
2049
|
|
|
2050
|
+
async syncUserToEndpoint(user) {
|
|
2051
|
+
if (this.config.cookieEndpoint) {
|
|
2052
|
+
try {
|
|
2053
|
+
fetch(this.config.cookieEndpoint + '/sync-auth', {
|
|
2054
|
+
method: 'POST',
|
|
2055
|
+
body: JSON.stringify({
|
|
2056
|
+
user: user,
|
|
2057
|
+
}),
|
|
2058
|
+
headers: {
|
|
2059
|
+
'Content-Type': 'application/json',
|
|
2060
|
+
},
|
|
2061
|
+
});
|
|
2062
|
+
} catch (error) {
|
|
2063
|
+
console.error('Error syncing user with external endpoint', error);
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
|
|
1915
2068
|
updateUser(newUser) {
|
|
2069
|
+
this.syncUserToEndpoint(newUser);
|
|
2070
|
+
|
|
1916
2071
|
const newV = { error: undefined, user: newUser };
|
|
1917
2072
|
this._currentUserCached = { isLoading: false, ...newV };
|
|
1918
2073
|
this._dataForQueryCache = {};
|