@instantdb/core 0.22.98 → 0.22.99-experimental.add-user-perm-rules.20792844601.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/esm/Reactor.js
CHANGED
|
@@ -1,3 +1,23 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
11
|
+
var t = {};
|
|
12
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
13
|
+
t[p] = s[p];
|
|
14
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
15
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
16
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
17
|
+
t[p[i]] = s[p[i]];
|
|
18
|
+
}
|
|
19
|
+
return t;
|
|
20
|
+
};
|
|
1
21
|
// @ts-check
|
|
2
22
|
import weakHash from "./utils/weakHash.js";
|
|
3
23
|
import instaql from "./instaql.js";
|
|
@@ -38,10 +58,10 @@ const STATUS = {
|
|
|
38
58
|
CLOSED: 'closed',
|
|
39
59
|
ERRORED: 'errored',
|
|
40
60
|
};
|
|
41
|
-
const QUERY_ONCE_TIMEOUT =
|
|
42
|
-
const PENDING_TX_CLEANUP_TIMEOUT =
|
|
61
|
+
const QUERY_ONCE_TIMEOUT = 30000;
|
|
62
|
+
const PENDING_TX_CLEANUP_TIMEOUT = 30000;
|
|
43
63
|
const PENDING_MUTATION_CLEANUP_THRESHOLD = 200;
|
|
44
|
-
const ONE_MIN_MS =
|
|
64
|
+
const ONE_MIN_MS = 1000 * 60;
|
|
45
65
|
const defaultConfig = {
|
|
46
66
|
apiURI: 'https://api.instantdb.com',
|
|
47
67
|
websocketURI: 'wss://api.instantdb.com/runtime/session',
|
|
@@ -90,15 +110,13 @@ const ignoreLogging = {
|
|
|
90
110
|
* @returns {QuerySub}
|
|
91
111
|
*/
|
|
92
112
|
function querySubFromStorage(x, useDateObjects) {
|
|
113
|
+
var _a;
|
|
93
114
|
const v = typeof x === 'string' ? JSON.parse(x) : x;
|
|
94
|
-
if (v
|
|
115
|
+
if ((_a = v === null || v === void 0 ? void 0 : v.result) === null || _a === void 0 ? void 0 : _a.store) {
|
|
95
116
|
const attrsStore = s.attrsStoreFromJSON(v.result.attrsStore, v.result.store);
|
|
96
117
|
if (attrsStore) {
|
|
97
118
|
const storeJSON = v.result.store;
|
|
98
|
-
v.result.store = s.fromJSON(attrsStore, {
|
|
99
|
-
...storeJSON,
|
|
100
|
-
useDateObjects: useDateObjects,
|
|
101
|
-
});
|
|
119
|
+
v.result.store = s.fromJSON(attrsStore, Object.assign(Object.assign({}, storeJSON), { useDateObjects: useDateObjects }));
|
|
102
120
|
v.result.attrsStore = attrsStore;
|
|
103
121
|
}
|
|
104
122
|
}
|
|
@@ -111,15 +129,11 @@ function querySubFromStorage(x, useDateObjects) {
|
|
|
111
129
|
* @returns QuerySubInStorage
|
|
112
130
|
*/
|
|
113
131
|
function querySubToStorage(_key, sub) {
|
|
114
|
-
const { result,
|
|
132
|
+
const { result } = sub, rest = __rest(sub, ["result"]);
|
|
115
133
|
const jsonSub = /** @type {import('./reactorTypes.ts').QuerySubInStorage} */ (rest);
|
|
116
134
|
if (result) {
|
|
117
135
|
/** @type {import('./reactorTypes.ts').QuerySubResultInStorage} */
|
|
118
|
-
const jsonResult = {
|
|
119
|
-
...result,
|
|
120
|
-
store: s.toJSON(result.store),
|
|
121
|
-
attrsStore: result.attrsStore.toJSON(),
|
|
122
|
-
};
|
|
136
|
+
const jsonResult = Object.assign(Object.assign({}, result), { store: s.toJSON(result.store), attrsStore: result.attrsStore.toJSON() });
|
|
123
137
|
jsonSub.result = jsonResult;
|
|
124
138
|
}
|
|
125
139
|
return jsonSub;
|
|
@@ -141,8 +155,8 @@ function kvToStorage(key, x) {
|
|
|
141
155
|
}
|
|
142
156
|
}
|
|
143
157
|
function onMergeQuerySub(_k, storageSub, inMemorySub) {
|
|
144
|
-
const storageResult = storageSub
|
|
145
|
-
const memoryResult = inMemorySub
|
|
158
|
+
const storageResult = storageSub === null || storageSub === void 0 ? void 0 : storageSub.result;
|
|
159
|
+
const memoryResult = inMemorySub === null || inMemorySub === void 0 ? void 0 : inMemorySub.result;
|
|
146
160
|
if (storageResult && !memoryResult && inMemorySub) {
|
|
147
161
|
inMemorySub.result = storageResult;
|
|
148
162
|
}
|
|
@@ -164,72 +178,241 @@ function sortedMutationEntries(entries) {
|
|
|
164
178
|
* @template {import('./presence.ts').RoomSchemaShape} [RoomSchema = {}]
|
|
165
179
|
*/
|
|
166
180
|
export default class Reactor {
|
|
167
|
-
/** @type {s.AttrsStore | undefined} */
|
|
168
|
-
attrs;
|
|
169
|
-
_isOnline = true;
|
|
170
|
-
_isShutdown = false;
|
|
171
|
-
status = STATUS.CONNECTING;
|
|
172
|
-
/** @type {PersistedObject<string, QuerySub, QuerySubInStorage>} */
|
|
173
|
-
querySubs;
|
|
174
|
-
/** @type {PersistedObject} */
|
|
175
|
-
kv;
|
|
176
|
-
/** @type {SyncTable} */
|
|
177
|
-
_syncTable;
|
|
178
|
-
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
|
|
179
|
-
queryCbs = {};
|
|
180
|
-
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
|
|
181
|
-
queryOnceDfds = {};
|
|
182
|
-
authCbs = [];
|
|
183
|
-
attrsCbs = [];
|
|
184
|
-
mutationErrorCbs = [];
|
|
185
|
-
connectionStatusCbs = [];
|
|
186
|
-
config;
|
|
187
|
-
mutationDeferredStore = new Map();
|
|
188
|
-
_reconnectTimeoutId = null;
|
|
189
|
-
_reconnectTimeoutMs = 0;
|
|
190
|
-
/** @type {Connection} */
|
|
191
|
-
_transport;
|
|
192
|
-
/** @type {TransportType} */
|
|
193
|
-
_transportType = 'ws';
|
|
194
|
-
/** @type {EventSourceConstructor} */
|
|
195
|
-
_EventSource;
|
|
196
|
-
/** @type {boolean | null} */
|
|
197
|
-
_wsOk = null;
|
|
198
|
-
_localIdPromises = {};
|
|
199
|
-
_errorMessage = null;
|
|
200
|
-
/** @type {Promise<null | {error: {message: string}}> | null}**/
|
|
201
|
-
_oauthCallbackResponse = null;
|
|
202
|
-
/** @type {null | import('./utils/linkIndex.ts').LinkIndex}} */
|
|
203
|
-
_linkIndex = null;
|
|
204
|
-
/** @type BroadcastChannel | undefined */
|
|
205
|
-
_broadcastChannel;
|
|
206
|
-
/** @type {Record<string, {isConnected: boolean; error: any}>} */
|
|
207
|
-
_rooms = {};
|
|
208
|
-
/** @type {Record<string, boolean>} */
|
|
209
|
-
_roomsPendingLeave = {};
|
|
210
|
-
_presence = {};
|
|
211
|
-
_broadcastQueue = [];
|
|
212
|
-
_broadcastSubs = {};
|
|
213
|
-
/** @type {{isLoading: boolean; error: any | undefined, user: any | undefined}} */
|
|
214
|
-
_currentUserCached = { isLoading: true, error: undefined, user: undefined };
|
|
215
|
-
_beforeUnloadCbs = [];
|
|
216
|
-
_dataForQueryCache = {};
|
|
217
|
-
/** @type {Logger} */
|
|
218
|
-
_log;
|
|
219
|
-
_pendingTxCleanupTimeout;
|
|
220
|
-
_pendingMutationCleanupThreshold;
|
|
221
|
-
_inFlightMutationEventIds = new Set();
|
|
222
181
|
constructor(config, Storage = IndexedDBStorage, NetworkListener = WindowNetworkListener, versions, EventSourceConstructor) {
|
|
182
|
+
var _a, _b, _c;
|
|
183
|
+
this._isOnline = true;
|
|
184
|
+
this._isShutdown = false;
|
|
185
|
+
this.status = STATUS.CONNECTING;
|
|
186
|
+
/** @type {Record<string, Array<{ q: any, cb: (data: any) => any }>>} */
|
|
187
|
+
this.queryCbs = {};
|
|
188
|
+
/** @type {Record<string, Array<{ q: any, eventId: string, dfd: Deferred }>>} */
|
|
189
|
+
this.queryOnceDfds = {};
|
|
190
|
+
this.authCbs = [];
|
|
191
|
+
this.attrsCbs = [];
|
|
192
|
+
this.mutationErrorCbs = [];
|
|
193
|
+
this.connectionStatusCbs = [];
|
|
194
|
+
this.mutationDeferredStore = new Map();
|
|
195
|
+
this._reconnectTimeoutId = null;
|
|
196
|
+
this._reconnectTimeoutMs = 0;
|
|
197
|
+
/** @type {TransportType} */
|
|
198
|
+
this._transportType = 'ws';
|
|
199
|
+
/** @type {boolean | null} */
|
|
200
|
+
this._wsOk = null;
|
|
201
|
+
this._localIdPromises = {};
|
|
202
|
+
this._errorMessage = null;
|
|
203
|
+
/** @type {Promise<null | {error: {message: string}}> | null}**/
|
|
204
|
+
this._oauthCallbackResponse = null;
|
|
205
|
+
/** @type {null | import('./utils/linkIndex.ts').LinkIndex}} */
|
|
206
|
+
this._linkIndex = null;
|
|
207
|
+
/** @type {Record<string, {isConnected: boolean; error: any}>} */
|
|
208
|
+
this._rooms = {};
|
|
209
|
+
/** @type {Record<string, boolean>} */
|
|
210
|
+
this._roomsPendingLeave = {};
|
|
211
|
+
this._presence = {};
|
|
212
|
+
this._broadcastQueue = [];
|
|
213
|
+
this._broadcastSubs = {};
|
|
214
|
+
/** @type {{isLoading: boolean; error: any | undefined, user: any | undefined}} */
|
|
215
|
+
this._currentUserCached = { isLoading: true, error: undefined, user: undefined };
|
|
216
|
+
this._beforeUnloadCbs = [];
|
|
217
|
+
this._dataForQueryCache = {};
|
|
218
|
+
this._inFlightMutationEventIds = new Set();
|
|
219
|
+
this._onMergeKv = (key, storageV, inMemoryV) => {
|
|
220
|
+
var _a, _b;
|
|
221
|
+
switch (key) {
|
|
222
|
+
case 'pendingMutations': {
|
|
223
|
+
const storageEntries = (_a = storageV === null || storageV === void 0 ? void 0 : storageV.entries()) !== null && _a !== void 0 ? _a : [];
|
|
224
|
+
const inMemoryEntries = (_b = inMemoryV === null || inMemoryV === void 0 ? void 0 : inMemoryV.entries()) !== null && _b !== void 0 ? _b : [];
|
|
225
|
+
const muts = new Map([...storageEntries, ...inMemoryEntries]);
|
|
226
|
+
const rewrittenStorageMuts = storageV
|
|
227
|
+
? this._rewriteMutationsSorted(this.attrs, storageV)
|
|
228
|
+
: [];
|
|
229
|
+
rewrittenStorageMuts.forEach(([k, mut]) => {
|
|
230
|
+
var _a;
|
|
231
|
+
if (!((_a = inMemoryV === null || inMemoryV === void 0 ? void 0 : inMemoryV.pendingMutations) === null || _a === void 0 ? void 0 : _a.has(k)) && !mut['tx-id']) {
|
|
232
|
+
this._sendMutation(k, mut);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
return muts;
|
|
236
|
+
}
|
|
237
|
+
default:
|
|
238
|
+
return inMemoryV || storageV;
|
|
239
|
+
}
|
|
240
|
+
};
|
|
241
|
+
// ---------------------------
|
|
242
|
+
// Queries
|
|
243
|
+
this.getPreviousResult = (q) => {
|
|
244
|
+
var _a;
|
|
245
|
+
const hash = weakHash(q);
|
|
246
|
+
return (_a = this.dataForQuery(hash)) === null || _a === void 0 ? void 0 : _a.data;
|
|
247
|
+
};
|
|
248
|
+
/** Re-run instaql and call all callbacks with new data */
|
|
249
|
+
this.notifyOne = (hash) => {
|
|
250
|
+
var _a, _b;
|
|
251
|
+
const cbs = (_a = this.queryCbs[hash]) !== null && _a !== void 0 ? _a : [];
|
|
252
|
+
const prevData = (_b = this._dataForQueryCache[hash]) === null || _b === void 0 ? void 0 : _b.data;
|
|
253
|
+
const resp = this.dataForQuery(hash);
|
|
254
|
+
if (!(resp === null || resp === void 0 ? void 0 : resp.data))
|
|
255
|
+
return;
|
|
256
|
+
this._dataForQueryCache[hash] = resp;
|
|
257
|
+
if (areObjectsDeepEqual(resp.data, prevData))
|
|
258
|
+
return;
|
|
259
|
+
cbs.forEach((r) => r.cb(resp.data));
|
|
260
|
+
};
|
|
261
|
+
this.notifyOneQueryOnce = (hash) => {
|
|
262
|
+
var _a, _b;
|
|
263
|
+
const dfds = (_a = this.queryOnceDfds[hash]) !== null && _a !== void 0 ? _a : [];
|
|
264
|
+
const data = (_b = this.dataForQuery(hash)) === null || _b === void 0 ? void 0 : _b.data;
|
|
265
|
+
dfds.forEach((r) => {
|
|
266
|
+
this._completeQueryOnce(r.q, hash, r.dfd);
|
|
267
|
+
r.dfd.resolve(data);
|
|
268
|
+
});
|
|
269
|
+
};
|
|
270
|
+
this.notifyQueryError = (hash, error) => {
|
|
271
|
+
const cbs = this.queryCbs[hash] || [];
|
|
272
|
+
cbs.forEach((r) => r.cb({ error }));
|
|
273
|
+
};
|
|
274
|
+
/** Applies transactions locally and sends transact message to server */
|
|
275
|
+
this.pushTx = (chunks) => {
|
|
276
|
+
// Throws if transactions are invalid
|
|
277
|
+
if (!this.config.disableValidation) {
|
|
278
|
+
validateTransactions(chunks, this.config.schema);
|
|
279
|
+
}
|
|
280
|
+
try {
|
|
281
|
+
const txSteps = instaml.transform({
|
|
282
|
+
attrsStore: this.optimisticAttrs(),
|
|
283
|
+
schema: this.config.schema,
|
|
284
|
+
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; }),
|
|
285
|
+
useDateObjects: this.config.useDateObjects,
|
|
286
|
+
}, chunks);
|
|
287
|
+
return this.pushOps(txSteps);
|
|
288
|
+
}
|
|
289
|
+
catch (e) {
|
|
290
|
+
return this.pushOps([], e);
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
/**
|
|
294
|
+
* @param {*} txSteps
|
|
295
|
+
* @param {*} [error]
|
|
296
|
+
* @returns
|
|
297
|
+
*/
|
|
298
|
+
this.pushOps = (txSteps, error) => {
|
|
299
|
+
const eventId = uuid();
|
|
300
|
+
const mutations = [...this._pendingMutations().values()];
|
|
301
|
+
const order = Math.max(0, ...mutations.map((mut) => mut.order || 0)) + 1;
|
|
302
|
+
const mutation = {
|
|
303
|
+
op: 'transact',
|
|
304
|
+
'tx-steps': txSteps,
|
|
305
|
+
created: Date.now(),
|
|
306
|
+
error,
|
|
307
|
+
order,
|
|
308
|
+
};
|
|
309
|
+
this._updatePendingMutations((prev) => {
|
|
310
|
+
prev.set(eventId, mutation);
|
|
311
|
+
});
|
|
312
|
+
const dfd = new Deferred();
|
|
313
|
+
this.mutationDeferredStore.set(eventId, dfd);
|
|
314
|
+
this._sendMutation(eventId, mutation);
|
|
315
|
+
this.notifyAll();
|
|
316
|
+
return dfd.promise;
|
|
317
|
+
};
|
|
318
|
+
this._transportOnOpen = (e) => {
|
|
319
|
+
const targetTransport = e.target;
|
|
320
|
+
if (this._transport !== targetTransport) {
|
|
321
|
+
this._log.info('[socket][open]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
this._log.info('[socket][open]', this._transport.id);
|
|
325
|
+
this._setStatus(STATUS.OPENED);
|
|
326
|
+
this.getCurrentUser()
|
|
327
|
+
.then((resp) => {
|
|
328
|
+
var _a;
|
|
329
|
+
this._trySend(uuid(), {
|
|
330
|
+
op: 'init',
|
|
331
|
+
'app-id': this.config.appId,
|
|
332
|
+
'refresh-token': (_a = resp.user) === null || _a === void 0 ? void 0 : _a['refresh_token'],
|
|
333
|
+
versions: this.versions,
|
|
334
|
+
// If an admin token is provided for an app, we will
|
|
335
|
+
// skip all permission checks. This is an advanced feature,
|
|
336
|
+
// to let users write internal tools
|
|
337
|
+
// This option is not exposed in `Config`, as it's
|
|
338
|
+
// not ready for prime time
|
|
339
|
+
'__admin-token': this.config.__adminToken,
|
|
340
|
+
});
|
|
341
|
+
})
|
|
342
|
+
.catch((e) => {
|
|
343
|
+
this._log.error('[socket][error]', targetTransport.id, e);
|
|
344
|
+
});
|
|
345
|
+
};
|
|
346
|
+
this._transportOnMessage = (e) => {
|
|
347
|
+
const targetTransport = e.target;
|
|
348
|
+
const m = e.message;
|
|
349
|
+
if (this._transport !== targetTransport) {
|
|
350
|
+
this._log.info('[socket][message]', targetTransport.id, m, 'skip; this is no longer the current transport');
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (!this._wsOk && targetTransport.type === 'ws') {
|
|
354
|
+
this._wsOk = true;
|
|
355
|
+
}
|
|
356
|
+
// Try to reconnect via websocket the next time we connect
|
|
357
|
+
this._transportType = 'ws';
|
|
358
|
+
if (Array.isArray(e.message)) {
|
|
359
|
+
for (const msg of e.message) {
|
|
360
|
+
this._handleReceive(targetTransport.id, msg);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
else {
|
|
364
|
+
this._handleReceive(targetTransport.id, e.message);
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
this._transportOnError = (e) => {
|
|
368
|
+
const targetTransport = e.target;
|
|
369
|
+
if (this._transport !== targetTransport) {
|
|
370
|
+
this._log.info('[socket][error]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
this._log.error('[socket][error]', targetTransport.id, e);
|
|
374
|
+
};
|
|
375
|
+
this._scheduleReconnect = () => {
|
|
376
|
+
// If we couldn't connect with a websocket last time, try sse
|
|
377
|
+
if (!this._wsOk && this._transportType !== 'sse') {
|
|
378
|
+
this._transportType = 'sse';
|
|
379
|
+
this._reconnectTimeoutMs = 0;
|
|
380
|
+
}
|
|
381
|
+
setTimeout(() => {
|
|
382
|
+
this._reconnectTimeoutMs = Math.min(this._reconnectTimeoutMs + 1000, 10000);
|
|
383
|
+
if (!this._isOnline) {
|
|
384
|
+
this._log.info('[socket][close]', this._transport.id, 'we are offline, no need to start socket');
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
this._startSocket();
|
|
388
|
+
}, this._reconnectTimeoutMs);
|
|
389
|
+
};
|
|
390
|
+
this._transportOnClose = (e) => {
|
|
391
|
+
const targetTransport = e.target;
|
|
392
|
+
if (this._transport !== targetTransport) {
|
|
393
|
+
this._log.info('[socket][close]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
this._setStatus(STATUS.CLOSED);
|
|
397
|
+
for (const room of Object.values(this._rooms)) {
|
|
398
|
+
room.isConnected = false;
|
|
399
|
+
}
|
|
400
|
+
if (this._isShutdown) {
|
|
401
|
+
this._log.info('[socket][close]', targetTransport.id, 'Reactor has been shut down and will not reconnect');
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
this._log.info('[socket][close]', targetTransport.id, 'schedule reconnect, ms =', this._reconnectTimeoutMs);
|
|
405
|
+
this._scheduleReconnect();
|
|
406
|
+
};
|
|
223
407
|
this._EventSource = EventSourceConstructor;
|
|
224
|
-
this.config = {
|
|
225
|
-
this.queryCacheLimit = this.config.queryCacheLimit
|
|
408
|
+
this.config = Object.assign(Object.assign({}, defaultConfig), config);
|
|
409
|
+
this.queryCacheLimit = (_a = this.config.queryCacheLimit) !== null && _a !== void 0 ? _a : 10;
|
|
226
410
|
this._pendingTxCleanupTimeout =
|
|
227
|
-
this.config.pendingTxCleanupTimeout
|
|
411
|
+
(_b = this.config.pendingTxCleanupTimeout) !== null && _b !== void 0 ? _b : PENDING_TX_CLEANUP_TIMEOUT;
|
|
228
412
|
this._pendingMutationCleanupThreshold =
|
|
229
|
-
this.config.pendingMutationCleanupThreshold
|
|
230
|
-
PENDING_MUTATION_CLEANUP_THRESHOLD;
|
|
413
|
+
(_c = this.config.pendingMutationCleanupThreshold) !== null && _c !== void 0 ? _c : PENDING_MUTATION_CLEANUP_THRESHOLD;
|
|
231
414
|
this._log = createLogger(config.verbose || flags.devBackend || flags.instantLogs, () => this._reactorStats());
|
|
232
|
-
this.versions = {
|
|
415
|
+
this.versions = Object.assign(Object.assign({}, (versions || {})), { '@instantdb/core': version });
|
|
233
416
|
if (this.config.schema) {
|
|
234
417
|
this._linkIndex = createLinkIndex(this.config.schema);
|
|
235
418
|
}
|
|
@@ -246,17 +429,18 @@ export default class Reactor {
|
|
|
246
429
|
}
|
|
247
430
|
if (typeof BroadcastChannel === 'function') {
|
|
248
431
|
this._broadcastChannel = new BroadcastChannel('@instantdb');
|
|
249
|
-
this._broadcastChannel.addEventListener('message',
|
|
432
|
+
this._broadcastChannel.addEventListener('message', (e) => __awaiter(this, void 0, void 0, function* () {
|
|
433
|
+
var _a;
|
|
250
434
|
try {
|
|
251
|
-
if (e.data
|
|
252
|
-
const res =
|
|
435
|
+
if (((_a = e.data) === null || _a === void 0 ? void 0 : _a.type) === 'auth') {
|
|
436
|
+
const res = yield this.getCurrentUser();
|
|
253
437
|
this.updateUser(res.user);
|
|
254
438
|
}
|
|
255
439
|
}
|
|
256
440
|
catch (e) {
|
|
257
441
|
this._log.error('[error] handle broadcast channel', e);
|
|
258
442
|
}
|
|
259
|
-
});
|
|
443
|
+
}));
|
|
260
444
|
}
|
|
261
445
|
this._initStorage(Storage);
|
|
262
446
|
this._syncTable = new SyncTable(this._trySendAuthed.bind(this), new Storage(this.config.appId, 'syncSubs'), {
|
|
@@ -269,10 +453,10 @@ export default class Reactor {
|
|
|
269
453
|
this.getCurrentUser().then((userInfo) => {
|
|
270
454
|
this.syncUserToEndpoint(userInfo.user);
|
|
271
455
|
});
|
|
272
|
-
setInterval(
|
|
273
|
-
const currentUser =
|
|
456
|
+
setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
457
|
+
const currentUser = yield this.getCurrentUser();
|
|
274
458
|
this.syncUserToEndpoint(currentUser.user);
|
|
275
|
-
}, ONE_MIN_MS);
|
|
459
|
+
}), ONE_MIN_MS);
|
|
276
460
|
NetworkListener.getIsOnline().then((isOnline) => {
|
|
277
461
|
this._isOnline = isOnline;
|
|
278
462
|
this._startSocket();
|
|
@@ -306,11 +490,7 @@ export default class Reactor {
|
|
|
306
490
|
return this.attrs;
|
|
307
491
|
}
|
|
308
492
|
updateSchema(schema) {
|
|
309
|
-
this.config = {
|
|
310
|
-
...this.config,
|
|
311
|
-
schema: schema,
|
|
312
|
-
cardinalityInference: Boolean(schema),
|
|
313
|
-
};
|
|
493
|
+
this.config = Object.assign(Object.assign({}, this.config), { schema: schema, cardinalityInference: Boolean(schema) });
|
|
314
494
|
this._linkIndex = schema ? createLinkIndex(this.config.schema) : null;
|
|
315
495
|
}
|
|
316
496
|
_reactorStats() {
|
|
@@ -332,14 +512,14 @@ export default class Reactor {
|
|
|
332
512
|
serialize: querySubToStorage,
|
|
333
513
|
parse: (_key, x) => querySubFromStorage(x, this.config.useDateObjects),
|
|
334
514
|
// objectSize
|
|
335
|
-
objectSize: (x) => x
|
|
515
|
+
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; },
|
|
336
516
|
logger: this._log,
|
|
337
517
|
preloadEntryCount: 10,
|
|
338
518
|
gc: {
|
|
339
519
|
maxAgeMs: 1000 * 60 * 60 * 24 * 7 * 52, // 1 year
|
|
340
520
|
maxEntries: 1000,
|
|
341
521
|
// Size of each query is the number of triples
|
|
342
|
-
maxSize:
|
|
522
|
+
maxSize: 1000000, // 1 million triples
|
|
343
523
|
},
|
|
344
524
|
});
|
|
345
525
|
this.querySubs.onKeyLoaded = (k) => this._onQuerySubLoaded(k);
|
|
@@ -385,7 +565,7 @@ export default class Reactor {
|
|
|
385
565
|
const ok = status !== 'error' && status !== 'timeout';
|
|
386
566
|
if (!dfd && !ok) {
|
|
387
567
|
// console.erroring here, as there are no listeners to let know
|
|
388
|
-
console.error('Mutation failed', { status, eventId,
|
|
568
|
+
console.error('Mutation failed', Object.assign({ status, eventId }, errorMsg));
|
|
389
569
|
}
|
|
390
570
|
if (!dfd) {
|
|
391
571
|
return;
|
|
@@ -395,16 +575,16 @@ export default class Reactor {
|
|
|
395
575
|
}
|
|
396
576
|
else {
|
|
397
577
|
// Check if error comes from server or client
|
|
398
|
-
if (errorMsg
|
|
399
|
-
const { status,
|
|
578
|
+
if (errorMsg === null || errorMsg === void 0 ? void 0 : errorMsg.type) {
|
|
579
|
+
const { status } = errorMsg, body = __rest(errorMsg, ["status"]);
|
|
400
580
|
dfd.reject(new InstantAPIError({
|
|
401
581
|
// @ts-expect-error body.type is not constant typed
|
|
402
582
|
body,
|
|
403
|
-
status: status
|
|
583
|
+
status: status !== null && status !== void 0 ? status : 0,
|
|
404
584
|
}));
|
|
405
585
|
}
|
|
406
586
|
else {
|
|
407
|
-
dfd.reject(new InstantError(errorMsg
|
|
587
|
+
dfd.reject(new InstantError((errorMsg === null || errorMsg === void 0 ? void 0 : errorMsg.message) || 'Unknown error', errorMsg === null || errorMsg === void 0 ? void 0 : errorMsg.hint));
|
|
408
588
|
}
|
|
409
589
|
}
|
|
410
590
|
}
|
|
@@ -413,28 +593,9 @@ export default class Reactor {
|
|
|
413
593
|
this._errorMessage = err;
|
|
414
594
|
this.notifyConnectionStatusSubs(status);
|
|
415
595
|
}
|
|
416
|
-
_onMergeKv = (key, storageV, inMemoryV) => {
|
|
417
|
-
switch (key) {
|
|
418
|
-
case 'pendingMutations': {
|
|
419
|
-
const storageEntries = storageV?.entries() ?? [];
|
|
420
|
-
const inMemoryEntries = inMemoryV?.entries() ?? [];
|
|
421
|
-
const muts = new Map([...storageEntries, ...inMemoryEntries]);
|
|
422
|
-
const rewrittenStorageMuts = storageV
|
|
423
|
-
? this._rewriteMutationsSorted(this.attrs, storageV)
|
|
424
|
-
: [];
|
|
425
|
-
rewrittenStorageMuts.forEach(([k, mut]) => {
|
|
426
|
-
if (!inMemoryV?.pendingMutations?.has(k) && !mut['tx-id']) {
|
|
427
|
-
this._sendMutation(k, mut);
|
|
428
|
-
}
|
|
429
|
-
});
|
|
430
|
-
return muts;
|
|
431
|
-
}
|
|
432
|
-
default:
|
|
433
|
-
return inMemoryV || storageV;
|
|
434
|
-
}
|
|
435
|
-
};
|
|
436
596
|
_flushEnqueuedRoomData(roomId) {
|
|
437
|
-
|
|
597
|
+
var _a, _b;
|
|
598
|
+
const enqueuedUserPresence = (_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.user;
|
|
438
599
|
const enqueuedBroadcasts = this._broadcastQueue[roomId];
|
|
439
600
|
this._broadcastQueue[roomId] = [];
|
|
440
601
|
if (enqueuedUserPresence) {
|
|
@@ -479,6 +640,7 @@ export default class Reactor {
|
|
|
479
640
|
this._cleanupPendingMutationsTimeout();
|
|
480
641
|
}
|
|
481
642
|
_handleReceive(connId, msg) {
|
|
643
|
+
var _a, _b, _c, _d, _e, _f;
|
|
482
644
|
// opt-out, enabled by default if schema
|
|
483
645
|
const enableCardinalityInference = Boolean(this.config.schema) &&
|
|
484
646
|
('cardinalityInference' in this.config
|
|
@@ -497,7 +659,7 @@ export default class Reactor {
|
|
|
497
659
|
// which item is us
|
|
498
660
|
this._sessionId = msg['session-id'];
|
|
499
661
|
for (const roomId of Object.keys(this._rooms)) {
|
|
500
|
-
const enqueuedUserPresence = this._presence[roomId]
|
|
662
|
+
const enqueuedUserPresence = (_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.user;
|
|
501
663
|
this._tryJoinRoom(roomId, enqueuedUserPresence);
|
|
502
664
|
}
|
|
503
665
|
break;
|
|
@@ -512,8 +674,8 @@ export default class Reactor {
|
|
|
512
674
|
if (!this._hasQueryListeners() && !this.querySubs.currentValue[hash]) {
|
|
513
675
|
break;
|
|
514
676
|
}
|
|
515
|
-
const pageInfo = result
|
|
516
|
-
const aggregate = result
|
|
677
|
+
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'];
|
|
678
|
+
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'];
|
|
517
679
|
const triples = extractTriples(result);
|
|
518
680
|
const attrsStore = this.ensureAttrs();
|
|
519
681
|
const store = s.createStore(attrsStore, triples, enableCardinalityInference, this.config.useDateObjects);
|
|
@@ -570,6 +732,7 @@ export default class Reactor {
|
|
|
570
732
|
}
|
|
571
733
|
const mutations = sortedMutationEntries(rewrittenMutations.entries());
|
|
572
734
|
const updates = computations.map((x) => {
|
|
735
|
+
var _a, _b, _c, _d;
|
|
573
736
|
const q = x['instaql-query'];
|
|
574
737
|
const result = x['instaql-result'];
|
|
575
738
|
const hash = weakHash(q);
|
|
@@ -577,8 +740,8 @@ export default class Reactor {
|
|
|
577
740
|
const attrsStore = this.ensureAttrs();
|
|
578
741
|
const store = s.createStore(attrsStore, triples, enableCardinalityInference, this.config.useDateObjects);
|
|
579
742
|
const { store: newStore, attrsStore: newAttrsStore } = this._applyOptimisticUpdates(store, attrsStore, mutations, processedTxId);
|
|
580
|
-
const pageInfo = result
|
|
581
|
-
const aggregate = result
|
|
743
|
+
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'];
|
|
744
|
+
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'];
|
|
582
745
|
return {
|
|
583
746
|
q,
|
|
584
747
|
hash,
|
|
@@ -619,11 +782,7 @@ export default class Reactor {
|
|
|
619
782
|
}
|
|
620
783
|
// update pendingMutation with server-side tx-id
|
|
621
784
|
this._updatePendingMutations((prev) => {
|
|
622
|
-
prev.set(eventId, {
|
|
623
|
-
...prev.get(eventId),
|
|
624
|
-
'tx-id': txId,
|
|
625
|
-
confirmed: Date.now(),
|
|
626
|
-
});
|
|
785
|
+
prev.set(eventId, Object.assign(Object.assign({}, prev.get(eventId)), { 'tx-id': txId, confirmed: Date.now() }));
|
|
627
786
|
});
|
|
628
787
|
const newAttrs = [];
|
|
629
788
|
for (const step of prevMutation['tx-steps']) {
|
|
@@ -697,11 +856,13 @@ export default class Reactor {
|
|
|
697
856
|
}
|
|
698
857
|
}
|
|
699
858
|
_pendingMutations() {
|
|
700
|
-
|
|
859
|
+
var _a;
|
|
860
|
+
return (_a = this.kv.currentValue.pendingMutations) !== null && _a !== void 0 ? _a : new Map();
|
|
701
861
|
}
|
|
702
862
|
_updatePendingMutations(f) {
|
|
703
863
|
this.kv.updateInPlace((prev) => {
|
|
704
|
-
|
|
864
|
+
var _a;
|
|
865
|
+
const muts = (_a = prev.pendingMutations) !== null && _a !== void 0 ? _a : new Map();
|
|
705
866
|
prev.pendingMutations = muts;
|
|
706
867
|
f(muts);
|
|
707
868
|
});
|
|
@@ -730,6 +891,7 @@ export default class Reactor {
|
|
|
730
891
|
}
|
|
731
892
|
}
|
|
732
893
|
_handleReceiveError(msg) {
|
|
894
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
733
895
|
console.log('error', msg);
|
|
734
896
|
const eventId = msg['client-event-id'];
|
|
735
897
|
// This might not be a mutation, but it can't hurt to delete it
|
|
@@ -745,18 +907,18 @@ export default class Reactor {
|
|
|
745
907
|
this._handleMutationError('error', eventId, msg);
|
|
746
908
|
return;
|
|
747
909
|
}
|
|
748
|
-
if (msg['original-event']
|
|
749
|
-
msg['original-event']
|
|
750
|
-
const q = msg['original-event']
|
|
910
|
+
if (((_a = msg['original-event']) === null || _a === void 0 ? void 0 : _a.hasOwnProperty('q')) &&
|
|
911
|
+
((_b = msg['original-event']) === null || _b === void 0 ? void 0 : _b.op) === 'add-query') {
|
|
912
|
+
const q = (_c = msg['original-event']) === null || _c === void 0 ? void 0 : _c.q;
|
|
751
913
|
const hash = weakHash(q);
|
|
752
914
|
this.notifyQueryError(weakHash(q), errorMessage);
|
|
753
915
|
this.notifyQueryOnceError(q, hash, eventId, errorMessage);
|
|
754
916
|
return;
|
|
755
917
|
}
|
|
756
|
-
const isInitError = msg['original-event']
|
|
918
|
+
const isInitError = ((_d = msg['original-event']) === null || _d === void 0 ? void 0 : _d.op) === 'init';
|
|
757
919
|
if (isInitError) {
|
|
758
920
|
if (msg.type === 'record-not-found' &&
|
|
759
|
-
msg.hint
|
|
921
|
+
((_e = msg.hint) === null || _e === void 0 ? void 0 : _e['record-type']) === 'app-user') {
|
|
760
922
|
// User has been logged out
|
|
761
923
|
this.changeCurrentUser(null);
|
|
762
924
|
return;
|
|
@@ -766,17 +928,17 @@ export default class Reactor {
|
|
|
766
928
|
this.notifyAll();
|
|
767
929
|
return;
|
|
768
930
|
}
|
|
769
|
-
if (msg['original-event']
|
|
931
|
+
if (((_f = msg['original-event']) === null || _f === void 0 ? void 0 : _f.op) === 'resync-table') {
|
|
770
932
|
this._syncTable.onResyncError(msg);
|
|
771
933
|
return;
|
|
772
934
|
}
|
|
773
|
-
if (msg['original-event']
|
|
935
|
+
if (((_g = msg['original-event']) === null || _g === void 0 ? void 0 : _g.op) === 'start-sync') {
|
|
774
936
|
this._syncTable.onStartSyncError(msg);
|
|
775
937
|
return;
|
|
776
938
|
}
|
|
777
939
|
// We've caught some error which has no corresponding listener.
|
|
778
940
|
// Let's console.error to let the user know.
|
|
779
|
-
const errorObj = {
|
|
941
|
+
const errorObj = Object.assign({}, msg);
|
|
780
942
|
delete errorObj.message;
|
|
781
943
|
delete errorObj.hint;
|
|
782
944
|
console.error(msg.message, errorObj);
|
|
@@ -785,7 +947,8 @@ export default class Reactor {
|
|
|
785
947
|
}
|
|
786
948
|
}
|
|
787
949
|
notifyQueryOnceError(q, hash, eventId, e) {
|
|
788
|
-
|
|
950
|
+
var _a;
|
|
951
|
+
const r = (_a = this.queryOnceDfds[hash]) === null || _a === void 0 ? void 0 : _a.find((r) => r.eventId === eventId);
|
|
789
952
|
if (!r)
|
|
790
953
|
return;
|
|
791
954
|
r.dfd.reject(e);
|
|
@@ -798,12 +961,6 @@ export default class Reactor {
|
|
|
798
961
|
}, {}), this._linkIndex);
|
|
799
962
|
this.notifyAttrsSubs();
|
|
800
963
|
}
|
|
801
|
-
// ---------------------------
|
|
802
|
-
// Queries
|
|
803
|
-
getPreviousResult = (q) => {
|
|
804
|
-
const hash = weakHash(q);
|
|
805
|
-
return this.dataForQuery(hash)?.data;
|
|
806
|
-
};
|
|
807
964
|
_startQuerySub(q, hash) {
|
|
808
965
|
const eventId = uuid();
|
|
809
966
|
this.querySubs.updateInPlace((prev) => {
|
|
@@ -827,18 +984,19 @@ export default class Reactor {
|
|
|
827
984
|
* Returns an unsubscribe function
|
|
828
985
|
*/
|
|
829
986
|
subscribeQuery(q, cb, opts) {
|
|
987
|
+
var _a;
|
|
830
988
|
if (!this.config.disableValidation) {
|
|
831
989
|
validateQuery(q, this.config.schema);
|
|
832
990
|
}
|
|
833
991
|
if (opts && 'ruleParams' in opts) {
|
|
834
|
-
q = { $$ruleParams: opts['ruleParams'],
|
|
992
|
+
q = Object.assign({ $$ruleParams: opts['ruleParams'] }, q);
|
|
835
993
|
}
|
|
836
994
|
const hash = weakHash(q);
|
|
837
995
|
const prevResult = this.getPreviousResult(q);
|
|
838
996
|
if (prevResult) {
|
|
839
997
|
cb(prevResult);
|
|
840
998
|
}
|
|
841
|
-
this.queryCbs[hash] = this.queryCbs[hash]
|
|
999
|
+
this.queryCbs[hash] = (_a = this.queryCbs[hash]) !== null && _a !== void 0 ? _a : [];
|
|
842
1000
|
this.queryCbs[hash].push({ q, cb });
|
|
843
1001
|
this._startQuerySub(q, hash);
|
|
844
1002
|
return () => {
|
|
@@ -846,11 +1004,12 @@ export default class Reactor {
|
|
|
846
1004
|
};
|
|
847
1005
|
}
|
|
848
1006
|
queryOnce(q, opts) {
|
|
1007
|
+
var _a;
|
|
849
1008
|
if (!this.config.disableValidation) {
|
|
850
1009
|
validateQuery(q, this.config.schema);
|
|
851
1010
|
}
|
|
852
1011
|
if (opts && 'ruleParams' in opts) {
|
|
853
|
-
q = { $$ruleParams: opts['ruleParams'],
|
|
1012
|
+
q = Object.assign({ $$ruleParams: opts['ruleParams'] }, q);
|
|
854
1013
|
}
|
|
855
1014
|
const dfd = new Deferred();
|
|
856
1015
|
if (!this._isOnline) {
|
|
@@ -863,7 +1022,7 @@ export default class Reactor {
|
|
|
863
1022
|
}
|
|
864
1023
|
const hash = weakHash(q);
|
|
865
1024
|
const eventId = this._startQuerySub(q, hash);
|
|
866
|
-
this.queryOnceDfds[hash] = this.queryOnceDfds[hash]
|
|
1025
|
+
this.queryOnceDfds[hash] = (_a = this.queryOnceDfds[hash]) !== null && _a !== void 0 ? _a : [];
|
|
867
1026
|
this.queryOnceDfds[hash].push({ q, dfd, eventId });
|
|
868
1027
|
setTimeout(() => dfd.reject(new Error('Query timed out')), QUERY_ONCE_TIMEOUT);
|
|
869
1028
|
return dfd.promise;
|
|
@@ -881,7 +1040,8 @@ export default class Reactor {
|
|
|
881
1040
|
this._cleanupQuery(q, hash);
|
|
882
1041
|
}
|
|
883
1042
|
_hasQueryListeners(hash) {
|
|
884
|
-
|
|
1043
|
+
var _a, _b;
|
|
1044
|
+
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));
|
|
885
1045
|
}
|
|
886
1046
|
_cleanupQuery(q, hash) {
|
|
887
1047
|
const hasListeners = this._hasQueryListeners(hash);
|
|
@@ -973,10 +1133,7 @@ export default class Reactor {
|
|
|
973
1133
|
};
|
|
974
1134
|
const rewritten = new Map();
|
|
975
1135
|
for (const [k, mut] of muts.entries()) {
|
|
976
|
-
rewritten.set(k, {
|
|
977
|
-
...mut,
|
|
978
|
-
'tx-steps': rewriteTxSteps(mut['tx-steps'], mut['tx-id']),
|
|
979
|
-
});
|
|
1136
|
+
rewritten.set(k, Object.assign(Object.assign({}, mut), { 'tx-steps': rewriteTxSteps(mut['tx-steps'], mut['tx-id']) }));
|
|
980
1137
|
}
|
|
981
1138
|
if (!mappingChanged) {
|
|
982
1139
|
return muts;
|
|
@@ -992,6 +1149,7 @@ export default class Reactor {
|
|
|
992
1149
|
* @returns {s.AttrsStore}
|
|
993
1150
|
*/
|
|
994
1151
|
optimisticAttrs() {
|
|
1152
|
+
var _a, _b;
|
|
995
1153
|
const pendingMutationSteps = [...this._pendingMutations().values()] // hack due to Map()
|
|
996
1154
|
.flatMap((x) => x['tx-steps']);
|
|
997
1155
|
const deletedAttrIds = new Set(pendingMutationSteps
|
|
@@ -1004,15 +1162,15 @@ export default class Reactor {
|
|
|
1004
1162
|
}
|
|
1005
1163
|
else if (_action === 'update-attr' &&
|
|
1006
1164
|
attr.id &&
|
|
1007
|
-
this.attrs
|
|
1008
|
-
const fullAttr = {
|
|
1165
|
+
((_a = this.attrs) === null || _a === void 0 ? void 0 : _a.getAttr(attr.id))) {
|
|
1166
|
+
const fullAttr = Object.assign(Object.assign({}, this.attrs.getAttr(attr.id)), attr);
|
|
1009
1167
|
pendingAttrs.push(fullAttr);
|
|
1010
1168
|
}
|
|
1011
1169
|
}
|
|
1012
1170
|
if (!deletedAttrIds.size && !pendingAttrs.length) {
|
|
1013
1171
|
return this.attrs || new s.AttrsStoreClass({}, this._linkIndex);
|
|
1014
1172
|
}
|
|
1015
|
-
const attrs = {
|
|
1173
|
+
const attrs = Object.assign({}, (((_b = this.attrs) === null || _b === void 0 ? void 0 : _b.attrs) || {}));
|
|
1016
1174
|
for (const attr of pendingAttrs) {
|
|
1017
1175
|
attrs[attr.id] = attr;
|
|
1018
1176
|
}
|
|
@@ -1066,30 +1224,6 @@ export default class Reactor {
|
|
|
1066
1224
|
}
|
|
1067
1225
|
return { store, attrsStore };
|
|
1068
1226
|
}
|
|
1069
|
-
/** Re-run instaql and call all callbacks with new data */
|
|
1070
|
-
notifyOne = (hash) => {
|
|
1071
|
-
const cbs = this.queryCbs[hash] ?? [];
|
|
1072
|
-
const prevData = this._dataForQueryCache[hash]?.data;
|
|
1073
|
-
const resp = this.dataForQuery(hash);
|
|
1074
|
-
if (!resp?.data)
|
|
1075
|
-
return;
|
|
1076
|
-
this._dataForQueryCache[hash] = resp;
|
|
1077
|
-
if (areObjectsDeepEqual(resp.data, prevData))
|
|
1078
|
-
return;
|
|
1079
|
-
cbs.forEach((r) => r.cb(resp.data));
|
|
1080
|
-
};
|
|
1081
|
-
notifyOneQueryOnce = (hash) => {
|
|
1082
|
-
const dfds = this.queryOnceDfds[hash] ?? [];
|
|
1083
|
-
const data = this.dataForQuery(hash)?.data;
|
|
1084
|
-
dfds.forEach((r) => {
|
|
1085
|
-
this._completeQueryOnce(r.q, hash, r.dfd);
|
|
1086
|
-
r.dfd.resolve(data);
|
|
1087
|
-
});
|
|
1088
|
-
};
|
|
1089
|
-
notifyQueryError = (hash, error) => {
|
|
1090
|
-
const cbs = this.queryCbs[hash] || [];
|
|
1091
|
-
cbs.forEach((r) => r.cb({ error }));
|
|
1092
|
-
};
|
|
1093
1227
|
/** Re-compute all subscriptions */
|
|
1094
1228
|
notifyAll() {
|
|
1095
1229
|
Object.keys(this.queryCbs).forEach((hash) => {
|
|
@@ -1105,54 +1239,11 @@ export default class Reactor {
|
|
|
1105
1239
|
.then(() => this.notifyAll())
|
|
1106
1240
|
.catch(() => this.notifyAll());
|
|
1107
1241
|
}
|
|
1108
|
-
/** Applies transactions locally and sends transact message to server */
|
|
1109
|
-
pushTx = (chunks) => {
|
|
1110
|
-
// Throws if transactions are invalid
|
|
1111
|
-
if (!this.config.disableValidation) {
|
|
1112
|
-
validateTransactions(chunks, this.config.schema);
|
|
1113
|
-
}
|
|
1114
|
-
try {
|
|
1115
|
-
const txSteps = instaml.transform({
|
|
1116
|
-
attrsStore: this.optimisticAttrs(),
|
|
1117
|
-
schema: this.config.schema,
|
|
1118
|
-
stores: Object.values(this.querySubs.currentValue).map((sub) => sub?.result?.store),
|
|
1119
|
-
useDateObjects: this.config.useDateObjects,
|
|
1120
|
-
}, chunks);
|
|
1121
|
-
return this.pushOps(txSteps);
|
|
1122
|
-
}
|
|
1123
|
-
catch (e) {
|
|
1124
|
-
return this.pushOps([], e);
|
|
1125
|
-
}
|
|
1126
|
-
};
|
|
1127
|
-
/**
|
|
1128
|
-
* @param {*} txSteps
|
|
1129
|
-
* @param {*} [error]
|
|
1130
|
-
* @returns
|
|
1131
|
-
*/
|
|
1132
|
-
pushOps = (txSteps, error) => {
|
|
1133
|
-
const eventId = uuid();
|
|
1134
|
-
const mutations = [...this._pendingMutations().values()];
|
|
1135
|
-
const order = Math.max(0, ...mutations.map((mut) => mut.order || 0)) + 1;
|
|
1136
|
-
const mutation = {
|
|
1137
|
-
op: 'transact',
|
|
1138
|
-
'tx-steps': txSteps,
|
|
1139
|
-
created: Date.now(),
|
|
1140
|
-
error,
|
|
1141
|
-
order,
|
|
1142
|
-
};
|
|
1143
|
-
this._updatePendingMutations((prev) => {
|
|
1144
|
-
prev.set(eventId, mutation);
|
|
1145
|
-
});
|
|
1146
|
-
const dfd = new Deferred();
|
|
1147
|
-
this.mutationDeferredStore.set(eventId, dfd);
|
|
1148
|
-
this._sendMutation(eventId, mutation);
|
|
1149
|
-
this.notifyAll();
|
|
1150
|
-
return dfd.promise;
|
|
1151
|
-
};
|
|
1152
1242
|
shutdown() {
|
|
1243
|
+
var _a;
|
|
1153
1244
|
this._log.info('[shutdown]', this.config.appId);
|
|
1154
1245
|
this._isShutdown = true;
|
|
1155
|
-
this._transport
|
|
1246
|
+
(_a = this._transport) === null || _a === void 0 ? void 0 : _a.close();
|
|
1156
1247
|
}
|
|
1157
1248
|
/**
|
|
1158
1249
|
* Sends mutation to server and schedules a timeout to cancel it if
|
|
@@ -1225,8 +1316,8 @@ export default class Reactor {
|
|
|
1225
1316
|
_cleanupPendingMutationsQueries() {
|
|
1226
1317
|
let minProcessedTxId = Number.MAX_SAFE_INTEGER;
|
|
1227
1318
|
for (const { result } of Object.values(this.querySubs.currentValue)) {
|
|
1228
|
-
if (result
|
|
1229
|
-
minProcessedTxId = Math.min(minProcessedTxId, result
|
|
1319
|
+
if (result === null || result === void 0 ? void 0 : result.processedTxId) {
|
|
1320
|
+
minProcessedTxId = Math.min(minProcessedTxId, result === null || result === void 0 ? void 0 : result.processedTxId);
|
|
1230
1321
|
}
|
|
1231
1322
|
}
|
|
1232
1323
|
this._updatePendingMutations((prev) => {
|
|
@@ -1279,96 +1370,8 @@ export default class Reactor {
|
|
|
1279
1370
|
this._inFlightMutationEventIds.clear();
|
|
1280
1371
|
}
|
|
1281
1372
|
}
|
|
1282
|
-
this._transport.send({ 'client-event-id': eventId,
|
|
1373
|
+
this._transport.send(Object.assign({ 'client-event-id': eventId }, msg));
|
|
1283
1374
|
}
|
|
1284
|
-
_transportOnOpen = (e) => {
|
|
1285
|
-
const targetTransport = e.target;
|
|
1286
|
-
if (this._transport !== targetTransport) {
|
|
1287
|
-
this._log.info('[socket][open]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
1288
|
-
return;
|
|
1289
|
-
}
|
|
1290
|
-
this._log.info('[socket][open]', this._transport.id);
|
|
1291
|
-
this._setStatus(STATUS.OPENED);
|
|
1292
|
-
this.getCurrentUser()
|
|
1293
|
-
.then((resp) => {
|
|
1294
|
-
this._trySend(uuid(), {
|
|
1295
|
-
op: 'init',
|
|
1296
|
-
'app-id': this.config.appId,
|
|
1297
|
-
'refresh-token': resp.user?.['refresh_token'],
|
|
1298
|
-
versions: this.versions,
|
|
1299
|
-
// If an admin token is provided for an app, we will
|
|
1300
|
-
// skip all permission checks. This is an advanced feature,
|
|
1301
|
-
// to let users write internal tools
|
|
1302
|
-
// This option is not exposed in `Config`, as it's
|
|
1303
|
-
// not ready for prime time
|
|
1304
|
-
'__admin-token': this.config.__adminToken,
|
|
1305
|
-
});
|
|
1306
|
-
})
|
|
1307
|
-
.catch((e) => {
|
|
1308
|
-
this._log.error('[socket][error]', targetTransport.id, e);
|
|
1309
|
-
});
|
|
1310
|
-
};
|
|
1311
|
-
_transportOnMessage = (e) => {
|
|
1312
|
-
const targetTransport = e.target;
|
|
1313
|
-
const m = e.message;
|
|
1314
|
-
if (this._transport !== targetTransport) {
|
|
1315
|
-
this._log.info('[socket][message]', targetTransport.id, m, 'skip; this is no longer the current transport');
|
|
1316
|
-
return;
|
|
1317
|
-
}
|
|
1318
|
-
if (!this._wsOk && targetTransport.type === 'ws') {
|
|
1319
|
-
this._wsOk = true;
|
|
1320
|
-
}
|
|
1321
|
-
// Try to reconnect via websocket the next time we connect
|
|
1322
|
-
this._transportType = 'ws';
|
|
1323
|
-
if (Array.isArray(e.message)) {
|
|
1324
|
-
for (const msg of e.message) {
|
|
1325
|
-
this._handleReceive(targetTransport.id, msg);
|
|
1326
|
-
}
|
|
1327
|
-
}
|
|
1328
|
-
else {
|
|
1329
|
-
this._handleReceive(targetTransport.id, e.message);
|
|
1330
|
-
}
|
|
1331
|
-
};
|
|
1332
|
-
_transportOnError = (e) => {
|
|
1333
|
-
const targetTransport = e.target;
|
|
1334
|
-
if (this._transport !== targetTransport) {
|
|
1335
|
-
this._log.info('[socket][error]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
1336
|
-
return;
|
|
1337
|
-
}
|
|
1338
|
-
this._log.error('[socket][error]', targetTransport.id, e);
|
|
1339
|
-
};
|
|
1340
|
-
_scheduleReconnect = () => {
|
|
1341
|
-
// If we couldn't connect with a websocket last time, try sse
|
|
1342
|
-
if (!this._wsOk && this._transportType !== 'sse') {
|
|
1343
|
-
this._transportType = 'sse';
|
|
1344
|
-
this._reconnectTimeoutMs = 0;
|
|
1345
|
-
}
|
|
1346
|
-
setTimeout(() => {
|
|
1347
|
-
this._reconnectTimeoutMs = Math.min(this._reconnectTimeoutMs + 1000, 10000);
|
|
1348
|
-
if (!this._isOnline) {
|
|
1349
|
-
this._log.info('[socket][close]', this._transport.id, 'we are offline, no need to start socket');
|
|
1350
|
-
return;
|
|
1351
|
-
}
|
|
1352
|
-
this._startSocket();
|
|
1353
|
-
}, this._reconnectTimeoutMs);
|
|
1354
|
-
};
|
|
1355
|
-
_transportOnClose = (e) => {
|
|
1356
|
-
const targetTransport = e.target;
|
|
1357
|
-
if (this._transport !== targetTransport) {
|
|
1358
|
-
this._log.info('[socket][close]', targetTransport.id, 'skip; this is no longer the current transport');
|
|
1359
|
-
return;
|
|
1360
|
-
}
|
|
1361
|
-
this._setStatus(STATUS.CLOSED);
|
|
1362
|
-
for (const room of Object.values(this._rooms)) {
|
|
1363
|
-
room.isConnected = false;
|
|
1364
|
-
}
|
|
1365
|
-
if (this._isShutdown) {
|
|
1366
|
-
this._log.info('[socket][close]', targetTransport.id, 'Reactor has been shut down and will not reconnect');
|
|
1367
|
-
return;
|
|
1368
|
-
}
|
|
1369
|
-
this._log.info('[socket][close]', targetTransport.id, 'schedule reconnect, ms =', this._reconnectTimeoutMs);
|
|
1370
|
-
this._scheduleReconnect();
|
|
1371
|
-
};
|
|
1372
1375
|
_startSocket() {
|
|
1373
1376
|
// Reset whether we support websockets each time we connect
|
|
1374
1377
|
// new networks may not support websockets
|
|
@@ -1397,7 +1400,7 @@ export default class Reactor {
|
|
|
1397
1400
|
this._transport.onclose = this._transportOnClose;
|
|
1398
1401
|
this._transport.onerror = this._transportOnError;
|
|
1399
1402
|
this._log.info('[socket][start]', this._transport.id);
|
|
1400
|
-
if (prevTransport
|
|
1403
|
+
if (prevTransport === null || prevTransport === void 0 ? void 0 : prevTransport.isOpen()) {
|
|
1401
1404
|
// When the network dies, it doesn't always mean that our
|
|
1402
1405
|
// socket connection will fire a close event.
|
|
1403
1406
|
//
|
|
@@ -1418,22 +1421,24 @@ export default class Reactor {
|
|
|
1418
1421
|
* Note: If the user deletes their local storage, this id will change.
|
|
1419
1422
|
*
|
|
1420
1423
|
*/
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1424
|
+
getLocalId(name) {
|
|
1425
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1426
|
+
const k = `localToken_${name}`;
|
|
1427
|
+
if (this.kv.currentValue[k]) {
|
|
1428
|
+
return this.kv.currentValue[k];
|
|
1429
|
+
}
|
|
1430
|
+
const current = yield this.kv.waitForKeyToLoad(k);
|
|
1431
|
+
if (current) {
|
|
1432
|
+
return current;
|
|
1433
|
+
}
|
|
1434
|
+
const newId = uuid();
|
|
1435
|
+
this.kv.updateInPlace((prev) => {
|
|
1436
|
+
if (prev[k])
|
|
1437
|
+
return;
|
|
1438
|
+
prev[k] = newId;
|
|
1439
|
+
});
|
|
1440
|
+
return yield this.kv.waitForKeyToLoad(k);
|
|
1435
1441
|
});
|
|
1436
|
-
return await this.kv.waitForKeyToLoad(k);
|
|
1437
1442
|
}
|
|
1438
1443
|
// ----
|
|
1439
1444
|
// Auth
|
|
@@ -1468,13 +1473,14 @@ export default class Reactor {
|
|
|
1468
1473
|
// The next.js app router will reset the URL when the router loads.
|
|
1469
1474
|
// This puts it back after the router loads.
|
|
1470
1475
|
const listener = (e) => {
|
|
1476
|
+
var _a;
|
|
1471
1477
|
if (!ran) {
|
|
1472
1478
|
ran = true;
|
|
1473
1479
|
// @ts-ignore (waiting for ts support)
|
|
1474
1480
|
navigation.removeEventListener('navigate', listener);
|
|
1475
1481
|
if (!e.userInitiated &&
|
|
1476
1482
|
e.navigationType === 'replace' &&
|
|
1477
|
-
e.destination
|
|
1483
|
+
((_a = e.destination) === null || _a === void 0 ? void 0 : _a.url) === startUrl) {
|
|
1478
1484
|
history.replaceState(history.state, '', newPath);
|
|
1479
1485
|
}
|
|
1480
1486
|
}
|
|
@@ -1488,52 +1494,57 @@ export default class Reactor {
|
|
|
1488
1494
|
*
|
|
1489
1495
|
* @returns Promise<null | {error: {message: string}}>
|
|
1490
1496
|
*/
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
typeof
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1497
|
+
_oauthLoginInit() {
|
|
1498
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1499
|
+
var _a, _b, _c, _d;
|
|
1500
|
+
if (typeof window === 'undefined' ||
|
|
1501
|
+
typeof window.location === 'undefined' ||
|
|
1502
|
+
typeof URLSearchParams === 'undefined') {
|
|
1503
|
+
return null;
|
|
1504
|
+
}
|
|
1505
|
+
const params = new URLSearchParams(window.location.search);
|
|
1506
|
+
if (!params.get(OAUTH_REDIRECT_PARAM)) {
|
|
1507
|
+
return null;
|
|
1508
|
+
}
|
|
1509
|
+
const error = params.get('error');
|
|
1510
|
+
if (error) {
|
|
1511
|
+
this._replaceUrlAfterOAuth();
|
|
1512
|
+
return { error: { message: error } };
|
|
1513
|
+
}
|
|
1514
|
+
const code = params.get('code');
|
|
1515
|
+
if (!code) {
|
|
1516
|
+
return null;
|
|
1517
|
+
}
|
|
1503
1518
|
this._replaceUrlAfterOAuth();
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
const { user } = await authAPI.exchangeCodeForToken({
|
|
1515
|
-
apiURI: this.config.apiURI,
|
|
1516
|
-
appId: this.config.appId,
|
|
1517
|
-
code,
|
|
1518
|
-
refreshToken: isGuest ? currentUser.refresh_token : undefined,
|
|
1519
|
-
});
|
|
1520
|
-
this.setCurrentUser(user);
|
|
1521
|
-
return null;
|
|
1522
|
-
}
|
|
1523
|
-
catch (e) {
|
|
1524
|
-
if (e?.body?.type === 'record-not-found' &&
|
|
1525
|
-
e?.body?.hint?.['record-type'] === 'app-oauth-code' &&
|
|
1526
|
-
(await this._hasCurrentUser())) {
|
|
1527
|
-
// We probably just weren't able to clean up the URL, so
|
|
1528
|
-
// let's just ignore this error
|
|
1519
|
+
try {
|
|
1520
|
+
const currentUser = yield this._getCurrentUser();
|
|
1521
|
+
const isGuest = (currentUser === null || currentUser === void 0 ? void 0 : currentUser.type) === 'guest';
|
|
1522
|
+
const { user } = yield authAPI.exchangeCodeForToken({
|
|
1523
|
+
apiURI: this.config.apiURI,
|
|
1524
|
+
appId: this.config.appId,
|
|
1525
|
+
code,
|
|
1526
|
+
refreshToken: isGuest ? currentUser.refresh_token : undefined,
|
|
1527
|
+
});
|
|
1528
|
+
this.setCurrentUser(user);
|
|
1529
1529
|
return null;
|
|
1530
1530
|
}
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1531
|
+
catch (e) {
|
|
1532
|
+
if (((_a = e === null || e === void 0 ? void 0 : e.body) === null || _a === void 0 ? void 0 : _a.type) === 'record-not-found' &&
|
|
1533
|
+
((_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' &&
|
|
1534
|
+
(yield this._hasCurrentUser())) {
|
|
1535
|
+
// We probably just weren't able to clean up the URL, so
|
|
1536
|
+
// let's just ignore this error
|
|
1537
|
+
return null;
|
|
1538
|
+
}
|
|
1539
|
+
const message = ((_d = e === null || e === void 0 ? void 0 : e.body) === null || _d === void 0 ? void 0 : _d.message) || 'Error logging in.';
|
|
1540
|
+
return { error: { message } };
|
|
1541
|
+
}
|
|
1542
|
+
});
|
|
1534
1543
|
}
|
|
1535
|
-
|
|
1536
|
-
return
|
|
1544
|
+
_waitForOAuthCallbackResponse() {
|
|
1545
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1546
|
+
return yield this._oauthCallbackResponse;
|
|
1547
|
+
});
|
|
1537
1548
|
}
|
|
1538
1549
|
__subscribeMutationErrors(cb) {
|
|
1539
1550
|
this.mutationErrorCbs.push(cb);
|
|
@@ -1560,12 +1571,14 @@ export default class Reactor {
|
|
|
1560
1571
|
this.authCbs = this.authCbs.filter((x) => x !== cb);
|
|
1561
1572
|
};
|
|
1562
1573
|
}
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1574
|
+
getAuth() {
|
|
1575
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1576
|
+
const { user, error } = yield this.getCurrentUser();
|
|
1577
|
+
if (error) {
|
|
1578
|
+
throw new InstantError('Could not get current user: ' + error.message);
|
|
1579
|
+
}
|
|
1580
|
+
return user;
|
|
1581
|
+
});
|
|
1569
1582
|
}
|
|
1570
1583
|
subscribeConnectionStatus(cb) {
|
|
1571
1584
|
this.connectionStatusCbs.push(cb);
|
|
@@ -1597,89 +1610,99 @@ export default class Reactor {
|
|
|
1597
1610
|
notifyConnectionStatusSubs(status) {
|
|
1598
1611
|
this.connectionStatusCbs.forEach((cb) => cb(status));
|
|
1599
1612
|
}
|
|
1600
|
-
|
|
1601
|
-
this
|
|
1602
|
-
prev
|
|
1613
|
+
setCurrentUser(user) {
|
|
1614
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1615
|
+
this.kv.updateInPlace((prev) => {
|
|
1616
|
+
prev[currentUserKey] = user;
|
|
1617
|
+
});
|
|
1618
|
+
yield this.kv.waitForKeyToLoad(currentUserKey);
|
|
1603
1619
|
});
|
|
1604
|
-
await this.kv.waitForKeyToLoad(currentUserKey);
|
|
1605
1620
|
}
|
|
1606
1621
|
getCurrentUserCached() {
|
|
1607
1622
|
return this._currentUserCached;
|
|
1608
1623
|
}
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
const oauthResp = await this._waitForOAuthCallbackResponse();
|
|
1615
|
-
if (oauthResp?.error) {
|
|
1616
|
-
const errorV = { error: oauthResp.error, user: undefined };
|
|
1617
|
-
this._currentUserCached = { isLoading: false, ...errorV };
|
|
1618
|
-
return errorV;
|
|
1619
|
-
}
|
|
1620
|
-
try {
|
|
1621
|
-
const user = await this._getCurrentUser();
|
|
1622
|
-
const userV = { user: user, error: undefined };
|
|
1623
|
-
this._currentUserCached = {
|
|
1624
|
-
isLoading: false,
|
|
1625
|
-
...userV,
|
|
1626
|
-
};
|
|
1627
|
-
return userV;
|
|
1628
|
-
}
|
|
1629
|
-
catch (e) {
|
|
1630
|
-
return {
|
|
1631
|
-
user: undefined,
|
|
1632
|
-
isLoading: false,
|
|
1633
|
-
error: { message: e?.message || 'Error loading user' },
|
|
1634
|
-
};
|
|
1635
|
-
}
|
|
1624
|
+
_getCurrentUser() {
|
|
1625
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1626
|
+
const user = yield this.kv.waitForKeyToLoad(currentUserKey);
|
|
1627
|
+
return typeof user === 'string' ? JSON.parse(user) : user;
|
|
1628
|
+
});
|
|
1636
1629
|
}
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1630
|
+
getCurrentUser() {
|
|
1631
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1632
|
+
const oauthResp = yield this._waitForOAuthCallbackResponse();
|
|
1633
|
+
if (oauthResp === null || oauthResp === void 0 ? void 0 : oauthResp.error) {
|
|
1634
|
+
const errorV = { error: oauthResp.error, user: undefined };
|
|
1635
|
+
this._currentUserCached = Object.assign({ isLoading: false }, errorV);
|
|
1636
|
+
return errorV;
|
|
1637
|
+
}
|
|
1638
|
+
try {
|
|
1639
|
+
const user = yield this._getCurrentUser();
|
|
1640
|
+
const userV = { user: user, error: undefined };
|
|
1641
|
+
this._currentUserCached = Object.assign({ isLoading: false }, userV);
|
|
1642
|
+
return userV;
|
|
1643
|
+
}
|
|
1644
|
+
catch (e) {
|
|
1645
|
+
return {
|
|
1646
|
+
user: undefined,
|
|
1647
|
+
isLoading: false,
|
|
1648
|
+
error: { message: (e === null || e === void 0 ? void 0 : e.message) || 'Error loading user' },
|
|
1649
|
+
};
|
|
1650
|
+
}
|
|
1651
|
+
});
|
|
1640
1652
|
}
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
return;
|
|
1647
|
-
}
|
|
1648
|
-
await this.setCurrentUser(newUser);
|
|
1649
|
-
// We need to remove all `result` from querySubs,
|
|
1650
|
-
// as they are no longer valid for the new user
|
|
1651
|
-
this.updateUser(newUser);
|
|
1652
|
-
try {
|
|
1653
|
-
this._broadcastChannel?.postMessage({ type: 'auth' });
|
|
1654
|
-
}
|
|
1655
|
-
catch (error) {
|
|
1656
|
-
console.error('Error posting message to broadcast channel', error);
|
|
1657
|
-
}
|
|
1653
|
+
_hasCurrentUser() {
|
|
1654
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1655
|
+
const user = yield this.kv.waitForKeyToLoad(currentUserKey);
|
|
1656
|
+
return typeof user === 'string' ? JSON.parse(user) != null : user != null;
|
|
1657
|
+
});
|
|
1658
1658
|
}
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1659
|
+
changeCurrentUser(newUser) {
|
|
1660
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1661
|
+
var _a;
|
|
1662
|
+
const { user: oldUser } = yield this.getCurrentUser();
|
|
1663
|
+
if (areObjectsDeepEqual(oldUser, newUser)) {
|
|
1664
|
+
// We were already logged in as the newUser, don't
|
|
1665
|
+
// bother updating
|
|
1666
|
+
return;
|
|
1667
|
+
}
|
|
1668
|
+
yield this.setCurrentUser(newUser);
|
|
1669
|
+
// We need to remove all `result` from querySubs,
|
|
1670
|
+
// as they are no longer valid for the new user
|
|
1671
|
+
this.updateUser(newUser);
|
|
1672
|
+
try {
|
|
1673
|
+
(_a = this._broadcastChannel) === null || _a === void 0 ? void 0 : _a.postMessage({ type: 'auth' });
|
|
1674
|
+
}
|
|
1675
|
+
catch (error) {
|
|
1676
|
+
console.error('Error posting message to broadcast channel', error);
|
|
1677
|
+
}
|
|
1678
|
+
});
|
|
1679
|
+
}
|
|
1680
|
+
syncUserToEndpoint(user) {
|
|
1681
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1682
|
+
if (!this.config.firstPartyPath)
|
|
1683
|
+
return;
|
|
1684
|
+
try {
|
|
1685
|
+
fetch(this.config.firstPartyPath + '/', {
|
|
1686
|
+
method: 'POST',
|
|
1687
|
+
body: JSON.stringify({
|
|
1688
|
+
type: 'sync-user',
|
|
1689
|
+
appId: this.config.appId,
|
|
1690
|
+
user: user,
|
|
1691
|
+
}),
|
|
1692
|
+
headers: {
|
|
1693
|
+
'Content-Type': 'application/json',
|
|
1694
|
+
},
|
|
1695
|
+
});
|
|
1696
|
+
}
|
|
1697
|
+
catch (error) {
|
|
1698
|
+
this._log.error('Error syncing user with external endpoint', error);
|
|
1699
|
+
}
|
|
1700
|
+
});
|
|
1678
1701
|
}
|
|
1679
1702
|
updateUser(newUser) {
|
|
1680
1703
|
this.syncUserToEndpoint(newUser);
|
|
1681
1704
|
const newV = { error: undefined, user: newUser };
|
|
1682
|
-
this._currentUserCached = { isLoading: false,
|
|
1705
|
+
this._currentUserCached = Object.assign({ isLoading: false }, newV);
|
|
1683
1706
|
this._dataForQueryCache = {};
|
|
1684
1707
|
this.querySubs.updateInPlace((prev) => {
|
|
1685
1708
|
Object.keys(prev).forEach((k) => {
|
|
@@ -1698,38 +1721,46 @@ export default class Reactor {
|
|
|
1698
1721
|
email: email,
|
|
1699
1722
|
});
|
|
1700
1723
|
}
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1724
|
+
signInWithMagicCode(_a) {
|
|
1725
|
+
return __awaiter(this, arguments, void 0, function* ({ email, code }) {
|
|
1726
|
+
var _b;
|
|
1727
|
+
const currentUser = yield this.getCurrentUser();
|
|
1728
|
+
const isGuest = ((_b = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _b === void 0 ? void 0 : _b.type) === 'guest';
|
|
1729
|
+
const res = yield authAPI.verifyMagicCode({
|
|
1730
|
+
apiURI: this.config.apiURI,
|
|
1731
|
+
appId: this.config.appId,
|
|
1732
|
+
email,
|
|
1733
|
+
code,
|
|
1734
|
+
refreshToken: isGuest ? currentUser.user.refresh_token : undefined,
|
|
1735
|
+
});
|
|
1736
|
+
yield this.changeCurrentUser(res.user);
|
|
1737
|
+
return res;
|
|
1710
1738
|
});
|
|
1711
|
-
await this.changeCurrentUser(res.user);
|
|
1712
|
-
return res;
|
|
1713
1739
|
}
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1740
|
+
signInWithCustomToken(authToken) {
|
|
1741
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1742
|
+
const res = yield authAPI.verifyRefreshToken({
|
|
1743
|
+
apiURI: this.config.apiURI,
|
|
1744
|
+
appId: this.config.appId,
|
|
1745
|
+
refreshToken: authToken,
|
|
1746
|
+
});
|
|
1747
|
+
yield this.changeCurrentUser(res.user);
|
|
1748
|
+
return res;
|
|
1719
1749
|
});
|
|
1720
|
-
await this.changeCurrentUser(res.user);
|
|
1721
|
-
return res;
|
|
1722
1750
|
}
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1751
|
+
signInAsGuest() {
|
|
1752
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1753
|
+
const res = yield authAPI.signInAsGuest({
|
|
1754
|
+
apiURI: this.config.apiURI,
|
|
1755
|
+
appId: this.config.appId,
|
|
1756
|
+
});
|
|
1757
|
+
yield this.changeCurrentUser(res.user);
|
|
1758
|
+
return res;
|
|
1727
1759
|
});
|
|
1728
|
-
await this.changeCurrentUser(res.user);
|
|
1729
|
-
return res;
|
|
1730
1760
|
}
|
|
1731
1761
|
potentiallyInvalidateToken(currentUser, opts) {
|
|
1732
|
-
|
|
1762
|
+
var _a;
|
|
1763
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
1733
1764
|
if (!refreshToken) {
|
|
1734
1765
|
return;
|
|
1735
1766
|
}
|
|
@@ -1749,10 +1780,12 @@ export default class Reactor {
|
|
|
1749
1780
|
})
|
|
1750
1781
|
.catch((e) => { });
|
|
1751
1782
|
}
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1783
|
+
signOut(opts) {
|
|
1784
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1785
|
+
const currentUser = yield this.getCurrentUser();
|
|
1786
|
+
this.potentiallyInvalidateToken(currentUser, opts);
|
|
1787
|
+
yield this.changeCurrentUser(null);
|
|
1788
|
+
});
|
|
1756
1789
|
}
|
|
1757
1790
|
/**
|
|
1758
1791
|
* Creates an OAuth authorization URL.
|
|
@@ -1771,18 +1804,21 @@ export default class Reactor {
|
|
|
1771
1804
|
* @param {string} params.code - The code received from the OAuth service.
|
|
1772
1805
|
* @param {string} [params.codeVerifier] - The code verifier used to generate the code challenge.
|
|
1773
1806
|
*/
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1807
|
+
exchangeCodeForToken(_a) {
|
|
1808
|
+
return __awaiter(this, arguments, void 0, function* ({ code, codeVerifier }) {
|
|
1809
|
+
var _b;
|
|
1810
|
+
const currentUser = yield this.getCurrentUser();
|
|
1811
|
+
const isGuest = ((_b = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _b === void 0 ? void 0 : _b.type) === 'guest';
|
|
1812
|
+
const res = yield authAPI.exchangeCodeForToken({
|
|
1813
|
+
apiURI: this.config.apiURI,
|
|
1814
|
+
appId: this.config.appId,
|
|
1815
|
+
code: code,
|
|
1816
|
+
codeVerifier,
|
|
1817
|
+
refreshToken: isGuest ? currentUser.user.refresh_token : undefined,
|
|
1818
|
+
});
|
|
1819
|
+
yield this.changeCurrentUser(res.user);
|
|
1820
|
+
return res;
|
|
1783
1821
|
});
|
|
1784
|
-
await this.changeCurrentUser(res.user);
|
|
1785
|
-
return res;
|
|
1786
1822
|
}
|
|
1787
1823
|
issuerURI() {
|
|
1788
1824
|
const { apiURI, appId } = this.config;
|
|
@@ -1794,19 +1830,22 @@ export default class Reactor {
|
|
|
1794
1830
|
* @param {string} params.idToken - The id_token from the external service
|
|
1795
1831
|
* @param {string | null | undefined} [params.nonce] - The nonce used when requesting the id_token from the external service
|
|
1796
1832
|
*/
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1833
|
+
signInWithIdToken(_a) {
|
|
1834
|
+
return __awaiter(this, arguments, void 0, function* ({ idToken, clientName, nonce }) {
|
|
1835
|
+
var _b;
|
|
1836
|
+
const currentUser = yield this.getCurrentUser();
|
|
1837
|
+
const refreshToken = (_b = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _b === void 0 ? void 0 : _b.refresh_token;
|
|
1838
|
+
const res = yield authAPI.signInWithIdToken({
|
|
1839
|
+
apiURI: this.config.apiURI,
|
|
1840
|
+
appId: this.config.appId,
|
|
1841
|
+
idToken,
|
|
1842
|
+
clientName,
|
|
1843
|
+
nonce,
|
|
1844
|
+
refreshToken,
|
|
1845
|
+
});
|
|
1846
|
+
yield this.changeCurrentUser(res.user);
|
|
1847
|
+
return res;
|
|
1807
1848
|
});
|
|
1808
|
-
await this.changeCurrentUser(res.user);
|
|
1809
|
-
return res;
|
|
1810
1849
|
}
|
|
1811
1850
|
// --------
|
|
1812
1851
|
// Rooms
|
|
@@ -1839,9 +1878,10 @@ export default class Reactor {
|
|
|
1839
1878
|
};
|
|
1840
1879
|
}
|
|
1841
1880
|
_cleanupRoom(roomId) {
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1881
|
+
var _a, _b, _c, _d;
|
|
1882
|
+
if (!((_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.handlers) === null || _b === void 0 ? void 0 : _b.length) &&
|
|
1883
|
+
!Object.keys((_c = this._broadcastSubs[roomId]) !== null && _c !== void 0 ? _c : {}).length) {
|
|
1884
|
+
const isConnected = (_d = this._rooms[roomId]) === null || _d === void 0 ? void 0 : _d.isConnected;
|
|
1845
1885
|
delete this._rooms[roomId];
|
|
1846
1886
|
delete this._presence[roomId];
|
|
1847
1887
|
delete this._broadcastSubs[roomId];
|
|
@@ -1861,11 +1901,7 @@ export default class Reactor {
|
|
|
1861
1901
|
const presence = this._presence[roomId];
|
|
1862
1902
|
if (!room || !presence || !presence.result)
|
|
1863
1903
|
return null;
|
|
1864
|
-
return {
|
|
1865
|
-
...buildPresenceSlice(presence.result, opts, this._sessionId),
|
|
1866
|
-
isLoading: !room.isConnected,
|
|
1867
|
-
error: room.error,
|
|
1868
|
-
};
|
|
1904
|
+
return Object.assign(Object.assign({}, buildPresenceSlice(presence.result, opts, this._sessionId)), { isLoading: !room.isConnected, error: room.error });
|
|
1869
1905
|
}
|
|
1870
1906
|
// TODO: look into typing again
|
|
1871
1907
|
publishPresence(roomType, roomId, partialData) {
|
|
@@ -1875,10 +1911,7 @@ export default class Reactor {
|
|
|
1875
1911
|
return;
|
|
1876
1912
|
}
|
|
1877
1913
|
presence.result = presence.result || {};
|
|
1878
|
-
const data = {
|
|
1879
|
-
...presence.result.user,
|
|
1880
|
-
...partialData,
|
|
1881
|
-
};
|
|
1914
|
+
const data = Object.assign(Object.assign({}, presence.result.user), partialData);
|
|
1882
1915
|
presence.result.user = data;
|
|
1883
1916
|
if (!room.isConnected) {
|
|
1884
1917
|
return;
|
|
@@ -1913,19 +1946,21 @@ export default class Reactor {
|
|
|
1913
1946
|
// Note: initialData is deprecated.
|
|
1914
1947
|
// Keeping here for backwards compatibility
|
|
1915
1948
|
opts.initialPresence || opts.initialData);
|
|
1916
|
-
const handler = {
|
|
1949
|
+
const handler = Object.assign(Object.assign({}, opts), { roomId, cb, prev: null });
|
|
1917
1950
|
this._presence[roomId] = this._presence[roomId] || {};
|
|
1918
1951
|
this._presence[roomId].handlers = this._presence[roomId].handlers || [];
|
|
1919
1952
|
this._presence[roomId].handlers.push(handler);
|
|
1920
1953
|
this._notifyPresenceSub(roomId, handler);
|
|
1921
1954
|
return () => {
|
|
1955
|
+
var _a, _b, _c;
|
|
1922
1956
|
this._presence[roomId].handlers =
|
|
1923
|
-
this._presence[roomId]
|
|
1957
|
+
(_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 : [];
|
|
1924
1958
|
leaveRoom();
|
|
1925
1959
|
};
|
|
1926
1960
|
}
|
|
1927
1961
|
_notifyPresenceSubs(roomId) {
|
|
1928
|
-
|
|
1962
|
+
var _a, _b;
|
|
1963
|
+
(_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.handlers) === null || _b === void 0 ? void 0 : _b.forEach((handler) => {
|
|
1929
1964
|
this._notifyPresenceSub(roomId, handler);
|
|
1930
1965
|
});
|
|
1931
1966
|
}
|
|
@@ -1941,9 +1976,10 @@ export default class Reactor {
|
|
|
1941
1976
|
handler.cb(slice);
|
|
1942
1977
|
}
|
|
1943
1978
|
_patchPresencePeers(roomId, edits) {
|
|
1944
|
-
|
|
1979
|
+
var _a, _b, _c;
|
|
1980
|
+
const peers = ((_b = (_a = this._presence[roomId]) === null || _a === void 0 ? void 0 : _a.result) === null || _b === void 0 ? void 0 : _b.peers) || {};
|
|
1945
1981
|
let sessions = Object.fromEntries(Object.entries(peers).map(([k, v]) => [k, { data: v }]));
|
|
1946
|
-
const myPresence = this._presence[roomId]
|
|
1982
|
+
const myPresence = (_c = this._presence[roomId]) === null || _c === void 0 ? void 0 : _c.result;
|
|
1947
1983
|
const newSessions = create(sessions, (draft) => {
|
|
1948
1984
|
for (let [path, op, value] of edits) {
|
|
1949
1985
|
switch (op) {
|
|
@@ -1964,7 +2000,7 @@ export default class Reactor {
|
|
|
1964
2000
|
this._setPresencePeers(roomId, newSessions);
|
|
1965
2001
|
}
|
|
1966
2002
|
_setPresencePeers(roomId, data) {
|
|
1967
|
-
const sessions = {
|
|
2003
|
+
const sessions = Object.assign({}, data);
|
|
1968
2004
|
// no need to keep track of `user`
|
|
1969
2005
|
delete sessions[this._sessionId];
|
|
1970
2006
|
const peers = Object.fromEntries(Object.entries(sessions).map(([k, v]) => [k, v.data]));
|
|
@@ -1975,12 +2011,13 @@ export default class Reactor {
|
|
|
1975
2011
|
// --------
|
|
1976
2012
|
// Broadcast
|
|
1977
2013
|
publishTopic({ roomType, roomId, topic, data }) {
|
|
2014
|
+
var _a;
|
|
1978
2015
|
const room = this._rooms[roomId];
|
|
1979
2016
|
if (!room) {
|
|
1980
2017
|
return;
|
|
1981
2018
|
}
|
|
1982
2019
|
if (!room.isConnected) {
|
|
1983
|
-
this._broadcastQueue[roomId] = this._broadcastQueue[roomId]
|
|
2020
|
+
this._broadcastQueue[roomId] = (_a = this._broadcastQueue[roomId]) !== null && _a !== void 0 ? _a : [];
|
|
1984
2021
|
this._broadcastQueue[roomId].push({ topic, roomType, data });
|
|
1985
2022
|
return;
|
|
1986
2023
|
}
|
|
@@ -2011,64 +2048,71 @@ export default class Reactor {
|
|
|
2011
2048
|
};
|
|
2012
2049
|
}
|
|
2013
2050
|
_notifyBroadcastSubs(room, topic, msg) {
|
|
2014
|
-
|
|
2015
|
-
|
|
2051
|
+
var _a, _b, _c;
|
|
2052
|
+
(_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) => {
|
|
2053
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2054
|
+
const data = (_a = msg.data) === null || _a === void 0 ? void 0 : _a.data;
|
|
2016
2055
|
const peer = msg.data['peer-id'] === this._sessionId
|
|
2017
|
-
? this._presence[room]
|
|
2018
|
-
: this._presence[room]
|
|
2056
|
+
? (_c = (_b = this._presence[room]) === null || _b === void 0 ? void 0 : _b.result) === null || _c === void 0 ? void 0 : _c.user
|
|
2057
|
+
: (_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']];
|
|
2019
2058
|
return cb(data, peer);
|
|
2020
2059
|
});
|
|
2021
2060
|
}
|
|
2022
2061
|
// --------
|
|
2023
2062
|
// Storage
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
apiURI: this.config.apiURI,
|
|
2030
|
-
appId: this.config.appId,
|
|
2031
|
-
path: path,
|
|
2032
|
-
file,
|
|
2033
|
-
refreshToken: refreshToken,
|
|
2063
|
+
uploadFile(path, file, opts) {
|
|
2064
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2065
|
+
var _a;
|
|
2066
|
+
const currentUser = yield this.getCurrentUser();
|
|
2067
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
2068
|
+
return StorageApi.uploadFile(Object.assign(Object.assign({}, opts), { apiURI: this.config.apiURI, appId: this.config.appId, path: path, file, refreshToken: refreshToken }));
|
|
2034
2069
|
});
|
|
2035
2070
|
}
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2071
|
+
deleteFile(path) {
|
|
2072
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2073
|
+
var _a;
|
|
2074
|
+
const currentUser = yield this.getCurrentUser();
|
|
2075
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
2076
|
+
const result = yield StorageApi.deleteFile({
|
|
2077
|
+
apiURI: this.config.apiURI,
|
|
2078
|
+
appId: this.config.appId,
|
|
2079
|
+
path,
|
|
2080
|
+
refreshToken: refreshToken,
|
|
2081
|
+
});
|
|
2082
|
+
return result;
|
|
2044
2083
|
});
|
|
2045
|
-
return result;
|
|
2046
2084
|
}
|
|
2047
2085
|
// Deprecated Storage API (Jan 2025)
|
|
2048
2086
|
// ---------------------------------
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2087
|
+
upload(path, file) {
|
|
2088
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2089
|
+
var _a;
|
|
2090
|
+
const currentUser = yield this.getCurrentUser();
|
|
2091
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
2092
|
+
const fileName = path || file.name;
|
|
2093
|
+
const url = yield StorageApi.getSignedUploadUrl({
|
|
2094
|
+
apiURI: this.config.apiURI,
|
|
2095
|
+
appId: this.config.appId,
|
|
2096
|
+
fileName: fileName,
|
|
2097
|
+
refreshToken: refreshToken,
|
|
2098
|
+
});
|
|
2099
|
+
const isSuccess = yield StorageApi.upload(url, file);
|
|
2100
|
+
return isSuccess;
|
|
2058
2101
|
});
|
|
2059
|
-
const isSuccess = await StorageApi.upload(url, file);
|
|
2060
|
-
return isSuccess;
|
|
2061
2102
|
}
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2103
|
+
getDownloadUrl(path) {
|
|
2104
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2105
|
+
var _a;
|
|
2106
|
+
const currentUser = yield this.getCurrentUser();
|
|
2107
|
+
const refreshToken = (_a = currentUser === null || currentUser === void 0 ? void 0 : currentUser.user) === null || _a === void 0 ? void 0 : _a.refresh_token;
|
|
2108
|
+
const url = yield StorageApi.getDownloadUrl({
|
|
2109
|
+
apiURI: this.config.apiURI,
|
|
2110
|
+
appId: this.config.appId,
|
|
2111
|
+
path: path,
|
|
2112
|
+
refreshToken: refreshToken,
|
|
2113
|
+
});
|
|
2114
|
+
return url;
|
|
2070
2115
|
});
|
|
2071
|
-
return url;
|
|
2072
2116
|
}
|
|
2073
2117
|
}
|
|
2074
2118
|
//# sourceMappingURL=Reactor.js.map
|