dexie-cloud-addon 4.0.1-beta.35 → 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.
@@ -2517,7 +2517,7 @@
2517
2517
  }
2518
2518
  }
2519
2519
  // Already authenticated according to given hints.
2520
- return;
2520
+ return false;
2521
2521
  }
2522
2522
  const context = new AuthPersistedContext(db, {
2523
2523
  claims: {},
@@ -2542,6 +2542,7 @@
2542
2542
  // Make sure to resync as the new login will be authorized
2543
2543
  // for new realms.
2544
2544
  triggerSync(db, "pull");
2545
+ return true;
2545
2546
  });
2546
2547
  }
2547
2548
 
@@ -2615,6 +2616,36 @@
2615
2616
  }
2616
2617
  }
2617
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
+ }
2618
2649
  class BroadcastedAndLocalEvent extends rxjs.Observable {
2619
2650
  constructor(name) {
2620
2651
  const bc = typeof BroadcastChannel === "undefined"
@@ -2628,16 +2659,24 @@
2628
2659
  subscriber.next(ev.data);
2629
2660
  }
2630
2661
  let unsubscribe;
2631
- self.addEventListener(`lbc-${name}`, onCustomEvent);
2632
- if (bc instanceof SWBroadcastChannel) {
2633
- unsubscribe = bc.subscribe(message => subscriber.next(message));
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
+ }
2634
2672
  }
2635
- else {
2636
- console.debug("BroadcastedAndLocalEvent: bc.addEventListener()", name, "bc is a", bc);
2637
- bc.addEventListener("message", onMessageEvent);
2673
+ catch (err) {
2674
+ // Service workers might fail to subscribe outside its initial script.
2675
+ console.warn('Failed to subscribe to broadcast channel', err);
2638
2676
  }
2639
2677
  return () => {
2640
- self.removeEventListener(`lbc-${name}`, onCustomEvent);
2678
+ //self.removeEventListener(`lbc-${name}`, onCustomEvent);
2679
+ removeListener(`lbc-${name}`, onCustomEvent);
2641
2680
  if (bc instanceof SWBroadcastChannel) {
2642
2681
  unsubscribe();
2643
2682
  }
@@ -2653,7 +2692,8 @@
2653
2692
  console.debug("BroadcastedAndLocalEvent: bc.postMessage()", Object.assign({}, message), "bc is a", this.bc);
2654
2693
  this.bc.postMessage(message);
2655
2694
  const ev = new CustomEvent(`lbc-${this.name}`, { detail: message });
2656
- self.dispatchEvent(ev);
2695
+ //self.dispatchEvent(ev);
2696
+ dispatch(ev);
2657
2697
  }
2658
2698
  }
2659
2699
 
@@ -3642,7 +3682,7 @@
3642
3682
  return _sync
3643
3683
  .apply(this, arguments)
3644
3684
  .then(() => {
3645
- if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) {
3685
+ if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) { // && syncOptions?.purpose !== 'push') {
3646
3686
  db.syncStateChangedEvent.next({
3647
3687
  phase: 'in-sync',
3648
3688
  });
@@ -3741,12 +3781,12 @@
3741
3781
  }
3742
3782
  return [clientChanges, syncState, baseRevs];
3743
3783
  }));
3744
- const syncIsNeeded = clientChangeSet.some((set) => set.muts.some((mut) => mut.keys.length > 0));
3784
+ const pushSyncIsNeeded = clientChangeSet.some((set) => set.muts.some((mut) => mut.keys.length > 0));
3745
3785
  if (justCheckIfNeeded) {
3746
- console.debug('Sync is needed:', syncIsNeeded);
3747
- return syncIsNeeded;
3786
+ console.debug('Sync is needed:', pushSyncIsNeeded);
3787
+ return pushSyncIsNeeded;
3748
3788
  }
3749
- if (purpose === 'push' && !syncIsNeeded) {
3789
+ if (purpose === 'push' && !pushSyncIsNeeded) {
3750
3790
  // The purpose of this request was to push changes
3751
3791
  return false;
3752
3792
  }
@@ -3864,6 +3904,7 @@
3864
3904
  return yield _sync(db, options, schema, { isInitialSync, cancelToken });
3865
3905
  }
3866
3906
  console.debug('SYNC DONE', { isInitialSync });
3907
+ db.syncCompleteEvent.next();
3867
3908
  return false; // Not needed anymore
3868
3909
  });
3869
3910
  }
@@ -4143,6 +4184,7 @@
4143
4184
  if (!db) {
4144
4185
  const localSyncEvent = new rxjs.Subject();
4145
4186
  let syncStateChangedEvent = new BroadcastedAndLocalEvent(`syncstatechanged-${dx.name}`);
4187
+ let syncCompleteEvent = new BroadcastedAndLocalEvent(`synccomplete-${dx.name}`);
4146
4188
  localSyncEvent['id'] = ++static_counter;
4147
4189
  let initiallySynced = false;
4148
4190
  db = {
@@ -4186,6 +4228,9 @@
4186
4228
  get syncStateChangedEvent() {
4187
4229
  return syncStateChangedEvent;
4188
4230
  },
4231
+ get syncCompleteEvent() {
4232
+ return syncCompleteEvent;
4233
+ },
4189
4234
  dx,
4190
4235
  };
4191
4236
  const helperMethods = {
@@ -4217,6 +4262,7 @@
4217
4262
  },
4218
4263
  reconfigure() {
4219
4264
  syncStateChangedEvent = new BroadcastedAndLocalEvent(`syncstatechanged-${dx.name}`);
4265
+ syncCompleteEvent = new BroadcastedAndLocalEvent(`synccomplete-${dx.name}`);
4220
4266
  },
4221
4267
  };
4222
4268
  Object.assign(db, helperMethods);
@@ -5120,7 +5166,15 @@
5120
5166
  function createObservable() {
5121
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.
5122
5168
  take(1), // Don't continue waking up whenever syncState change
5123
- switchMap((syncState) => db.cloud.currentUser.pipe(map((userLogin) => [userLogin, syncState]))), switchMap(([userLogin, syncState]) => userIsReallyActive.pipe(map((isActive) => [isActive ? userLogin : null, syncState]))), switchMap(([userLogin, syncState]) => __awaiter(this, void 0, void 0, function* () { return [userLogin, yield computeRealmSetHash(syncState)]; })), switchMap(([userLogin, realmSetHash]) =>
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]) =>
5124
5178
  // Let server end query changes from last entry of same client-ID and forward.
5125
5179
  // If no new entries, server won't bother the client. If new entries, server sends only those
5126
5180
  // and the baseRev of the last from same client-ID.
@@ -5989,6 +6043,7 @@
5989
6043
  localSyncWorker = null;
5990
6044
  currentUserEmitter.next(UNAUTHORIZED_USER);
5991
6045
  });
6046
+ const syncComplete = new rxjs.Subject();
5992
6047
  dexie.cloud = {
5993
6048
  version: '{version}',
5994
6049
  options: Object.assign({}, DEFAULT_OPTIONS),
@@ -6001,6 +6056,9 @@
6001
6056
  phase: 'initial',
6002
6057
  status: 'not-started',
6003
6058
  }),
6059
+ events: {
6060
+ syncComplete,
6061
+ },
6004
6062
  persistedSyncState: new rxjs.BehaviorSubject(undefined),
6005
6063
  userInteraction: new rxjs.BehaviorSubject(undefined),
6006
6064
  webSocketStatus: new rxjs.BehaviorSubject('not-started'),
@@ -6094,6 +6152,8 @@
6094
6152
  if (!db.cloud.isServiceWorkerDB) {
6095
6153
  subscriptions.push(computeSyncState(db).subscribe(dexie.cloud.syncState));
6096
6154
  }
6155
+ // Forward db.syncCompleteEvent to be publicly consumable via db.cloud.events.syncComplete:
6156
+ subscriptions.push(db.syncCompleteEvent.subscribe(syncComplete));
6097
6157
  //verifyConfig(db.cloud.options); Not needed (yet at least!)
6098
6158
  // Verify the user has allowed version increment.
6099
6159
  if (!db.tables.every((table) => table.core)) {
@@ -6201,15 +6261,16 @@
6201
6261
  ]).toPromise();
6202
6262
  }
6203
6263
  // HERE: If requireAuth, do athentication now.
6264
+ let changedUser = false;
6204
6265
  if ((_c = db.cloud.options) === null || _c === void 0 ? void 0 : _c.requireAuth) {
6205
- yield login(db);
6266
+ changedUser = yield login(db);
6206
6267
  }
6207
6268
  if (localSyncWorker)
6208
6269
  localSyncWorker.stop();
6209
6270
  localSyncWorker = null;
6210
6271
  throwIfClosed();
6211
6272
  if (db.cloud.usingServiceWorker && ((_d = db.cloud.options) === null || _d === void 0 ? void 0 : _d.databaseUrl)) {
6212
- registerSyncEvent(db, 'push').catch(() => { });
6273
+ registerSyncEvent(db, changedUser ? 'pull' : 'push').catch(() => { });
6213
6274
  registerPeriodicSyncEvent(db).catch(() => { });
6214
6275
  }
6215
6276
  else if (((_e = db.cloud.options) === null || _e === void 0 ? void 0 : _e.databaseUrl) &&
@@ -6218,7 +6279,7 @@
6218
6279
  // There's no SW. Start SyncWorker instead.
6219
6280
  localSyncWorker = LocalSyncWorker(db, db.cloud.options, db.cloud.schema);
6220
6281
  localSyncWorker.start();
6221
- triggerSync(db, 'push');
6282
+ triggerSync(db, changedUser ? 'pull' : 'push');
6222
6283
  }
6223
6284
  // Listen to online event and do sync.
6224
6285
  throwIfClosed();