@instantdb/core 0.22.96-experimental.drewh-ts-target.20761590091.1 → 0.22.97-experimental.bump-next-cia.20761479934.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/Connection.js +51 -50
- package/dist/commonjs/Connection.js.map +1 -1
- package/dist/commonjs/InMemoryStorage.js +32 -13
- package/dist/commonjs/InMemoryStorage.js.map +1 -1
- package/dist/commonjs/IndexedDBStorage.js +217 -193
- package/dist/commonjs/IndexedDBStorage.js.map +1 -1
- package/dist/commonjs/InstantError.js +0 -1
- package/dist/commonjs/InstantError.js.map +1 -1
- package/dist/commonjs/Reactor.js +610 -566
- package/dist/commonjs/Reactor.js.map +1 -1
- package/dist/commonjs/StorageAPI.js +70 -51
- package/dist/commonjs/StorageAPI.js.map +1 -1
- package/dist/commonjs/SyncTable.js +81 -68
- package/dist/commonjs/SyncTable.js.map +1 -1
- package/dist/commonjs/WindowNetworkListener.js +13 -2
- package/dist/commonjs/WindowNetworkListener.js.map +1 -1
- package/dist/commonjs/__types__/fieldsTypeTest.js +16 -8
- package/dist/commonjs/__types__/fieldsTypeTest.js.map +1 -1
- package/dist/commonjs/__types__/useDatesTypeTest.js +6 -3
- package/dist/commonjs/__types__/useDatesTypeTest.js.map +1 -1
- package/dist/commonjs/authAPI.js +79 -62
- package/dist/commonjs/authAPI.js.map +1 -1
- package/dist/commonjs/createRouteHandler.js +15 -5
- package/dist/commonjs/createRouteHandler.js.map +1 -1
- package/dist/commonjs/datalog.js +1 -1
- package/dist/commonjs/datalog.js.map +1 -1
- package/dist/commonjs/devtool.js +8 -26
- package/dist/commonjs/devtool.js.map +1 -1
- package/dist/commonjs/framework.d.ts.map +1 -1
- package/dist/commonjs/framework.js +152 -142
- package/dist/commonjs/framework.js.map +1 -1
- package/dist/commonjs/index.js +190 -204
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/instaml.js +30 -44
- package/dist/commonjs/instaml.js.map +1 -1
- package/dist/commonjs/instaql.js +33 -25
- package/dist/commonjs/instaql.js.map +1 -1
- package/dist/commonjs/parseSchemaFromJSON.js +7 -6
- package/dist/commonjs/parseSchemaFromJSON.js.map +1 -1
- package/dist/commonjs/presence.js +8 -7
- package/dist/commonjs/presence.js.map +1 -1
- package/dist/commonjs/queryValidation.js +2 -1
- package/dist/commonjs/queryValidation.js.map +1 -1
- package/dist/commonjs/schema.js +6 -8
- package/dist/commonjs/schema.js.map +1 -1
- package/dist/commonjs/schemaTypes.js +3 -22
- package/dist/commonjs/schemaTypes.js.map +1 -1
- package/dist/commonjs/store.js +38 -29
- package/dist/commonjs/store.js.map +1 -1
- package/dist/commonjs/transactionValidation.js +2 -1
- package/dist/commonjs/transactionValidation.js.map +1 -1
- package/dist/commonjs/utils/Deferred.js +0 -3
- package/dist/commonjs/utils/Deferred.js.map +1 -1
- package/dist/commonjs/utils/PersistedObject.js +233 -216
- package/dist/commonjs/utils/PersistedObject.js.map +1 -1
- package/dist/commonjs/utils/fetch.js +19 -9
- package/dist/commonjs/utils/fetch.js.map +1 -1
- package/dist/commonjs/utils/linkIndex.js +4 -2
- package/dist/commonjs/utils/linkIndex.js.map +1 -1
- package/dist/commonjs/utils/object.js +1 -1
- package/dist/commonjs/utils/object.js.map +1 -1
- package/dist/esm/Connection.js +51 -50
- package/dist/esm/Connection.js.map +1 -1
- package/dist/esm/InMemoryStorage.js +32 -13
- package/dist/esm/InMemoryStorage.js.map +1 -1
- package/dist/esm/IndexedDBStorage.js +217 -193
- package/dist/esm/IndexedDBStorage.js.map +1 -1
- package/dist/esm/InstantError.js +0 -1
- package/dist/esm/InstantError.js.map +1 -1
- package/dist/esm/Reactor.js +610 -566
- package/dist/esm/Reactor.js.map +1 -1
- package/dist/esm/StorageAPI.js +70 -51
- package/dist/esm/StorageAPI.js.map +1 -1
- package/dist/esm/SyncTable.js +81 -68
- package/dist/esm/SyncTable.js.map +1 -1
- package/dist/esm/WindowNetworkListener.js +13 -2
- package/dist/esm/WindowNetworkListener.js.map +1 -1
- package/dist/esm/__types__/fieldsTypeTest.js +16 -8
- package/dist/esm/__types__/fieldsTypeTest.js.map +1 -1
- package/dist/esm/__types__/useDatesTypeTest.js +6 -3
- package/dist/esm/__types__/useDatesTypeTest.js.map +1 -1
- package/dist/esm/authAPI.js +79 -62
- package/dist/esm/authAPI.js.map +1 -1
- package/dist/esm/createRouteHandler.js +15 -5
- package/dist/esm/createRouteHandler.js.map +1 -1
- package/dist/esm/datalog.js +1 -1
- package/dist/esm/datalog.js.map +1 -1
- package/dist/esm/devtool.js +8 -26
- package/dist/esm/devtool.js.map +1 -1
- package/dist/esm/framework.d.ts.map +1 -1
- package/dist/esm/framework.js +152 -142
- package/dist/esm/framework.js.map +1 -1
- package/dist/esm/index.js +190 -204
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/instaml.js +30 -44
- package/dist/esm/instaml.js.map +1 -1
- package/dist/esm/instaql.js +33 -25
- package/dist/esm/instaql.js.map +1 -1
- package/dist/esm/parseSchemaFromJSON.js +7 -6
- package/dist/esm/parseSchemaFromJSON.js.map +1 -1
- package/dist/esm/presence.js +8 -7
- package/dist/esm/presence.js.map +1 -1
- package/dist/esm/queryValidation.js +2 -1
- package/dist/esm/queryValidation.js.map +1 -1
- package/dist/esm/schema.js +6 -8
- package/dist/esm/schema.js.map +1 -1
- package/dist/esm/schemaTypes.js +3 -22
- package/dist/esm/schemaTypes.js.map +1 -1
- package/dist/esm/store.js +38 -29
- package/dist/esm/store.js.map +1 -1
- package/dist/esm/transactionValidation.js +2 -1
- package/dist/esm/transactionValidation.js.map +1 -1
- package/dist/esm/utils/Deferred.js +0 -3
- package/dist/esm/utils/Deferred.js.map +1 -1
- package/dist/esm/utils/PersistedObject.js +233 -216
- package/dist/esm/utils/PersistedObject.js.map +1 -1
- package/dist/esm/utils/fetch.js +19 -9
- package/dist/esm/utils/fetch.js.map +1 -1
- package/dist/esm/utils/linkIndex.js +4 -2
- package/dist/esm/utils/linkIndex.js.map +1 -1
- package/dist/esm/utils/object.js +1 -1
- package/dist/esm/utils/object.js.map +1 -1
- package/dist/standalone/index.js +2367 -2610
- package/dist/standalone/index.umd.cjs +3 -3
- package/package.json +2 -2
- package/src/framework.ts +1 -0
package/dist/commonjs/Reactor.js
CHANGED
|
@@ -32,6 +32,26 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
32
32
|
return result;
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
45
|
+
var t = {};
|
|
46
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
47
|
+
t[p] = s[p];
|
|
48
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
49
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
50
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
51
|
+
t[p[i]] = s[p[i]];
|
|
52
|
+
}
|
|
53
|
+
return t;
|
|
54
|
+
};
|
|
35
55
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
56
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
57
|
};
|
|
@@ -76,10 +96,10 @@ const STATUS = {
|
|
|
76
96
|
CLOSED: 'closed',
|
|
77
97
|
ERRORED: 'errored',
|
|
78
98
|
};
|
|
79
|
-
const QUERY_ONCE_TIMEOUT =
|
|
80
|
-
const PENDING_TX_CLEANUP_TIMEOUT =
|
|
99
|
+
const QUERY_ONCE_TIMEOUT = 30000;
|
|
100
|
+
const PENDING_TX_CLEANUP_TIMEOUT = 30000;
|
|
81
101
|
const PENDING_MUTATION_CLEANUP_THRESHOLD = 200;
|
|
82
|
-
const ONE_MIN_MS =
|
|
102
|
+
const ONE_MIN_MS = 1000 * 60;
|
|
83
103
|
const defaultConfig = {
|
|
84
104
|
apiURI: 'https://api.instantdb.com',
|
|
85
105
|
websocketURI: 'wss://api.instantdb.com/runtime/session',
|
|
@@ -128,15 +148,13 @@ const ignoreLogging = {
|
|
|
128
148
|
* @returns {QuerySub}
|
|
129
149
|
*/
|
|
130
150
|
function querySubFromStorage(x, useDateObjects) {
|
|
151
|
+
var _a;
|
|
131
152
|
const v = typeof x === 'string' ? JSON.parse(x) : x;
|
|
132
|
-
if (v
|
|
153
|
+
if ((_a = v === null || v === void 0 ? void 0 : v.result) === null || _a === void 0 ? void 0 : _a.store) {
|
|
133
154
|
const attrsStore = s.attrsStoreFromJSON(v.result.attrsStore, v.result.store);
|
|
134
155
|
if (attrsStore) {
|
|
135
156
|
const storeJSON = v.result.store;
|
|
136
|
-
v.result.store = s.fromJSON(attrsStore, {
|
|
137
|
-
...storeJSON,
|
|
138
|
-
useDateObjects: useDateObjects,
|
|
139
|
-
});
|
|
157
|
+
v.result.store = s.fromJSON(attrsStore, Object.assign(Object.assign({}, storeJSON), { useDateObjects: useDateObjects }));
|
|
140
158
|
v.result.attrsStore = attrsStore;
|
|
141
159
|
}
|
|
142
160
|
}
|
|
@@ -149,15 +167,11 @@ function querySubFromStorage(x, useDateObjects) {
|
|
|
149
167
|
* @returns QuerySubInStorage
|
|
150
168
|
*/
|
|
151
169
|
function querySubToStorage(_key, sub) {
|
|
152
|
-
const { result,
|
|
170
|
+
const { result } = sub, rest = __rest(sub, ["result"]);
|
|
153
171
|
const jsonSub = /** @type {import('./reactorTypes.ts').QuerySubInStorage} */ (rest);
|
|
154
172
|
if (result) {
|
|
155
173
|
/** @type {import('./reactorTypes.ts').QuerySubResultInStorage} */
|
|
156
|
-
const jsonResult = {
|
|
157
|
-
...result,
|
|
158
|
-
store: s.toJSON(result.store),
|
|
159
|
-
attrsStore: result.attrsStore.toJSON(),
|
|
160
|
-
};
|
|
174
|
+
const jsonResult = Object.assign(Object.assign({}, result), { store: s.toJSON(result.store), attrsStore: result.attrsStore.toJSON() });
|
|
161
175
|
jsonSub.result = jsonResult;
|
|
162
176
|
}
|
|
163
177
|
return jsonSub;
|
|
@@ -179,8 +193,8 @@ function kvToStorage(key, x) {
|
|
|
179
193
|
}
|
|
180
194
|
}
|
|
181
195
|
function onMergeQuerySub(_k, storageSub, inMemorySub) {
|
|
182
|
-
const storageResult = storageSub
|
|
183
|
-
const memoryResult = inMemorySub
|
|
196
|
+
const storageResult = storageSub === null || storageSub === void 0 ? void 0 : storageSub.result;
|
|
197
|
+
const memoryResult = inMemorySub === null || inMemorySub === void 0 ? void 0 : inMemorySub.result;
|
|
184
198
|
if (storageResult && !memoryResult && inMemorySub) {
|
|
185
199
|
inMemorySub.result = storageResult;
|
|
186
200
|
}
|
|
@@ -202,72 +216,241 @@ function sortedMutationEntries(entries) {
|
|
|
202
216
|
* @template {import('./presence.ts').RoomSchemaShape} [RoomSchema = {}]
|
|
203
217
|
*/
|
|
204
218
|
class Reactor {
|
|
205
|
-
/** @type {s.AttrsStore | undefined} */
|
|
206
|
-
attrs;
|
|
207
|
-
_isOnline = true;
|
|
208
|
-
_isShutdown = false;
|
|
209
|
-
status = STATUS.CONNECTING;
|
|
210
|
-
/** @type {PersistedObject<string, QuerySub, QuerySubInStorage>} */
|
|
211
|
-
querySubs;
|
|
212
|
-
/** @type {PersistedObject} */
|
|
213
|
-
kv;
|
|
214
|
-
/** @type {SyncTable} */
|
|
215
|
-
_syncTable;
|
|
216
|
-
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
|
|
217
|
-
queryCbs = {};
|
|
218
|
-
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
|
|
219
|
-
queryOnceDfds = {};
|
|
220
|
-
authCbs = [];
|
|
221
|
-
attrsCbs = [];
|
|
222
|
-
mutationErrorCbs = [];
|
|
223
|
-
connectionStatusCbs = [];
|
|
224
|
-
config;
|
|
225
|
-
mutationDeferredStore = new Map();
|
|
226
|
-
_reconnectTimeoutId = null;
|
|
227
|
-
_reconnectTimeoutMs = 0;
|
|
228
|
-
/** @type {Connection} */
|
|
229
|
-
_transport;
|
|
230
|
-
/** @type {TransportType} */
|
|
231
|
-
_transportType = 'ws';
|
|
232
|
-
/** @type {EventSourceConstructor} */
|
|
233
|
-
_EventSource;
|
|
234
|
-
/** @type {boolean | null} */
|
|
235
|
-
_wsOk = null;
|
|
236
|
-
_localIdPromises = {};
|
|
237
|
-
_errorMessage = null;
|
|
238
|
-
/** @type {Promise<null | {error: {message: string}}> | null}**/
|
|
239
|
-
_oauthCallbackResponse = null;
|
|
240
|
-
/** @type {null | import('./utils/linkIndex.ts').LinkIndex}} */
|
|
241
|
-
_linkIndex = null;
|
|
242
|
-
/** @type BroadcastChannel | undefined */
|
|
243
|
-
_broadcastChannel;
|
|
244
|
-
/** @type {Record<string, {isConnected: boolean; error: any}>} */
|
|
245
|
-
_rooms = {};
|
|
246
|
-
/** @type {Record<string, boolean>} */
|
|
247
|
-
_roomsPendingLeave = {};
|
|
248
|
-
_presence = {};
|
|
249
|
-
_broadcastQueue = [];
|
|
250
|
-
_broadcastSubs = {};
|
|
251
|
-
/** @type {{isLoading: boolean; error: any | undefined, user: any | undefined}} */
|
|
252
|
-
_currentUserCached = { isLoading: true, error: undefined, user: undefined };
|
|
253
|
-
_beforeUnloadCbs = [];
|
|
254
|
-
_dataForQueryCache = {};
|
|
255
|
-
/** @type {Logger} */
|
|
256
|
-
_log;
|
|
257
|
-
_pendingTxCleanupTimeout;
|
|
258
|
-
_pendingMutationCleanupThreshold;
|
|
259
|
-
_inFlightMutationEventIds = new Set();
|
|
260
219
|
constructor(config, Storage = IndexedDBStorage_ts_1.default, NetworkListener = WindowNetworkListener_js_1.default, versions, EventSourceConstructor) {
|
|
220
|
+
var _a, _b, _c;
|
|
221
|
+
this._isOnline = true;
|
|
222
|
+
this._isShutdown = false;
|
|
223
|
+
this.status = STATUS.CONNECTING;
|
|
224
|
+
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
|
|
225
|
+
this.queryCbs = {};
|
|
226
|
+
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
|
|
227
|
+
this.queryOnceDfds = {};
|
|
228
|
+
this.authCbs = [];
|
|
229
|
+
this.attrsCbs = [];
|
|
230
|
+
this.mutationErrorCbs = [];
|
|
231
|
+
this.connectionStatusCbs = [];
|
|
232
|
+
this.mutationDeferredStore = new Map();
|
|
233
|
+
this._reconnectTimeoutId = null;
|
|
234
|
+
this._reconnectTimeoutMs = 0;
|
|
235
|
+
/** @type {TransportType} */
|
|
236
|
+
this._transportType = 'ws';
|
|
237
|
+
/** @type {boolean | null} */
|
|
238
|
+
this._wsOk = null;
|
|
239
|
+
this._localIdPromises = {};
|
|
240
|
+
this._errorMessage = null;
|
|
241
|
+
/** @type {Promise<null | {error: {message: string}}> | null}**/
|
|
242
|
+
this._oauthCallbackResponse = null;
|
|
243
|
+
/** @type {null | import('./utils/linkIndex.ts').LinkIndex}} */
|
|
244
|
+
this._linkIndex = null;
|
|
245
|
+
/** @type {Record<string, {isConnected: boolean; error: any}>} */
|
|
246
|
+
this._rooms = {};
|
|
247
|
+
/** @type {Record<string, boolean>} */
|
|
248
|
+
this._roomsPendingLeave = {};
|
|
249
|
+
this._presence = {};
|
|
250
|
+
this._broadcastQueue = [];
|
|
251
|
+
this._broadcastSubs = {};
|
|
252
|
+
/** @type {{isLoading: boolean; error: any | undefined, user: any | undefined}} */
|
|
253
|
+
this._currentUserCached = { isLoading: true, error: undefined, user: undefined };
|
|
254
|
+
this._beforeUnloadCbs = [];
|
|
255
|
+
this._dataForQueryCache = {};
|
|
256
|
+
this._inFlightMutationEventIds = new Set();
|
|
257
|
+
this._onMergeKv = (key, storageV, inMemoryV) => {
|
|
258
|
+
var _a, _b;
|
|
259
|
+
switch (key) {
|
|
260
|
+
case 'pendingMutations': {
|
|
261
|
+
const storageEntries = (_a = storageV === null || storageV === void 0 ? void 0 : storageV.entries()) !== null && _a !== void 0 ? _a : [];
|
|
262
|
+
const inMemoryEntries = (_b = inMemoryV === null || inMemoryV === void 0 ? void 0 : inMemoryV.entries()) !== null && _b !== void 0 ? _b : [];
|
|
263
|
+
const muts = new Map([...storageEntries, ...inMemoryEntries]);
|
|
264
|
+
const rewrittenStorageMuts = storageV
|
|
265
|
+
? this._rewriteMutationsSorted(this.attrs, storageV)
|
|
266
|
+
: [];
|
|
267
|
+
rewrittenStorageMuts.forEach(([k, mut]) => {
|
|
268
|
+
var _a;
|
|
269
|
+
if (!((_a = inMemoryV === null || inMemoryV === void 0 ? void 0 : inMemoryV.pendingMutations) === null || _a === void 0 ? void 0 : _a.has(k)) && !mut['tx-id']) {
|
|
270
|
+
this._sendMutation(k, mut);
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
return muts;
|
|
274
|
+
}
|
|
275
|
+
default:
|
|
276
|
+
return inMemoryV || storageV;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
// ---------------------------
|
|
280
|
+
// Queries
|
|
281
|
+
this.getPreviousResult = (q) => {
|
|
282
|
+
var _a;
|
|
283
|
+
const hash = (0, weakHash_ts_1.default)(q);
|
|
284
|
+
return (_a = this.dataForQuery(hash)) === null || _a === void 0 ? void 0 : _a.data;
|
|
285
|
+
};
|
|
286
|
+
/** Re-run instaql and call all callbacks with new data */
|
|
287
|
+
this.notifyOne = (hash) => {
|
|
288
|
+
var _a, _b;
|
|
289
|
+
const cbs = (_a = this.queryCbs[hash]) !== null && _a !== void 0 ? _a : [];
|
|
290
|
+
const prevData = (_b = this._dataForQueryCache[hash]) === null || _b === void 0 ? void 0 : _b.data;
|
|
291
|
+
const resp = this.dataForQuery(hash);
|
|
292
|
+
if (!(resp === null || resp === void 0 ? void 0 : resp.data))
|
|
293
|
+
return;
|
|
294
|
+
this._dataForQueryCache[hash] = resp;
|
|
295
|
+
if ((0, object_js_1.areObjectsDeepEqual)(resp.data, prevData))
|
|
296
|
+
return;
|
|
297
|
+
cbs.forEach((r) => r.cb(resp.data));
|
|
298
|
+
};
|
|
299
|
+
this.notifyOneQueryOnce = (hash) => {
|
|
300
|
+
var _a, _b;
|
|
301
|
+
const dfds = (_a = this.queryOnceDfds[hash]) !== null && _a !== void 0 ? _a : [];
|
|
302
|
+
const data = (_b = this.dataForQuery(hash)) === null || _b === void 0 ? void 0 : _b.data;
|
|
303
|
+
dfds.forEach((r) => {
|
|
304
|
+
this._completeQueryOnce(r.q, hash, r.dfd);
|
|
305
|
+
r.dfd.resolve(data);
|
|
306
|
+
});
|
|
307
|
+
};
|
|
308
|
+
this.notifyQueryError = (hash, error) => {
|
|
309
|
+
const cbs = this.queryCbs[hash] || [];
|
|
310
|
+
cbs.forEach((r) => r.cb({ error }));
|
|
311
|
+
};
|
|
312
|
+
/** Applies transactions locally and sends transact message to server */
|
|
313
|
+
this.pushTx = (chunks) => {
|
|
314
|
+
// Throws if transactions are invalid
|
|
315
|
+
if (!this.config.disableValidation) {
|
|
316
|
+
(0, transactionValidation_ts_1.validateTransactions)(chunks, this.config.schema);
|
|
317
|
+
}
|
|
318
|
+
try {
|
|
319
|
+
const txSteps = instaml.transform({
|
|
320
|
+
attrsStore: this.optimisticAttrs(),
|
|
321
|
+
schema: this.config.schema,
|
|
322
|
+
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; }),
|
|
323
|
+
useDateObjects: this.config.useDateObjects,
|
|
324
|
+
}, chunks);
|
|
325
|
+
return this.pushOps(txSteps);
|
|
326
|
+
}
|
|
327
|
+
catch (e) {
|
|
328
|
+
return this.pushOps([], e);
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* @param {*} txSteps
|
|
333
|
+
* @param {*} [error]
|
|
334
|
+
* @returns
|
|
335
|
+
*/
|
|
336
|
+
this.pushOps = (txSteps, error) => {
|
|
337
|
+
const eventId = (0, id_ts_1.default)();
|
|
338
|
+
const mutations = [...this._pendingMutations().values()];
|
|
339
|
+
const order = Math.max(0, ...mutations.map((mut) => mut.order || 0)) + 1;
|
|
340
|
+
const mutation = {
|
|
341
|
+
op: 'transact',
|
|
342
|
+
'tx-steps': txSteps,
|
|
343
|
+
created: Date.now(),
|
|
344
|
+
error,
|
|
345
|
+
order,
|
|
346
|
+
};
|
|
347
|
+
this._updatePendingMutations((prev) => {
|
|
348
|
+
prev.set(eventId, mutation);
|
|
349
|
+
});
|
|
350
|
+
const dfd = new Deferred_js_1.Deferred();
|
|
351
|
+
this.mutationDeferredStore.set(eventId, dfd);
|
|
352
|
+
this._sendMutation(eventId, mutation);
|
|
353
|
+
this.notifyAll();
|
|
354
|
+
return dfd.promise;
|
|
355
|
+
};
|
|
356
|
+
this._transportOnOpen = (e) => {
|
|
357
|
+
const targetTransport = e.target;
|
|
358
|
+
if (this._transport !== targetTransport) {
|
|
359
|
+
this._log.info('[socket][open]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
this._log.info('[socket][open]', this._transport.id);
|
|
363
|
+
this._setStatus(STATUS.OPENED);
|
|
364
|
+
this.getCurrentUser()
|
|
365
|
+
.then((resp) => {
|
|
366
|
+
var _a;
|
|
367
|
+
this._trySend((0, id_ts_1.default)(), {
|
|
368
|
+
op: 'init',
|
|
369
|
+
'app-id': this.config.appId,
|
|
370
|
+
'refresh-token': (_a = resp.user) === null || _a === void 0 ? void 0 : _a['refresh_token'],
|
|
371
|
+
versions: this.versions,
|
|
372
|
+
// If an admin token is provided for an app, we will
|
|
373
|
+
// skip all permission checks. This is an advanced feature,
|
|
374
|
+
// to let users write internal tools
|
|
375
|
+
// This option is not exposed in `Config`, as it's
|
|
376
|
+
// not ready for prime time
|
|
377
|
+
'__admin-token': this.config.__adminToken,
|
|
378
|
+
});
|
|
379
|
+
})
|
|
380
|
+
.catch((e) => {
|
|
381
|
+
this._log.error('[socket][error]', targetTransport.id, e);
|
|
382
|
+
});
|
|
383
|
+
};
|
|
384
|
+
this._transportOnMessage = (e) => {
|
|
385
|
+
const targetTransport = e.target;
|
|
386
|
+
const m = e.message;
|
|
387
|
+
if (this._transport !== targetTransport) {
|
|
388
|
+
this._log.info('[socket][message]', targetTransport.id, m, 'skip; this is no longer the current transport');
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (!this._wsOk && targetTransport.type === 'ws') {
|
|
392
|
+
this._wsOk = true;
|
|
393
|
+
}
|
|
394
|
+
// Try to reconnect via websocket the next time we connect
|
|
395
|
+
this._transportType = 'ws';
|
|
396
|
+
if (Array.isArray(e.message)) {
|
|
397
|
+
for (const msg of e.message) {
|
|
398
|
+
this._handleReceive(targetTransport.id, msg);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
else {
|
|
402
|
+
this._handleReceive(targetTransport.id, e.message);
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
this._transportOnError = (e) => {
|
|
406
|
+
const targetTransport = e.target;
|
|
407
|
+
if (this._transport !== targetTransport) {
|
|
408
|
+
this._log.info('[socket][error]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
this._log.error('[socket][error]', targetTransport.id, e);
|
|
412
|
+
};
|
|
413
|
+
this._scheduleReconnect = () => {
|
|
414
|
+
// If we couldn't connect with a websocket last time, try sse
|
|
415
|
+
if (!this._wsOk && this._transportType !== 'sse') {
|
|
416
|
+
this._transportType = 'sse';
|
|
417
|
+
this._reconnectTimeoutMs = 0;
|
|
418
|
+
}
|
|
419
|
+
setTimeout(() => {
|
|
420
|
+
this._reconnectTimeoutMs = Math.min(this._reconnectTimeoutMs + 1000, 10000);
|
|
421
|
+
if (!this._isOnline) {
|
|
422
|
+
this._log.info('[socket][close]', this._transport.id, 'we are offline, no need to start socket');
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
this._startSocket();
|
|
426
|
+
}, this._reconnectTimeoutMs);
|
|
427
|
+
};
|
|
428
|
+
this._transportOnClose = (e) => {
|
|
429
|
+
const targetTransport = e.target;
|
|
430
|
+
if (this._transport !== targetTransport) {
|
|
431
|
+
this._log.info('[socket][close]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
this._setStatus(STATUS.CLOSED);
|
|
435
|
+
for (const room of Object.values(this._rooms)) {
|
|
436
|
+
room.isConnected = false;
|
|
437
|
+
}
|
|
438
|
+
if (this._isShutdown) {
|
|
439
|
+
this._log.info('[socket][close]', targetTransport.id, 'Reactor has been shut down and will not reconnect');
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
this._log.info('[socket][close]', targetTransport.id, 'schedule reconnect, ms =', this._reconnectTimeoutMs);
|
|
443
|
+
this._scheduleReconnect();
|
|
444
|
+
};
|
|
261
445
|
this._EventSource = EventSourceConstructor;
|
|
262
|
-
this.config = {
|
|
263
|
-
this.queryCacheLimit = this.config.queryCacheLimit
|
|
446
|
+
this.config = Object.assign(Object.assign({}, defaultConfig), config);
|
|
447
|
+
this.queryCacheLimit = (_a = this.config.queryCacheLimit) !== null && _a !== void 0 ? _a : 10;
|
|
264
448
|
this._pendingTxCleanupTimeout =
|
|
265
|
-
this.config.pendingTxCleanupTimeout
|
|
449
|
+
(_b = this.config.pendingTxCleanupTimeout) !== null && _b !== void 0 ? _b : PENDING_TX_CLEANUP_TIMEOUT;
|
|
266
450
|
this._pendingMutationCleanupThreshold =
|
|
267
|
-
this.config.pendingMutationCleanupThreshold
|
|
268
|
-
PENDING_MUTATION_CLEANUP_THRESHOLD;
|
|
451
|
+
(_c = this.config.pendingMutationCleanupThreshold) !== null && _c !== void 0 ? _c : PENDING_MUTATION_CLEANUP_THRESHOLD;
|
|
269
452
|
this._log = (0, log_ts_1.default)(config.verbose || flags.devBackend || flags.instantLogs, () => this._reactorStats());
|
|
270
|
-
this.versions = {
|
|
453
|
+
this.versions = Object.assign(Object.assign({}, (versions || {})), { '@instantdb/core': version_ts_1.default });
|
|
271
454
|
if (this.config.schema) {
|
|
272
455
|
this._linkIndex = (0, linkIndex_ts_1.createLinkIndex)(this.config.schema);
|
|
273
456
|
}
|
|
@@ -284,17 +467,18 @@ class Reactor {
|
|
|
284
467
|
}
|
|
285
468
|
if (typeof BroadcastChannel === 'function') {
|
|
286
469
|
this._broadcastChannel = new BroadcastChannel('@instantdb');
|
|
287
|
-
this._broadcastChannel.addEventListener('message',
|
|
470
|
+
this._broadcastChannel.addEventListener('message', (e) => __awaiter(this, void 0, void 0, function* () {
|
|
471
|
+
var _a;
|
|
288
472
|
try {
|
|
289
|
-
if (e.data
|
|
290
|
-
const res =
|
|
473
|
+
if (((_a = e.data) === null || _a === void 0 ? void 0 : _a.type) === 'auth') {
|
|
474
|
+
const res = yield this.getCurrentUser();
|
|
291
475
|
this.updateUser(res.user);
|
|
292
476
|
}
|
|
293
477
|
}
|
|
294
478
|
catch (e) {
|
|
295
479
|
this._log.error('[error] handle broadcast channel', e);
|
|
296
480
|
}
|
|
297
|
-
});
|
|
481
|
+
}));
|
|
298
482
|
}
|
|
299
483
|
this._initStorage(Storage);
|
|
300
484
|
this._syncTable = new SyncTable_ts_1.SyncTable(this._trySendAuthed.bind(this), new Storage(this.config.appId, 'syncSubs'), {
|
|
@@ -307,10 +491,10 @@ class Reactor {
|
|
|
307
491
|
this.getCurrentUser().then((userInfo) => {
|
|
308
492
|
this.syncUserToEndpoint(userInfo.user);
|
|
309
493
|
});
|
|
310
|
-
setInterval(
|
|
311
|
-
const currentUser =
|
|
494
|
+
setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
495
|
+
const currentUser = yield this.getCurrentUser();
|
|
312
496
|
this.syncUserToEndpoint(currentUser.user);
|
|
313
|
-
}, ONE_MIN_MS);
|
|
497
|
+
}), ONE_MIN_MS);
|
|
314
498
|
NetworkListener.getIsOnline().then((isOnline) => {
|
|
315
499
|
this._isOnline = isOnline;
|
|
316
500
|
this._startSocket();
|
|
@@ -344,11 +528,7 @@ class Reactor {
|
|
|
344
528
|
return this.attrs;
|
|
345
529
|
}
|
|
346
530
|
updateSchema(schema) {
|
|
347
|
-
this.config = {
|
|
348
|
-
...this.config,
|
|
349
|
-
schema: schema,
|
|
350
|
-
cardinalityInference: Boolean(schema),
|
|
351
|
-
};
|
|
531
|
+
this.config = Object.assign(Object.assign({}, this.config), { schema: schema, cardinalityInference: Boolean(schema) });
|
|
352
532
|
this._linkIndex = schema ? (0, linkIndex_ts_1.createLinkIndex)(this.config.schema) : null;
|
|
353
533
|
}
|
|
354
534
|
_reactorStats() {
|
|
@@ -370,14 +550,14 @@ class Reactor {
|
|
|
370
550
|
serialize: querySubToStorage,
|
|
371
551
|
parse: (_key, x) => querySubFromStorage(x, this.config.useDateObjects),
|
|
372
552
|
// objectSize
|
|
373
|
-
objectSize: (x) => x
|
|
553
|
+
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; },
|
|
374
554
|
logger: this._log,
|
|
375
555
|
preloadEntryCount: 10,
|
|
376
556
|
gc: {
|
|
377
557
|
maxAgeMs: 1000 * 60 * 60 * 24 * 7 * 52, // 1 year
|
|
378
558
|
maxEntries: 1000,
|
|
379
559
|
// Size of each query is the number of triples
|
|
380
|
-
maxSize:
|
|
560
|
+
maxSize: 1000000, // 1 million triples
|
|
381
561
|
},
|
|
382
562
|
});
|
|
383
563
|
this.querySubs.onKeyLoaded = (k) => this._onQuerySubLoaded(k);
|
|
@@ -423,7 +603,7 @@ class Reactor {
|
|
|
423
603
|
const ok = status !== 'error' && status !== 'timeout';
|
|
424
604
|
if (!dfd && !ok) {
|
|
425
605
|
// console.erroring here, as there are no listeners to let know
|
|
426
|
-
console.error('Mutation failed', { status, eventId,
|
|
606
|
+
console.error('Mutation failed', Object.assign({ status, eventId }, errorMsg));
|
|
427
607
|
}
|
|
428
608
|
if (!dfd) {
|
|
429
609
|
return;
|
|
@@ -433,16 +613,16 @@ class Reactor {
|
|
|
433
613
|
}
|
|
434
614
|
else {
|
|
435
615
|
// Check if error comes from server or client
|
|
436
|
-
if (errorMsg
|
|
437
|
-
const { status,
|
|
616
|
+
if (errorMsg === null || errorMsg === void 0 ? void 0 : errorMsg.type) {
|
|
617
|
+
const { status } = errorMsg, body = __rest(errorMsg, ["status"]);
|
|
438
618
|
dfd.reject(new fetch_ts_1.InstantAPIError({
|
|
439
619
|
// @ts-expect-error body.type is not constant typed
|
|
440
620
|
body,
|
|
441
|
-
status: status
|
|
621
|
+
status: status !== null && status !== void 0 ? status : 0,
|
|
442
622
|
}));
|
|
443
623
|
}
|
|
444
624
|
else {
|
|
445
|
-
dfd.reject(new InstantError_ts_1.InstantError(errorMsg
|
|
625
|
+
dfd.reject(new InstantError_ts_1.InstantError((errorMsg === null || errorMsg === void 0 ? void 0 : errorMsg.message) || 'Unknown error', errorMsg === null || errorMsg === void 0 ? void 0 : errorMsg.hint));
|
|
446
626
|
}
|
|
447
627
|
}
|
|
448
628
|
}
|
|
@@ -451,28 +631,9 @@ class Reactor {
|
|
|
451
631
|
this._errorMessage = err;
|
|
452
632
|
this.notifyConnectionStatusSubs(status);
|
|
453
633
|
}
|
|
454
|
-
_onMergeKv = (key, storageV, inMemoryV) => {
|
|
455
|
-
switch (key) {
|
|
456
|
-
case 'pendingMutations': {
|
|
457
|
-
const storageEntries = storageV?.entries() ?? [];
|
|
458
|
-
const inMemoryEntries = inMemoryV?.entries() ?? [];
|
|
459
|
-
const muts = new Map([...storageEntries, ...inMemoryEntries]);
|
|
460
|
-
const rewrittenStorageMuts = storageV
|
|
461
|
-
? this._rewriteMutationsSorted(this.attrs, storageV)
|
|
462
|
-
: [];
|
|
463
|
-
rewrittenStorageMuts.forEach(([k, mut]) => {
|
|
464
|
-
if (!inMemoryV?.pendingMutations?.has(k) && !mut['tx-id']) {
|
|
465
|
-
this._sendMutation(k, mut);
|
|
466
|
-
}
|
|
467
|
-
});
|
|
468
|
-
return muts;
|
|
469
|
-
}
|
|
470
|
-
default:
|
|
471
|
-
return inMemoryV || storageV;
|
|
472
|
-
}
|
|
473
|
-
};
|
|
474
634
|
_flushEnqueuedRoomData(roomId) {
|
|
475
|
-
|
|
635
|
+
var _a, _b;
|
|
636
|
+
const enqueuedUserPresence = (_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.user;
|
|
476
637
|
const enqueuedBroadcasts = this._broadcastQueue[roomId];
|
|
477
638
|
this._broadcastQueue[roomId] = [];
|
|
478
639
|
if (enqueuedUserPresence) {
|
|
@@ -517,6 +678,7 @@ class Reactor {
|
|
|
517
678
|
this._cleanupPendingMutationsTimeout();
|
|
518
679
|
}
|
|
519
680
|
_handleReceive(connId, msg) {
|
|
681
|
+
var _a, _b, _c, _d, _e, _f;
|
|
520
682
|
// opt-out, enabled by default if schema
|
|
521
683
|
const enableCardinalityInference = Boolean(this.config.schema) &&
|
|
522
684
|
('cardinalityInference' in this.config
|
|
@@ -535,7 +697,7 @@ class Reactor {
|
|
|
535
697
|
// which item is us
|
|
536
698
|
this._sessionId = msg['session-id'];
|
|
537
699
|
for (const roomId of Object.keys(this._rooms)) {
|
|
538
|
-
const enqueuedUserPresence = this._presence[roomId]
|
|
700
|
+
const enqueuedUserPresence = (_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.user;
|
|
539
701
|
this._tryJoinRoom(roomId, enqueuedUserPresence);
|
|
540
702
|
}
|
|
541
703
|
break;
|
|
@@ -550,8 +712,8 @@ class Reactor {
|
|
|
550
712
|
if (!this._hasQueryListeners() && !this.querySubs.currentValue[hash]) {
|
|
551
713
|
break;
|
|
552
714
|
}
|
|
553
|
-
const pageInfo = result
|
|
554
|
-
const aggregate = result
|
|
715
|
+
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'];
|
|
716
|
+
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'];
|
|
555
717
|
const triples = (0, instaqlResult_js_1.extractTriples)(result);
|
|
556
718
|
const attrsStore = this.ensureAttrs();
|
|
557
719
|
const store = s.createStore(attrsStore, triples, enableCardinalityInference, this.config.useDateObjects);
|
|
@@ -608,6 +770,7 @@ class Reactor {
|
|
|
608
770
|
}
|
|
609
771
|
const mutations = sortedMutationEntries(rewrittenMutations.entries());
|
|
610
772
|
const updates = computations.map((x) => {
|
|
773
|
+
var _a, _b, _c, _d;
|
|
611
774
|
const q = x['instaql-query'];
|
|
612
775
|
const result = x['instaql-result'];
|
|
613
776
|
const hash = (0, weakHash_ts_1.default)(q);
|
|
@@ -615,8 +778,8 @@ class Reactor {
|
|
|
615
778
|
const attrsStore = this.ensureAttrs();
|
|
616
779
|
const store = s.createStore(attrsStore, triples, enableCardinalityInference, this.config.useDateObjects);
|
|
617
780
|
const { store: newStore, attrsStore: newAttrsStore } = this._applyOptimisticUpdates(store, attrsStore, mutations, processedTxId);
|
|
618
|
-
const pageInfo = result
|
|
619
|
-
const aggregate = result
|
|
781
|
+
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'];
|
|
782
|
+
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'];
|
|
620
783
|
return {
|
|
621
784
|
q,
|
|
622
785
|
hash,
|
|
@@ -657,11 +820,7 @@ class Reactor {
|
|
|
657
820
|
}
|
|
658
821
|
// update pendingMutation with server-side tx-id
|
|
659
822
|
this._updatePendingMutations((prev) => {
|
|
660
|
-
prev.set(eventId, {
|
|
661
|
-
...prev.get(eventId),
|
|
662
|
-
'tx-id': txId,
|
|
663
|
-
confirmed: Date.now(),
|
|
664
|
-
});
|
|
823
|
+
prev.set(eventId, Object.assign(Object.assign({}, prev.get(eventId)), { 'tx-id': txId, confirmed: Date.now() }));
|
|
665
824
|
});
|
|
666
825
|
const newAttrs = [];
|
|
667
826
|
for (const step of prevMutation['tx-steps']) {
|
|
@@ -735,11 +894,13 @@ class Reactor {
|
|
|
735
894
|
}
|
|
736
895
|
}
|
|
737
896
|
_pendingMutations() {
|
|
738
|
-
|
|
897
|
+
var _a;
|
|
898
|
+
return (_a = this.kv.currentValue.pendingMutations) !== null && _a !== void 0 ? _a : new Map();
|
|
739
899
|
}
|
|
740
900
|
_updatePendingMutations(f) {
|
|
741
901
|
this.kv.updateInPlace((prev) => {
|
|
742
|
-
|
|
902
|
+
var _a;
|
|
903
|
+
const muts = (_a = prev.pendingMutations) !== null && _a !== void 0 ? _a : new Map();
|
|
743
904
|
prev.pendingMutations = muts;
|
|
744
905
|
f(muts);
|
|
745
906
|
});
|
|
@@ -768,6 +929,7 @@ class Reactor {
|
|
|
768
929
|
}
|
|
769
930
|
}
|
|
770
931
|
_handleReceiveError(msg) {
|
|
932
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
771
933
|
console.log('error', msg);
|
|
772
934
|
const eventId = msg['client-event-id'];
|
|
773
935
|
// This might not be a mutation, but it can't hurt to delete it
|
|
@@ -783,18 +945,18 @@ class Reactor {
|
|
|
783
945
|
this._handleMutationError('error', eventId, msg);
|
|
784
946
|
return;
|
|
785
947
|
}
|
|
786
|
-
if (msg['original-event']
|
|
787
|
-
msg['original-event']
|
|
788
|
-
const q = msg['original-event']
|
|
948
|
+
if (((_a = msg['original-event']) === null || _a === void 0 ? void 0 : _a.hasOwnProperty('q')) &&
|
|
949
|
+
((_b = msg['original-event']) === null || _b === void 0 ? void 0 : _b.op) === 'add-query') {
|
|
950
|
+
const q = (_c = msg['original-event']) === null || _c === void 0 ? void 0 : _c.q;
|
|
789
951
|
const hash = (0, weakHash_ts_1.default)(q);
|
|
790
952
|
this.notifyQueryError((0, weakHash_ts_1.default)(q), errorMessage);
|
|
791
953
|
this.notifyQueryOnceError(q, hash, eventId, errorMessage);
|
|
792
954
|
return;
|
|
793
955
|
}
|
|
794
|
-
const isInitError = msg['original-event']
|
|
956
|
+
const isInitError = ((_d = msg['original-event']) === null || _d === void 0 ? void 0 : _d.op) === 'init';
|
|
795
957
|
if (isInitError) {
|
|
796
958
|
if (msg.type === 'record-not-found' &&
|
|
797
|
-
msg.hint
|
|
959
|
+
((_e = msg.hint) === null || _e === void 0 ? void 0 : _e['record-type']) === 'app-user') {
|
|
798
960
|
// User has been logged out
|
|
799
961
|
this.changeCurrentUser(null);
|
|
800
962
|
return;
|
|
@@ -804,17 +966,17 @@ class Reactor {
|
|
|
804
966
|
this.notifyAll();
|
|
805
967
|
return;
|
|
806
968
|
}
|
|
807
|
-
if (msg['original-event']
|
|
969
|
+
if (((_f = msg['original-event']) === null || _f === void 0 ? void 0 : _f.op) === 'resync-table') {
|
|
808
970
|
this._syncTable.onResyncError(msg);
|
|
809
971
|
return;
|
|
810
972
|
}
|
|
811
|
-
if (msg['original-event']
|
|
973
|
+
if (((_g = msg['original-event']) === null || _g === void 0 ? void 0 : _g.op) === 'start-sync') {
|
|
812
974
|
this._syncTable.onStartSyncError(msg);
|
|
813
975
|
return;
|
|
814
976
|
}
|
|
815
977
|
// We've caught some error which has no corresponding listener.
|
|
816
978
|
// Let's console.error to let the user know.
|
|
817
|
-
const errorObj = {
|
|
979
|
+
const errorObj = Object.assign({}, msg);
|
|
818
980
|
delete errorObj.message;
|
|
819
981
|
delete errorObj.hint;
|
|
820
982
|
console.error(msg.message, errorObj);
|
|
@@ -823,7 +985,8 @@ class Reactor {
|
|
|
823
985
|
}
|
|
824
986
|
}
|
|
825
987
|
notifyQueryOnceError(q, hash, eventId, e) {
|
|
826
|
-
|
|
988
|
+
var _a;
|
|
989
|
+
const r = (_a = this.queryOnceDfds[hash]) === null || _a === void 0 ? void 0 : _a.find((r) => r.eventId === eventId);
|
|
827
990
|
if (!r)
|
|
828
991
|
return;
|
|
829
992
|
r.dfd.reject(e);
|
|
@@ -836,12 +999,6 @@ class Reactor {
|
|
|
836
999
|
}, {}), this._linkIndex);
|
|
837
1000
|
this.notifyAttrsSubs();
|
|
838
1001
|
}
|
|
839
|
-
// ---------------------------
|
|
840
|
-
// Queries
|
|
841
|
-
getPreviousResult = (q) => {
|
|
842
|
-
const hash = (0, weakHash_ts_1.default)(q);
|
|
843
|
-
return this.dataForQuery(hash)?.data;
|
|
844
|
-
};
|
|
845
1002
|
_startQuerySub(q, hash) {
|
|
846
1003
|
const eventId = (0, id_ts_1.default)();
|
|
847
1004
|
this.querySubs.updateInPlace((prev) => {
|
|
@@ -865,18 +1022,19 @@ class Reactor {
|
|
|
865
1022
|
* Returns an unsubscribe function
|
|
866
1023
|
*/
|
|
867
1024
|
subscribeQuery(q, cb, opts) {
|
|
1025
|
+
var _a;
|
|
868
1026
|
if (!this.config.disableValidation) {
|
|
869
1027
|
(0, queryValidation_ts_1.validateQuery)(q, this.config.schema);
|
|
870
1028
|
}
|
|
871
1029
|
if (opts && 'ruleParams' in opts) {
|
|
872
|
-
q = { $$ruleParams: opts['ruleParams'],
|
|
1030
|
+
q = Object.assign({ $$ruleParams: opts['ruleParams'] }, q);
|
|
873
1031
|
}
|
|
874
1032
|
const hash = (0, weakHash_ts_1.default)(q);
|
|
875
1033
|
const prevResult = this.getPreviousResult(q);
|
|
876
1034
|
if (prevResult) {
|
|
877
1035
|
cb(prevResult);
|
|
878
1036
|
}
|
|
879
|
-
this.queryCbs[hash] = this.queryCbs[hash]
|
|
1037
|
+
this.queryCbs[hash] = (_a = this.queryCbs[hash]) !== null && _a !== void 0 ? _a : [];
|
|
880
1038
|
this.queryCbs[hash].push({ q, cb });
|
|
881
1039
|
this._startQuerySub(q, hash);
|
|
882
1040
|
return () => {
|
|
@@ -884,11 +1042,12 @@ class Reactor {
|
|
|
884
1042
|
};
|
|
885
1043
|
}
|
|
886
1044
|
queryOnce(q, opts) {
|
|
1045
|
+
var _a;
|
|
887
1046
|
if (!this.config.disableValidation) {
|
|
888
1047
|
(0, queryValidation_ts_1.validateQuery)(q, this.config.schema);
|
|
889
1048
|
}
|
|
890
1049
|
if (opts && 'ruleParams' in opts) {
|
|
891
|
-
q = { $$ruleParams: opts['ruleParams'],
|
|
1050
|
+
q = Object.assign({ $$ruleParams: opts['ruleParams'] }, q);
|
|
892
1051
|
}
|
|
893
1052
|
const dfd = new Deferred_js_1.Deferred();
|
|
894
1053
|
if (!this._isOnline) {
|
|
@@ -901,7 +1060,7 @@ class Reactor {
|
|
|
901
1060
|
}
|
|
902
1061
|
const hash = (0, weakHash_ts_1.default)(q);
|
|
903
1062
|
const eventId = this._startQuerySub(q, hash);
|
|
904
|
-
this.queryOnceDfds[hash] = this.queryOnceDfds[hash]
|
|
1063
|
+
this.queryOnceDfds[hash] = (_a = this.queryOnceDfds[hash]) !== null && _a !== void 0 ? _a : [];
|
|
905
1064
|
this.queryOnceDfds[hash].push({ q, dfd, eventId });
|
|
906
1065
|
setTimeout(() => dfd.reject(new Error('Query timed out')), QUERY_ONCE_TIMEOUT);
|
|
907
1066
|
return dfd.promise;
|
|
@@ -919,7 +1078,8 @@ class Reactor {
|
|
|
919
1078
|
this._cleanupQuery(q, hash);
|
|
920
1079
|
}
|
|
921
1080
|
_hasQueryListeners(hash) {
|
|
922
|
-
|
|
1081
|
+
var _a, _b;
|
|
1082
|
+
return !!(((_a = this.queryCbs[hash]) === null || _a === void 0 ? void 0 : _a.length) || ((_b = this.queryOnceDfds[hash]) === null || _b === void 0 ? void 0 : _b.length));
|
|
923
1083
|
}
|
|
924
1084
|
_cleanupQuery(q, hash) {
|
|
925
1085
|
const hasListeners = this._hasQueryListeners(hash);
|
|
@@ -1011,10 +1171,7 @@ class Reactor {
|
|
|
1011
1171
|
};
|
|
1012
1172
|
const rewritten = new Map();
|
|
1013
1173
|
for (const [k, mut] of muts.entries()) {
|
|
1014
|
-
rewritten.set(k, {
|
|
1015
|
-
...mut,
|
|
1016
|
-
'tx-steps': rewriteTxSteps(mut['tx-steps'], mut['tx-id']),
|
|
1017
|
-
});
|
|
1174
|
+
rewritten.set(k, Object.assign(Object.assign({}, mut), { 'tx-steps': rewriteTxSteps(mut['tx-steps'], mut['tx-id']) }));
|
|
1018
1175
|
}
|
|
1019
1176
|
if (!mappingChanged) {
|
|
1020
1177
|
return muts;
|
|
@@ -1030,6 +1187,7 @@ class Reactor {
|
|
|
1030
1187
|
* @returns {s.AttrsStore}
|
|
1031
1188
|
*/
|
|
1032
1189
|
optimisticAttrs() {
|
|
1190
|
+
var _a, _b;
|
|
1033
1191
|
const pendingMutationSteps = [...this._pendingMutations().values()] // hack due to Map()
|
|
1034
1192
|
.flatMap((x) => x['tx-steps']);
|
|
1035
1193
|
const deletedAttrIds = new Set(pendingMutationSteps
|
|
@@ -1042,15 +1200,15 @@ class Reactor {
|
|
|
1042
1200
|
}
|
|
1043
1201
|
else if (_action === 'update-attr' &&
|
|
1044
1202
|
attr.id &&
|
|
1045
|
-
this.attrs
|
|
1046
|
-
const fullAttr = {
|
|
1203
|
+
((_a = this.attrs) === null || _a === void 0 ? void 0 : _a.getAttr(attr.id))) {
|
|
1204
|
+
const fullAttr = Object.assign(Object.assign({}, this.attrs.getAttr(attr.id)), attr);
|
|
1047
1205
|
pendingAttrs.push(fullAttr);
|
|
1048
1206
|
}
|
|
1049
1207
|
}
|
|
1050
1208
|
if (!deletedAttrIds.size && !pendingAttrs.length) {
|
|
1051
1209
|
return this.attrs || new s.AttrsStoreClass({}, this._linkIndex);
|
|
1052
1210
|
}
|
|
1053
|
-
const attrs = {
|
|
1211
|
+
const attrs = Object.assign({}, (((_b = this.attrs) === null || _b === void 0 ? void 0 : _b.attrs) || {}));
|
|
1054
1212
|
for (const attr of pendingAttrs) {
|
|
1055
1213
|
attrs[attr.id] = attr;
|
|
1056
1214
|
}
|
|
@@ -1104,30 +1262,6 @@ class Reactor {
|
|
|
1104
1262
|
}
|
|
1105
1263
|
return { store, attrsStore };
|
|
1106
1264
|
}
|
|
1107
|
-
/** Re-run instaql and call all callbacks with new data */
|
|
1108
|
-
notifyOne = (hash) => {
|
|
1109
|
-
const cbs = this.queryCbs[hash] ?? [];
|
|
1110
|
-
const prevData = this._dataForQueryCache[hash]?.data;
|
|
1111
|
-
const resp = this.dataForQuery(hash);
|
|
1112
|
-
if (!resp?.data)
|
|
1113
|
-
return;
|
|
1114
|
-
this._dataForQueryCache[hash] = resp;
|
|
1115
|
-
if ((0, object_js_1.areObjectsDeepEqual)(resp.data, prevData))
|
|
1116
|
-
return;
|
|
1117
|
-
cbs.forEach((r) => r.cb(resp.data));
|
|
1118
|
-
};
|
|
1119
|
-
notifyOneQueryOnce = (hash) => {
|
|
1120
|
-
const dfds = this.queryOnceDfds[hash] ?? [];
|
|
1121
|
-
const data = this.dataForQuery(hash)?.data;
|
|
1122
|
-
dfds.forEach((r) => {
|
|
1123
|
-
this._completeQueryOnce(r.q, hash, r.dfd);
|
|
1124
|
-
r.dfd.resolve(data);
|
|
1125
|
-
});
|
|
1126
|
-
};
|
|
1127
|
-
notifyQueryError = (hash, error) => {
|
|
1128
|
-
const cbs = this.queryCbs[hash] || [];
|
|
1129
|
-
cbs.forEach((r) => r.cb({ error }));
|
|
1130
|
-
};
|
|
1131
1265
|
/** Re-compute all subscriptions */
|
|
1132
1266
|
notifyAll() {
|
|
1133
1267
|
Object.keys(this.queryCbs).forEach((hash) => {
|
|
@@ -1143,54 +1277,11 @@ class Reactor {
|
|
|
1143
1277
|
.then(() => this.notifyAll())
|
|
1144
1278
|
.catch(() => this.notifyAll());
|
|
1145
1279
|
}
|
|
1146
|
-
/** Applies transactions locally and sends transact message to server */
|
|
1147
|
-
pushTx = (chunks) => {
|
|
1148
|
-
// Throws if transactions are invalid
|
|
1149
|
-
if (!this.config.disableValidation) {
|
|
1150
|
-
(0, transactionValidation_ts_1.validateTransactions)(chunks, this.config.schema);
|
|
1151
|
-
}
|
|
1152
|
-
try {
|
|
1153
|
-
const txSteps = instaml.transform({
|
|
1154
|
-
attrsStore: this.optimisticAttrs(),
|
|
1155
|
-
schema: this.config.schema,
|
|
1156
|
-
stores: Object.values(this.querySubs.currentValue).map((sub) => sub?.result?.store),
|
|
1157
|
-
useDateObjects: this.config.useDateObjects,
|
|
1158
|
-
}, chunks);
|
|
1159
|
-
return this.pushOps(txSteps);
|
|
1160
|
-
}
|
|
1161
|
-
catch (e) {
|
|
1162
|
-
return this.pushOps([], e);
|
|
1163
|
-
}
|
|
1164
|
-
};
|
|
1165
|
-
/**
|
|
1166
|
-
* @param {*} txSteps
|
|
1167
|
-
* @param {*} [error]
|
|
1168
|
-
* @returns
|
|
1169
|
-
*/
|
|
1170
|
-
pushOps = (txSteps, error) => {
|
|
1171
|
-
const eventId = (0, id_ts_1.default)();
|
|
1172
|
-
const mutations = [...this._pendingMutations().values()];
|
|
1173
|
-
const order = Math.max(0, ...mutations.map((mut) => mut.order || 0)) + 1;
|
|
1174
|
-
const mutation = {
|
|
1175
|
-
op: 'transact',
|
|
1176
|
-
'tx-steps': txSteps,
|
|
1177
|
-
created: Date.now(),
|
|
1178
|
-
error,
|
|
1179
|
-
order,
|
|
1180
|
-
};
|
|
1181
|
-
this._updatePendingMutations((prev) => {
|
|
1182
|
-
prev.set(eventId, mutation);
|
|
1183
|
-
});
|
|
1184
|
-
const dfd = new Deferred_js_1.Deferred();
|
|
1185
|
-
this.mutationDeferredStore.set(eventId, dfd);
|
|
1186
|
-
this._sendMutation(eventId, mutation);
|
|
1187
|
-
this.notifyAll();
|
|
1188
|
-
return dfd.promise;
|
|
1189
|
-
};
|
|
1190
1280
|
shutdown() {
|
|
1281
|
+
var _a;
|
|
1191
1282
|
this._log.info('[shutdown]', this.config.appId);
|
|
1192
1283
|
this._isShutdown = true;
|
|
1193
|
-
this._transport
|
|
1284
|
+
(_a = this._transport) === null || _a === void 0 ? void 0 : _a.close();
|
|
1194
1285
|
}
|
|
1195
1286
|
/**
|
|
1196
1287
|
* Sends mutation to server and schedules a timeout to cancel it if
|
|
@@ -1263,8 +1354,8 @@ class Reactor {
|
|
|
1263
1354
|
_cleanupPendingMutationsQueries() {
|
|
1264
1355
|
let minProcessedTxId = Number.MAX_SAFE_INTEGER;
|
|
1265
1356
|
for (const { result } of Object.values(this.querySubs.currentValue)) {
|
|
1266
|
-
if (result
|
|
1267
|
-
minProcessedTxId = Math.min(minProcessedTxId, result
|
|
1357
|
+
if (result === null || result === void 0 ? void 0 : result.processedTxId) {
|
|
1358
|
+
minProcessedTxId = Math.min(minProcessedTxId, result === null || result === void 0 ? void 0 : result.processedTxId);
|
|
1268
1359
|
}
|
|
1269
1360
|
}
|
|
1270
1361
|
this._updatePendingMutations((prev) => {
|
|
@@ -1317,96 +1408,8 @@ class Reactor {
|
|
|
1317
1408
|
this._inFlightMutationEventIds.clear();
|
|
1318
1409
|
}
|
|
1319
1410
|
}
|
|
1320
|
-
this._transport.send({ 'client-event-id': eventId,
|
|
1411
|
+
this._transport.send(Object.assign({ 'client-event-id': eventId }, msg));
|
|
1321
1412
|
}
|
|
1322
|
-
_transportOnOpen = (e) => {
|
|
1323
|
-
const targetTransport = e.target;
|
|
1324
|
-
if (this._transport !== targetTransport) {
|
|
1325
|
-
this._log.info('[socket][open]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
1326
|
-
return;
|
|
1327
|
-
}
|
|
1328
|
-
this._log.info('[socket][open]', this._transport.id);
|
|
1329
|
-
this._setStatus(STATUS.OPENED);
|
|
1330
|
-
this.getCurrentUser()
|
|
1331
|
-
.then((resp) => {
|
|
1332
|
-
this._trySend((0, id_ts_1.default)(), {
|
|
1333
|
-
op: 'init',
|
|
1334
|
-
'app-id': this.config.appId,
|
|
1335
|
-
'refresh-token': resp.user?.['refresh_token'],
|
|
1336
|
-
versions: this.versions,
|
|
1337
|
-
// If an admin token is provided for an app, we will
|
|
1338
|
-
// skip all permission checks. This is an advanced feature,
|
|
1339
|
-
// to let users write internal tools
|
|
1340
|
-
// This option is not exposed in `Config`, as it's
|
|
1341
|
-
// not ready for prime time
|
|
1342
|
-
'__admin-token': this.config.__adminToken,
|
|
1343
|
-
});
|
|
1344
|
-
})
|
|
1345
|
-
.catch((e) => {
|
|
1346
|
-
this._log.error('[socket][error]', targetTransport.id, e);
|
|
1347
|
-
});
|
|
1348
|
-
};
|
|
1349
|
-
_transportOnMessage = (e) => {
|
|
1350
|
-
const targetTransport = e.target;
|
|
1351
|
-
const m = e.message;
|
|
1352
|
-
if (this._transport !== targetTransport) {
|
|
1353
|
-
this._log.info('[socket][message]', targetTransport.id, m, 'skip; this is no longer the current transport');
|
|
1354
|
-
return;
|
|
1355
|
-
}
|
|
1356
|
-
if (!this._wsOk && targetTransport.type === 'ws') {
|
|
1357
|
-
this._wsOk = true;
|
|
1358
|
-
}
|
|
1359
|
-
// Try to reconnect via websocket the next time we connect
|
|
1360
|
-
this._transportType = 'ws';
|
|
1361
|
-
if (Array.isArray(e.message)) {
|
|
1362
|
-
for (const msg of e.message) {
|
|
1363
|
-
this._handleReceive(targetTransport.id, msg);
|
|
1364
|
-
}
|
|
1365
|
-
}
|
|
1366
|
-
else {
|
|
1367
|
-
this._handleReceive(targetTransport.id, e.message);
|
|
1368
|
-
}
|
|
1369
|
-
};
|
|
1370
|
-
_transportOnError = (e) => {
|
|
1371
|
-
const targetTransport = e.target;
|
|
1372
|
-
if (this._transport !== targetTransport) {
|
|
1373
|
-
this._log.info('[socket][error]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
1374
|
-
return;
|
|
1375
|
-
}
|
|
1376
|
-
this._log.error('[socket][error]', targetTransport.id, e);
|
|
1377
|
-
};
|
|
1378
|
-
_scheduleReconnect = () => {
|
|
1379
|
-
// If we couldn't connect with a websocket last time, try sse
|
|
1380
|
-
if (!this._wsOk && this._transportType !== 'sse') {
|
|
1381
|
-
this._transportType = 'sse';
|
|
1382
|
-
this._reconnectTimeoutMs = 0;
|
|
1383
|
-
}
|
|
1384
|
-
setTimeout(() => {
|
|
1385
|
-
this._reconnectTimeoutMs = Math.min(this._reconnectTimeoutMs + 1000, 10000);
|
|
1386
|
-
if (!this._isOnline) {
|
|
1387
|
-
this._log.info('[socket][close]', this._transport.id, 'we are offline, no need to start socket');
|
|
1388
|
-
return;
|
|
1389
|
-
}
|
|
1390
|
-
this._startSocket();
|
|
1391
|
-
}, this._reconnectTimeoutMs);
|
|
1392
|
-
};
|
|
1393
|
-
_transportOnClose = (e) => {
|
|
1394
|
-
const targetTransport = e.target;
|
|
1395
|
-
if (this._transport !== targetTransport) {
|
|
1396
|
-
this._log.info('[socket][close]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
1397
|
-
return;
|
|
1398
|
-
}
|
|
1399
|
-
this._setStatus(STATUS.CLOSED);
|
|
1400
|
-
for (const room of Object.values(this._rooms)) {
|
|
1401
|
-
room.isConnected = false;
|
|
1402
|
-
}
|
|
1403
|
-
if (this._isShutdown) {
|
|
1404
|
-
this._log.info('[socket][close]', targetTransport.id, 'Reactor has been shut down and will not reconnect');
|
|
1405
|
-
return;
|
|
1406
|
-
}
|
|
1407
|
-
this._log.info('[socket][close]', targetTransport.id, 'schedule reconnect, ms =', this._reconnectTimeoutMs);
|
|
1408
|
-
this._scheduleReconnect();
|
|
1409
|
-
};
|
|
1410
1413
|
_startSocket() {
|
|
1411
1414
|
// Reset whether we support websockets each time we connect
|
|
1412
1415
|
// new networks may not support websockets
|
|
@@ -1435,7 +1438,7 @@ class Reactor {
|
|
|
1435
1438
|
this._transport.onclose = this._transportOnClose;
|
|
1436
1439
|
this._transport.onerror = this._transportOnError;
|
|
1437
1440
|
this._log.info('[socket][start]', this._transport.id);
|
|
1438
|
-
if (prevTransport
|
|
1441
|
+
if (prevTransport === null || prevTransport === void 0 ? void 0 : prevTransport.isOpen()) {
|
|
1439
1442
|
// When the network dies, it doesn't always mean that our
|
|
1440
1443
|
// socket connection will fire a close event.
|
|
1441
1444
|
//
|
|
@@ -1456,22 +1459,24 @@ class Reactor {
|
|
|
1456
1459
|
* Note: If the user deletes their local storage, this id will change.
|
|
1457
1460
|
*
|
|
1458
1461
|
*/
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1462
|
+
getLocalId(name) {
|
|
1463
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1464
|
+
const k = `localToken_${name}`;
|
|
1465
|
+
if (this.kv.currentValue[k]) {
|
|
1466
|
+
return this.kv.currentValue[k];
|
|
1467
|
+
}
|
|
1468
|
+
const current = yield this.kv.waitForKeyToLoad(k);
|
|
1469
|
+
if (current) {
|
|
1470
|
+
return current;
|
|
1471
|
+
}
|
|
1472
|
+
const newId = (0, id_ts_1.default)();
|
|
1473
|
+
this.kv.updateInPlace((prev) => {
|
|
1474
|
+
if (prev[k])
|
|
1475
|
+
return;
|
|
1476
|
+
prev[k] = newId;
|
|
1477
|
+
});
|
|
1478
|
+
return yield this.kv.waitForKeyToLoad(k);
|
|
1473
1479
|
});
|
|
1474
|
-
return await this.kv.waitForKeyToLoad(k);
|
|
1475
1480
|
}
|
|
1476
1481
|
// ----
|
|
1477
1482
|
// Auth
|
|
@@ -1506,13 +1511,14 @@ class Reactor {
|
|
|
1506
1511
|
// The next.js app router will reset the URL when the router loads.
|
|
1507
1512
|
// This puts it back after the router loads.
|
|
1508
1513
|
const listener = (e) => {
|
|
1514
|
+
var _a;
|
|
1509
1515
|
if (!ran) {
|
|
1510
1516
|
ran = true;
|
|
1511
1517
|
// @ts-ignore (waiting for ts support)
|
|
1512
1518
|
navigation.removeEventListener('navigate', listener);
|
|
1513
1519
|
if (!e.userInitiated &&
|
|
1514
1520
|
e.navigationType === 'replace' &&
|
|
1515
|
-
e.destination
|
|
1521
|
+
((_a = e.destination) === null || _a === void 0 ? void 0 : _a.url) === startUrl) {
|
|
1516
1522
|
history.replaceState(history.state, '', newPath);
|
|
1517
1523
|
}
|
|
1518
1524
|
}
|
|
@@ -1526,52 +1532,57 @@ class Reactor {
|
|
|
1526
1532
|
*
|
|
1527
1533
|
* @returns Promise<null | {error: {message: string}}>
|
|
1528
1534
|
*/
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
typeof
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1535
|
+
_oauthLoginInit() {
|
|
1536
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1537
|
+
var _a, _b, _c, _d;
|
|
1538
|
+
if (typeof window === 'undefined' ||
|
|
1539
|
+
typeof window.location === 'undefined' ||
|
|
1540
|
+
typeof URLSearchParams === 'undefined') {
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
const params = new URLSearchParams(window.location.search);
|
|
1544
|
+
if (!params.get(OAUTH_REDIRECT_PARAM)) {
|
|
1545
|
+
return null;
|
|
1546
|
+
}
|
|
1547
|
+
const error = params.get('error');
|
|
1548
|
+
if (error) {
|
|
1549
|
+
this._replaceUrlAfterOAuth();
|
|
1550
|
+
return { error: { message: error } };
|
|
1551
|
+
}
|
|
1552
|
+
const code = params.get('code');
|
|
1553
|
+
if (!code) {
|
|
1554
|
+
return null;
|
|
1555
|
+
}
|
|
1541
1556
|
this._replaceUrlAfterOAuth();
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
const { user } = await authAPI.exchangeCodeForToken({
|
|
1553
|
-
apiURI: this.config.apiURI,
|
|
1554
|
-
appId: this.config.appId,
|
|
1555
|
-
code,
|
|
1556
|
-
refreshToken: isGuest ? currentUser.refresh_token : undefined,
|
|
1557
|
-
});
|
|
1558
|
-
this.setCurrentUser(user);
|
|
1559
|
-
return null;
|
|
1560
|
-
}
|
|
1561
|
-
catch (e) {
|
|
1562
|
-
if (e?.body?.type === 'record-not-found' &&
|
|
1563
|
-
e?.body?.hint?.['record-type'] === 'app-oauth-code' &&
|
|
1564
|
-
(await this._hasCurrentUser())) {
|
|
1565
|
-
// We probably just weren't able to clean up the URL, so
|
|
1566
|
-
// let's just ignore this error
|
|
1557
|
+
try {
|
|
1558
|
+
const currentUser = yield this._getCurrentUser();
|
|
1559
|
+
const isGuest = (currentUser === null || currentUser === void 0 ? void 0 : currentUser.type) === 'guest';
|
|
1560
|
+
const { user } = yield authAPI.exchangeCodeForToken({
|
|
1561
|
+
apiURI: this.config.apiURI,
|
|
1562
|
+
appId: this.config.appId,
|
|
1563
|
+
code,
|
|
1564
|
+
refreshToken: isGuest ? currentUser.refresh_token : undefined,
|
|
1565
|
+
});
|
|
1566
|
+
this.setCurrentUser(user);
|
|
1567
1567
|
return null;
|
|
1568
1568
|
}
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1569
|
+
catch (e) {
|
|
1570
|
+
if (((_a = e === null || e === void 0 ? void 0 : e.body) === null || _a === void 0 ? void 0 : _a.type) === 'record-not-found' &&
|
|
1571
|
+
((_c = (_b = e === null || e === void 0 ? void 0 : e.body) === null || _b === void 0 ? void 0 : _b.hint) === null || _c === void 0 ? void 0 : _c['record-type']) === 'app-oauth-code' &&
|
|
1572
|
+
(yield this._hasCurrentUser())) {
|
|
1573
|
+
// We probably just weren't able to clean up the URL, so
|
|
1574
|
+
// let's just ignore this error
|
|
1575
|
+
return null;
|
|
1576
|
+
}
|
|
1577
|
+
const message = ((_d = e === null || e === void 0 ? void 0 : e.body) === null || _d === void 0 ? void 0 : _d.message) || 'Error logging in.';
|
|
1578
|
+
return { error: { message } };
|
|
1579
|
+
}
|
|
1580
|
+
});
|
|
1572
1581
|
}
|
|
1573
|
-
|
|
1574
|
-
return
|
|
1582
|
+
_waitForOAuthCallbackResponse() {
|
|
1583
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1584
|
+
return yield this._oauthCallbackResponse;
|
|
1585
|
+
});
|
|
1575
1586
|
}
|
|
1576
1587
|
__subscribeMutationErrors(cb) {
|
|
1577
1588
|
this.mutationErrorCbs.push(cb);
|
|
@@ -1598,12 +1609,14 @@ class Reactor {
|
|
|
1598
1609
|
this.authCbs = this.authCbs.filter((x) => x !== cb);
|
|
1599
1610
|
};
|
|
1600
1611
|
}
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1612
|
+
getAuth() {
|
|
1613
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1614
|
+
const { user, error } = yield this.getCurrentUser();
|
|
1615
|
+
if (error) {
|
|
1616
|
+
throw new InstantError_ts_1.InstantError('Could not get current user: ' + error.message);
|
|
1617
|
+
}
|
|
1618
|
+
return user;
|
|
1619
|
+
});
|
|
1607
1620
|
}
|
|
1608
1621
|
subscribeConnectionStatus(cb) {
|
|
1609
1622
|
this.connectionStatusCbs.push(cb);
|
|
@@ -1635,89 +1648,99 @@ class Reactor {
|
|
|
1635
1648
|
notifyConnectionStatusSubs(status) {
|
|
1636
1649
|
this.connectionStatusCbs.forEach((cb) => cb(status));
|
|
1637
1650
|
}
|
|
1638
|
-
|
|
1639
|
-
this
|
|
1640
|
-
prev
|
|
1651
|
+
setCurrentUser(user) {
|
|
1652
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1653
|
+
this.kv.updateInPlace((prev) => {
|
|
1654
|
+
prev[currentUserKey] = user;
|
|
1655
|
+
});
|
|
1656
|
+
yield this.kv.waitForKeyToLoad(currentUserKey);
|
|
1641
1657
|
});
|
|
1642
|
-
await this.kv.waitForKeyToLoad(currentUserKey);
|
|
1643
1658
|
}
|
|
1644
1659
|
getCurrentUserCached() {
|
|
1645
1660
|
return this._currentUserCached;
|
|
1646
1661
|
}
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
const oauthResp = await this._waitForOAuthCallbackResponse();
|
|
1653
|
-
if (oauthResp?.error) {
|
|
1654
|
-
const errorV = { error: oauthResp.error, user: undefined };
|
|
1655
|
-
this._currentUserCached = { isLoading: false, ...errorV };
|
|
1656
|
-
return errorV;
|
|
1657
|
-
}
|
|
1658
|
-
try {
|
|
1659
|
-
const user = await this._getCurrentUser();
|
|
1660
|
-
const userV = { user: user, error: undefined };
|
|
1661
|
-
this._currentUserCached = {
|
|
1662
|
-
isLoading: false,
|
|
1663
|
-
...userV,
|
|
1664
|
-
};
|
|
1665
|
-
return userV;
|
|
1666
|
-
}
|
|
1667
|
-
catch (e) {
|
|
1668
|
-
return {
|
|
1669
|
-
user: undefined,
|
|
1670
|
-
isLoading: false,
|
|
1671
|
-
error: { message: e?.message || 'Error loading user' },
|
|
1672
|
-
};
|
|
1673
|
-
}
|
|
1662
|
+
_getCurrentUser() {
|
|
1663
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1664
|
+
const user = yield this.kv.waitForKeyToLoad(currentUserKey);
|
|
1665
|
+
return typeof user === 'string' ? JSON.parse(user) : user;
|
|
1666
|
+
});
|
|
1674
1667
|
}
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1668
|
+
getCurrentUser() {
|
|
1669
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1670
|
+
const oauthResp = yield this._waitForOAuthCallbackResponse();
|
|
1671
|
+
if (oauthResp === null || oauthResp === void 0 ? void 0 : oauthResp.error) {
|
|
1672
|
+
const errorV = { error: oauthResp.error, user: undefined };
|
|
1673
|
+
this._currentUserCached = Object.assign({ isLoading: false }, errorV);
|
|
1674
|
+
return errorV;
|
|
1675
|
+
}
|
|
1676
|
+
try {
|
|
1677
|
+
const user = yield this._getCurrentUser();
|
|
1678
|
+
const userV = { user: user, error: undefined };
|
|
1679
|
+
this._currentUserCached = Object.assign({ isLoading: false }, userV);
|
|
1680
|
+
return userV;
|
|
1681
|
+
}
|
|
1682
|
+
catch (e) {
|
|
1683
|
+
return {
|
|
1684
|
+
user: undefined,
|
|
1685
|
+
isLoading: false,
|
|
1686
|
+
error: { message: (e === null || e === void 0 ? void 0 : e.message) || 'Error loading user' },
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
});
|
|
1678
1690
|
}
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
return;
|
|
1685
|
-
}
|
|
1686
|
-
await this.setCurrentUser(newUser);
|
|
1687
|
-
// We need to remove all `result` from querySubs,
|
|
1688
|
-
// as they are no longer valid for the new user
|
|
1689
|
-
this.updateUser(newUser);
|
|
1690
|
-
try {
|
|
1691
|
-
this._broadcastChannel?.postMessage({ type: 'auth' });
|
|
1692
|
-
}
|
|
1693
|
-
catch (error) {
|
|
1694
|
-
console.error('Error posting message to broadcast channel', error);
|
|
1695
|
-
}
|
|
1691
|
+
_hasCurrentUser() {
|
|
1692
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1693
|
+
const user = yield this.kv.waitForKeyToLoad(currentUserKey);
|
|
1694
|
+
return typeof user === 'string' ? JSON.parse(user) != null : user != null;
|
|
1695
|
+
});
|
|
1696
1696
|
}
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1697
|
+
changeCurrentUser(newUser) {
|
|
1698
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1699
|
+
var _a;
|
|
1700
|
+
const { user: oldUser } = yield this.getCurrentUser();
|
|
1701
|
+
if ((0, object_js_1.areObjectsDeepEqual)(oldUser, newUser)) {
|
|
1702
|
+
// We were already logged in as the newUser, don't
|
|
1703
|
+
// bother updating
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1706
|
+
yield this.setCurrentUser(newUser);
|
|
1707
|
+
// We need to remove all `result` from querySubs,
|
|
1708
|
+
// as they are no longer valid for the new user
|
|
1709
|
+
this.updateUser(newUser);
|
|
1710
|
+
try {
|
|
1711
|
+
(_a = this._broadcastChannel) === null || _a === void 0 ? void 0 : _a.postMessage({ type: 'auth' });
|
|
1712
|
+
}
|
|
1713
|
+
catch (error) {
|
|
1714
|
+
console.error('Error posting message to broadcast channel', error);
|
|
1715
|
+
}
|
|
1716
|
+
});
|
|
1717
|
+
}
|
|
1718
|
+
syncUserToEndpoint(user) {
|
|
1719
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1720
|
+
if (!this.config.firstPartyPath)
|
|
1721
|
+
return;
|
|
1722
|
+
try {
|
|
1723
|
+
fetch(this.config.firstPartyPath + '/', {
|
|
1724
|
+
method: 'POST',
|
|
1725
|
+
body: JSON.stringify({
|
|
1726
|
+
type: 'sync-user',
|
|
1727
|
+
appId: this.config.appId,
|
|
1728
|
+
user: user,
|
|
1729
|
+
}),
|
|
1730
|
+
headers: {
|
|
1731
|
+
'Content-Type': 'application/json',
|
|
1732
|
+
},
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
catch (error) {
|
|
1736
|
+
this._log.error('Error syncing user with external endpoint', error);
|
|
1737
|
+
}
|
|
1738
|
+
});
|
|
1716
1739
|
}
|
|
1717
1740
|
updateUser(newUser) {
|
|
1718
1741
|
this.syncUserToEndpoint(newUser);
|
|
1719
1742
|
const newV = { error: undefined, user: newUser };
|
|
1720
|
-
this._currentUserCached = { isLoading: false,
|
|
1743
|
+
this._currentUserCached = Object.assign({ isLoading: false }, newV);
|
|
1721
1744
|
this._dataForQueryCache = {};
|
|
1722
1745
|
this.querySubs.updateInPlace((prev) => {
|
|
1723
1746
|
Object.keys(prev).forEach((k) => {
|
|
@@ -1736,38 +1759,46 @@ class Reactor {
|
|
|
1736
1759
|
email: email,
|
|
1737
1760
|
});
|
|
1738
1761
|
}
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1762
|
+
signInWithMagicCode(_a) {
|
|
1763
|
+
return __awaiter(this, arguments, void 0, function* ({ email, code }) {
|
|
1764
|
+
var _b;
|
|
1765
|
+
const currentUser = yield this.getCurrentUser();
|
|
1766
|
+
const isGuest = ((_b = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _b === void 0 ? void 0 : _b.type) === 'guest';
|
|
1767
|
+
const res = yield authAPI.verifyMagicCode({
|
|
1768
|
+
apiURI: this.config.apiURI,
|
|
1769
|
+
appId: this.config.appId,
|
|
1770
|
+
email,
|
|
1771
|
+
code,
|
|
1772
|
+
refreshToken: isGuest ? currentUser.user.refresh_token : undefined,
|
|
1773
|
+
});
|
|
1774
|
+
yield this.changeCurrentUser(res.user);
|
|
1775
|
+
return res;
|
|
1748
1776
|
});
|
|
1749
|
-
await this.changeCurrentUser(res.user);
|
|
1750
|
-
return res;
|
|
1751
1777
|
}
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1778
|
+
signInWithCustomToken(authToken) {
|
|
1779
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1780
|
+
const res = yield authAPI.verifyRefreshToken({
|
|
1781
|
+
apiURI: this.config.apiURI,
|
|
1782
|
+
appId: this.config.appId,
|
|
1783
|
+
refreshToken: authToken,
|
|
1784
|
+
});
|
|
1785
|
+
yield this.changeCurrentUser(res.user);
|
|
1786
|
+
return res;
|
|
1757
1787
|
});
|
|
1758
|
-
await this.changeCurrentUser(res.user);
|
|
1759
|
-
return res;
|
|
1760
1788
|
}
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1789
|
+
signInAsGuest() {
|
|
1790
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1791
|
+
const res = yield authAPI.signInAsGuest({
|
|
1792
|
+
apiURI: this.config.apiURI,
|
|
1793
|
+
appId: this.config.appId,
|
|
1794
|
+
});
|
|
1795
|
+
yield this.changeCurrentUser(res.user);
|
|
1796
|
+
return res;
|
|
1765
1797
|
});
|
|
1766
|
-
await this.changeCurrentUser(res.user);
|
|
1767
|
-
return res;
|
|
1768
1798
|
}
|
|
1769
1799
|
potentiallyInvalidateToken(currentUser, opts) {
|
|
1770
|
-
|
|
1800
|
+
var _a;
|
|
1801
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
1771
1802
|
if (!refreshToken) {
|
|
1772
1803
|
return;
|
|
1773
1804
|
}
|
|
@@ -1787,10 +1818,12 @@ class Reactor {
|
|
|
1787
1818
|
})
|
|
1788
1819
|
.catch((e) => { });
|
|
1789
1820
|
}
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1821
|
+
signOut(opts) {
|
|
1822
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1823
|
+
const currentUser = yield this.getCurrentUser();
|
|
1824
|
+
this.potentiallyInvalidateToken(currentUser, opts);
|
|
1825
|
+
yield this.changeCurrentUser(null);
|
|
1826
|
+
});
|
|
1794
1827
|
}
|
|
1795
1828
|
/**
|
|
1796
1829
|
* Creates an OAuth authorization URL.
|
|
@@ -1809,18 +1842,21 @@ class Reactor {
|
|
|
1809
1842
|
* @param {string} params.code - The code received from the OAuth service.
|
|
1810
1843
|
* @param {string} [params.codeVerifier] - The code verifier used to generate the code challenge.
|
|
1811
1844
|
*/
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1845
|
+
exchangeCodeForToken(_a) {
|
|
1846
|
+
return __awaiter(this, arguments, void 0, function* ({ code, codeVerifier }) {
|
|
1847
|
+
var _b;
|
|
1848
|
+
const currentUser = yield this.getCurrentUser();
|
|
1849
|
+
const isGuest = ((_b = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _b === void 0 ? void 0 : _b.type) === 'guest';
|
|
1850
|
+
const res = yield authAPI.exchangeCodeForToken({
|
|
1851
|
+
apiURI: this.config.apiURI,
|
|
1852
|
+
appId: this.config.appId,
|
|
1853
|
+
code: code,
|
|
1854
|
+
codeVerifier,
|
|
1855
|
+
refreshToken: isGuest ? currentUser.user.refresh_token : undefined,
|
|
1856
|
+
});
|
|
1857
|
+
yield this.changeCurrentUser(res.user);
|
|
1858
|
+
return res;
|
|
1821
1859
|
});
|
|
1822
|
-
await this.changeCurrentUser(res.user);
|
|
1823
|
-
return res;
|
|
1824
1860
|
}
|
|
1825
1861
|
issuerURI() {
|
|
1826
1862
|
const { apiURI, appId } = this.config;
|
|
@@ -1832,19 +1868,22 @@ class Reactor {
|
|
|
1832
1868
|
* @param {string} params.idToken - The id_token from the external service
|
|
1833
1869
|
* @param {string | null | undefined} [params.nonce] - The nonce used when requesting the id_token from the external service
|
|
1834
1870
|
*/
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1871
|
+
signInWithIdToken(_a) {
|
|
1872
|
+
return __awaiter(this, arguments, void 0, function* ({ idToken, clientName, nonce }) {
|
|
1873
|
+
var _b;
|
|
1874
|
+
const currentUser = yield this.getCurrentUser();
|
|
1875
|
+
const refreshToken = (_b = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _b === void 0 ? void 0 : _b.refresh_token;
|
|
1876
|
+
const res = yield authAPI.signInWithIdToken({
|
|
1877
|
+
apiURI: this.config.apiURI,
|
|
1878
|
+
appId: this.config.appId,
|
|
1879
|
+
idToken,
|
|
1880
|
+
clientName,
|
|
1881
|
+
nonce,
|
|
1882
|
+
refreshToken,
|
|
1883
|
+
});
|
|
1884
|
+
yield this.changeCurrentUser(res.user);
|
|
1885
|
+
return res;
|
|
1845
1886
|
});
|
|
1846
|
-
await this.changeCurrentUser(res.user);
|
|
1847
|
-
return res;
|
|
1848
1887
|
}
|
|
1849
1888
|
// --------
|
|
1850
1889
|
// Rooms
|
|
@@ -1877,9 +1916,10 @@ class Reactor {
|
|
|
1877
1916
|
};
|
|
1878
1917
|
}
|
|
1879
1918
|
_cleanupRoom(roomId) {
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1919
|
+
var _a, _b, _c, _d;
|
|
1920
|
+
if (!((_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.handlers) === null || _b === void 0 ? void 0 : _b.length) &&
|
|
1921
|
+
!Object.keys((_c = this._broadcastSubs[roomId]) !== null && _c !== void 0 ? _c : {}).length) {
|
|
1922
|
+
const isConnected = (_d = this._rooms[roomId]) === null || _d === void 0 ? void 0 : _d.isConnected;
|
|
1883
1923
|
delete this._rooms[roomId];
|
|
1884
1924
|
delete this._presence[roomId];
|
|
1885
1925
|
delete this._broadcastSubs[roomId];
|
|
@@ -1899,11 +1939,7 @@ class Reactor {
|
|
|
1899
1939
|
const presence = this._presence[roomId];
|
|
1900
1940
|
if (!room || !presence || !presence.result)
|
|
1901
1941
|
return null;
|
|
1902
|
-
return {
|
|
1903
|
-
...(0, presence_ts_1.buildPresenceSlice)(presence.result, opts, this._sessionId),
|
|
1904
|
-
isLoading: !room.isConnected,
|
|
1905
|
-
error: room.error,
|
|
1906
|
-
};
|
|
1942
|
+
return Object.assign(Object.assign({}, (0, presence_ts_1.buildPresenceSlice)(presence.result, opts, this._sessionId)), { isLoading: !room.isConnected, error: room.error });
|
|
1907
1943
|
}
|
|
1908
1944
|
// TODO: look into typing again
|
|
1909
1945
|
publishPresence(roomType, roomId, partialData) {
|
|
@@ -1913,10 +1949,7 @@ class Reactor {
|
|
|
1913
1949
|
return;
|
|
1914
1950
|
}
|
|
1915
1951
|
presence.result = presence.result || {};
|
|
1916
|
-
const data = {
|
|
1917
|
-
...presence.result.user,
|
|
1918
|
-
...partialData,
|
|
1919
|
-
};
|
|
1952
|
+
const data = Object.assign(Object.assign({}, presence.result.user), partialData);
|
|
1920
1953
|
presence.result.user = data;
|
|
1921
1954
|
if (!room.isConnected) {
|
|
1922
1955
|
return;
|
|
@@ -1951,19 +1984,21 @@ class Reactor {
|
|
|
1951
1984
|
// Note: initialData is deprecated.
|
|
1952
1985
|
// Keeping here for backwards compatibility
|
|
1953
1986
|
opts.initialPresence || opts.initialData);
|
|
1954
|
-
const handler = {
|
|
1987
|
+
const handler = Object.assign(Object.assign({}, opts), { roomId, cb, prev: null });
|
|
1955
1988
|
this._presence[roomId] = this._presence[roomId] || {};
|
|
1956
1989
|
this._presence[roomId].handlers = this._presence[roomId].handlers || [];
|
|
1957
1990
|
this._presence[roomId].handlers.push(handler);
|
|
1958
1991
|
this._notifyPresenceSub(roomId, handler);
|
|
1959
1992
|
return () => {
|
|
1993
|
+
var _a, _b, _c;
|
|
1960
1994
|
this._presence[roomId].handlers =
|
|
1961
|
-
this._presence[roomId]
|
|
1995
|
+
(_c = (_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.handlers) === null || _b === void 0 ? void 0 : _b.filter((x) => x !== handler)) !== null && _c !== void 0 ? _c : [];
|
|
1962
1996
|
leaveRoom();
|
|
1963
1997
|
};
|
|
1964
1998
|
}
|
|
1965
1999
|
_notifyPresenceSubs(roomId) {
|
|
1966
|
-
|
|
2000
|
+
var _a, _b;
|
|
2001
|
+
(_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.handlers) === null || _b === void 0 ? void 0 : _b.forEach((handler) => {
|
|
1967
2002
|
this._notifyPresenceSub(roomId, handler);
|
|
1968
2003
|
});
|
|
1969
2004
|
}
|
|
@@ -1979,9 +2014,10 @@ class Reactor {
|
|
|
1979
2014
|
handler.cb(slice);
|
|
1980
2015
|
}
|
|
1981
2016
|
_patchPresencePeers(roomId, edits) {
|
|
1982
|
-
|
|
2017
|
+
var _a, _b, _c;
|
|
2018
|
+
const peers = ((_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.peers) || {};
|
|
1983
2019
|
let sessions = Object.fromEntries(Object.entries(peers).map(([k, v]) => [k, { data: v }]));
|
|
1984
|
-
const myPresence = this._presence[roomId]
|
|
2020
|
+
const myPresence = (_c = this._presence[roomId]) === null || _c === void 0 ? void 0 : _c.result;
|
|
1985
2021
|
const newSessions = (0, mutative_1.create)(sessions, (draft) => {
|
|
1986
2022
|
for (let [path, op, value] of edits) {
|
|
1987
2023
|
switch (op) {
|
|
@@ -2002,7 +2038,7 @@ class Reactor {
|
|
|
2002
2038
|
this._setPresencePeers(roomId, newSessions);
|
|
2003
2039
|
}
|
|
2004
2040
|
_setPresencePeers(roomId, data) {
|
|
2005
|
-
const sessions = {
|
|
2041
|
+
const sessions = Object.assign({}, data);
|
|
2006
2042
|
// no need to keep track of `user`
|
|
2007
2043
|
delete sessions[this._sessionId];
|
|
2008
2044
|
const peers = Object.fromEntries(Object.entries(sessions).map(([k, v]) => [k, v.data]));
|
|
@@ -2013,12 +2049,13 @@ class Reactor {
|
|
|
2013
2049
|
// --------
|
|
2014
2050
|
// Broadcast
|
|
2015
2051
|
publishTopic({ roomType, roomId, topic, data }) {
|
|
2052
|
+
var _a;
|
|
2016
2053
|
const room = this._rooms[roomId];
|
|
2017
2054
|
if (!room) {
|
|
2018
2055
|
return;
|
|
2019
2056
|
}
|
|
2020
2057
|
if (!room.isConnected) {
|
|
2021
|
-
this._broadcastQueue[roomId] = this._broadcastQueue[roomId]
|
|
2058
|
+
this._broadcastQueue[roomId] = (_a = this._broadcastQueue[roomId]) !== null && _a !== void 0 ? _a : [];
|
|
2022
2059
|
this._broadcastQueue[roomId].push({ topic, roomType, data });
|
|
2023
2060
|
return;
|
|
2024
2061
|
}
|
|
@@ -2049,64 +2086,71 @@ class Reactor {
|
|
|
2049
2086
|
};
|
|
2050
2087
|
}
|
|
2051
2088
|
_notifyBroadcastSubs(room, topic, msg) {
|
|
2052
|
-
|
|
2053
|
-
|
|
2089
|
+
var _a, _b, _c;
|
|
2090
|
+
(_c = (_b = (_a = this._broadcastSubs) === null || _a === void 0 ? void 0 : _a[room]) === null || _b === void 0 ? void 0 : _b[topic]) === null || _c === void 0 ? void 0 : _c.forEach((cb) => {
|
|
2091
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2092
|
+
const data = (_a = msg.data) === null || _a === void 0 ? void 0 : _a.data;
|
|
2054
2093
|
const peer = msg.data['peer-id'] === this._sessionId
|
|
2055
|
-
? this._presence[room]
|
|
2056
|
-
: this._presence[room]
|
|
2094
|
+
? (_c = (_b = this._presence[room]) === null || _b === void 0 ? void 0 : _b.result) === null || _c === void 0 ? void 0 : _c.user
|
|
2095
|
+
: (_f = (_e = (_d = this._presence[room]) === null || _d === void 0 ? void 0 : _d.result) === null || _e === void 0 ? void 0 : _e.peers) === null || _f === void 0 ? void 0 : _f[msg.data['peer-id']];
|
|
2057
2096
|
return cb(data, peer);
|
|
2058
2097
|
});
|
|
2059
2098
|
}
|
|
2060
2099
|
// --------
|
|
2061
2100
|
// Storage
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
apiURI: this.config.apiURI,
|
|
2068
|
-
appId: this.config.appId,
|
|
2069
|
-
path: path,
|
|
2070
|
-
file,
|
|
2071
|
-
refreshToken: refreshToken,
|
|
2101
|
+
uploadFile(path, file, opts) {
|
|
2102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2103
|
+
var _a;
|
|
2104
|
+
const currentUser = yield this.getCurrentUser();
|
|
2105
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
2106
|
+
return StorageApi.uploadFile(Object.assign(Object.assign({}, opts), { apiURI: this.config.apiURI, appId: this.config.appId, path: path, file, refreshToken: refreshToken }));
|
|
2072
2107
|
});
|
|
2073
2108
|
}
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2109
|
+
deleteFile(path) {
|
|
2110
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2111
|
+
var _a;
|
|
2112
|
+
const currentUser = yield this.getCurrentUser();
|
|
2113
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
2114
|
+
const result = yield StorageApi.deleteFile({
|
|
2115
|
+
apiURI: this.config.apiURI,
|
|
2116
|
+
appId: this.config.appId,
|
|
2117
|
+
path,
|
|
2118
|
+
refreshToken: refreshToken,
|
|
2119
|
+
});
|
|
2120
|
+
return result;
|
|
2082
2121
|
});
|
|
2083
|
-
return result;
|
|
2084
2122
|
}
|
|
2085
2123
|
// Deprecated Storage API (Jan 2025)
|
|
2086
2124
|
// ---------------------------------
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2125
|
+
upload(path, file) {
|
|
2126
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2127
|
+
var _a;
|
|
2128
|
+
const currentUser = yield this.getCurrentUser();
|
|
2129
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
2130
|
+
const fileName = path || file.name;
|
|
2131
|
+
const url = yield StorageApi.getSignedUploadUrl({
|
|
2132
|
+
apiURI: this.config.apiURI,
|
|
2133
|
+
appId: this.config.appId,
|
|
2134
|
+
fileName: fileName,
|
|
2135
|
+
refreshToken: refreshToken,
|
|
2136
|
+
});
|
|
2137
|
+
const isSuccess = yield StorageApi.upload(url, file);
|
|
2138
|
+
return isSuccess;
|
|
2096
2139
|
});
|
|
2097
|
-
const isSuccess = await StorageApi.upload(url, file);
|
|
2098
|
-
return isSuccess;
|
|
2099
2140
|
}
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2141
|
+
getDownloadUrl(path) {
|
|
2142
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2143
|
+
var _a;
|
|
2144
|
+
const currentUser = yield this.getCurrentUser();
|
|
2145
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
2146
|
+
const url = yield StorageApi.getDownloadUrl({
|
|
2147
|
+
apiURI: this.config.apiURI,
|
|
2148
|
+
appId: this.config.appId,
|
|
2149
|
+
path: path,
|
|
2150
|
+
refreshToken: refreshToken,
|
|
2151
|
+
});
|
|
2152
|
+
return url;
|
|
2108
2153
|
});
|
|
2109
|
-
return url;
|
|
2110
2154
|
}
|
|
2111
2155
|
}
|
|
2112
2156
|
exports.default = Reactor;
|