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
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
|
|
27
27
|
var Dexie__default = /*#__PURE__*/_interopDefaultLegacy(Dexie);
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
/******************************************************************************
|
|
30
30
|
Copyright (c) Microsoft Corporation.
|
|
31
31
|
|
|
32
32
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
ar[i] = from[i];
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
|
-
return to.concat(ar || from);
|
|
134
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
function __await(v) {
|
|
@@ -1306,7 +1306,6 @@
|
|
|
1306
1306
|
return _this;
|
|
1307
1307
|
}
|
|
1308
1308
|
AsyncAction.prototype.schedule = function (state, delay) {
|
|
1309
|
-
var _a;
|
|
1310
1309
|
if (delay === void 0) { delay = 0; }
|
|
1311
1310
|
if (this.closed) {
|
|
1312
1311
|
return this;
|
|
@@ -1319,7 +1318,7 @@
|
|
|
1319
1318
|
}
|
|
1320
1319
|
this.pending = true;
|
|
1321
1320
|
this.delay = delay;
|
|
1322
|
-
this.id =
|
|
1321
|
+
this.id = this.id || this.requestAsyncId(scheduler, this.id, delay);
|
|
1323
1322
|
return this;
|
|
1324
1323
|
};
|
|
1325
1324
|
AsyncAction.prototype.requestAsyncId = function (scheduler, _id, delay) {
|
|
@@ -1331,9 +1330,7 @@
|
|
|
1331
1330
|
if (delay != null && this.delay === delay && this.pending === false) {
|
|
1332
1331
|
return id;
|
|
1333
1332
|
}
|
|
1334
|
-
|
|
1335
|
-
intervalProvider.clearInterval(id);
|
|
1336
|
-
}
|
|
1333
|
+
intervalProvider.clearInterval(id);
|
|
1337
1334
|
return undefined;
|
|
1338
1335
|
};
|
|
1339
1336
|
AsyncAction.prototype.execute = function (state, delay) {
|
|
@@ -1409,6 +1406,7 @@
|
|
|
1409
1406
|
var _this = _super.call(this, SchedulerAction, now) || this;
|
|
1410
1407
|
_this.actions = [];
|
|
1411
1408
|
_this._active = false;
|
|
1409
|
+
_this._scheduled = undefined;
|
|
1412
1410
|
return _this;
|
|
1413
1411
|
}
|
|
1414
1412
|
AsyncScheduler.prototype.flush = function (action) {
|
|
@@ -1818,7 +1816,7 @@
|
|
|
1818
1816
|
return concat$1(subscriptionDelay.pipe(take(1), ignoreElements()), source.pipe(delayWhen(delayDurationSelector)));
|
|
1819
1817
|
};
|
|
1820
1818
|
}
|
|
1821
|
-
return mergeMap(function (value, index) { return
|
|
1819
|
+
return mergeMap(function (value, index) { return delayDurationSelector(value, index).pipe(take(1), mapTo(value)); });
|
|
1822
1820
|
}
|
|
1823
1821
|
|
|
1824
1822
|
function delay(due, scheduler) {
|
|
@@ -2235,6 +2233,14 @@
|
|
|
2235
2233
|
}
|
|
2236
2234
|
function userAuthenticate(context, fetchToken, userInteraction, hints) {
|
|
2237
2235
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2236
|
+
if (!crypto.subtle) {
|
|
2237
|
+
if (typeof location !== 'undefined' && location.protocol === 'http:') {
|
|
2238
|
+
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)`);
|
|
2239
|
+
}
|
|
2240
|
+
else {
|
|
2241
|
+
throw new Error(`This browser does not support WebCrypto.`);
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2238
2244
|
const { privateKey, publicKey } = yield crypto.subtle.generateKey({
|
|
2239
2245
|
name: 'RSASSA-PKCS1-v1_5',
|
|
2240
2246
|
modulusLength: 2048,
|
|
@@ -2280,7 +2286,7 @@
|
|
|
2280
2286
|
type: 'error',
|
|
2281
2287
|
messageCode: 'GENERIC_ERROR',
|
|
2282
2288
|
message: `We're having a problem authenticating right now.`,
|
|
2283
|
-
messageParams: {}
|
|
2289
|
+
messageParams: {},
|
|
2284
2290
|
}).catch(() => { });
|
|
2285
2291
|
throw error;
|
|
2286
2292
|
}
|
|
@@ -2511,18 +2517,32 @@
|
|
|
2511
2517
|
}
|
|
2512
2518
|
}
|
|
2513
2519
|
// Already authenticated according to given hints.
|
|
2514
|
-
return;
|
|
2520
|
+
return false;
|
|
2515
2521
|
}
|
|
2516
2522
|
const context = new AuthPersistedContext(db, {
|
|
2517
2523
|
claims: {},
|
|
2518
2524
|
lastLogin: new Date(0),
|
|
2519
2525
|
});
|
|
2520
2526
|
yield authenticate(db.cloud.options.databaseUrl, context, db.cloud.options.fetchTokens || otpFetchTokenCallback(db), db.cloud.userInteraction, hints);
|
|
2521
|
-
|
|
2527
|
+
try {
|
|
2528
|
+
yield context.save();
|
|
2529
|
+
}
|
|
2530
|
+
catch (e) {
|
|
2531
|
+
try {
|
|
2532
|
+
if (e.name === 'DataCloneError') {
|
|
2533
|
+
console.debug(`Login context property names:`, Object.keys(context));
|
|
2534
|
+
console.debug(`Login context:`, context);
|
|
2535
|
+
console.debug(`Login context JSON:`, JSON.stringify(context));
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
catch (_a) { }
|
|
2539
|
+
throw e;
|
|
2540
|
+
}
|
|
2522
2541
|
yield setCurrentUser(db, context);
|
|
2523
2542
|
// Make sure to resync as the new login will be authorized
|
|
2524
2543
|
// for new realms.
|
|
2525
2544
|
triggerSync(db, "pull");
|
|
2545
|
+
return true;
|
|
2526
2546
|
});
|
|
2527
2547
|
}
|
|
2528
2548
|
|
|
@@ -2596,6 +2616,36 @@
|
|
|
2596
2616
|
}
|
|
2597
2617
|
}
|
|
2598
2618
|
|
|
2619
|
+
const events = globalThis['lbc-events'] || (globalThis['lbc-events'] = new Map());
|
|
2620
|
+
function addListener(name, listener) {
|
|
2621
|
+
if (events.has(name)) {
|
|
2622
|
+
events.get(name).push(listener);
|
|
2623
|
+
}
|
|
2624
|
+
else {
|
|
2625
|
+
events.set(name, [listener]);
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
function removeListener(name, listener) {
|
|
2629
|
+
const listeners = events.get(name);
|
|
2630
|
+
if (listeners) {
|
|
2631
|
+
const idx = listeners.indexOf(listener);
|
|
2632
|
+
if (idx !== -1) {
|
|
2633
|
+
listeners.splice(idx, 1);
|
|
2634
|
+
}
|
|
2635
|
+
}
|
|
2636
|
+
}
|
|
2637
|
+
function dispatch(ev) {
|
|
2638
|
+
const listeners = events.get(ev.type);
|
|
2639
|
+
if (listeners) {
|
|
2640
|
+
listeners.forEach(listener => {
|
|
2641
|
+
try {
|
|
2642
|
+
listener(ev);
|
|
2643
|
+
}
|
|
2644
|
+
catch (_a) {
|
|
2645
|
+
}
|
|
2646
|
+
});
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2599
2649
|
class BroadcastedAndLocalEvent extends rxjs.Observable {
|
|
2600
2650
|
constructor(name) {
|
|
2601
2651
|
const bc = typeof BroadcastChannel === "undefined"
|
|
@@ -2609,16 +2659,24 @@
|
|
|
2609
2659
|
subscriber.next(ev.data);
|
|
2610
2660
|
}
|
|
2611
2661
|
let unsubscribe;
|
|
2612
|
-
self.addEventListener(`lbc-${name}`, onCustomEvent);
|
|
2613
|
-
|
|
2614
|
-
|
|
2662
|
+
//self.addEventListener(`lbc-${name}`, onCustomEvent); // Fails in service workers
|
|
2663
|
+
addListener(`lbc-${name}`, onCustomEvent); // Works better in service worker
|
|
2664
|
+
try {
|
|
2665
|
+
if (bc instanceof SWBroadcastChannel) {
|
|
2666
|
+
unsubscribe = bc.subscribe(message => subscriber.next(message));
|
|
2667
|
+
}
|
|
2668
|
+
else {
|
|
2669
|
+
console.debug("BroadcastedAndLocalEvent: bc.addEventListener()", name, "bc is a", bc);
|
|
2670
|
+
bc.addEventListener("message", onMessageEvent);
|
|
2671
|
+
}
|
|
2615
2672
|
}
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2673
|
+
catch (err) {
|
|
2674
|
+
// Service workers might fail to subscribe outside its initial script.
|
|
2675
|
+
console.warn('Failed to subscribe to broadcast channel', err);
|
|
2619
2676
|
}
|
|
2620
2677
|
return () => {
|
|
2621
|
-
self.removeEventListener(`lbc-${name}`, onCustomEvent);
|
|
2678
|
+
//self.removeEventListener(`lbc-${name}`, onCustomEvent);
|
|
2679
|
+
removeListener(`lbc-${name}`, onCustomEvent);
|
|
2622
2680
|
if (bc instanceof SWBroadcastChannel) {
|
|
2623
2681
|
unsubscribe();
|
|
2624
2682
|
}
|
|
@@ -2634,7 +2692,8 @@
|
|
|
2634
2692
|
console.debug("BroadcastedAndLocalEvent: bc.postMessage()", Object.assign({}, message), "bc is a", this.bc);
|
|
2635
2693
|
this.bc.postMessage(message);
|
|
2636
2694
|
const ev = new CustomEvent(`lbc-${this.name}`, { detail: message });
|
|
2637
|
-
self.dispatchEvent(ev);
|
|
2695
|
+
//self.dispatchEvent(ev);
|
|
2696
|
+
dispatch(ev);
|
|
2638
2697
|
}
|
|
2639
2698
|
}
|
|
2640
2699
|
|
|
@@ -3623,7 +3682,7 @@
|
|
|
3623
3682
|
return _sync
|
|
3624
3683
|
.apply(this, arguments)
|
|
3625
3684
|
.then(() => {
|
|
3626
|
-
if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) {
|
|
3685
|
+
if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) { // && syncOptions?.purpose !== 'push') {
|
|
3627
3686
|
db.syncStateChangedEvent.next({
|
|
3628
3687
|
phase: 'in-sync',
|
|
3629
3688
|
});
|
|
@@ -3722,12 +3781,12 @@
|
|
|
3722
3781
|
}
|
|
3723
3782
|
return [clientChanges, syncState, baseRevs];
|
|
3724
3783
|
}));
|
|
3725
|
-
const
|
|
3784
|
+
const pushSyncIsNeeded = clientChangeSet.some((set) => set.muts.some((mut) => mut.keys.length > 0));
|
|
3726
3785
|
if (justCheckIfNeeded) {
|
|
3727
|
-
console.debug('Sync is needed:',
|
|
3728
|
-
return
|
|
3786
|
+
console.debug('Sync is needed:', pushSyncIsNeeded);
|
|
3787
|
+
return pushSyncIsNeeded;
|
|
3729
3788
|
}
|
|
3730
|
-
if (purpose === 'push' && !
|
|
3789
|
+
if (purpose === 'push' && !pushSyncIsNeeded) {
|
|
3731
3790
|
// The purpose of this request was to push changes
|
|
3732
3791
|
return false;
|
|
3733
3792
|
}
|
|
@@ -3845,6 +3904,7 @@
|
|
|
3845
3904
|
return yield _sync(db, options, schema, { isInitialSync, cancelToken });
|
|
3846
3905
|
}
|
|
3847
3906
|
console.debug('SYNC DONE', { isInitialSync });
|
|
3907
|
+
db.syncCompleteEvent.next();
|
|
3848
3908
|
return false; // Not needed anymore
|
|
3849
3909
|
});
|
|
3850
3910
|
}
|
|
@@ -4124,6 +4184,7 @@
|
|
|
4124
4184
|
if (!db) {
|
|
4125
4185
|
const localSyncEvent = new rxjs.Subject();
|
|
4126
4186
|
let syncStateChangedEvent = new BroadcastedAndLocalEvent(`syncstatechanged-${dx.name}`);
|
|
4187
|
+
let syncCompleteEvent = new BroadcastedAndLocalEvent(`synccomplete-${dx.name}`);
|
|
4127
4188
|
localSyncEvent['id'] = ++static_counter;
|
|
4128
4189
|
let initiallySynced = false;
|
|
4129
4190
|
db = {
|
|
@@ -4167,6 +4228,9 @@
|
|
|
4167
4228
|
get syncStateChangedEvent() {
|
|
4168
4229
|
return syncStateChangedEvent;
|
|
4169
4230
|
},
|
|
4231
|
+
get syncCompleteEvent() {
|
|
4232
|
+
return syncCompleteEvent;
|
|
4233
|
+
},
|
|
4170
4234
|
dx,
|
|
4171
4235
|
};
|
|
4172
4236
|
const helperMethods = {
|
|
@@ -4198,6 +4262,7 @@
|
|
|
4198
4262
|
},
|
|
4199
4263
|
reconfigure() {
|
|
4200
4264
|
syncStateChangedEvent = new BroadcastedAndLocalEvent(`syncstatechanged-${dx.name}`);
|
|
4265
|
+
syncCompleteEvent = new BroadcastedAndLocalEvent(`synccomplete-${dx.name}`);
|
|
4201
4266
|
},
|
|
4202
4267
|
};
|
|
4203
4268
|
Object.assign(db, helperMethods);
|
|
@@ -5101,7 +5166,15 @@
|
|
|
5101
5166
|
function createObservable() {
|
|
5102
5167
|
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.
|
|
5103
5168
|
take(1), // Don't continue waking up whenever syncState change
|
|
5104
|
-
switchMap((syncState) => db.cloud.currentUser.pipe(map((userLogin) => [userLogin, syncState]))), switchMap(([userLogin, syncState]) => userIsReallyActive.pipe(map((isActive) => [isActive ? userLogin : null, syncState]))), switchMap(([userLogin, syncState]) =>
|
|
5169
|
+
switchMap((syncState) => db.cloud.currentUser.pipe(map((userLogin) => [userLogin, syncState]))), switchMap(([userLogin, syncState]) => userIsReallyActive.pipe(map((isActive) => [isActive ? userLogin : null, syncState]))), switchMap(([userLogin, syncState]) => {
|
|
5170
|
+
if ((userLogin === null || userLogin === void 0 ? void 0 : userLogin.isLoggedIn) && !(syncState === null || syncState === void 0 ? void 0 : syncState.realms.includes(userLogin.userId))) {
|
|
5171
|
+
// We're in an in-between state when user is logged in but the user's realms are not yet synced.
|
|
5172
|
+
// Don't make this change reconnect the websocket just yet. Wait till syncState is updated
|
|
5173
|
+
// to iclude the user's realm.
|
|
5174
|
+
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]));
|
|
5175
|
+
}
|
|
5176
|
+
return new rxjs.BehaviorSubject([userLogin, syncState]);
|
|
5177
|
+
}), switchMap(([userLogin, syncState]) => __awaiter(this, void 0, void 0, function* () { return [userLogin, yield computeRealmSetHash(syncState)]; })), switchMap(([userLogin, realmSetHash]) =>
|
|
5105
5178
|
// Let server end query changes from last entry of same client-ID and forward.
|
|
5106
5179
|
// If no new entries, server won't bother the client. If new entries, server sends only those
|
|
5107
5180
|
// and the baseRev of the last from same client-ID.
|
|
@@ -5970,6 +6043,7 @@
|
|
|
5970
6043
|
localSyncWorker = null;
|
|
5971
6044
|
currentUserEmitter.next(UNAUTHORIZED_USER);
|
|
5972
6045
|
});
|
|
6046
|
+
const syncComplete = new rxjs.Subject();
|
|
5973
6047
|
dexie.cloud = {
|
|
5974
6048
|
version: '{version}',
|
|
5975
6049
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
@@ -5982,6 +6056,9 @@
|
|
|
5982
6056
|
phase: 'initial',
|
|
5983
6057
|
status: 'not-started',
|
|
5984
6058
|
}),
|
|
6059
|
+
events: {
|
|
6060
|
+
syncComplete,
|
|
6061
|
+
},
|
|
5985
6062
|
persistedSyncState: new rxjs.BehaviorSubject(undefined),
|
|
5986
6063
|
userInteraction: new rxjs.BehaviorSubject(undefined),
|
|
5987
6064
|
webSocketStatus: new rxjs.BehaviorSubject('not-started'),
|
|
@@ -6075,6 +6152,8 @@
|
|
|
6075
6152
|
if (!db.cloud.isServiceWorkerDB) {
|
|
6076
6153
|
subscriptions.push(computeSyncState(db).subscribe(dexie.cloud.syncState));
|
|
6077
6154
|
}
|
|
6155
|
+
// Forward db.syncCompleteEvent to be publicly consumable via db.cloud.events.syncComplete:
|
|
6156
|
+
subscriptions.push(db.syncCompleteEvent.subscribe(syncComplete));
|
|
6078
6157
|
//verifyConfig(db.cloud.options); Not needed (yet at least!)
|
|
6079
6158
|
// Verify the user has allowed version increment.
|
|
6080
6159
|
if (!db.tables.every((table) => table.core)) {
|
|
@@ -6182,15 +6261,16 @@
|
|
|
6182
6261
|
]).toPromise();
|
|
6183
6262
|
}
|
|
6184
6263
|
// HERE: If requireAuth, do athentication now.
|
|
6264
|
+
let changedUser = false;
|
|
6185
6265
|
if ((_c = db.cloud.options) === null || _c === void 0 ? void 0 : _c.requireAuth) {
|
|
6186
|
-
yield login(db);
|
|
6266
|
+
changedUser = yield login(db);
|
|
6187
6267
|
}
|
|
6188
6268
|
if (localSyncWorker)
|
|
6189
6269
|
localSyncWorker.stop();
|
|
6190
6270
|
localSyncWorker = null;
|
|
6191
6271
|
throwIfClosed();
|
|
6192
6272
|
if (db.cloud.usingServiceWorker && ((_d = db.cloud.options) === null || _d === void 0 ? void 0 : _d.databaseUrl)) {
|
|
6193
|
-
registerSyncEvent(db, 'push').catch(() => { });
|
|
6273
|
+
registerSyncEvent(db, changedUser ? 'pull' : 'push').catch(() => { });
|
|
6194
6274
|
registerPeriodicSyncEvent(db).catch(() => { });
|
|
6195
6275
|
}
|
|
6196
6276
|
else if (((_e = db.cloud.options) === null || _e === void 0 ? void 0 : _e.databaseUrl) &&
|
|
@@ -6199,7 +6279,7 @@
|
|
|
6199
6279
|
// There's no SW. Start SyncWorker instead.
|
|
6200
6280
|
localSyncWorker = LocalSyncWorker(db, db.cloud.options, db.cloud.schema);
|
|
6201
6281
|
localSyncWorker.start();
|
|
6202
|
-
triggerSync(db, 'push');
|
|
6282
|
+
triggerSync(db, changedUser ? 'pull' : 'push');
|
|
6203
6283
|
}
|
|
6204
6284
|
// Listen to online event and do sync.
|
|
6205
6285
|
throwIfClosed();
|