dexie-cloud-addon 4.0.1-beta.34 → 4.0.1-beta.36
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/modern/dexie-cloud-addon.js +111 -31
- package/dist/modern/dexie-cloud-addon.js.map +1 -1
- package/dist/modern/dexie-cloud-addon.min.js +1 -1
- package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
- package/dist/modern/service-worker.js +110 -30
- package/dist/modern/service-worker.js.map +1 -1
- package/dist/modern/service-worker.min.js +1 -1
- package/dist/modern/service-worker.min.js.map +1 -1
- package/dist/module-es5/dexie-cloud-addon.js +128 -45
- package/dist/module-es5/dexie-cloud-addon.js.map +1 -1
- package/dist/module-es5/dexie-cloud-addon.min.js +1 -1
- package/dist/module-es5/dexie-cloud-addon.min.js.map +1 -1
- package/dist/types/DexieCloudAPI.d.ts +3 -0
- package/dist/types/authentication/login.d.ts +1 -1
- package/dist/types/db/DexieCloudDB.d.ts +3 -2
- package/dist/types/sync/getTablesToSyncify.d.ts +1 -1
- package/dist/umd/dexie-cloud-addon.js +128 -45
- package/dist/umd/dexie-cloud-addon.js.map +1 -1
- package/dist/umd/dexie-cloud-addon.min.js +1 -1
- package/dist/umd/dexie-cloud-addon.min.js.map +1 -1
- package/dist/umd/service-worker.js +110 -30
- package/dist/umd/service-worker.js.map +1 -1
- package/dist/umd/service-worker.min.js +1 -1
- package/dist/umd/service-worker.min.js.map +1 -1
- package/dist/umd-modern/dexie-cloud-addon.js +108 -28
- package/dist/umd-modern/dexie-cloud-addon.js.map +1 -1
- package/dist/umd-modern/dexie-cloud-addon.min.js +1 -1
- package/dist/umd-modern/dexie-cloud-addon.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
var Dexie__default = /*#__PURE__*/_interopDefaultLegacy(Dexie);
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/******************************************************************************
|
|
12
12
|
Copyright (c) Microsoft Corporation.
|
|
13
13
|
|
|
14
14
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
ar[i] = from[i];
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
|
-
return to.concat(ar || from);
|
|
116
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
function __await(v) {
|
|
@@ -210,6 +210,36 @@
|
|
|
210
210
|
}
|
|
211
211
|
}
|
|
212
212
|
|
|
213
|
+
const events = globalThis['lbc-events'] || (globalThis['lbc-events'] = new Map());
|
|
214
|
+
function addListener(name, listener) {
|
|
215
|
+
if (events.has(name)) {
|
|
216
|
+
events.get(name).push(listener);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
events.set(name, [listener]);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
function removeListener(name, listener) {
|
|
223
|
+
const listeners = events.get(name);
|
|
224
|
+
if (listeners) {
|
|
225
|
+
const idx = listeners.indexOf(listener);
|
|
226
|
+
if (idx !== -1) {
|
|
227
|
+
listeners.splice(idx, 1);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
function dispatch(ev) {
|
|
232
|
+
const listeners = events.get(ev.type);
|
|
233
|
+
if (listeners) {
|
|
234
|
+
listeners.forEach(listener => {
|
|
235
|
+
try {
|
|
236
|
+
listener(ev);
|
|
237
|
+
}
|
|
238
|
+
catch (_a) {
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
213
243
|
class BroadcastedAndLocalEvent extends rxjs.Observable {
|
|
214
244
|
constructor(name) {
|
|
215
245
|
const bc = typeof BroadcastChannel === "undefined"
|
|
@@ -223,16 +253,24 @@
|
|
|
223
253
|
subscriber.next(ev.data);
|
|
224
254
|
}
|
|
225
255
|
let unsubscribe;
|
|
226
|
-
self.addEventListener(`lbc-${name}`, onCustomEvent);
|
|
227
|
-
|
|
228
|
-
|
|
256
|
+
//self.addEventListener(`lbc-${name}`, onCustomEvent); // Fails in service workers
|
|
257
|
+
addListener(`lbc-${name}`, onCustomEvent); // Works better in service worker
|
|
258
|
+
try {
|
|
259
|
+
if (bc instanceof SWBroadcastChannel) {
|
|
260
|
+
unsubscribe = bc.subscribe(message => subscriber.next(message));
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
console.debug("BroadcastedAndLocalEvent: bc.addEventListener()", name, "bc is a", bc);
|
|
264
|
+
bc.addEventListener("message", onMessageEvent);
|
|
265
|
+
}
|
|
229
266
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
267
|
+
catch (err) {
|
|
268
|
+
// Service workers might fail to subscribe outside its initial script.
|
|
269
|
+
console.warn('Failed to subscribe to broadcast channel', err);
|
|
233
270
|
}
|
|
234
271
|
return () => {
|
|
235
|
-
self.removeEventListener(`lbc-${name}`, onCustomEvent);
|
|
272
|
+
//self.removeEventListener(`lbc-${name}`, onCustomEvent);
|
|
273
|
+
removeListener(`lbc-${name}`, onCustomEvent);
|
|
236
274
|
if (bc instanceof SWBroadcastChannel) {
|
|
237
275
|
unsubscribe();
|
|
238
276
|
}
|
|
@@ -248,7 +286,8 @@
|
|
|
248
286
|
console.debug("BroadcastedAndLocalEvent: bc.postMessage()", Object.assign({}, message), "bc is a", this.bc);
|
|
249
287
|
this.bc.postMessage(message);
|
|
250
288
|
const ev = new CustomEvent(`lbc-${this.name}`, { detail: message });
|
|
251
|
-
self.dispatchEvent(ev);
|
|
289
|
+
//self.dispatchEvent(ev);
|
|
290
|
+
dispatch(ev);
|
|
252
291
|
}
|
|
253
292
|
}
|
|
254
293
|
|
|
@@ -1096,7 +1135,6 @@
|
|
|
1096
1135
|
return _this;
|
|
1097
1136
|
}
|
|
1098
1137
|
AsyncAction.prototype.schedule = function (state, delay) {
|
|
1099
|
-
var _a;
|
|
1100
1138
|
if (delay === void 0) { delay = 0; }
|
|
1101
1139
|
if (this.closed) {
|
|
1102
1140
|
return this;
|
|
@@ -1109,7 +1147,7 @@
|
|
|
1109
1147
|
}
|
|
1110
1148
|
this.pending = true;
|
|
1111
1149
|
this.delay = delay;
|
|
1112
|
-
this.id =
|
|
1150
|
+
this.id = this.id || this.requestAsyncId(scheduler, this.id, delay);
|
|
1113
1151
|
return this;
|
|
1114
1152
|
};
|
|
1115
1153
|
AsyncAction.prototype.requestAsyncId = function (scheduler, _id, delay) {
|
|
@@ -1121,9 +1159,7 @@
|
|
|
1121
1159
|
if (delay != null && this.delay === delay && this.pending === false) {
|
|
1122
1160
|
return id;
|
|
1123
1161
|
}
|
|
1124
|
-
|
|
1125
|
-
intervalProvider.clearInterval(id);
|
|
1126
|
-
}
|
|
1162
|
+
intervalProvider.clearInterval(id);
|
|
1127
1163
|
return undefined;
|
|
1128
1164
|
};
|
|
1129
1165
|
AsyncAction.prototype.execute = function (state, delay) {
|
|
@@ -1199,6 +1235,7 @@
|
|
|
1199
1235
|
var _this = _super.call(this, SchedulerAction, now) || this;
|
|
1200
1236
|
_this.actions = [];
|
|
1201
1237
|
_this._active = false;
|
|
1238
|
+
_this._scheduled = undefined;
|
|
1202
1239
|
return _this;
|
|
1203
1240
|
}
|
|
1204
1241
|
AsyncScheduler.prototype.flush = function (action) {
|
|
@@ -1608,7 +1645,7 @@
|
|
|
1608
1645
|
return concat$1(subscriptionDelay.pipe(take(1), ignoreElements()), source.pipe(delayWhen(delayDurationSelector)));
|
|
1609
1646
|
};
|
|
1610
1647
|
}
|
|
1611
|
-
return mergeMap(function (value, index) { return
|
|
1648
|
+
return mergeMap(function (value, index) { return delayDurationSelector(value, index).pipe(take(1), mapTo(value)); });
|
|
1612
1649
|
}
|
|
1613
1650
|
|
|
1614
1651
|
function delay(due, scheduler) {
|
|
@@ -2492,6 +2529,14 @@
|
|
|
2492
2529
|
}
|
|
2493
2530
|
function userAuthenticate(context, fetchToken, userInteraction, hints) {
|
|
2494
2531
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2532
|
+
if (!crypto.subtle) {
|
|
2533
|
+
if (typeof location !== 'undefined' && location.protocol === 'http:') {
|
|
2534
|
+
throw new Error(`Dexie Cloud Addon needs to use WebCrypto, but your browser has disabled it due to being served from an insecure location. Please serve it from https or http://localhost:<port> (See https://stackoverflow.com/questions/46670556/how-to-enable-crypto-subtle-for-unsecure-origins-in-chrome/46671627#46671627)`);
|
|
2535
|
+
}
|
|
2536
|
+
else {
|
|
2537
|
+
throw new Error(`This browser does not support WebCrypto.`);
|
|
2538
|
+
}
|
|
2539
|
+
}
|
|
2495
2540
|
const { privateKey, publicKey } = yield crypto.subtle.generateKey({
|
|
2496
2541
|
name: 'RSASSA-PKCS1-v1_5',
|
|
2497
2542
|
modulusLength: 2048,
|
|
@@ -2537,7 +2582,7 @@
|
|
|
2537
2582
|
type: 'error',
|
|
2538
2583
|
messageCode: 'GENERIC_ERROR',
|
|
2539
2584
|
message: `We're having a problem authenticating right now.`,
|
|
2540
|
-
messageParams: {}
|
|
2585
|
+
messageParams: {},
|
|
2541
2586
|
}).catch(() => { });
|
|
2542
2587
|
throw error;
|
|
2543
2588
|
}
|
|
@@ -3390,7 +3435,7 @@
|
|
|
3390
3435
|
return _sync
|
|
3391
3436
|
.apply(this, arguments)
|
|
3392
3437
|
.then(() => {
|
|
3393
|
-
if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) {
|
|
3438
|
+
if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) { // && syncOptions?.purpose !== 'push') {
|
|
3394
3439
|
db.syncStateChangedEvent.next({
|
|
3395
3440
|
phase: 'in-sync',
|
|
3396
3441
|
});
|
|
@@ -3489,12 +3534,12 @@
|
|
|
3489
3534
|
}
|
|
3490
3535
|
return [clientChanges, syncState, baseRevs];
|
|
3491
3536
|
}));
|
|
3492
|
-
const
|
|
3537
|
+
const pushSyncIsNeeded = clientChangeSet.some((set) => set.muts.some((mut) => mut.keys.length > 0));
|
|
3493
3538
|
if (justCheckIfNeeded) {
|
|
3494
|
-
console.debug('Sync is needed:',
|
|
3495
|
-
return
|
|
3539
|
+
console.debug('Sync is needed:', pushSyncIsNeeded);
|
|
3540
|
+
return pushSyncIsNeeded;
|
|
3496
3541
|
}
|
|
3497
|
-
if (purpose === 'push' && !
|
|
3542
|
+
if (purpose === 'push' && !pushSyncIsNeeded) {
|
|
3498
3543
|
// The purpose of this request was to push changes
|
|
3499
3544
|
return false;
|
|
3500
3545
|
}
|
|
@@ -3612,6 +3657,7 @@
|
|
|
3612
3657
|
return yield _sync(db, options, schema, { isInitialSync, cancelToken });
|
|
3613
3658
|
}
|
|
3614
3659
|
console.debug('SYNC DONE', { isInitialSync });
|
|
3660
|
+
db.syncCompleteEvent.next();
|
|
3615
3661
|
return false; // Not needed anymore
|
|
3616
3662
|
});
|
|
3617
3663
|
}
|
|
@@ -3891,6 +3937,7 @@
|
|
|
3891
3937
|
if (!db) {
|
|
3892
3938
|
const localSyncEvent = new rxjs.Subject();
|
|
3893
3939
|
let syncStateChangedEvent = new BroadcastedAndLocalEvent(`syncstatechanged-${dx.name}`);
|
|
3940
|
+
let syncCompleteEvent = new BroadcastedAndLocalEvent(`synccomplete-${dx.name}`);
|
|
3894
3941
|
localSyncEvent['id'] = ++static_counter;
|
|
3895
3942
|
let initiallySynced = false;
|
|
3896
3943
|
db = {
|
|
@@ -3934,6 +3981,9 @@
|
|
|
3934
3981
|
get syncStateChangedEvent() {
|
|
3935
3982
|
return syncStateChangedEvent;
|
|
3936
3983
|
},
|
|
3984
|
+
get syncCompleteEvent() {
|
|
3985
|
+
return syncCompleteEvent;
|
|
3986
|
+
},
|
|
3937
3987
|
dx,
|
|
3938
3988
|
};
|
|
3939
3989
|
const helperMethods = {
|
|
@@ -3965,6 +4015,7 @@
|
|
|
3965
4015
|
},
|
|
3966
4016
|
reconfigure() {
|
|
3967
4017
|
syncStateChangedEvent = new BroadcastedAndLocalEvent(`syncstatechanged-${dx.name}`);
|
|
4018
|
+
syncCompleteEvent = new BroadcastedAndLocalEvent(`synccomplete-${dx.name}`);
|
|
3968
4019
|
},
|
|
3969
4020
|
};
|
|
3970
4021
|
Object.assign(db, helperMethods);
|
|
@@ -4179,18 +4230,32 @@
|
|
|
4179
4230
|
}
|
|
4180
4231
|
}
|
|
4181
4232
|
// Already authenticated according to given hints.
|
|
4182
|
-
return;
|
|
4233
|
+
return false;
|
|
4183
4234
|
}
|
|
4184
4235
|
const context = new AuthPersistedContext(db, {
|
|
4185
4236
|
claims: {},
|
|
4186
4237
|
lastLogin: new Date(0),
|
|
4187
4238
|
});
|
|
4188
4239
|
yield authenticate(db.cloud.options.databaseUrl, context, db.cloud.options.fetchTokens || otpFetchTokenCallback(db), db.cloud.userInteraction, hints);
|
|
4189
|
-
|
|
4240
|
+
try {
|
|
4241
|
+
yield context.save();
|
|
4242
|
+
}
|
|
4243
|
+
catch (e) {
|
|
4244
|
+
try {
|
|
4245
|
+
if (e.name === 'DataCloneError') {
|
|
4246
|
+
console.debug(`Login context property names:`, Object.keys(context));
|
|
4247
|
+
console.debug(`Login context:`, context);
|
|
4248
|
+
console.debug(`Login context JSON:`, JSON.stringify(context));
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
catch (_a) { }
|
|
4252
|
+
throw e;
|
|
4253
|
+
}
|
|
4190
4254
|
yield setCurrentUser(db, context);
|
|
4191
4255
|
// Make sure to resync as the new login will be authorized
|
|
4192
4256
|
// for new realms.
|
|
4193
4257
|
triggerSync(db, "pull");
|
|
4258
|
+
return true;
|
|
4194
4259
|
});
|
|
4195
4260
|
}
|
|
4196
4261
|
|
|
@@ -5083,7 +5148,15 @@
|
|
|
5083
5148
|
function createObservable() {
|
|
5084
5149
|
return db.cloud.persistedSyncState.pipe(filter((syncState) => syncState === null || syncState === void 0 ? void 0 : syncState.serverRevision), // Don't connect before there's no initial sync performed.
|
|
5085
5150
|
take(1), // Don't continue waking up whenever syncState change
|
|
5086
|
-
switchMap((syncState) => db.cloud.currentUser.pipe(map((userLogin) => [userLogin, syncState]))), switchMap(([userLogin, syncState]) => userIsReallyActive.pipe(map((isActive) => [isActive ? userLogin : null, syncState]))), switchMap(([userLogin, syncState]) =>
|
|
5151
|
+
switchMap((syncState) => db.cloud.currentUser.pipe(map((userLogin) => [userLogin, syncState]))), switchMap(([userLogin, syncState]) => userIsReallyActive.pipe(map((isActive) => [isActive ? userLogin : null, syncState]))), switchMap(([userLogin, syncState]) => {
|
|
5152
|
+
if ((userLogin === null || userLogin === void 0 ? void 0 : userLogin.isLoggedIn) && !(syncState === null || syncState === void 0 ? void 0 : syncState.realms.includes(userLogin.userId))) {
|
|
5153
|
+
// We're in an in-between state when user is logged in but the user's realms are not yet synced.
|
|
5154
|
+
// Don't make this change reconnect the websocket just yet. Wait till syncState is updated
|
|
5155
|
+
// to iclude the user's realm.
|
|
5156
|
+
return db.cloud.persistedSyncState.pipe(filter((syncState) => (syncState === null || syncState === void 0 ? void 0 : syncState.realms.includes(userLogin.userId)) || false), take(1), map((syncState) => [userLogin, syncState]));
|
|
5157
|
+
}
|
|
5158
|
+
return new rxjs.BehaviorSubject([userLogin, syncState]);
|
|
5159
|
+
}), switchMap(([userLogin, syncState]) => __awaiter(this, void 0, void 0, function* () { return [userLogin, yield computeRealmSetHash(syncState)]; })), switchMap(([userLogin, realmSetHash]) =>
|
|
5087
5160
|
// Let server end query changes from last entry of same client-ID and forward.
|
|
5088
5161
|
// If no new entries, server won't bother the client. If new entries, server sends only those
|
|
5089
5162
|
// and the baseRev of the last from same client-ID.
|
|
@@ -5945,8 +6018,9 @@
|
|
|
5945
6018
|
localSyncWorker = null;
|
|
5946
6019
|
currentUserEmitter.next(UNAUTHORIZED_USER);
|
|
5947
6020
|
});
|
|
6021
|
+
const syncComplete = new rxjs.Subject();
|
|
5948
6022
|
dexie.cloud = {
|
|
5949
|
-
version: '4.0.1-beta.
|
|
6023
|
+
version: '4.0.1-beta.36',
|
|
5950
6024
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
5951
6025
|
schema: null,
|
|
5952
6026
|
get currentUserId() {
|
|
@@ -5957,6 +6031,9 @@
|
|
|
5957
6031
|
phase: 'initial',
|
|
5958
6032
|
status: 'not-started',
|
|
5959
6033
|
}),
|
|
6034
|
+
events: {
|
|
6035
|
+
syncComplete,
|
|
6036
|
+
},
|
|
5960
6037
|
persistedSyncState: new rxjs.BehaviorSubject(undefined),
|
|
5961
6038
|
userInteraction: new rxjs.BehaviorSubject(undefined),
|
|
5962
6039
|
webSocketStatus: new rxjs.BehaviorSubject('not-started'),
|
|
@@ -6050,6 +6127,8 @@
|
|
|
6050
6127
|
if (!db.cloud.isServiceWorkerDB) {
|
|
6051
6128
|
subscriptions.push(computeSyncState(db).subscribe(dexie.cloud.syncState));
|
|
6052
6129
|
}
|
|
6130
|
+
// Forward db.syncCompleteEvent to be publicly consumable via db.cloud.events.syncComplete:
|
|
6131
|
+
subscriptions.push(db.syncCompleteEvent.subscribe(syncComplete));
|
|
6053
6132
|
//verifyConfig(db.cloud.options); Not needed (yet at least!)
|
|
6054
6133
|
// Verify the user has allowed version increment.
|
|
6055
6134
|
if (!db.tables.every((table) => table.core)) {
|
|
@@ -6157,15 +6236,16 @@
|
|
|
6157
6236
|
]).toPromise();
|
|
6158
6237
|
}
|
|
6159
6238
|
// HERE: If requireAuth, do athentication now.
|
|
6239
|
+
let changedUser = false;
|
|
6160
6240
|
if ((_c = db.cloud.options) === null || _c === void 0 ? void 0 : _c.requireAuth) {
|
|
6161
|
-
yield login(db);
|
|
6241
|
+
changedUser = yield login(db);
|
|
6162
6242
|
}
|
|
6163
6243
|
if (localSyncWorker)
|
|
6164
6244
|
localSyncWorker.stop();
|
|
6165
6245
|
localSyncWorker = null;
|
|
6166
6246
|
throwIfClosed();
|
|
6167
6247
|
if (db.cloud.usingServiceWorker && ((_d = db.cloud.options) === null || _d === void 0 ? void 0 : _d.databaseUrl)) {
|
|
6168
|
-
registerSyncEvent(db, 'push').catch(() => { });
|
|
6248
|
+
registerSyncEvent(db, changedUser ? 'pull' : 'push').catch(() => { });
|
|
6169
6249
|
registerPeriodicSyncEvent(db).catch(() => { });
|
|
6170
6250
|
}
|
|
6171
6251
|
else if (((_e = db.cloud.options) === null || _e === void 0 ? void 0 : _e.databaseUrl) &&
|
|
@@ -6174,7 +6254,7 @@
|
|
|
6174
6254
|
// There's no SW. Start SyncWorker instead.
|
|
6175
6255
|
localSyncWorker = LocalSyncWorker(db, db.cloud.options, db.cloud.schema);
|
|
6176
6256
|
localSyncWorker.start();
|
|
6177
|
-
triggerSync(db, 'push');
|
|
6257
|
+
triggerSync(db, changedUser ? 'pull' : 'push');
|
|
6178
6258
|
}
|
|
6179
6259
|
// Listen to online event and do sync.
|
|
6180
6260
|
throwIfClosed();
|
|
@@ -6201,7 +6281,7 @@
|
|
|
6201
6281
|
});
|
|
6202
6282
|
}
|
|
6203
6283
|
}
|
|
6204
|
-
dexieCloud.version = '4.0.1-beta.
|
|
6284
|
+
dexieCloud.version = '4.0.1-beta.36';
|
|
6205
6285
|
Dexie__default["default"].Cloud = dexieCloud;
|
|
6206
6286
|
|
|
6207
6287
|
// In case the SW lives for a while, let it reuse already opened connections:
|