dexie-cloud-addon 4.0.1-beta.46 → 4.0.1-beta.48

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.
Files changed (264) hide show
  1. package/dist/{types → modern}/DexieCloudAPI.d.ts +3 -0
  2. package/dist/{types → modern}/DexieCloudOptions.d.ts +1 -0
  3. package/dist/modern/InvalidLicenseError.d.ts +5 -0
  4. package/dist/{types → modern}/TSON.d.ts +1 -1
  5. package/dist/modern/authentication/TokenErrorResponseError.d.ts +10 -0
  6. package/dist/{types → modern}/authentication/authenticate.d.ts +3 -3
  7. package/dist/{types → modern}/authentication/interactWithUser.d.ts +3 -0
  8. package/dist/modern/authentication/logout.d.ts +5 -0
  9. package/dist/modern/authentication/waitUntil.d.ts +3 -0
  10. package/dist/{types → modern}/currentUserEmitter.d.ts +1 -1
  11. package/dist/{types → modern}/db/entities/UserLogin.d.ts +6 -0
  12. package/dist/modern/default-ui/LoginDialog.d.ts +3 -0
  13. package/dist/modern/dexie-cloud-addon.d.ts +3 -0
  14. package/dist/modern/dexie-cloud-addon.js +488 -367
  15. package/dist/modern/dexie-cloud-addon.js.map +1 -1
  16. package/dist/modern/dexie-cloud-addon.min.js +2 -2
  17. package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
  18. package/dist/{types → modern}/dexie-cloud-client.d.ts +2 -0
  19. package/dist/modern/helpers/resolveText.d.ts +16 -0
  20. package/dist/modern/isEagerSyncDisabled.d.ts +2 -0
  21. package/dist/{types → modern}/middlewares/createMutationTrackingMiddleware.d.ts +1 -1
  22. package/dist/modern/prodLog.d.ts +9 -0
  23. package/dist/modern/service-worker.js +2027 -268
  24. package/dist/modern/service-worker.js.map +1 -1
  25. package/dist/modern/service-worker.min.js +2 -2
  26. package/dist/modern/service-worker.min.js.map +1 -1
  27. package/dist/modern/sync/performGuardedJob.d.ts +2 -0
  28. package/dist/modern/sync/ratelimit.d.ts +3 -0
  29. package/dist/{types → modern}/sync/sync.d.ts +0 -1
  30. package/dist/{types → modern}/types/DXCAlert.d.ts +1 -1
  31. package/dist/{types → modern}/types/DXCUserInteraction.d.ts +40 -2
  32. package/dist/{types → modern}/types/SyncState.d.ts +1 -0
  33. package/dist/umd/DISABLE_SERVICEWORKER_STRATEGY.d.ts +1 -0
  34. package/dist/umd/DXCWebSocketStatus.d.ts +1 -0
  35. package/dist/umd/DexieCloudAPI.d.ts +72 -0
  36. package/dist/umd/DexieCloudOptions.d.ts +22 -0
  37. package/dist/umd/DexieCloudSyncOptions.d.ts +4 -0
  38. package/dist/umd/DexieCloudTable.d.ts +18 -0
  39. package/dist/umd/InvalidLicenseError.d.ts +5 -0
  40. package/dist/umd/Invite.d.ts +8 -0
  41. package/dist/umd/PermissionChecker.d.ts +15 -0
  42. package/dist/umd/TSON.d.ts +17 -0
  43. package/dist/umd/WSObservable.d.ts +68 -0
  44. package/dist/umd/associate.d.ts +1 -0
  45. package/dist/umd/authentication/AuthPersistedContext.d.ts +9 -0
  46. package/dist/umd/authentication/TokenErrorResponseError.d.ts +10 -0
  47. package/dist/umd/authentication/TokenExpiredError.d.ts +3 -0
  48. package/dist/umd/authentication/UNAUTHORIZED_USER.d.ts +2 -0
  49. package/dist/umd/authentication/authenticate.d.ts +20 -0
  50. package/dist/umd/authentication/currentUserObservable.d.ts +1 -0
  51. package/dist/umd/authentication/interactWithUser.d.ts +21 -0
  52. package/dist/umd/authentication/login.d.ts +6 -0
  53. package/dist/umd/authentication/logout.d.ts +5 -0
  54. package/dist/umd/authentication/otpFetchTokenCallback.d.ts +3 -0
  55. package/dist/umd/authentication/setCurrentUser.d.ts +14 -0
  56. package/dist/umd/authentication/waitUntil.d.ts +3 -0
  57. package/dist/umd/computeSyncState.d.ts +4 -0
  58. package/dist/umd/createSharedValueObservable.d.ts +3 -0
  59. package/dist/umd/currentUserEmitter.d.ts +3 -0
  60. package/dist/umd/db/DexieCloudDB.d.ts +59 -0
  61. package/dist/umd/db/entities/BaseRevisionMapEntry.d.ts +5 -0
  62. package/dist/umd/db/entities/EntityCommon.d.ts +5 -0
  63. package/dist/umd/db/entities/GuardedJob.d.ts +5 -0
  64. package/dist/umd/db/entities/Member.d.ts +19 -0
  65. package/dist/umd/db/entities/PersistedSyncState.d.ts +14 -0
  66. package/dist/umd/db/entities/Realm.d.ts +16 -0
  67. package/dist/umd/db/entities/Role.d.ts +11 -0
  68. package/dist/umd/db/entities/UserLogin.d.ts +22 -0
  69. package/dist/umd/default-ui/Dialog.d.ts +5 -0
  70. package/dist/umd/default-ui/LoginDialog.d.ts +3 -0
  71. package/dist/umd/default-ui/Styles.d.ts +3 -0
  72. package/dist/umd/default-ui/index.d.ts +24 -0
  73. package/dist/umd/dexie-cloud-addon.d.ts +3 -0
  74. package/dist/umd/dexie-cloud-addon.js +505 -388
  75. package/dist/umd/dexie-cloud-addon.js.map +1 -1
  76. package/dist/umd/dexie-cloud-client.d.ts +13 -0
  77. package/dist/umd/errors/HttpError.d.ts +5 -0
  78. package/dist/umd/extend-dexie-interface.d.ts +23 -0
  79. package/dist/umd/getGlobalRolesObservable.d.ts +5 -0
  80. package/dist/umd/getInternalAccessControlObservable.d.ts +12 -0
  81. package/dist/umd/getInvitesObservable.d.ts +23 -0
  82. package/dist/umd/getPermissionsLookupObservable.d.ts +16 -0
  83. package/dist/umd/getTiedRealmId.d.ts +2 -0
  84. package/dist/umd/helpers/BroadcastedAndLocalEvent.d.ts +8 -0
  85. package/dist/umd/helpers/CancelToken.d.ts +4 -0
  86. package/dist/umd/helpers/IS_SERVICE_WORKER.d.ts +1 -0
  87. package/dist/umd/helpers/SWBroadcastChannel.d.ts +12 -0
  88. package/dist/umd/helpers/allSettled.d.ts +1 -0
  89. package/dist/umd/helpers/bulkUpdate.d.ts +4 -0
  90. package/dist/umd/helpers/computeRealmSetHash.d.ts +2 -0
  91. package/dist/umd/helpers/date-constants.d.ts +5 -0
  92. package/dist/umd/helpers/dbOnClosed.d.ts +2 -0
  93. package/dist/umd/helpers/flatten.d.ts +1 -0
  94. package/dist/umd/helpers/getMutationTable.d.ts +1 -0
  95. package/dist/umd/helpers/getSyncableTables.d.ts +4 -0
  96. package/dist/umd/helpers/getTableFromMutationTable.d.ts +1 -0
  97. package/dist/umd/helpers/makeArray.d.ts +1 -0
  98. package/dist/umd/helpers/randomString.d.ts +1 -0
  99. package/dist/umd/helpers/resolveText.d.ts +16 -0
  100. package/dist/umd/helpers/throwVersionIncrementNeeded.d.ts +1 -0
  101. package/dist/umd/helpers/visibilityState.d.ts +1 -0
  102. package/dist/umd/isEagerSyncDisabled.d.ts +2 -0
  103. package/dist/umd/isFirefox.d.ts +1 -0
  104. package/dist/umd/isSafari.d.ts +2 -0
  105. package/dist/umd/mapValueObservable.d.ts +5 -0
  106. package/dist/umd/mergePermissions.d.ts +2 -0
  107. package/dist/umd/middleware-helpers/guardedTable.d.ts +11 -0
  108. package/dist/umd/middleware-helpers/idGenerationHelpers.d.ts +18 -0
  109. package/dist/umd/middlewares/createIdGenerationMiddleware.d.ts +3 -0
  110. package/dist/umd/middlewares/createImplicitPropSetterMiddleware.d.ts +3 -0
  111. package/dist/umd/middlewares/createMutationTrackingMiddleware.d.ts +17 -0
  112. package/dist/umd/middlewares/outstandingTransaction.d.ts +4 -0
  113. package/dist/umd/overrideParseStoresSpec.d.ts +4 -0
  114. package/dist/umd/performInitialSync.d.ts +4 -0
  115. package/dist/umd/permissions.d.ts +9 -0
  116. package/dist/umd/prodLog.d.ts +9 -0
  117. package/dist/umd/service-worker.d.ts +1 -0
  118. package/dist/umd/service-worker.js +2078 -322
  119. package/dist/umd/service-worker.js.map +1 -1
  120. package/dist/umd/sync/LocalSyncWorker.d.ts +7 -0
  121. package/dist/umd/sync/SyncRequiredError.d.ts +3 -0
  122. package/dist/umd/sync/applyServerChanges.d.ts +3 -0
  123. package/dist/umd/sync/connectWebSocket.d.ts +2 -0
  124. package/dist/umd/sync/encodeIdsForServer.d.ts +4 -0
  125. package/dist/umd/sync/extractRealm.d.ts +2 -0
  126. package/dist/umd/sync/getLatestRevisionsPerTable.d.ts +6 -0
  127. package/dist/umd/sync/getTablesToSyncify.d.ts +3 -0
  128. package/dist/umd/sync/isOnline.d.ts +1 -0
  129. package/dist/umd/sync/isSyncNeeded.d.ts +2 -0
  130. package/dist/umd/sync/listClientChanges.d.ts +9 -0
  131. package/dist/umd/sync/listSyncifiedChanges.d.ts +5 -0
  132. package/dist/umd/sync/messageConsumerIsReady.d.ts +2 -0
  133. package/dist/umd/sync/messagesFromServerQueue.d.ts +8 -0
  134. package/dist/umd/sync/modifyLocalObjectsWithNewUserId.d.ts +4 -0
  135. package/dist/umd/sync/myId.d.ts +1 -0
  136. package/dist/umd/sync/numUnsyncedMutations.d.ts +2 -0
  137. package/dist/umd/sync/old_startSyncingClientChanges.d.ts +39 -0
  138. package/dist/umd/sync/performGuardedJob.d.ts +2 -0
  139. package/dist/umd/sync/ratelimit.d.ts +3 -0
  140. package/dist/umd/sync/registerSyncEvent.d.ts +3 -0
  141. package/dist/umd/sync/sync.d.ts +15 -0
  142. package/dist/umd/sync/syncIfPossible.d.ts +5 -0
  143. package/dist/umd/sync/syncWithServer.d.ts +6 -0
  144. package/dist/umd/sync/triggerSync.d.ts +2 -0
  145. package/dist/umd/sync/updateBaseRevs.d.ts +5 -0
  146. package/dist/umd/types/DXCAlert.d.ts +25 -0
  147. package/dist/umd/types/DXCInputField.d.ts +11 -0
  148. package/dist/umd/types/DXCUserInteraction.d.ts +93 -0
  149. package/dist/umd/types/NewIdOptions.d.ts +3 -0
  150. package/dist/umd/types/SWMessageEvent.d.ts +3 -0
  151. package/dist/umd/types/SWSyncEvent.d.ts +4 -0
  152. package/dist/umd/types/SyncState.d.ts +9 -0
  153. package/dist/umd/types/TXExpandos.d.ts +11 -0
  154. package/dist/umd/updateSchemaFromOptions.d.ts +3 -0
  155. package/dist/umd/userIsActive.d.ts +7 -0
  156. package/dist/umd/verifyConfig.d.ts +2 -0
  157. package/dist/umd/verifySchema.d.ts +2 -0
  158. package/package.json +14 -48
  159. package/LICENSE +0 -202
  160. package/copydts.sh +0 -5
  161. package/dist/types/default-ui/LoginDialog.d.ts +0 -6
  162. package/dist/types/helpers/resolveText.d.ts +0 -2
  163. package/dist/types/sync/performGuardedJob.d.ts +0 -4
  164. package/dist/umd/dexie-cloud-addon.min.js +0 -2
  165. package/dist/umd/dexie-cloud-addon.min.js.map +0 -1
  166. package/dist/umd/service-worker.min.js +0 -2
  167. package/dist/umd/service-worker.min.js.map +0 -1
  168. /package/dist/{types → modern}/DISABLE_SERVICEWORKER_STRATEGY.d.ts +0 -0
  169. /package/dist/{types → modern}/DXCWebSocketStatus.d.ts +0 -0
  170. /package/dist/{types → modern}/DexieCloudSyncOptions.d.ts +0 -0
  171. /package/dist/{types → modern}/DexieCloudTable.d.ts +0 -0
  172. /package/dist/{types → modern}/Invite.d.ts +0 -0
  173. /package/dist/{types → modern}/PermissionChecker.d.ts +0 -0
  174. /package/dist/{types → modern}/WSObservable.d.ts +0 -0
  175. /package/dist/{types → modern}/associate.d.ts +0 -0
  176. /package/dist/{types → modern}/authentication/AuthPersistedContext.d.ts +0 -0
  177. /package/dist/{types → modern}/authentication/TokenExpiredError.d.ts +0 -0
  178. /package/dist/{types → modern}/authentication/UNAUTHORIZED_USER.d.ts +0 -0
  179. /package/dist/{types → modern}/authentication/currentUserObservable.d.ts +0 -0
  180. /package/dist/{types → modern}/authentication/login.d.ts +0 -0
  181. /package/dist/{types → modern}/authentication/otpFetchTokenCallback.d.ts +0 -0
  182. /package/dist/{types → modern}/authentication/setCurrentUser.d.ts +0 -0
  183. /package/dist/{types → modern}/computeSyncState.d.ts +0 -0
  184. /package/dist/{types → modern}/createSharedValueObservable.d.ts +0 -0
  185. /package/dist/{types → modern}/db/DexieCloudDB.d.ts +0 -0
  186. /package/dist/{types → modern}/db/entities/BaseRevisionMapEntry.d.ts +0 -0
  187. /package/dist/{types → modern}/db/entities/EntityCommon.d.ts +0 -0
  188. /package/dist/{types → modern}/db/entities/GuardedJob.d.ts +0 -0
  189. /package/dist/{types → modern}/db/entities/Member.d.ts +0 -0
  190. /package/dist/{types → modern}/db/entities/PersistedSyncState.d.ts +0 -0
  191. /package/dist/{types → modern}/db/entities/Realm.d.ts +0 -0
  192. /package/dist/{types → modern}/db/entities/Role.d.ts +0 -0
  193. /package/dist/{types → modern}/default-ui/Dialog.d.ts +0 -0
  194. /package/dist/{types → modern}/default-ui/Styles.d.ts +0 -0
  195. /package/dist/{types → modern}/default-ui/index.d.ts +0 -0
  196. /package/dist/{types → modern}/errors/HttpError.d.ts +0 -0
  197. /package/dist/{types → modern}/extend-dexie-interface.d.ts +0 -0
  198. /package/dist/{types → modern}/getGlobalRolesObservable.d.ts +0 -0
  199. /package/dist/{types → modern}/getInternalAccessControlObservable.d.ts +0 -0
  200. /package/dist/{types → modern}/getInvitesObservable.d.ts +0 -0
  201. /package/dist/{types → modern}/getPermissionsLookupObservable.d.ts +0 -0
  202. /package/dist/{types → modern}/getTiedRealmId.d.ts +0 -0
  203. /package/dist/{types → modern}/helpers/BroadcastedAndLocalEvent.d.ts +0 -0
  204. /package/dist/{types → modern}/helpers/CancelToken.d.ts +0 -0
  205. /package/dist/{types → modern}/helpers/IS_SERVICE_WORKER.d.ts +0 -0
  206. /package/dist/{types → modern}/helpers/SWBroadcastChannel.d.ts +0 -0
  207. /package/dist/{types → modern}/helpers/allSettled.d.ts +0 -0
  208. /package/dist/{types → modern}/helpers/bulkUpdate.d.ts +0 -0
  209. /package/dist/{types → modern}/helpers/computeRealmSetHash.d.ts +0 -0
  210. /package/dist/{types → modern}/helpers/date-constants.d.ts +0 -0
  211. /package/dist/{types → modern}/helpers/dbOnClosed.d.ts +0 -0
  212. /package/dist/{types → modern}/helpers/flatten.d.ts +0 -0
  213. /package/dist/{types → modern}/helpers/getMutationTable.d.ts +0 -0
  214. /package/dist/{types → modern}/helpers/getSyncableTables.d.ts +0 -0
  215. /package/dist/{types → modern}/helpers/getTableFromMutationTable.d.ts +0 -0
  216. /package/dist/{types → modern}/helpers/makeArray.d.ts +0 -0
  217. /package/dist/{types → modern}/helpers/randomString.d.ts +0 -0
  218. /package/dist/{types → modern}/helpers/throwVersionIncrementNeeded.d.ts +0 -0
  219. /package/dist/{types → modern}/helpers/visibilityState.d.ts +0 -0
  220. /package/dist/{types → modern}/isFirefox.d.ts +0 -0
  221. /package/dist/{types → modern}/isSafari.d.ts +0 -0
  222. /package/dist/{types → modern}/mapValueObservable.d.ts +0 -0
  223. /package/dist/{types → modern}/mergePermissions.d.ts +0 -0
  224. /package/dist/{types → modern}/middleware-helpers/guardedTable.d.ts +0 -0
  225. /package/dist/{types → modern}/middleware-helpers/idGenerationHelpers.d.ts +0 -0
  226. /package/dist/{types → modern}/middlewares/createIdGenerationMiddleware.d.ts +0 -0
  227. /package/dist/{types → modern}/middlewares/createImplicitPropSetterMiddleware.d.ts +0 -0
  228. /package/dist/{types → modern}/middlewares/outstandingTransaction.d.ts +0 -0
  229. /package/dist/{types → modern}/overrideParseStoresSpec.d.ts +0 -0
  230. /package/dist/{types → modern}/performInitialSync.d.ts +0 -0
  231. /package/dist/{types → modern}/permissions.d.ts +0 -0
  232. /package/dist/{types → modern}/service-worker.d.ts +0 -0
  233. /package/dist/{types → modern}/sync/LocalSyncWorker.d.ts +0 -0
  234. /package/dist/{types → modern}/sync/SyncRequiredError.d.ts +0 -0
  235. /package/dist/{types → modern}/sync/applyServerChanges.d.ts +0 -0
  236. /package/dist/{types → modern}/sync/connectWebSocket.d.ts +0 -0
  237. /package/dist/{types → modern}/sync/encodeIdsForServer.d.ts +0 -0
  238. /package/dist/{types → modern}/sync/extractRealm.d.ts +0 -0
  239. /package/dist/{types → modern}/sync/getLatestRevisionsPerTable.d.ts +0 -0
  240. /package/dist/{types → modern}/sync/getTablesToSyncify.d.ts +0 -0
  241. /package/dist/{types → modern}/sync/isOnline.d.ts +0 -0
  242. /package/dist/{types → modern}/sync/isSyncNeeded.d.ts +0 -0
  243. /package/dist/{types → modern}/sync/listClientChanges.d.ts +0 -0
  244. /package/dist/{types → modern}/sync/listSyncifiedChanges.d.ts +0 -0
  245. /package/dist/{types → modern}/sync/messageConsumerIsReady.d.ts +0 -0
  246. /package/dist/{types → modern}/sync/messagesFromServerQueue.d.ts +0 -0
  247. /package/dist/{types → modern}/sync/modifyLocalObjectsWithNewUserId.d.ts +0 -0
  248. /package/dist/{types → modern}/sync/myId.d.ts +0 -0
  249. /package/dist/{types → modern}/sync/numUnsyncedMutations.d.ts +0 -0
  250. /package/dist/{types → modern}/sync/old_startSyncingClientChanges.d.ts +0 -0
  251. /package/dist/{types → modern}/sync/registerSyncEvent.d.ts +0 -0
  252. /package/dist/{types → modern}/sync/syncIfPossible.d.ts +0 -0
  253. /package/dist/{types → modern}/sync/syncWithServer.d.ts +0 -0
  254. /package/dist/{types → modern}/sync/triggerSync.d.ts +0 -0
  255. /package/dist/{types → modern}/sync/updateBaseRevs.d.ts +0 -0
  256. /package/dist/{types → modern}/types/DXCInputField.d.ts +0 -0
  257. /package/dist/{types → modern}/types/NewIdOptions.d.ts +0 -0
  258. /package/dist/{types → modern}/types/SWMessageEvent.d.ts +0 -0
  259. /package/dist/{types → modern}/types/SWSyncEvent.d.ts +0 -0
  260. /package/dist/{types → modern}/types/TXExpandos.d.ts +0 -0
  261. /package/dist/{types → modern}/updateSchemaFromOptions.d.ts +0 -0
  262. /package/dist/{types → modern}/userIsActive.d.ts +0 -0
  263. /package/dist/{types → modern}/verifyConfig.d.ts +0 -0
  264. /package/dist/{types → modern}/verifySchema.d.ts +0 -0
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * ==========================================================================
10
10
  *
11
- * Version 4.0.1-beta.46, Sat Aug 05 2023
11
+ * Version 4.0.1-beta.48, Tue Oct 17 2023
12
12
  *
13
13
  * https://dexie.org
14
14
  *
@@ -22,10 +22,6 @@
22
22
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.DexieCloud = {}, global.Dexie, global.rxjs));
23
23
  })(this, (function (exports, Dexie, rxjs) { 'use strict';
24
24
 
25
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
26
-
27
- var Dexie__default = /*#__PURE__*/_interopDefaultLegacy(Dexie);
28
-
29
25
  /******************************************************************************
30
26
  Copyright (c) Microsoft Corporation.
31
27
 
@@ -687,11 +683,7 @@
687
683
 
688
684
  function reportUnhandledError(err) {
689
685
  timeoutProvider.setTimeout(function () {
690
- var onUnhandledError = config.onUnhandledError;
691
- if (onUnhandledError) {
692
- onUnhandledError(err);
693
- }
694
- else {
686
+ {
695
687
  throw err;
696
688
  }
697
689
  });
@@ -699,38 +691,8 @@
699
691
 
700
692
  function noop() { }
701
693
 
702
- var COMPLETE_NOTIFICATION = (function () { return createNotification('C', undefined, undefined); })();
703
- function errorNotification(error) {
704
- return createNotification('E', undefined, error);
705
- }
706
- function nextNotification(value) {
707
- return createNotification('N', value, undefined);
708
- }
709
- function createNotification(kind, value, error) {
710
- return {
711
- kind: kind,
712
- value: value,
713
- error: error,
714
- };
715
- }
716
-
717
- var context = null;
718
694
  function errorContext(cb) {
719
- if (config.useDeprecatedSynchronousErrorHandling) {
720
- var isRoot = !context;
721
- if (isRoot) {
722
- context = { errorThrown: false, error: null };
723
- }
724
- cb();
725
- if (isRoot) {
726
- var _a = context, errorThrown = _a.errorThrown, error = _a.error;
727
- context = null;
728
- if (errorThrown) {
729
- throw error;
730
- }
731
- }
732
- }
733
- else {
695
+ {
734
696
  cb();
735
697
  }
736
698
  }
@@ -755,26 +717,20 @@
755
717
  return new SafeSubscriber(next, error, complete);
756
718
  };
757
719
  Subscriber.prototype.next = function (value) {
758
- if (this.isStopped) {
759
- handleStoppedNotification(nextNotification(value), this);
760
- }
720
+ if (this.isStopped) ;
761
721
  else {
762
722
  this._next(value);
763
723
  }
764
724
  };
765
725
  Subscriber.prototype.error = function (err) {
766
- if (this.isStopped) {
767
- handleStoppedNotification(errorNotification(err), this);
768
- }
726
+ if (this.isStopped) ;
769
727
  else {
770
728
  this.isStopped = true;
771
729
  this._error(err);
772
730
  }
773
731
  };
774
732
  Subscriber.prototype.complete = function () {
775
- if (this.isStopped) {
776
- handleStoppedNotification(COMPLETE_NOTIFICATION, this);
777
- }
733
+ if (this.isStopped) ;
778
734
  else {
779
735
  this.isStopped = true;
780
736
  this._complete();
@@ -894,10 +850,6 @@
894
850
  function defaultErrorHandler(err) {
895
851
  throw err;
896
852
  }
897
- function handleStoppedNotification(notification, subscriber) {
898
- var onStoppedNotification = config.onStoppedNotification;
899
- onStoppedNotification && timeoutProvider.setTimeout(function () { return onStoppedNotification(notification, subscriber); });
900
- }
901
853
  var EMPTY_OBSERVER = {
902
854
  closed: true,
903
855
  next: noop,
@@ -1924,58 +1876,6 @@
1924
1876
  identity;
1925
1877
  }
1926
1878
 
1927
- var TimeoutError = createErrorClass(function (_super) {
1928
- return function TimeoutErrorImpl(info) {
1929
- if (info === void 0) { info = null; }
1930
- _super(this);
1931
- this.message = 'Timeout has occurred';
1932
- this.name = 'TimeoutError';
1933
- this.info = info;
1934
- };
1935
- });
1936
- function timeout(config, schedulerArg) {
1937
- var _a = (isValidDate(config) ? { first: config } : typeof config === 'number' ? { each: config } : config), first = _a.first, each = _a.each, _b = _a.with, _with = _b === void 0 ? timeoutErrorFactory : _b, _c = _a.scheduler, scheduler = _c === void 0 ? schedulerArg !== null && schedulerArg !== void 0 ? schedulerArg : asyncScheduler : _c, _d = _a.meta, meta = _d === void 0 ? null : _d;
1938
- if (first == null && each == null) {
1939
- throw new TypeError('No timeout provided.');
1940
- }
1941
- return operate(function (source, subscriber) {
1942
- var originalSourceSubscription;
1943
- var timerSubscription;
1944
- var lastValue = null;
1945
- var seen = 0;
1946
- var startTimer = function (delay) {
1947
- timerSubscription = executeSchedule(subscriber, scheduler, function () {
1948
- try {
1949
- originalSourceSubscription.unsubscribe();
1950
- innerFrom(_with({
1951
- meta: meta,
1952
- lastValue: lastValue,
1953
- seen: seen,
1954
- })).subscribe(subscriber);
1955
- }
1956
- catch (err) {
1957
- subscriber.error(err);
1958
- }
1959
- }, delay);
1960
- };
1961
- originalSourceSubscription = source.subscribe(createOperatorSubscriber(subscriber, function (value) {
1962
- timerSubscription === null || timerSubscription === void 0 ? void 0 : timerSubscription.unsubscribe();
1963
- seen++;
1964
- subscriber.next((lastValue = value));
1965
- each > 0 && startTimer(each);
1966
- }, undefined, undefined, function () {
1967
- if (!(timerSubscription === null || timerSubscription === void 0 ? void 0 : timerSubscription.closed)) {
1968
- timerSubscription === null || timerSubscription === void 0 ? void 0 : timerSubscription.unsubscribe();
1969
- }
1970
- lastValue = null;
1971
- }));
1972
- !seen && startTimer(first != null ? (typeof first === 'number' ? first : +first - scheduler.now()) : each);
1973
- });
1974
- }
1975
- function timeoutErrorFactory(info) {
1976
- throw new TimeoutError(info);
1977
- }
1978
-
1979
1879
  //const hasSW = 'serviceWorker' in navigator;
1980
1880
  let hasComplainedAboutSyncEvent = false;
1981
1881
  function registerSyncEvent(db, purpose) {
@@ -2036,6 +1936,7 @@
2036
1936
 
2037
1937
  function triggerSync(db, purpose) {
2038
1938
  if (db.cloud.usingServiceWorker) {
1939
+ console.debug('registering sync event');
2039
1940
  registerSyncEvent(db, purpose);
2040
1941
  }
2041
1942
  else {
@@ -2064,17 +1965,34 @@
2064
1965
  }
2065
1966
  }
2066
1967
  : (b) => {
2067
- return btoa(String.fromCharCode.apply(null, ArrayBuffer.isView(b) ? b : new Uint8Array(b)));
1968
+ const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);
1969
+ const CHUNK_SIZE = 0x1000;
1970
+ const strs = [];
1971
+ for (let i = 0, l = u8a.length; i < l; i += CHUNK_SIZE) {
1972
+ const chunk = u8a.subarray(i, i + CHUNK_SIZE);
1973
+ strs.push(String.fromCharCode.apply(null, chunk));
1974
+ }
1975
+ return btoa(strs.join(""));
2068
1976
  };
2069
1977
 
1978
+ class TokenErrorResponseError extends Error {
1979
+ constructor({ title, message, messageCode, messageParams, }) {
1980
+ super(message);
1981
+ this.name = 'TokenErrorResponseError';
1982
+ this.title = title;
1983
+ this.messageCode = messageCode;
1984
+ this.messageParams = messageParams;
1985
+ }
1986
+ }
1987
+
2070
1988
  function interactWithUser(userInteraction, req) {
2071
1989
  return new Promise((resolve, reject) => {
2072
- const interactionProps = Object.assign(Object.assign({}, req), { onSubmit: (res) => {
1990
+ const interactionProps = Object.assign(Object.assign({ submitLabel: 'Submit', cancelLabel: 'Cancel' }, req), { onSubmit: (res) => {
2073
1991
  userInteraction.next(undefined);
2074
1992
  resolve(res);
2075
1993
  }, onCancel: () => {
2076
1994
  userInteraction.next(undefined);
2077
- reject(new Dexie__default["default"].AbortError("User cancelled"));
1995
+ reject(new Dexie.AbortError('User cancelled'));
2078
1996
  } });
2079
1997
  userInteraction.next(interactionProps);
2080
1998
  // Start subscribing for external updates to db.cloud.userInteraction, and if so, cancel this request.
@@ -2093,7 +2011,9 @@
2093
2011
  type: 'message-alert',
2094
2012
  title,
2095
2013
  alerts,
2096
- fields: {}
2014
+ fields: {},
2015
+ submitLabel: 'OK',
2016
+ cancelLabel: null,
2097
2017
  });
2098
2018
  }
2099
2019
  function promptForEmail(userInteraction, title, emailHint) {
@@ -2152,22 +2072,48 @@
2152
2072
  return otp;
2153
2073
  });
2154
2074
  }
2075
+ function confirmLogout(userInteraction, currentUserId, numUnsyncedChanges) {
2076
+ return __awaiter(this, void 0, void 0, function* () {
2077
+ const alerts = [
2078
+ {
2079
+ type: 'warning',
2080
+ messageCode: 'LOGOUT_CONFIRMATION',
2081
+ message: `{numUnsyncedChanges} unsynced changes will get lost!
2082
+ Logout anyway?`,
2083
+ messageParams: {
2084
+ currentUserId,
2085
+ numUnsyncedChanges: numUnsyncedChanges.toString(),
2086
+ }
2087
+ },
2088
+ ];
2089
+ return yield interactWithUser(userInteraction, {
2090
+ type: 'logout-confirmation',
2091
+ title: 'Confirm Logout',
2092
+ alerts,
2093
+ fields: {},
2094
+ submitLabel: 'Confirm logout',
2095
+ cancelLabel: 'Cancel'
2096
+ })
2097
+ .then(() => true)
2098
+ .catch(() => false);
2099
+ });
2100
+ }
2155
2101
 
2156
2102
  function loadAccessToken(db) {
2157
- var _a, _b;
2103
+ var _a, _b, _c;
2158
2104
  return __awaiter(this, void 0, void 0, function* () {
2159
2105
  const currentUser = yield db.getCurrentUser();
2160
2106
  const { accessToken, accessTokenExpiration, refreshToken, refreshTokenExpiration, claims, } = currentUser;
2161
2107
  if (!accessToken)
2162
- return;
2108
+ return null;
2163
2109
  const expTime = (_a = accessTokenExpiration === null || accessTokenExpiration === void 0 ? void 0 : accessTokenExpiration.getTime()) !== null && _a !== void 0 ? _a : Infinity;
2164
- if (expTime > Date.now()) {
2165
- return accessToken;
2110
+ if (expTime > Date.now() && (((_b = currentUser.license) === null || _b === void 0 ? void 0 : _b.status) || 'ok') === 'ok') {
2111
+ return currentUser;
2166
2112
  }
2167
2113
  if (!refreshToken) {
2168
2114
  throw new Error(`Refresh token missing`);
2169
2115
  }
2170
- const refreshExpTime = (_b = refreshTokenExpiration === null || refreshTokenExpiration === void 0 ? void 0 : refreshTokenExpiration.getTime()) !== null && _b !== void 0 ? _b : Infinity;
2116
+ const refreshExpTime = (_c = refreshTokenExpiration === null || refreshTokenExpiration === void 0 ? void 0 : refreshTokenExpiration.getTime()) !== null && _c !== void 0 ? _c : Infinity;
2171
2117
  if (refreshExpTime <= Date.now()) {
2172
2118
  throw new Error(`Refresh token has expired`);
2173
2119
  }
@@ -2175,8 +2121,10 @@
2175
2121
  yield db.table('$logins').update(claims.sub, {
2176
2122
  accessToken: refreshedLogin.accessToken,
2177
2123
  accessTokenExpiration: refreshedLogin.accessTokenExpiration,
2124
+ claims: refreshedLogin.claims,
2125
+ license: refreshedLogin.license,
2178
2126
  });
2179
- return refreshedLogin.accessToken;
2127
+ return refreshedLogin;
2180
2128
  });
2181
2129
  }
2182
2130
  function authenticate(url, context, fetchToken, userInteraction, hints) {
@@ -2224,10 +2172,24 @@
2224
2172
  if (res.status !== 200)
2225
2173
  throw new Error(`RefreshToken: Status ${res.status} from ${url}/token`);
2226
2174
  const response = yield res.json();
2175
+ if (response.type === 'error') {
2176
+ throw new TokenErrorResponseError(response);
2177
+ }
2227
2178
  login.accessToken = response.accessToken;
2228
2179
  login.accessTokenExpiration = response.accessTokenExpiration
2229
2180
  ? new Date(response.accessTokenExpiration)
2230
2181
  : undefined;
2182
+ login.claims = response.claims;
2183
+ login.license = {
2184
+ type: response.userType,
2185
+ status: response.claims.license || 'ok',
2186
+ };
2187
+ if (response.evalDaysLeft != null) {
2188
+ login.license.evalDaysLeft = response.evalDaysLeft;
2189
+ }
2190
+ if (response.userValidUntil != null) {
2191
+ login.license.validUntil = new Date(response.userValidUntil);
2192
+ }
2231
2193
  return login;
2232
2194
  });
2233
2195
  }
@@ -2259,8 +2221,15 @@
2259
2221
  public_key: publicKeyPEM,
2260
2222
  hints,
2261
2223
  });
2224
+ if (response2.type === 'error') {
2225
+ throw new TokenErrorResponseError(response2);
2226
+ }
2262
2227
  if (response2.type !== 'tokens')
2263
2228
  throw new Error(`Unexpected response type from token endpoint: ${response2.type}`);
2229
+ /*const licenseStatus = response2.claims.license || 'ok';
2230
+ if (licenseStatus !== 'ok') {
2231
+ throw new InvalidLicenseError(licenseStatus);
2232
+ }*/
2264
2233
  context.accessToken = response2.accessToken;
2265
2234
  context.accessTokenExpiration = new Date(response2.accessTokenExpiration);
2266
2235
  context.refreshToken = response2.refreshToken;
@@ -2271,6 +2240,16 @@
2271
2240
  context.email = response2.claims.email;
2272
2241
  context.name = response2.claims.name;
2273
2242
  context.claims = response2.claims;
2243
+ context.license = {
2244
+ type: response2.userType,
2245
+ status: response2.claims.license || 'ok',
2246
+ };
2247
+ if (response2.evalDaysLeft != null) {
2248
+ context.license.evalDaysLeft = response2.evalDaysLeft;
2249
+ }
2250
+ if (response2.userValidUntil != null) {
2251
+ context.license.validUntil = new Date(response2.userValidUntil);
2252
+ }
2274
2253
  if (response2.alerts && response2.alerts.length > 0) {
2275
2254
  yield interactWithUser(userInteraction, {
2276
2255
  type: 'message-alert',
@@ -2282,12 +2261,36 @@
2282
2261
  return context;
2283
2262
  }
2284
2263
  catch (error) {
2285
- yield alertUser(userInteraction, 'Authentication Failed', {
2286
- type: 'error',
2287
- messageCode: 'GENERIC_ERROR',
2288
- message: `We're having a problem authenticating right now.`,
2289
- messageParams: {},
2290
- }).catch(() => { });
2264
+ if (error instanceof TokenErrorResponseError) {
2265
+ yield alertUser(userInteraction, error.title, {
2266
+ type: 'error',
2267
+ messageCode: error.messageCode,
2268
+ message: error.message,
2269
+ messageParams: {},
2270
+ });
2271
+ throw error;
2272
+ }
2273
+ let message = `We're having a problem authenticating right now.`;
2274
+ console.error(`Error authenticating`, error);
2275
+ if (error instanceof TypeError) {
2276
+ const isOffline = typeof navigator !== undefined && !navigator.onLine;
2277
+ if (isOffline) {
2278
+ message = `You seem to be offline. Please connect to the internet and try again.`;
2279
+ }
2280
+ else if (Dexie.debug || (typeof location !== 'undefined' && (location.hostname === 'localhost' || location.hostname === '127.0.0.1'))) {
2281
+ // The audience is most likely the developer. Suggest to whitelist the localhost origin:
2282
+ message = `Could not connect to server. Please verify that your origin '${location.origin}' is whitelisted using \`npx dexie-cloud whitelist\``;
2283
+ }
2284
+ else {
2285
+ message = `Could not connect to server. Please verify the connection.`;
2286
+ }
2287
+ yield alertUser(userInteraction, 'Authentication Failed', {
2288
+ type: 'error',
2289
+ messageCode: 'GENERIC_ERROR',
2290
+ message,
2291
+ messageParams: {},
2292
+ }).catch(() => { });
2293
+ }
2291
2294
  throw error;
2292
2295
  }
2293
2296
  });
@@ -2334,6 +2337,75 @@
2334
2337
  }
2335
2338
  }
2336
2339
 
2340
+ const UNAUTHORIZED_USER = {
2341
+ userId: "unauthorized",
2342
+ name: "Unauthorized",
2343
+ claims: {
2344
+ sub: "unauthorized",
2345
+ },
2346
+ lastLogin: new Date(0)
2347
+ };
2348
+ try {
2349
+ Object.freeze(UNAUTHORIZED_USER);
2350
+ Object.freeze(UNAUTHORIZED_USER.claims);
2351
+ }
2352
+ catch (_a) { }
2353
+
2354
+ function waitUntil(o, // Works with Dexie's liveQuery observables if we'd need that
2355
+ predicate) {
2356
+ return rxjs.firstValueFrom(rxjs.from(o).pipe(rxjs.filter(predicate)));
2357
+ }
2358
+
2359
+ function logout(db) {
2360
+ return __awaiter(this, void 0, void 0, function* () {
2361
+ const numUnsyncedChanges = yield _logout(db);
2362
+ if (numUnsyncedChanges) {
2363
+ if (yield confirmLogout(db.cloud.userInteraction, db.cloud.currentUserId, numUnsyncedChanges)) {
2364
+ yield _logout(db, { deleteUnsyncedData: true });
2365
+ }
2366
+ else {
2367
+ throw new Error(`User cancelled logout due to unsynced changes`);
2368
+ }
2369
+ }
2370
+ });
2371
+ }
2372
+ function _logout(db, { deleteUnsyncedData = false } = {}) {
2373
+ return __awaiter(this, void 0, void 0, function* () {
2374
+ // Clear the database without emptying configuration options.
2375
+ const [numUnsynced, loggedOut] = yield db.dx.transaction('rw', db.dx.tables, (tx) => __awaiter(this, void 0, void 0, function* () {
2376
+ // @ts-ignore
2377
+ const idbtrans = tx.idbtrans;
2378
+ idbtrans.disableChangeTracking = true;
2379
+ idbtrans.disableAccessControl = true;
2380
+ const mutationTables = tx.storeNames.filter((tableName) => tableName.endsWith('_mutations'));
2381
+ // Count unsynced changes
2382
+ const unsyncCounts = yield Promise.all(mutationTables.map((mutationTable) => tx.table(mutationTable).count()));
2383
+ const sumUnSynced = unsyncCounts.reduce((a, b) => a + b, 0);
2384
+ if (sumUnSynced > 0 && !deleteUnsyncedData) {
2385
+ // Let caller ask user if they want to delete unsynced data.
2386
+ return [sumUnSynced, false];
2387
+ }
2388
+ // Either there are no unsynched changes, or caller provided flag deleteUnsynchedData = true.
2389
+ // Clear all tables except $jobs and $syncState (except the persisted sync state which is
2390
+ // also cleared because we're going to rebuild it using a fresh sync).
2391
+ db.$syncState.delete('syncState');
2392
+ for (const table of db.dx.tables) {
2393
+ if (table.name !== '$jobs' && table.name !== '$syncState') {
2394
+ table.clear();
2395
+ }
2396
+ }
2397
+ return [sumUnSynced, true];
2398
+ }));
2399
+ if (loggedOut) {
2400
+ // Wait for currentUser observable to emit UNAUTHORIZED_USER
2401
+ yield waitUntil(db.cloud.currentUser, (user) => user.userId === UNAUTHORIZED_USER.userId);
2402
+ // Then perform an initial sync
2403
+ yield db.cloud.sync({ purpose: 'pull', wait: true });
2404
+ }
2405
+ return numUnsynced;
2406
+ });
2407
+ }
2408
+
2337
2409
  class HttpError extends Error {
2338
2410
  constructor(res, message) {
2339
2411
  super(message || `${res.status} ${res.statusText}`);
@@ -2387,8 +2459,9 @@
2387
2459
  throw new HttpError(res1, errMsg);
2388
2460
  }
2389
2461
  const response = yield res1.json();
2390
- if (response.type === 'tokens') {
2462
+ if (response.type === 'tokens' || response.type === 'error') {
2391
2463
  // Demo user request can get a "tokens" response right away
2464
+ // Error can also be returned right away.
2392
2465
  return response;
2393
2466
  }
2394
2467
  else if (tokenRequest.grant_type === 'otp') {
@@ -2420,12 +2493,6 @@
2420
2493
  }
2421
2494
  if (res2.status !== 200) {
2422
2495
  const errMsg = yield res2.text();
2423
- yield alertUser(userInteraction, "OTP Authentication Failed", {
2424
- type: 'error',
2425
- messageCode: 'GENERIC_ERROR',
2426
- message: errMsg,
2427
- messageParams: {}
2428
- }).catch(() => { });
2429
2496
  throw new HttpError(res2, errMsg);
2430
2497
  }
2431
2498
  const response2 = yield res2.json();
@@ -2438,6 +2505,18 @@
2438
2505
  };
2439
2506
  }
2440
2507
 
2508
+ /** A way to log to console in production without terser stripping out
2509
+ * it from the release bundle.
2510
+ * This should be used very rarely and only in places where it's
2511
+ * absolutely necessary to log something in production.
2512
+ *
2513
+ * @param level
2514
+ * @param args
2515
+ */
2516
+ function prodLog(level, ...args) {
2517
+ globalThis["con" + "sole"][level](...args);
2518
+ }
2519
+
2441
2520
  /** This function changes or sets the current user as requested.
2442
2521
  *
2443
2522
  * Use cases:
@@ -2464,102 +2543,76 @@
2464
2543
  }));
2465
2544
  user.isLoggedIn = true;
2466
2545
  user.lastLogin = new Date();
2467
- yield user.save();
2468
- console.debug('Saved new user', user.email);
2469
- }));
2470
- yield new Promise((resolve) => {
2471
- if (db.cloud.currentUserId === user.userId) {
2472
- resolve(null);
2546
+ try {
2547
+ yield user.save();
2473
2548
  }
2474
- else {
2475
- const subscription = db.cloud.currentUser.subscribe((currentUser) => {
2476
- if (currentUser.userId === user.userId) {
2477
- subscription.unsubscribe();
2478
- resolve(null);
2549
+ catch (e) {
2550
+ try {
2551
+ if (e.name === 'DataCloneError') {
2552
+ // We've seen this buggy behavior in some browsers and in case it happens
2553
+ // again we really need to collect the details to understand what's going on.
2554
+ prodLog('debug', `Login context property names:`, Object.keys(user));
2555
+ prodLog('debug', `Login context property names:`, Object.keys(user));
2556
+ prodLog('debug', `Login context:`, user);
2557
+ prodLog('debug', `Login context JSON:`, JSON.stringify(user));
2479
2558
  }
2480
- });
2559
+ }
2560
+ catch (_a) { }
2561
+ throw e;
2481
2562
  }
2482
- });
2483
- // TANKAR!!!!
2484
- // V: Service workern kommer inte ha tillgång till currentUserObservable om den inte istället härrör från ett liveQuery.
2485
- // V: Samma med andra windows.
2486
- // V: Så kanske göra om den till att häröra från liveQuery som läser $logins.orderBy('lastLogin').last().
2487
- // V: Då bara vara medveten om:
2488
- // V: En sån observable börjar hämta data vid första subscribe
2489
- // V: Vi har inget "inital value" men kan emulera det till att vara ANONYMOUS_USER
2490
- // V: Om requireAuth är true, så borde db.on(ready) hålla databasen stängd för alla utom denna observable.
2491
- // V: Om inte så behöver den inte blocka.
2492
- // Andra tankar:
2493
- // * Man kan inte byta användare när man är offline. Skulle gå att flytta realms till undanstuff-tabell vid user-change.
2494
- // men troligen inte värt det.
2495
- // * Istället: sälj inte inte switch-user funktionalitet utan tala enbart om inloggat vs icke inloggat läge.
2496
- // * populate $logins med ANONYMOUS så att en påbörjad inloggning inte räknas, alternativt ha en boolean prop!
2497
- // Kanske bäst ha en boolean prop!
2498
- // * Alternativ switch-user funktionalitet:
2499
- // * DBCore gömmer data från realms man inte har tillgång till.
2500
- // * Cursor impl behövs också då.
2501
- // * Då blir det snabba user switch.
2502
- // * claims-settet som skickas till servern blir summan av alla claims. Då måste servern stödja multipla tokens eller
2503
- // att ens token är ett samlad.
2563
+ console.debug('Saved new user', user.email);
2564
+ }));
2565
+ yield waitUntil(db.cloud.currentUser, (currentUser) => currentUser.userId === user.userId);
2504
2566
  });
2505
2567
  }
2506
2568
 
2507
2569
  function login(db, hints) {
2570
+ var _a;
2508
2571
  return __awaiter(this, void 0, void 0, function* () {
2509
2572
  const currentUser = yield db.getCurrentUser();
2510
- if (currentUser.isLoggedIn) {
2511
- if (hints) {
2512
- if (hints.email && db.cloud.currentUser.value.email !== hints.email) {
2513
- throw new Error(`Must logout before changing user`);
2514
- }
2515
- if (hints.userId && db.cloud.currentUserId !== hints.userId) {
2516
- throw new Error(`Must logout before changing user`);
2517
- }
2573
+ const origUserId = currentUser.userId;
2574
+ if (currentUser.isLoggedIn && (!hints || (!hints.email && !hints.userId))) {
2575
+ const licenseStatus = ((_a = currentUser.license) === null || _a === void 0 ? void 0 : _a.status) || 'ok';
2576
+ if (licenseStatus === 'ok' && currentUser.accessToken && (!currentUser.accessTokenExpiration || currentUser.accessTokenExpiration.getTime() > Date.now())) {
2577
+ // Already authenticated according to given hints. And license is valid.
2578
+ return false;
2518
2579
  }
2519
- // Already authenticated according to given hints.
2520
- return false;
2580
+ if (currentUser.refreshToken && (!currentUser.refreshTokenExpiration || currentUser.refreshTokenExpiration.getTime() > Date.now())) {
2581
+ // Refresh the token
2582
+ yield loadAccessToken(db);
2583
+ return false;
2584
+ }
2585
+ // No refresh token - must re-authenticate:
2521
2586
  }
2522
2587
  const context = new AuthPersistedContext(db, {
2523
2588
  claims: {},
2524
2589
  lastLogin: new Date(0),
2525
2590
  });
2526
2591
  yield authenticate(db.cloud.options.databaseUrl, context, db.cloud.options.fetchTokens || otpFetchTokenCallback(db), db.cloud.userInteraction, hints);
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
- }
2592
+ if (origUserId !== UNAUTHORIZED_USER.userId && context.userId !== origUserId) {
2593
+ // User was logged in before, but now logged in as another user.
2594
+ yield logout(db);
2595
+ }
2596
+ /*try {
2597
+ await context.save();
2598
+ } catch (e) {
2599
+ try {
2600
+ if (e.name === 'DataCloneError') {
2601
+ console.debug(`Login context property names:`, Object.keys(context));
2602
+ console.debug(`Login context:`, context);
2603
+ console.debug(`Login context JSON:`, JSON.stringify(context));
2604
+ }
2605
+ } catch {}
2606
+ throw e;
2607
+ }*/
2541
2608
  yield setCurrentUser(db, context);
2542
2609
  // Make sure to resync as the new login will be authorized
2543
2610
  // for new realms.
2544
2611
  triggerSync(db, "pull");
2545
- return true;
2612
+ return context.userId !== origUserId;
2546
2613
  });
2547
2614
  }
2548
2615
 
2549
- const UNAUTHORIZED_USER = {
2550
- userId: "unauthorized",
2551
- name: "Unauthorized",
2552
- claims: {
2553
- sub: "unauthorized",
2554
- },
2555
- lastLogin: new Date(0)
2556
- };
2557
- try {
2558
- Object.freeze(UNAUTHORIZED_USER);
2559
- Object.freeze(UNAUTHORIZED_USER.claims);
2560
- }
2561
- catch (_a) { }
2562
-
2563
2616
  const swHolder = {};
2564
2617
  const swContainer = typeof self !== 'undefined' && self.document && // self.document is to verify we're not the SW ourself
2565
2618
  typeof navigator !== 'undefined' && navigator.serviceWorker;
@@ -3065,13 +3118,13 @@
3065
3118
  },
3066
3119
  };
3067
3120
 
3068
- const _global = typeof globalThis !== "undefined"
3121
+ const _global = typeof globalThis !== "undefined" // All modern environments (node, bun, deno, browser, workers, webview etc)
3069
3122
  ? globalThis
3070
- : typeof self !== "undefined"
3123
+ : typeof self !== "undefined" // Older browsers, workers, webview, window etc
3071
3124
  ? self
3072
- : typeof global === "undefined"
3125
+ : typeof global !== "undefined" // Older versions of node
3073
3126
  ? global
3074
- : undefined;
3127
+ : undefined; // Unsupported environment. No idea to return 'this' since we are in a module or a function scope anyway.
3075
3128
 
3076
3129
  var TypedArraysDefs = [
3077
3130
  "Int8Array",
@@ -3437,7 +3490,7 @@
3437
3490
  const rewrittenKey = `${key}:${currentUser.userId}`;
3438
3491
  mutClone.keys[keyIndex] = rewrittenKey;
3439
3492
  if (rewriteValues) {
3440
- Dexie__default["default"].setByKeyPath(mutClone.values[keyIndex], primaryKey.keyPath, rewrittenKey);
3493
+ Dexie.setByKeyPath(mutClone.values[keyIndex], primaryKey.keyPath, rewrittenKey);
3441
3494
  }
3442
3495
  }
3443
3496
  });
@@ -3456,6 +3509,40 @@
3456
3509
  : change.muts.map((m) => (Object.assign(Object.assign({}, m), { keys: m.keys.slice() }))) });
3457
3510
  }
3458
3511
 
3512
+ // If we get Ratelimit-Limit and Ratelimit-Remaining where Ratelimit-Remaining is below
3513
+ // (Ratelimit-Limit / 2), we should delay the next sync by (Ratelimit-Reset / Ratelimit-Remaining)
3514
+ // seconds (given that there is a Ratelimit-Reset header).
3515
+ let syncRatelimitDelays = new WeakMap();
3516
+ function checkSyncRateLimitDelay(db) {
3517
+ var _a, _b;
3518
+ return __awaiter(this, void 0, void 0, function* () {
3519
+ const delatMilliseconds = ((_b = (_a = syncRatelimitDelays.get(db)) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0) - Date.now();
3520
+ if (delatMilliseconds > 0) {
3521
+ console.debug(`Stalling sync request ${delatMilliseconds} ms to spare ratelimits`);
3522
+ yield new Promise(resolve => setTimeout(resolve, delatMilliseconds));
3523
+ }
3524
+ });
3525
+ }
3526
+ function updateSyncRateLimitDelays(db, res) {
3527
+ const limit = res.headers.get('Ratelimit-Limit');
3528
+ const remaining = res.headers.get('Ratelimit-Remaining');
3529
+ const reset = res.headers.get('Ratelimit-Reset');
3530
+ if (limit && remaining && reset) {
3531
+ const limitNum = Number(limit);
3532
+ const remainingNum = Math.max(0, Number(remaining));
3533
+ const willResetInSeconds = Number(reset);
3534
+ if (remainingNum < limitNum / 2) {
3535
+ const delay = Math.ceil(willResetInSeconds / (remainingNum + 1));
3536
+ syncRatelimitDelays.set(db, new Date(Date.now() + delay * 1000));
3537
+ console.debug(`Sync ratelimit delay set to ${delay} seconds`);
3538
+ }
3539
+ else {
3540
+ syncRatelimitDelays.delete(db);
3541
+ console.debug(`Sync ratelimit delay cleared`);
3542
+ }
3543
+ }
3544
+ }
3545
+
3459
3546
  //import {BisonWebStreamReader} from "dreambase-library/dist/typeson-simplified/BisonWebStreamReader";
3460
3547
  function syncWithServer(changes, syncState, baseRevs, db, databaseUrl, schema, clientIdentity, currentUser) {
3461
3548
  return __awaiter(this, void 0, void 0, function* () {
@@ -3464,9 +3551,20 @@
3464
3551
  //
3465
3552
  const headers = {
3466
3553
  Accept: 'application/json, application/x-bison, application/x-bison-stream',
3467
- 'Content-Type': 'application/tson'
3554
+ 'Content-Type': 'application/tson',
3468
3555
  };
3469
- const accessToken = yield loadAccessToken(db);
3556
+ const updatedUser = yield loadAccessToken(db);
3557
+ /*
3558
+ if (updatedUser?.license && changes.length > 0) {
3559
+ if (updatedUser.license.status === 'expired') {
3560
+ throw new Error(`License has expired`);
3561
+ }
3562
+ if (updatedUser.license.status === 'deactivated') {
3563
+ throw new Error(`License deactivated`);
3564
+ }
3565
+ }
3566
+ */
3567
+ const accessToken = updatedUser === null || updatedUser === void 0 ? void 0 : updatedUser.accessToken;
3470
3568
  if (accessToken) {
3471
3569
  headers.Authorization = `Bearer ${accessToken}`;
3472
3570
  }
@@ -3475,27 +3573,31 @@
3475
3573
  dbID: syncState === null || syncState === void 0 ? void 0 : syncState.remoteDbId,
3476
3574
  clientIdentity,
3477
3575
  schema: schema || {},
3478
- lastPull: syncState ? {
3479
- serverRevision: syncState.serverRevision,
3480
- realms: syncState.realms,
3481
- inviteRealms: syncState.inviteRealms
3482
- } : undefined,
3576
+ lastPull: syncState
3577
+ ? {
3578
+ serverRevision: syncState.serverRevision,
3579
+ realms: syncState.realms,
3580
+ inviteRealms: syncState.inviteRealms,
3581
+ }
3582
+ : undefined,
3483
3583
  baseRevs,
3484
- changes: encodeIdsForServer(db.dx.core.schema, currentUser, changes)
3584
+ changes: encodeIdsForServer(db.dx.core.schema, currentUser, changes),
3485
3585
  };
3486
- console.debug("Sync request", syncRequest);
3586
+ console.debug('Sync request', syncRequest);
3487
3587
  db.syncStateChangedEvent.next({
3488
3588
  phase: 'pushing',
3489
3589
  });
3490
3590
  const res = yield fetch(`${databaseUrl}/sync`, {
3491
3591
  method: 'post',
3492
3592
  headers,
3493
- body: TSON.stringify(syncRequest)
3593
+ credentials: 'include',
3594
+ body: TSON.stringify(syncRequest),
3494
3595
  });
3495
3596
  //const contentLength = Number(res.headers.get('content-length'));
3496
3597
  db.syncStateChangedEvent.next({
3497
- phase: 'pulling'
3598
+ phase: 'pulling',
3498
3599
  });
3600
+ updateSyncRateLimitDelays(db, res);
3499
3601
  if (!res.ok) {
3500
3602
  throw new HttpError(res);
3501
3603
  }
@@ -3552,7 +3654,7 @@
3552
3654
 
3553
3655
  function throwIfCancelled(cancelToken) {
3554
3656
  if (cancelToken === null || cancelToken === void 0 ? void 0 : cancelToken.cancelled)
3555
- throw new Dexie__default["default"].AbortError(`Operation was cancelled`);
3657
+ throw new Dexie.AbortError(`Operation was cancelled`);
3556
3658
  }
3557
3659
 
3558
3660
  /* Need this because navigator.onLine seems to say "false" when it is actually online.
@@ -3604,7 +3706,7 @@
3604
3706
  }
3605
3707
  }
3606
3708
  else {
3607
- Dexie__default["default"].setByKeyPath(obj, keyPath, value);
3709
+ Dexie.setByKeyPath(obj, keyPath, value);
3608
3710
  }
3609
3711
  }
3610
3712
  resultKeys.push(key);
@@ -3619,7 +3721,7 @@
3619
3721
 
3620
3722
  function applyServerChanges(changes, db) {
3621
3723
  return __awaiter(this, void 0, void 0, function* () {
3622
- console.debug('Applying server changes', changes, Dexie__default["default"].currentTransaction);
3724
+ console.debug('Applying server changes', changes, Dexie.currentTransaction);
3623
3725
  for (const { table: tableName, muts } of changes) {
3624
3726
  const table = db.table(tableName);
3625
3727
  if (!table)
@@ -3656,7 +3758,7 @@
3656
3758
  else {
3657
3759
  keys.forEach((key, i) => {
3658
3760
  // Make sure inbound keys are consistent
3659
- Dexie__default["default"].setByKeyPath(mut.values[i], primaryKey.keyPath, key);
3761
+ Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath, key);
3660
3762
  });
3661
3763
  yield table.bulkAdd(mut.values);
3662
3764
  }
@@ -3668,7 +3770,7 @@
3668
3770
  else {
3669
3771
  keys.forEach((key, i) => {
3670
3772
  // Make sure inbound keys are consistent
3671
- Dexie__default["default"].setByKeyPath(mut.values[i], primaryKey.keyPath, key);
3773
+ Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath, key);
3672
3774
  });
3673
3775
  yield table.bulkPut(mut.values);
3674
3776
  }
@@ -3697,12 +3799,13 @@
3697
3799
  function sync(db, options, schema, syncOptions) {
3698
3800
  return _sync
3699
3801
  .apply(this, arguments)
3700
- .then(() => {
3802
+ .then((result) => {
3701
3803
  if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) { // && syncOptions?.purpose !== 'push') {
3702
3804
  db.syncStateChangedEvent.next({
3703
3805
  phase: 'in-sync',
3704
3806
  });
3705
3807
  }
3808
+ return result;
3706
3809
  })
3707
3810
  .catch((error) => __awaiter(this, void 0, void 0, function* () {
3708
3811
  if (syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)
@@ -3917,6 +4020,7 @@
3917
4020
  }));
3918
4021
  if (!done) {
3919
4022
  console.debug('MORE SYNC NEEDED. Go for it again!');
4023
+ yield checkSyncRateLimitDelay(db);
3920
4024
  return yield _sync(db, options, schema, { isInitialSync, cancelToken });
3921
4025
  }
3922
4026
  console.debug('SYNC DONE', { isInitialSync });
@@ -4053,6 +4157,8 @@
4053
4157
  yield db.table('$logins').update(user.userId, {
4054
4158
  accessToken: refreshedLogin.accessToken,
4055
4159
  accessTokenExpiration: refreshedLogin.accessTokenExpiration,
4160
+ claims: refreshedLogin.claims,
4161
+ license: refreshedLogin.license,
4056
4162
  });
4057
4163
  // Updating $logins will trigger emission of db.cloud.currentUser observable, which
4058
4164
  // in turn will lead to that connectWebSocket.ts will reconnect the socket with the
@@ -4129,7 +4235,7 @@
4129
4235
  return; // Ignore message
4130
4236
  }
4131
4237
  // Verify also that the message is based on the exact same set of realms
4132
- const ourRealmSetHash = yield Dexie__default["default"].waitFor(
4238
+ const ourRealmSetHash = yield Dexie.waitFor(
4133
4239
  // Keep TX in non-IDB work
4134
4240
  computeRealmSetHash(syncState));
4135
4241
  console.debug('ourRealmSetHash', ourRealmSetHash);
@@ -4336,7 +4442,7 @@
4336
4442
  const IS_SERVICE_WORKER = typeof self !== "undefined" && "clients" in self && !self.document;
4337
4443
 
4338
4444
  function throwVersionIncrementNeeded() {
4339
- throw new Dexie__default["default"].SchemaError(`Version increment needed to allow dexie-cloud change tracking`);
4445
+ throw new Dexie.SchemaError(`Version increment needed to allow dexie-cloud change tracking`);
4340
4446
  }
4341
4447
 
4342
4448
  const { toString } = {};
@@ -4452,14 +4558,14 @@
4452
4558
  if (!table.schema.primaryKey.outbound) {
4453
4559
  if (!valueClones)
4454
4560
  valueClones = req.values.slice();
4455
- valueClones[idx] = Dexie__default["default"].deepClone(valueClones[idx]);
4456
- Dexie__default["default"].setByKeyPath(valueClones[idx], table.schema.primaryKey.keyPath, keys[idx]);
4561
+ valueClones[idx] = Dexie.deepClone(valueClones[idx]);
4562
+ Dexie.setByKeyPath(valueClones[idx], table.schema.primaryKey.keyPath, keys[idx]);
4457
4563
  }
4458
4564
  }
4459
4565
  else if (typeof key !== 'string' ||
4460
4566
  (!key.startsWith(idPrefix) && !key.startsWith('#' + idPrefix))) {
4461
4567
  // Key was specified by caller. Verify it complies with id prefix.
4462
- throw new Dexie__default["default"].ConstraintError(`The ID "${key}" is not valid for table "${tableName}". ` +
4568
+ throw new Dexie.ConstraintError(`The ID "${key}" is not valid for table "${tableName}". ` +
4463
4569
  `Primary '@' keys requires the key to be prefixed with "${idPrefix}" (or "#${idPrefix}).\n` +
4464
4570
  `If you want to generate IDs programmatically, remove '@' from the schema to get rid of this constraint. Dexie Cloud supports custom IDs as long as they are random and globally unique.`);
4465
4571
  }
@@ -4484,7 +4590,7 @@
4484
4590
  const type = Array.isArray(key)
4485
4591
  ? key.map(toStringTag).join(',')
4486
4592
  : toStringTag(key);
4487
- throw new Dexie__default["default"].ConstraintError(`Invalid primary key type ${type} for table ${tableName}. Tables marked for sync has primary keys of type string or Array of string (and optional numbers)`);
4593
+ throw new Dexie.ConstraintError(`Invalid primary key type ${type} for table ${tableName}. Tables marked for sync has primary keys of type string or Array of string (and optional numbers)`);
4488
4594
  }
4489
4595
  });
4490
4596
  }
@@ -4621,6 +4727,13 @@
4621
4727
 
4622
4728
  const outstandingTransactions = new rxjs.BehaviorSubject(new Set());
4623
4729
 
4730
+ function isEagerSyncDisabled(db) {
4731
+ var _a, _b, _c, _d;
4732
+ return (((_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.disableEagerSync) ||
4733
+ ((_c = (_b = db.cloud.currentUser.value) === null || _b === void 0 ? void 0 : _b.license) === null || _c === void 0 ? void 0 : _c.status) !== 'ok' ||
4734
+ !((_d = db.cloud.options) === null || _d === void 0 ? void 0 : _d.databaseUrl));
4735
+ }
4736
+
4624
4737
  /** Tracks all mutations in the same transaction as the mutations -
4625
4738
  * so it is guaranteed that no mutation goes untracked - and if transaction
4626
4739
  * aborts, the mutations won't be tracked.
@@ -4629,7 +4742,7 @@
4629
4742
  * changes to server and cleanup the tracked mutations once the server has
4630
4743
  * ackowledged that it got them.
4631
4744
  */
4632
- function createMutationTrackingMiddleware({ currentUserObservable, db }) {
4745
+ function createMutationTrackingMiddleware({ currentUserObservable, db, }) {
4633
4746
  return {
4634
4747
  stack: 'dbcore',
4635
4748
  name: 'MutationTrackingMiddleware',
@@ -4640,7 +4753,7 @@
4640
4753
  try {
4641
4754
  mutTableMap = new Map(ordinaryTables.map((tbl) => [
4642
4755
  tbl.name,
4643
- core.table(`$${tbl.name}_mutations`)
4756
+ core.table(`$${tbl.name}_mutations`),
4644
4757
  ]));
4645
4758
  }
4646
4759
  catch (_a) {
@@ -4674,15 +4787,9 @@
4674
4787
  outstandingTransactions.next(outstandingTransactions.value);
4675
4788
  };
4676
4789
  const txComplete = () => {
4677
- var _a;
4678
- if (tx.mutationsAdded && ((_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.databaseUrl)) {
4679
- if (db.cloud.usingServiceWorker) {
4680
- console.debug('registering sync event');
4681
- registerSyncEvent(db, "push");
4682
- }
4683
- else {
4684
- db.localSyncEvent.next({ purpose: "push" });
4685
- }
4790
+ if (tx.mutationsAdded &&
4791
+ !isEagerSyncDisabled(db)) {
4792
+ triggerSync(db, 'push');
4686
4793
  }
4687
4794
  removeTransaction();
4688
4795
  };
@@ -4749,7 +4856,7 @@
4749
4856
  .query({
4750
4857
  query: { range: req.range, index: schema.primaryKey },
4751
4858
  trans: req.trans,
4752
- values: false
4859
+ values: false,
4753
4860
  })
4754
4861
  // Do a delete request instead, but keep the criteria info for the server to execute
4755
4862
  .then((res) => {
@@ -4757,7 +4864,7 @@
4757
4864
  type: 'delete',
4758
4865
  keys: res.result,
4759
4866
  trans: req.trans,
4760
- criteria: { index: null, range: req.range }
4867
+ criteria: { index: null, range: req.range },
4761
4868
  });
4762
4869
  })
4763
4870
  : mutateAndLog(req);
@@ -4765,7 +4872,7 @@
4765
4872
  function mutateAndLog(req) {
4766
4873
  const trans = req.trans;
4767
4874
  trans.mutationsAdded = true;
4768
- const { txid, currentUser: { userId } } = trans;
4875
+ const { txid, currentUser: { userId }, } = trans;
4769
4876
  const { type } = req;
4770
4877
  const opNo = ++trans.opCount;
4771
4878
  return table.mutate(req).then((res) => {
@@ -4786,7 +4893,7 @@
4786
4893
  keys,
4787
4894
  criteria: req.criteria,
4788
4895
  txid,
4789
- userId
4896
+ userId,
4790
4897
  }
4791
4898
  : req.type === 'add'
4792
4899
  ? {
@@ -4796,7 +4903,7 @@
4796
4903
  keys,
4797
4904
  txid,
4798
4905
  userId,
4799
- values
4906
+ values,
4800
4907
  }
4801
4908
  : req.criteria && req.changeSpec
4802
4909
  ? {
@@ -4808,7 +4915,7 @@
4808
4915
  criteria: req.criteria,
4809
4916
  changeSpec: req.changeSpec,
4810
4917
  txid,
4811
- userId
4918
+ userId,
4812
4919
  }
4813
4920
  : updates
4814
4921
  ? {
@@ -4819,7 +4926,7 @@
4819
4926
  keys: updates.keys,
4820
4927
  changeSpecs: updates.changeSpecs,
4821
4928
  txid,
4822
- userId
4929
+ userId,
4823
4930
  }
4824
4931
  : {
4825
4932
  type: 'upsert',
@@ -4828,7 +4935,7 @@
4828
4935
  keys,
4829
4936
  values,
4830
4937
  txid,
4831
- userId
4938
+ userId,
4832
4939
  };
4833
4940
  return keys.length > 0 || ('criteria' in req && req.criteria)
4834
4941
  ? mutsTable
@@ -4838,7 +4945,7 @@
4838
4945
  });
4839
4946
  }
4840
4947
  } });
4841
- }
4948
+ },
4842
4949
  };
4843
4950
  }
4844
4951
 
@@ -5197,6 +5304,20 @@
5197
5304
  }
5198
5305
  }
5199
5306
 
5307
+ class InvalidLicenseError extends Error {
5308
+ constructor(license) {
5309
+ super(license === 'expired'
5310
+ ? `License expired`
5311
+ : license === 'deactivated'
5312
+ ? `User deactivated`
5313
+ : 'Invalid license');
5314
+ this.name = 'InvalidLicenseError';
5315
+ if (license) {
5316
+ this.license = license;
5317
+ }
5318
+ }
5319
+ }
5320
+
5200
5321
  function sleep(ms) {
5201
5322
  return new Promise((resolve) => setTimeout(resolve, ms));
5202
5323
  }
@@ -5230,7 +5351,12 @@
5230
5351
  function createObservable() {
5231
5352
  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.
5232
5353
  take(1), // Don't continue waking up whenever syncState change
5233
- switchMap((syncState) => db.cloud.currentUser.pipe(map((userLogin) => [userLogin, syncState]))), switchMap(([userLogin, syncState]) => userIsReallyActive.pipe(map((isActive) => [isActive ? userLogin : null, syncState]))), switchMap(([userLogin, syncState]) => {
5354
+ switchMap((syncState) => db.cloud.currentUser.pipe(map((userLogin) => [userLogin, syncState]))), switchMap(([userLogin, syncState]) => {
5355
+ /*if (userLogin.license?.status && userLogin.license.status !== 'ok') {
5356
+ throw new InvalidLicenseError();
5357
+ }*/
5358
+ return userIsReallyActive.pipe(map((isActive) => [isActive ? userLogin : null, syncState]));
5359
+ }), switchMap(([userLogin, syncState]) => {
5234
5360
  if ((userLogin === null || userLogin === void 0 ? void 0 : userLogin.isLoggedIn) && !(syncState === null || syncState === void 0 ? void 0 : syncState.realms.includes(userLogin.userId))) {
5235
5361
  // We're in an in-between state when user is logged in but the user's realms are not yet synced.
5236
5362
  // Don't make this change reconnect the websocket just yet. Wait till syncState is updated
@@ -5259,14 +5385,20 @@
5259
5385
  yield db.table('$logins').update(user.userId, {
5260
5386
  accessToken: refreshedLogin.accessToken,
5261
5387
  accessTokenExpiration: refreshedLogin.accessTokenExpiration,
5388
+ claims: refreshedLogin.claims,
5389
+ license: refreshedLogin.license,
5262
5390
  });
5263
5391
  })), switchMap(() => createObservable()));
5264
5392
  }
5265
5393
  else {
5266
- return rxjs.throwError(error);
5394
+ return rxjs.throwError(() => error);
5267
5395
  }
5268
5396
  }), catchError((error) => {
5269
5397
  db.cloud.webSocketStatus.next("error");
5398
+ if (error instanceof InvalidLicenseError) {
5399
+ // Don't retry. Just throw and don't try connect again.
5400
+ return rxjs.throwError(() => error);
5401
+ }
5270
5402
  return rxjs.from(waitAndReconnectWhenUserDoesSomething(error)).pipe(switchMap(() => createObservable()));
5271
5403
  }));
5272
5404
  }
@@ -5295,97 +5427,12 @@
5295
5427
  });
5296
5428
  }
5297
5429
 
5298
- const SECONDS = 1000;
5299
- const MINUTES = 60 * SECONDS;
5300
-
5301
- const myId = randomString(16);
5302
-
5303
- const GUARDED_JOB_HEARTBEAT = 1 * SECONDS;
5304
- const GUARDED_JOB_TIMEOUT = 1 * MINUTES;
5305
- function performGuardedJob(db, jobName, jobsTableName, job, { awaitRemoteJob } = {}) {
5306
- return __awaiter(this, void 0, void 0, function* () {
5307
- // Start working.
5308
- //
5309
- // Check if someone else is working on this already.
5310
- //
5311
- const jobsTable = db.table(jobsTableName);
5312
- function aquireLock() {
5313
- return __awaiter(this, void 0, void 0, function* () {
5314
- const gotTheLock = yield db.transaction('rw!', jobsTableName, () => __awaiter(this, void 0, void 0, function* () {
5315
- const currentWork = yield jobsTable.get(jobName);
5316
- if (!currentWork) {
5317
- // No one else is working. Let's record that we are.
5318
- yield jobsTable.add({
5319
- nodeId: myId,
5320
- started: new Date(),
5321
- heartbeat: new Date()
5322
- }, jobName);
5323
- return true;
5324
- }
5325
- else if (currentWork.heartbeat.getTime() <
5326
- Date.now() - GUARDED_JOB_TIMEOUT) {
5327
- console.warn(`Latest ${jobName} worker seem to have died.\n`, `The dead job started:`, currentWork.started, `\n`, `Last heart beat was:`, currentWork.heartbeat, '\n', `We're now taking over!`);
5328
- // Now, take over!
5329
- yield jobsTable.put({
5330
- nodeId: myId,
5331
- started: new Date(),
5332
- heartbeat: new Date()
5333
- }, jobName);
5334
- return true;
5335
- }
5336
- return false;
5337
- }));
5338
- if (gotTheLock)
5339
- return true;
5340
- // Someone else took the job.
5341
- if (awaitRemoteJob) {
5342
- try {
5343
- const jobDoneObservable = rxjs.from(Dexie.liveQuery(() => jobsTable.get(jobName))).pipe(timeout(GUARDED_JOB_TIMEOUT), filter((job) => !job)); // Wait til job is not there anymore.
5344
- yield jobDoneObservable.toPromise();
5345
- return false;
5346
- }
5347
- catch (err) {
5348
- if (err.name !== 'TimeoutError') {
5349
- throw err;
5350
- }
5351
- // Timeout stopped us! Try aquire the lock now.
5352
- // It will likely succeed this time unless
5353
- // another client took it.
5354
- return yield aquireLock();
5355
- }
5356
- }
5357
- return false;
5358
- });
5359
- }
5360
- if (yield aquireLock()) {
5361
- // We own the lock entry and can do our job undisturbed.
5362
- // We're not within a transaction, but these type of locks
5363
- // spans over transactions.
5364
- // Start our heart beat during the job.
5365
- // Use setInterval to make sure we are updating heartbeat even during long-lived fetch calls.
5366
- const heartbeat = setInterval(() => {
5367
- jobsTable.update(jobName, (job) => {
5368
- if (job.nodeId === myId) {
5369
- job.heartbeat = new Date();
5370
- }
5371
- });
5372
- }, GUARDED_JOB_HEARTBEAT);
5373
- try {
5374
- return yield job();
5375
- }
5376
- finally {
5377
- // Stop heartbeat
5378
- clearInterval(heartbeat);
5379
- // Remove the persisted job state:
5380
- yield db.transaction('rw!', jobsTableName, () => __awaiter(this, void 0, void 0, function* () {
5381
- const currentWork = yield jobsTable.get(jobName);
5382
- if (currentWork && currentWork.nodeId === myId) {
5383
- yield jobsTable.delete(jobName);
5384
- }
5385
- }));
5386
- }
5387
- }
5388
- });
5430
+ function performGuardedJob(db, jobName, job) {
5431
+ if (typeof navigator === 'undefined' || !navigator.locks) {
5432
+ // No support for guarding jobs. IE11, node.js, etc.
5433
+ return job();
5434
+ }
5435
+ return navigator.locks.request(db.name + '|' + jobName, () => job());
5389
5436
  }
5390
5437
 
5391
5438
  const ongoingSyncs = new WeakMap();
@@ -5439,6 +5486,9 @@
5439
5486
  function _syncIfPossible() {
5440
5487
  return __awaiter(this, void 0, void 0, function* () {
5441
5488
  try {
5489
+ // Check if should delay sync due to ratelimit:
5490
+ yield checkSyncRateLimitDelay(db);
5491
+ // Check if we need to lock the sync job. Not needed if we are the service worker.
5442
5492
  if (db.cloud.isServiceWorkerDB) {
5443
5493
  // We are the dedicated sync SW:
5444
5494
  yield sync(db, cloudOptions, cloudSchema, options);
@@ -5446,7 +5496,7 @@
5446
5496
  else if (!db.cloud.usingServiceWorker) {
5447
5497
  // We use a flow that is better suited for the case when multiple workers want to
5448
5498
  // do the same thing.
5449
- yield performGuardedJob(db, CURRENT_SYNC_WORKER, '$jobs', () => sync(db, cloudOptions, cloudSchema, options));
5499
+ yield performGuardedJob(db, CURRENT_SYNC_WORKER, () => sync(db, cloudOptions, cloudSchema, options));
5450
5500
  }
5451
5501
  else {
5452
5502
  assert(false);
@@ -5468,19 +5518,29 @@
5468
5518
  }
5469
5519
  }
5470
5520
 
5521
+ const SECONDS = 1000;
5522
+ const MINUTES = 60 * SECONDS;
5523
+
5471
5524
  function LocalSyncWorker(db, cloudOptions, cloudSchema) {
5472
5525
  let localSyncEventSubscription = null;
5473
5526
  //let syncHandler: ((event: Event) => void) | null = null;
5474
5527
  //let periodicSyncHandler: ((event: Event) => void) | null = null;
5475
5528
  let cancelToken = { cancelled: false };
5529
+ let retryHandle = null;
5530
+ let retryPurpose = null; // "pull" is superset of "push"
5476
5531
  function syncAndRetry(purpose, retryNum = 1) {
5477
5532
  // Use setTimeout() to get onto a clean stack and
5478
5533
  // break free from possible active transaction:
5479
5534
  setTimeout(() => {
5535
+ if (retryHandle)
5536
+ clearTimeout(retryHandle);
5537
+ const combPurpose = retryPurpose === 'pull' ? 'pull' : purpose;
5538
+ retryHandle = null;
5539
+ retryPurpose = null;
5480
5540
  syncIfPossible(db, cloudOptions, cloudSchema, {
5481
5541
  cancelToken,
5482
5542
  retryImmediatelyOnFetchError: true,
5483
- purpose,
5543
+ purpose: combPurpose,
5484
5544
  }).catch((e) => {
5485
5545
  console.error('error in syncIfPossible()', e);
5486
5546
  if (cancelToken.cancelled) {
@@ -5490,7 +5550,13 @@
5490
5550
  // Mimic service worker sync event: retry 3 times
5491
5551
  // * first retry after 5 minutes
5492
5552
  // * second retry 15 minutes later
5493
- setTimeout(() => syncAndRetry(purpose, retryNum + 1), [0, 5, 15][retryNum] * MINUTES);
5553
+ const combinedPurpose = retryPurpose && retryPurpose === 'pull' ? 'pull' : purpose;
5554
+ const handle = setTimeout(() => syncAndRetry(combinedPurpose, retryNum + 1), [0, 5, 15][retryNum] * MINUTES);
5555
+ // Cancel the previous retryHandle if it exists to avoid scheduling loads of retries.
5556
+ if (retryHandle)
5557
+ clearTimeout(retryHandle);
5558
+ retryHandle = handle;
5559
+ retryPurpose = combinedPurpose;
5494
5560
  }
5495
5561
  });
5496
5562
  }, 0);
@@ -5538,11 +5604,11 @@
5538
5604
  for (const table of db.tables) {
5539
5605
  if ((_b = (_a = db.cloud.schema) === null || _a === void 0 ? void 0 : _a[table.name]) === null || _b === void 0 ? void 0 : _b.markedForSync) {
5540
5606
  if (table.schema.primKey.auto) {
5541
- throw new Dexie__default["default"].SchemaError(`Table ${table.name} is both autoIncremented and synced. ` +
5607
+ throw new Dexie.SchemaError(`Table ${table.name} is both autoIncremented and synced. ` +
5542
5608
  `Use db.cloud.configure({unsyncedTables: [${JSON.stringify(table.name)}]}) to blacklist it from sync`);
5543
5609
  }
5544
5610
  if (!table.schema.primKey.keyPath) {
5545
- throw new Dexie__default["default"].SchemaError(`Table ${table.name} cannot be both synced and outbound. ` +
5611
+ throw new Dexie.SchemaError(`Table ${table.name} cannot be both synced and outbound. ` +
5546
5612
  `Use db.cloud.configure({unsyncedTables: [${JSON.stringify(table.name)}]}) to blacklist it from sync`);
5547
5613
  }
5548
5614
  }
@@ -5557,10 +5623,12 @@
5557
5623
  },
5558
5624
  Alert: {
5559
5625
  error: {
5560
- color: "red"
5626
+ color: "red",
5627
+ fontWeight: "bold"
5561
5628
  },
5562
5629
  warning: {
5563
- color: "yellow"
5630
+ color: "#f80",
5631
+ fontWeight: "bold"
5564
5632
  },
5565
5633
  info: {
5566
5634
  color: "black"
@@ -5601,7 +5669,8 @@
5601
5669
  border: "3px solid #3d3d5d",
5602
5670
  borderRadius: "8px",
5603
5671
  boxShadow: "0 0 80px 10px #666",
5604
- width: "auto"
5672
+ width: "auto",
5673
+ fontFamily: "sans-serif",
5605
5674
  },
5606
5675
  Input: {
5607
5676
  height: "35px",
@@ -5622,11 +5691,26 @@
5622
5691
 
5623
5692
  var t,r,u,i,o=0,c=[],f=[],e=l$1.__b,a=l$1.__r,v=l$1.diffed,l=l$1.__c,m=l$1.unmount;function d(t,u){l$1.__h&&l$1.__h(r,t,o||u),o=0;var i=r.__H||(r.__H={__:[],__h:[]});return t>=i.__.length&&i.__.push({__V:f}),i.__[t]}function p(n){return o=1,y(z,n)}function y(n,u,i){var o=d(t++,2);if(o.t=n,!o.__c&&(o.__=[i?i(u):z(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}));}],o.__c=r,!r.u)){r.u=!0;var c=r.shouldComponentUpdate;r.shouldComponentUpdate=function(n,t,r){if(!o.__c.__H)return !0;var u=o.__c.__H.__.filter(function(n){return n.__c});if(u.every(function(n){return !n.__N}))return !c||c.call(this,n,t,r);var i=!1;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=!0);}}),!!i&&(!c||c.call(this,n,t,r))};}return o.__N||o.__}function s(u,i){var o=d(t++,4);!l$1.__s&&w(o.__H,i)&&(o.__=u,o.i=i,r.__h.push(o));}function _(n){return o=5,F(function(){return {current:n}},[])}function F(n,r){var u=d(t++,7);return w(u.__H,r)?(u.__V=n(),u.i=r,u.__h=n,u.__V):u.__}function b(){for(var t;t=c.shift();)if(t.__P&&t.__H)try{t.__H.__h.forEach(j),t.__H.__h.forEach(k),t.__H.__h=[];}catch(r){t.__H.__h=[],l$1.__e(r,t.__v);}}l$1.__b=function(n){r=null,e&&e(n);},l$1.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.__V=f,n.__N=n.i=void 0;})):(i.__h.forEach(j),i.__h.forEach(k),i.__h=[])),u=r;},l$1.diffed=function(t){v&&v(t);var o=t.__c;o&&o.__H&&(o.__H.__h.length&&(1!==c.push(o)&&i===l$1.requestAnimationFrame||((i=l$1.requestAnimationFrame)||function(n){var t,r=function(){clearTimeout(u),g&&cancelAnimationFrame(t),setTimeout(n);},u=setTimeout(r,100);g&&(t=requestAnimationFrame(r));})(b)),o.__H.__.forEach(function(n){n.i&&(n.__H=n.i),n.__V!==f&&(n.__=n.__V),n.i=void 0,n.__V=f;})),u=r=null;},l$1.__c=function(t,r){r.some(function(t){try{t.__h.forEach(j),t.__h=t.__h.filter(function(n){return !n.__||k(n)});}catch(u){r.some(function(n){n.__h&&(n.__h=[]);}),r=[],l$1.__e(u,t.__v);}}),l&&l(t,r);},l$1.unmount=function(t){m&&m(t);var r,u=t.__c;u&&u.__H&&(u.__H.__.forEach(function(n){try{j(n);}catch(n){r=n;}}),r&&l$1.__e(r,u.__v));};var g="function"==typeof requestAnimationFrame;function j(n){var t=r,u=n.__c;"function"==typeof u&&(n.__c=void 0,u()),r=t;}function k(n){var t=r;n.__c=n.__(),r=t;}function w(n,t){return !n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function z(n,t){return "function"==typeof t?t(n):t}
5624
5693
 
5694
+ /** Resolve a message template with parameters.
5695
+ *
5696
+ * Example:
5697
+ * resolveText({
5698
+ * message: "Hello {name}!",
5699
+ * messageCode: "HELLO",
5700
+ * messageParams: {name: "David"}
5701
+ * }) => "Hello David!"
5702
+ *
5703
+ * @param message Template message with {vars} in it.
5704
+ * @param messageCode Unique code for the message. Can be used for translation.
5705
+ * @param messageParams Parameters to be used in the message.
5706
+ * @returns A final message where parameters have been replaced with values.
5707
+ */
5625
5708
  function resolveText({ message, messageCode, messageParams }) {
5626
- return message.replace(/\{\w+\}/ig, n => messageParams[n.substr(1, n.length - 2)]);
5709
+ return message.replace(/\{\w+\}/ig, n => messageParams[n.substring(1, n.length - 1)]);
5627
5710
  }
5628
5711
 
5629
- function LoginDialog({ title, alerts, fields, onCancel, onSubmit, }) {
5712
+ const OTP_LENGTH = 8;
5713
+ function LoginDialog({ title, type, alerts, fields, submitLabel, cancelLabel, onCancel, onSubmit, }) {
5630
5714
  const [params, setParams] = p({});
5631
5715
  const firstFieldRef = _(null);
5632
5716
  s(() => { var _a; return (_a = firstFieldRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, []);
@@ -5634,21 +5718,34 @@
5634
5718
  h(p$1, null,
5635
5719
  h("h3", { style: Styles.WindowHeader }, title),
5636
5720
  alerts.map((alert) => (h("p", { style: Styles.Alert[alert.type] }, resolveText(alert)))),
5637
- h("form", { onSubmit: ev => {
5721
+ h("form", { onSubmit: (ev) => {
5638
5722
  ev.preventDefault();
5639
5723
  onSubmit(params);
5640
- } }, Object.entries(fields).map(([fieldName, { type, label, placeholder }], idx) => (h("label", { style: Styles.Label },
5724
+ } }, Object.entries(fields).map(([fieldName, { type, label, placeholder }], idx) => (h("label", { style: Styles.Label, key: idx },
5641
5725
  label ? `${label}: ` : '',
5642
- h("input", { ref: idx === 0 ? firstFieldRef : undefined, type: type, name: fieldName, autoComplete: "on", style: Styles.Input, autoFocus: true, placeholder: placeholder, value: params[fieldName] || '', onInput: (ev) => { var _a; return setParams(Object.assign(Object.assign({}, params), { [fieldName]: valueTransformer(type, (_a = ev.target) === null || _a === void 0 ? void 0 : _a['value']) })); } })))))),
5726
+ h("input", { ref: idx === 0 ? firstFieldRef : undefined, type: type, name: fieldName, autoComplete: "on", style: Styles.Input, autoFocus: true, placeholder: placeholder, value: params[fieldName] || '', onInput: (ev) => {
5727
+ var _a;
5728
+ const value = valueTransformer(type, (_a = ev.target) === null || _a === void 0 ? void 0 : _a['value']);
5729
+ let updatedParams = Object.assign(Object.assign({}, params), { [fieldName]: value });
5730
+ setParams(updatedParams);
5731
+ if (type === 'otp' && (value === null || value === void 0 ? void 0 : value.trim().length) === OTP_LENGTH) {
5732
+ // Auto-submit when OTP is filled in.
5733
+ onSubmit(updatedParams);
5734
+ }
5735
+ } })))))),
5643
5736
  h("div", { style: Styles.ButtonsDiv },
5644
- h("button", { type: "submit", style: Styles.Button, onClick: () => onSubmit(params) }, "Submit"),
5645
- h("button", { style: Styles.Button, onClick: onCancel }, "Cancel"))));
5737
+ h(p$1, null,
5738
+ h("button", { type: "submit", style: Styles.Button, onClick: () => onSubmit(params) }, submitLabel),
5739
+ cancelLabel && (h("button", { style: Styles.Button, onClick: onCancel }, cancelLabel))))));
5646
5740
  }
5647
5741
  function valueTransformer(type, value) {
5648
5742
  switch (type) {
5649
- case "email": return value.toLowerCase();
5650
- case "otp": return value.toUpperCase();
5651
- default: return value;
5743
+ case 'email':
5744
+ return value.toLowerCase();
5745
+ case 'otp':
5746
+ return value.toUpperCase();
5747
+ default:
5748
+ return value;
5652
5749
  }
5653
5750
  }
5654
5751
 
@@ -5702,11 +5799,20 @@
5702
5799
  }
5703
5800
  };
5704
5801
  }
5705
- // TODO:
5706
- /*
5707
- * Gjort klart allt kring user interaction förutom att mounta default-ui på ett element.
5708
- * Också att kolla först om nån annan subscribar och i så fall inte göra nåt.
5709
- */
5802
+
5803
+ function associate(factory) {
5804
+ const wm = new WeakMap();
5805
+ return (x) => {
5806
+ let rv = wm.get(x);
5807
+ if (!rv) {
5808
+ rv = factory(x);
5809
+ wm.set(x, rv);
5810
+ }
5811
+ return rv;
5812
+ };
5813
+ }
5814
+
5815
+ const getCurrentUserEmitter = associate((db) => new rxjs.BehaviorSubject(UNAUTHORIZED_USER));
5710
5816
 
5711
5817
  function computeSyncState(db) {
5712
5818
  let _prevStatus = db.cloud.webSocketStatus.value;
@@ -5734,8 +5840,17 @@
5734
5840
  return rxjs.combineLatest([
5735
5841
  lazyWebSocketStatus,
5736
5842
  db.syncStateChangedEvent.pipe(startWith({ phase: 'initial' })),
5843
+ getCurrentUserEmitter(db.dx._novip),
5737
5844
  userIsReallyActive
5738
- ]).pipe(map(([status, syncState, userIsActive]) => {
5845
+ ]).pipe(map(([status, syncState, user, userIsActive]) => {
5846
+ var _a;
5847
+ if (((_a = user.license) === null || _a === void 0 ? void 0 : _a.status) && user.license.status !== 'ok') {
5848
+ return {
5849
+ phase: 'offline',
5850
+ status: 'offline',
5851
+ license: user.license.status
5852
+ };
5853
+ }
5739
5854
  let { phase, error, progress } = syncState;
5740
5855
  let adjustedStatus = status;
5741
5856
  if (phase === 'error') {
@@ -5768,23 +5883,12 @@
5768
5883
  error,
5769
5884
  progress,
5770
5885
  status: isOnline ? adjustedStatus : 'offline',
5886
+ license: 'ok'
5771
5887
  };
5772
5888
  return retState;
5773
5889
  }));
5774
5890
  }
5775
5891
 
5776
- function associate(factory) {
5777
- const wm = new WeakMap();
5778
- return (x) => {
5779
- let rv = wm.get(x);
5780
- if (!rv) {
5781
- rv = factory(x);
5782
- wm.set(x, rv);
5783
- }
5784
- return rv;
5785
- };
5786
- }
5787
-
5788
5892
  function createSharedValueObservable(o, defaultValue) {
5789
5893
  let currentValue = defaultValue;
5790
5894
  let shared = rxjs.from(o).pipe(rxjs.map((x) => (currentValue = x)), rxjs.share({ resetOnRefCountZero: () => rxjs.timer(1000) }));
@@ -5826,8 +5930,6 @@
5826
5930
  })), {});
5827
5931
  });
5828
5932
 
5829
- const getCurrentUserEmitter = associate((db) => new rxjs.BehaviorSubject(UNAUTHORIZED_USER));
5830
-
5831
5933
  const getInternalAccessControlObservable = associate((db) => {
5832
5934
  return createSharedValueObservable(getCurrentUserEmitter(db._novip).pipe(switchMap((currentUser) => Dexie.liveQuery(() => db.transaction('r', 'realms', 'members', () => Promise.all([
5833
5935
  db.members.where({ userId: currentUser.userId }).toArray(),
@@ -6106,7 +6208,7 @@
6106
6208
  let closed = false;
6107
6209
  function throwIfClosed() {
6108
6210
  if (closed)
6109
- throw new Dexie__default["default"].DatabaseClosedError();
6211
+ throw new Dexie.DatabaseClosedError();
6110
6212
  }
6111
6213
  dbOnClosed(dexie, () => {
6112
6214
  subscriptions.forEach((subscription) => subscription.unsubscribe());
@@ -6117,7 +6219,7 @@
6117
6219
  });
6118
6220
  const syncComplete = new rxjs.Subject();
6119
6221
  dexie.cloud = {
6120
- version: '4.0.1-beta.46',
6222
+ version: '{version}',
6121
6223
  options: Object.assign({}, DEFAULT_OPTIONS),
6122
6224
  schema: null,
6123
6225
  get currentUserId() {
@@ -6153,11 +6255,24 @@
6153
6255
  }
6154
6256
  updateSchemaFromOptions(dexie.cloud.schema, dexie.cloud.options);
6155
6257
  },
6258
+ logout({ force } = {}) {
6259
+ return __awaiter(this, void 0, void 0, function* () {
6260
+ force
6261
+ ? yield _logout(DexieCloudDB(dexie), { deleteUnsyncedData: true })
6262
+ : yield logout(DexieCloudDB(dexie));
6263
+ });
6264
+ },
6156
6265
  sync({ wait, purpose } = { wait: true, purpose: 'push' }) {
6266
+ var _a;
6157
6267
  return __awaiter(this, void 0, void 0, function* () {
6158
6268
  if (wait === undefined)
6159
6269
  wait = true;
6160
6270
  const db = DexieCloudDB(dexie);
6271
+ const licenseStatus = ((_a = db.cloud.currentUser.value.license) === null || _a === void 0 ? void 0 : _a.status) || 'ok';
6272
+ if (licenseStatus !== 'ok') {
6273
+ // Refresh access token to check for updated license
6274
+ yield loadAccessToken(db);
6275
+ }
6161
6276
  if (purpose === 'pull') {
6162
6277
  const syncState = db.cloud.persistedSyncState.value;
6163
6278
  triggerSync(db, purpose);
@@ -6195,7 +6310,7 @@
6195
6310
  return permissions(dexie._novip, obj, tableName);
6196
6311
  },
6197
6312
  };
6198
- dexie.Version.prototype['_parseStoresSpec'] = Dexie__default["default"].override(dexie.Version.prototype['_parseStoresSpec'], (origFunc) => overrideParseStoresSpec(origFunc, dexie));
6313
+ dexie.Version.prototype['_parseStoresSpec'] = Dexie.override(dexie.Version.prototype['_parseStoresSpec'], (origFunc) => overrideParseStoresSpec(origFunc, dexie));
6199
6314
  dexie.Table.prototype.newId = function ({ colocateWith } = {}) {
6200
6315
  const shardKey = colocateWith && colocateWith.substr(colocateWith.length - 3);
6201
6316
  return generateKey(dexie.cloud.schema[this.name].idPrefix || '', shardKey);
@@ -6361,7 +6476,9 @@
6361
6476
  db.syncStateChangedEvent.next({
6362
6477
  phase: 'not-in-sync',
6363
6478
  });
6364
- triggerSync(db, 'push');
6479
+ if (!isEagerSyncDisabled(db)) {
6480
+ triggerSync(db, 'push');
6481
+ }
6365
6482
  }), rxjs.fromEvent(self, 'offline').subscribe(() => {
6366
6483
  console.debug('offline!');
6367
6484
  db.syncStateChangedEvent.next({
@@ -6378,10 +6495,10 @@
6378
6495
  });
6379
6496
  }
6380
6497
  }
6381
- dexieCloud.version = '4.0.1-beta.46';
6382
- Dexie__default["default"].Cloud = dexieCloud;
6498
+ dexieCloud.version = '{version}';
6499
+ Dexie.Cloud = dexieCloud;
6383
6500
 
6384
- exports["default"] = dexieCloud;
6501
+ exports.default = dexieCloud;
6385
6502
  exports.dexieCloud = dexieCloud;
6386
6503
  exports.getTiedObjectId = getTiedObjectId;
6387
6504
  exports.getTiedRealmId = getTiedRealmId;