dexie-cloud-addon 4.2.0-alpha.4 → 4.2.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modern/dexie-cloud-addon.js +4 -12
- package/dist/modern/dexie-cloud-addon.js.map +1 -1
- package/dist/modern/dexie-cloud-addon.min.js +1 -1
- package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
- package/dist/modern/service-worker.js +4 -12
- package/dist/modern/service-worker.js.map +1 -1
- package/dist/modern/service-worker.min.js +1 -1
- package/dist/modern/service-worker.min.js.map +1 -1
- package/dist/modern/yjs/awareness.d.ts +3 -4
- package/dist/umd/dexie-cloud-addon.js +457 -21
- package/dist/umd/dexie-cloud-addon.js.map +1 -1
- package/dist/umd/dexie-cloud-addon.min.js +1 -1
- package/dist/umd/dexie-cloud-addon.min.js.map +1 -1
- package/dist/umd/service-worker.js +457 -21
- package/dist/umd/service-worker.js.map +1 -1
- package/dist/umd/service-worker.min.js +1 -1
- package/dist/umd/service-worker.min.js.map +1 -1
- package/dist/umd/yjs/awareness.d.ts +3 -4
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-worker.min.js","sources":["../../../../node_modules/.pnpm/@rollup+plugin-typescript@11.1.5_rollup@4.1.4_tslib@2.4.0_typescript@5.6.3/node_modules/tslib/tslib.es6.js","../../src/authentication/UNAUTHORIZED_USER.ts","../../src/helpers/SWBroadcastChannel.ts","../../src/helpers/BroadcastedAndLocalEvent.ts","../../src/sync/registerSyncEvent.ts","../../src/sync/triggerSync.ts","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/common/base64.js","../../src/helpers/computeRealmSetHash.ts","../../src/helpers/getSyncableTables.ts","../../src/helpers/getMutationTable.ts","../../src/helpers/getTableFromMutationTable.ts","../../src/helpers/flatten.ts","../../src/sync/listClientChanges.ts","../../src/helpers/randomString.ts","../../../../libs/dexie-cloud-common/dist/utils.js","../../../../libs/dexie-cloud-common/dist/validation/isValidSyncableID.js","../../../../libs/dexie-cloud-common/dist/change-processing/applyOperation.js","../../../../libs/dexie-cloud-common/dist/change-processing/applyOperations.js","../../../../libs/dexie-cloud-common/dist/async-generators/consumeChunkedBinaryStream.js","../../src/authentication/TokenErrorResponseError.ts","../../src/authentication/interactWithUser.ts","../../src/authentication/authenticate.ts","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/TypesonSimplified.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/BisonBinaryTypes.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/number.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/bigint.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/Date.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/Set.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/Map.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/common/_global.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/TypedArray.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/common/b64lex.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/ArrayBuffer.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/FakeBlob.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/readBlobSync.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/string2ArrayBuffer.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/Blob.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/presets/builtin.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/Bison.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/undefined.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/File.js","../../src/TSON.ts","../../src/errors/HttpError.ts","../../src/sync/encodeIdsForServer.ts","../../src/sync/ratelimit.ts","../../src/sync/syncWithServer.ts","../../src/helpers/CancelToken.ts","../../src/sync/isOnline.ts","../../src/sync/updateBaseRevs.ts","../../src/sync/getLatestRevisionsPerTable.ts","../../src/helpers/bulkUpdate.ts","../../src/sync/applyServerChanges.ts","../../src/sync/DEXIE_CLOUD_SYNCER_ID.ts","../../src/yjs/listUpdatesSince.ts","../../src/yjs/getUpdatesTable.ts","../../src/yjs/applyYMessages.ts","../../src/yjs/downloadYDocsFromServer.ts","../../../../libs/dexie-cloud-common/dist/async-generators/asyncIterablePipeline.js","../../../../libs/dexie-cloud-common/dist/async-generators/getFetchResponseBodyGenerator.js","../../src/sync/sync.ts","../../src/sync/getTablesToSyncify.ts","../../src/sync/modifyLocalObjectsWithNewUserId.ts","../../src/yjs/listYClientMessagesAndStateVector.ts","../../src/sync/listSyncifiedChanges.ts","../../src/yjs/updateYSyncStates.ts","../../../../libs/dexie-cloud-common/dist/change-processing/subtractChanges.js","../../../../libs/dexie-cloud-common/dist/change-processing/toDBOperationSet.js","../../src/sync/messagesFromServerQueue.ts","../../src/db/DexieCloudDB.ts","../../src/authentication/AuthPersistedContext.ts","../../src/authentication/waitUntil.ts","../../src/authentication/logout.ts","../../src/prodLog.ts","../../src/authentication/login.ts","../../src/authentication/otpFetchTokenCallback.ts","../../src/authentication/setCurrentUser.ts","../../src/isFirefox.ts","../../src/isSafari.ts","../../src/DISABLE_SERVICEWORKER_STRATEGY.ts","../../src/helpers/IS_SERVICE_WORKER.ts","../../src/middleware-helpers/idGenerationHelpers.ts","../../src/middlewares/createIdGenerationMiddleware.ts","../../src/middleware-helpers/guardedTable.ts","../../src/helpers/allSettled.ts","../../src/middlewares/outstandingTransaction.ts","../../src/isEagerSyncDisabled.ts","../../src/middlewares/createMutationTrackingMiddleware.ts","../../src/overrideParseStoresSpec.ts","../../src/sync/performGuardedJob.ts","../../src/userIsActive.ts","../../src/authentication/TokenExpiredError.ts","../../src/yjs/awareness.ts","../../src/yjs/reopenDocSignal.ts","../../src/WSObservable.ts","../../../../libs/dexie-cloud-common/dist/yjs/decoding.js","../../../../libs/dexie-cloud-common/dist/yjs/encoding.js","../../src/yjs/createYClientUpdateObservable.ts","../../src/InvalidLicenseError.ts","../../src/sync/connectWebSocket.ts","../../src/sync/isSyncNeeded.ts","../../src/sync/syncIfPossible.ts","../../src/helpers/date-constants.ts","../../src/sync/LocalSyncWorker.ts","../../src/updateSchemaFromOptions.ts","../../../../node_modules/.pnpm/preact@10.10.6/node_modules/preact/dist/preact.module.js","../../src/default-ui/Styles.ts","../../src/default-ui/Dialog.tsx","../../../../node_modules/.pnpm/preact@10.10.6/node_modules/preact/hooks/dist/hooks.module.js","../../src/default-ui/LoginDialog.tsx","../../src/helpers/resolveText.ts","../../src/default-ui/index.tsx","../../src/associate.ts","../../src/currentUserEmitter.ts","../../src/createSharedValueObservable.ts","../../src/getGlobalRolesObservable.ts","../../src/getInternalAccessControlObservable.ts","../../src/mergePermissions.ts","../../src/getPermissionsLookupObservable.ts","../../src/mapValueObservable.ts","../../src/PermissionChecker.ts","../../src/getInvitesObservable.ts","../../src/yjs/createYHandler.ts","../../src/dexie-cloud-client.ts","../../src/computeSyncState.ts","../../src/helpers/throwVersionIncrementNeeded.ts","../../src/verifySchema.ts","../../src/performInitialSync.ts","../../src/middlewares/createImplicitPropSetterMiddleware.ts","../../../../libs/dexie-cloud-common/dist/getDbNameFromDbUrl.js","../../src/permissions.ts","../../src/service-worker.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n","import { UserLogin } from '../db/entities/UserLogin';\n\nexport const UNAUTHORIZED_USER: UserLogin = {\n userId: \"unauthorized\",\n name: \"Unauthorized\",\n claims: {\n sub: \"unauthorized\",\n },\n lastLogin: new Date(0)\n}\n\ntry {\n Object.freeze(UNAUTHORIZED_USER);\n Object.freeze(UNAUTHORIZED_USER.claims);\n} catch {}\n","const swHolder: { registration?: ServiceWorkerRegistration } = {};\nconst swContainer = typeof self !== 'undefined' && self.document && // self.document is to verify we're not the SW ourself\n typeof navigator !== 'undefined' && navigator.serviceWorker; \nif (swContainer)\n swContainer.ready.then(\n (registration) => (swHolder.registration = registration)\n );\n\nif (typeof self !== 'undefined' && 'clients' in self && !self.document) {\n // We are the service worker. Propagate messages to all our clients.\n addEventListener('message', (ev: any) => {\n if (ev.data?.type?.startsWith('sw-broadcast-')) {\n [...self['clients'].matchAll({ includeUncontrolled: true })].forEach(\n (client) => client.id !== ev.source?.id && client.postMessage(ev.data)\n );\n }\n });\n}\n\n/** This class is a fallback for browsers that lacks BroadcastChannel but have\n * service workers (which is Safari versions 11.1 through 15.3).\n * Safari 15.4 with BroadcastChannel was released on 2022-03-14.\n * We might be able to remove this class in a near future as Safari < 15.4 is\n * already very low in market share as of 2023-03-10.\n */\nexport class SWBroadcastChannel {\n name: string;\n constructor(name: string) {\n this.name = name;\n }\n subscribe(listener: (message: any) => void) {\n if (!swContainer) return () => {};\n const forwarder = (ev: MessageEvent) => {\n if (ev.data?.type === `sw-broadcast-${this.name}`) {\n listener(ev.data.message);\n }\n };\n swContainer.addEventListener('message', forwarder);\n return () => swContainer.removeEventListener('message', forwarder);\n }\n postMessage(message: any) {\n if (typeof self['clients'] === 'object') {\n // We're a service worker. Propagate to our browser clients.\n [...self['clients'].matchAll({ includeUncontrolled: true })].forEach(\n (client) =>\n client.postMessage({\n type: `sw-broadcast-${this.name}`,\n message,\n })\n );\n } else if (swHolder.registration) {\n // We're a client (browser window or other worker)\n // Post to SW so it can repost to all its clients and to itself\n swHolder.registration.active?.postMessage({\n type: `sw-broadcast-${this.name}`,\n message,\n });\n }\n }\n}\n","import { Observable } from \"rxjs\";\nimport { SWBroadcastChannel } from \"./SWBroadcastChannel\";\n\nconst events: Map<string, Array<(ev: CustomEvent)=>void>> =\n globalThis['lbc-events'] || (globalThis['lbc-events'] = new Map<string, Array<(ev: CustomEvent)=>void>>());\n\nfunction addListener(name: string, listener: (ev: CustomEvent)=>void) {\n if (events.has(name)) {\n events.get(name)!.push(listener);\n } else {\n events.set(name, [listener]);\n }\n}\nfunction removeListener(name: string, listener: (ev: CustomEvent)=>void) {\n const listeners = events.get(name);\n if (listeners) {\n const idx = listeners.indexOf(listener);\n if (idx !== -1) {\n listeners.splice(idx, 1);\n }\n }\n}\nfunction dispatch(ev: CustomEvent) {\n const listeners = events.get(ev.type);\n if (listeners) {\n listeners.forEach(listener => {\n try {\n listener(ev);\n } catch {\n }\n });\n }\n}\n\nexport class BroadcastedAndLocalEvent<T> extends Observable<T>{\n name: string;\n bc: BroadcastChannel | SWBroadcastChannel\n\n constructor(name: string) {\n const bc = typeof BroadcastChannel === \"undefined\"\n ? new SWBroadcastChannel(name) : new BroadcastChannel(name);\n super(subscriber => {\n function onCustomEvent(ev: CustomEvent) {\n subscriber.next(ev.detail);\n }\n function onMessageEvent(ev: MessageEvent) {\n console.debug(\"BroadcastedAndLocalEvent: onMessageEvent\", ev);\n subscriber.next(ev.data);\n }\n let unsubscribe: ()=>void;\n //self.addEventListener(`lbc-${name}`, onCustomEvent); // Fails in service workers\n addListener(`lbc-${name}`, onCustomEvent); // Works better in service worker\n\n try { \n if (bc instanceof SWBroadcastChannel) {\n unsubscribe = bc.subscribe(message => subscriber.next(message));\n } else {\n console.debug(\"BroadcastedAndLocalEvent: bc.addEventListener()\", name, \"bc is a\", bc);\n bc.addEventListener(\"message\", onMessageEvent);\n }\n } catch (err) {\n // Service workers might fail to subscribe outside its initial script.\n console.warn('Failed to subscribe to broadcast channel', err);\n }\n return () => {\n //self.removeEventListener(`lbc-${name}`, onCustomEvent);\n removeListener(`lbc-${name}`, onCustomEvent);\n if (bc instanceof SWBroadcastChannel) {\n unsubscribe!();\n } else {\n bc.removeEventListener(\"message\", onMessageEvent);\n }\n }\n });\n this.name = name;\n this.bc = bc;\n }\n\n next(message: T) {\n console.debug(\"BroadcastedAndLocalEvent: bc.postMessage()\", {...message}, \"bc is a\", this.bc);\n this.bc.postMessage(message);\n const ev = new CustomEvent(`lbc-${this.name}`, { detail: message });\n //self.dispatchEvent(ev);\n dispatch(ev);\n }\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\n\n//const hasSW = 'serviceWorker' in navigator;\nlet hasComplainedAboutSyncEvent = false;\n\nexport async function registerSyncEvent(db: DexieCloudDB, purpose: \"push\" | \"pull\") {\n try {\n // Send sync event to SW:\n const sw: ServiceWorkerRegistration & {sync?: any} = await navigator.serviceWorker.ready;\n if (purpose === \"push\" && sw.sync) {\n await sw.sync.register(`dexie-cloud:${db.name}`);\n }\n if (sw.active) {\n // Use postMessage for pull syncs and for browsers not supporting sync event (Firefox, Safari).\n // Also chromium based browsers with sw.sync as a fallback for sleepy sync events not taking action for a while.\n sw.active.postMessage({\n type: 'dexie-cloud-sync',\n dbName: db.name,\n purpose\n });\n } else {\n throw new Error(`Failed to trigger sync - there's no active service worker`);\n }\n return;\n } catch (e) {\n if (!hasComplainedAboutSyncEvent) {\n console.debug(`Dexie Cloud: Could not register sync event`, e);\n hasComplainedAboutSyncEvent = true;\n }\n }\n}\n\nexport async function registerPeriodicSyncEvent(db: DexieCloudDB) {\n try {\n // Register periodicSync event to SW:\n // @ts-ignore\n const { periodicSync } = await navigator.serviceWorker.ready;\n if (periodicSync) {\n try {\n await periodicSync.register(\n `dexie-cloud:${db.name}`,\n db.cloud.options?.periodicSync\n );\n console.debug(\n `Dexie Cloud: Successfully registered periodicsync event for ${db.name}`\n );\n } catch (e) {\n console.debug(`Dexie Cloud: Failed to register periodic sync. Your PWA must be installed to allow background sync.`, e);\n }\n } else {\n console.debug(`Dexie Cloud: periodicSync not supported.`);\n }\n } catch (e) {\n console.debug(\n `Dexie Cloud: Could not register periodicSync for ${db.name}`,\n e\n );\n }\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { registerSyncEvent } from \"./registerSyncEvent\";\n\nexport function triggerSync(db: DexieCloudDB, purpose: \"push\" | \"pull\") {\n if (db.cloud.usingServiceWorker) {\n console.debug('registering sync event');\n registerSyncEvent(db, purpose);\n } else {\n db.localSyncEvent.next({purpose});\n }\n}","const hasArrayBufferFromBase64 = \"fromBase64\" in Uint8Array; // https://github.com/tc39/proposal-arraybuffer-base64;\nconst hasArrayBufferToBase64 = \"toBase64\" in Uint8Array.prototype; // https://github.com/tc39/proposal-arraybuffer-base64;\nexport const b64decode = typeof Buffer !== \"undefined\"\n ? (base64) => Buffer.from(base64, \"base64\") // Node\n : hasArrayBufferFromBase64\n ? // @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64\n (base64) => Uint8Array.fromBase64(base64) // Modern javascript standard\n : (base64) => {\n // Legacy DOM workaround\n const binary_string = atob(base64);\n const len = binary_string.length;\n const bytes = new Uint8Array(len);\n for (var i = 0; i < len; i++) {\n bytes[i] = binary_string.charCodeAt(i);\n }\n return bytes;\n };\nexport const b64encode = typeof Buffer !== \"undefined\"\n ? (b) => {\n // Node\n if (ArrayBuffer.isView(b)) {\n return Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString(\"base64\");\n }\n else {\n return Buffer.from(b).toString(\"base64\");\n }\n }\n : hasArrayBufferToBase64\n ? (b) => {\n // Uint8Array.prototype.toBase64 is available in modern browsers\n const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);\n // @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64\n return u8a.toBase64();\n }\n : (b) => {\n // Legacy DOM workaround\n const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);\n const CHUNK_SIZE = 0x1000;\n const strs = [];\n for (let i = 0, l = u8a.length; i < l; i += CHUNK_SIZE) {\n const chunk = u8a.subarray(i, i + CHUNK_SIZE);\n strs.push(String.fromCharCode.apply(null, chunk));\n }\n return btoa(strs.join(\"\"));\n };\n","import { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { b64encode } from 'dreambase-library/dist/common/base64';\n\nexport async function computeRealmSetHash({\n realms,\n inviteRealms,\n}: PersistedSyncState) {\n const data = JSON.stringify(\n [\n ...realms.map((realmId) => ({ realmId, accepted: true })),\n ...inviteRealms.map((realmId) => ({ realmId, accepted: false })),\n ].sort((a, b) =>\n a.realmId < b.realmId ? -1 : a.realmId > b.realmId ? 1 : 0\n )\n );\n const byteArray = new TextEncoder().encode(data);\n const digestBytes = await crypto.subtle.digest('SHA-1', byteArray);\n const base64 = b64encode(digestBytes);\n return base64;\n}\n","import { IndexableType, Table } from \"dexie\";\nimport { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { EntityCommon } from \"../db/entities/EntityCommon\";\n\nexport function getSyncableTables(db: DexieCloudDB): Table<EntityCommon>[] {\n return Object.entries(db.cloud.schema || {})\n .filter(([, { markedForSync }]) => markedForSync)\n .map(([tbl]) => db.tables.filter(({name}) => name === tbl)[0])\n .filter(cloudTableSchema => cloudTableSchema);\n}\n","\n\nexport function getMutationTable(tableName: string) {\n return `$${tableName}_mutations`;\n}\n","\n\nexport function getTableFromMutationTable(mutationTable: string) {\n const tableName = /^\\$(.*)_mutations$/.exec(mutationTable)?.[1];\n if (!tableName) throw new Error(`Given mutationTable ${mutationTable} is not correct`);\n return tableName;\n}\n","const concat = [].concat;\nexport function flatten<T>(a: (T | T[])[]): T[] {\n return concat.apply([], a);\n}\n","import { Table } from 'dexie';\nimport { getTableFromMutationTable } from '../helpers/getTableFromMutationTable';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { DBOperation, DBOperationsSet } from 'dexie-cloud-common';\nimport { flatten } from '../helpers/flatten';\n\nexport async function listClientChanges(\n mutationTables: Table[],\n db: DexieCloudDB,\n { since = {} as { [table: string]: number }, limit = Infinity } = {}\n): Promise<DBOperationsSet> {\n const allMutsOnTables = await Promise.all(\n mutationTables.map(async (mutationTable) => {\n const tableName = getTableFromMutationTable(mutationTable.name);\n const lastRevision = since[tableName];\n\n let query = lastRevision\n ? mutationTable.where('rev').above(lastRevision)\n : mutationTable;\n\n if (limit < Infinity) query = query.limit(limit);\n\n const muts: DBOperation[] = await query.toArray();\n\n //const objTable = db.table(tableName);\n /*for (const mut of muts) {\n if (mut.type === \"insert\" || mut.type === \"upsert\") {\n mut.values = await objTable.bulkGet(mut.keys);\n }\n }*/\n return muts.map((mut) => ({\n table: tableName,\n mut,\n }));\n })\n );\n\n // Sort by time to get a true order of the operations (between tables)\n const sorted = flatten(allMutsOnTables).sort((a, b) => a.mut.txid === b.mut.txid\n ? a.mut.opNo! - b.mut.opNo! // Within same transaction, sort by opNo\n : a.mut.ts! - b.mut.ts! // Different transactions - sort by timestamp when mutation resolved\n );\n const result: DBOperationsSet = [];\n let currentEntry: {\n table: string;\n muts: DBOperation[];\n } | null = null;\n let currentTxid: string | null = null;\n for (const { table, mut } of sorted) {\n if (\n currentEntry &&\n currentEntry.table === table &&\n currentTxid === mut.txid\n ) {\n currentEntry.muts.push(mut);\n } else {\n currentEntry = {\n table,\n muts: [mut],\n };\n currentTxid = mut.txid!;\n result.push(currentEntry);\n }\n }\n\n // Filter out those tables that doesn't have any mutations:\n return result;\n}\n","export function randomString(bytes: number) {\n const buf = new Uint8Array(bytes);\n if (typeof crypto !== 'undefined') {\n crypto.getRandomValues(buf);\n } else {\n for (let i = 0; i < bytes; i++) buf[i] = Math.floor(Math.random() * 256);\n }\n if (typeof Buffer !== 'undefined' && Buffer.from) {\n return Buffer.from(buf).toString('base64');\n } else if (typeof btoa !== 'undefined') {\n return btoa(String.fromCharCode.apply(null, buf));\n } else {\n throw new Error('No btoa or Buffer available');\n }\n}\n","export function assert(b) {\n if (!b)\n throw new Error('Assertion Failed');\n}\nconst _hasOwn = {}.hasOwnProperty;\nexport function hasOwn(obj, prop) {\n return _hasOwn.call(obj, prop);\n}\nexport function setByKeyPath(obj, keyPath, value) {\n if (!obj || keyPath === undefined)\n return;\n if ('isFrozen' in Object && Object.isFrozen(obj))\n return;\n if (typeof keyPath !== 'string' && 'length' in keyPath) {\n assert(typeof value !== 'string' && 'length' in value);\n for (var i = 0, l = keyPath.length; i < l; ++i) {\n setByKeyPath(obj, keyPath[i], value[i]);\n }\n }\n else {\n var period = keyPath.indexOf('.');\n if (period !== -1) {\n var currentKeyPath = keyPath.substr(0, period);\n var remainingKeyPath = keyPath.substr(period + 1);\n if (remainingKeyPath === '')\n if (value === undefined) {\n if (Array.isArray(obj)) {\n if (!isNaN(parseInt(currentKeyPath)))\n obj.splice(parseInt(currentKeyPath), 1);\n }\n else\n delete obj[currentKeyPath];\n // @ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n }\n else\n obj[currentKeyPath] = value;\n else {\n //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n var innerObj = obj[currentKeyPath];\n //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n if (!innerObj || !hasOwn(obj, currentKeyPath))\n innerObj = (obj[currentKeyPath] = {});\n setByKeyPath(innerObj, remainingKeyPath, value);\n }\n }\n else {\n if (value === undefined) {\n if (Array.isArray(obj) && !isNaN(parseInt(keyPath)))\n // @ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n obj.splice(keyPath, 1);\n //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n else\n delete obj[keyPath];\n //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n }\n else\n obj[keyPath] = value;\n }\n }\n}\nexport const randomString = typeof self !== 'undefined' && typeof crypto !== 'undefined' ? (bytes, randomFill = crypto.getRandomValues.bind(crypto)) => {\n // Web\n const buf = new Uint8Array(bytes);\n randomFill(buf);\n return self.btoa(String.fromCharCode.apply(null, buf));\n} : typeof Buffer !== 'undefined' ? (bytes, randomFill = simpleRandomFill) => {\n // Node\n const buf = Buffer.alloc(bytes);\n randomFill(buf);\n return buf.toString(\"base64\");\n} : () => { throw new Error(\"No implementation of randomString was found\"); };\nfunction simpleRandomFill(buf) {\n for (let i = 0; i < buf.length; ++i) {\n buf[i] = Math.floor(Math.random() * 256);\n }\n}\n","const validIDTypes = {\n Uint8Array,\n};\n/** Verifies that given primary key is valid.\n * The reason we narrow validity for valid keys are twofold:\n * 1: Make sure to only support types that can be used as an object index in DBKeyMutationSet.\n * For example, ArrayBuffer cannot be used (gives \"object ArrayBuffer\") but Uint8Array can be\n * used (gives comma-delimited list of included bytes).\n * 2: Avoid using plain numbers and Dates as keys when they are synced, as they are not globally unique.\n * 3: Since we store the key as a VARCHAR server side in current version, try not promote types that stringifies to become very long server side.\n *\n * @param id\n * @returns\n */\nexport function isValidSyncableID(id) {\n if (typeof id === \"string\")\n return true;\n //if (validIDTypes[toStringTag(id)]) return true;\n //if (Array.isArray(id)) return id.every((part) => isValidSyncableID(part));\n if (Array.isArray(id) && id.some(key => isValidSyncableID(key)) && id.every(isValidSyncableIDPart))\n return true;\n return false;\n}\n/** Verifies that given key part is valid.\n * 1: Make sure that arrays of this types are stringified correclty and works with DBKeyMutationSet.\n * For example, ArrayBuffer cannot be used (gives \"object ArrayBuffer\") but Uint8Array can be\n * used (gives comma-delimited list of included bytes).\n * 2: Since we store the key as a VARCHAR server side in current version, try not promote types that stringifies to become very long server side.\n*/\nfunction isValidSyncableIDPart(part) {\n return typeof part === \"string\" || typeof part === \"number\" || Array.isArray(part) && part.every(isValidSyncableIDPart);\n}\nexport function isValidAtID(id, idPrefix) {\n return !idPrefix || (typeof id === \"string\" && id.startsWith(idPrefix));\n}\n","import { setByKeyPath } from \"../utils.js\";\nexport function applyOperation(target, table, op) {\n const tbl = target[table] || (target[table] = {});\n const keys = op.keys.map(key => typeof key === 'string' ? key : JSON.stringify(key));\n switch (op.type) {\n case \"insert\":\n // TODO: Don't treat insert and upsert the same?\n case \"upsert\":\n keys.forEach((key, idx) => {\n tbl[key] = {\n type: \"ups\",\n val: op.values[idx],\n };\n });\n break;\n case \"update\":\n case \"modify\": {\n keys.forEach((key, idx) => {\n const changeSpec = op.type === \"update\"\n ? op.changeSpecs[idx]\n : op.changeSpec;\n const entry = tbl[key];\n if (!entry) {\n tbl[key] = {\n type: \"upd\",\n mod: changeSpec,\n };\n }\n else {\n switch (entry.type) {\n case \"ups\":\n // Adjust the existing upsert with additional updates\n for (const [propPath, value] of Object.entries(changeSpec)) {\n setByKeyPath(entry.val, propPath, value);\n }\n break;\n case \"del\":\n // No action.\n break;\n case \"upd\":\n // Adjust existing update with additional updates\n Object.assign(entry.mod, changeSpec); // May work for deep props as well - new keys is added later, right? Does the prop order persist along TSON and all? But it will not be 100% when combined with some server code (seach for \"address.city\": \"Stockholm\" comment)\n break;\n }\n }\n });\n break;\n }\n case \"delete\":\n keys.forEach((key) => {\n tbl[key] = {\n type: \"del\",\n };\n });\n break;\n }\n return target;\n}\n","import { applyOperation } from \"./applyOperation.js\";\nexport function applyOperations(target, ops) {\n for (const { table, muts } of ops) {\n for (const mut of muts) {\n applyOperation(target, table, mut);\n }\n }\n}\n","import { __asyncGenerator, __asyncValues, __await } from \"tslib\";\nexport function consumeChunkedBinaryStream(source) {\n return __asyncGenerator(this, arguments, function* consumeChunkedBinaryStream_1() {\n var _a, e_1, _b, _c;\n let state = 0;\n let sizeBuf = new Uint8Array(4);\n let sizeBufPos = 0;\n let bufs = [];\n let len = 0;\n try {\n for (var _d = true, source_1 = __asyncValues(source), source_1_1; source_1_1 = yield __await(source_1.next()), _a = source_1_1.done, !_a; _d = true) {\n _c = source_1_1.value;\n _d = false;\n const chunk = _c;\n const dw = new DataView(chunk.buffer, chunk.byteOffset, chunk.byteLength);\n let pos = 0;\n while (pos < chunk.byteLength) {\n switch (state) {\n case 0:\n // Beginning of a size header\n if (pos + 4 > chunk.byteLength) {\n for (const b of chunk.slice(pos)) {\n if (sizeBufPos === 4)\n break;\n sizeBuf[sizeBufPos++] = b;\n ++pos;\n }\n if (sizeBufPos < 4) {\n // Need more bytes in order to read length.\n // Will go out from while loop as well because pos is defenitely = chunk.byteLength here.\n break;\n }\n }\n else if (sizeBufPos > 0 && sizeBufPos < 4) {\n for (const b of chunk.slice(pos, pos + 4 - sizeBufPos)) {\n sizeBuf[sizeBufPos++] = b;\n ++pos;\n }\n }\n // Intentional fall-through...\n case 1:\n len =\n sizeBufPos === 4\n ? new DataView(sizeBuf.buffer, 0, 4).getUint32(0, false)\n : dw.getUint32(pos, false);\n if (sizeBufPos)\n sizeBufPos = 0; // in this case pos is already forwarded\n else\n pos += 4; // else pos is not yet forwarded - that's why we do it now\n // Intentional fall-through...\n case 2:\n // Eat the chunk\n if (pos >= chunk.byteLength) {\n state = 2;\n break;\n }\n if (pos + len > chunk.byteLength) {\n bufs.push(chunk.slice(pos));\n len -= (chunk.byteLength - pos);\n state = 2;\n pos = chunk.byteLength; // will break while loop.\n }\n else {\n if (bufs.length > 0) {\n const concats = new Uint8Array(bufs.reduce((p, c) => p + c.byteLength, len));\n let p = 0;\n for (const buf of bufs) {\n concats.set(buf, p);\n p += buf.byteLength;\n }\n concats.set(chunk.slice(pos, pos + len), p);\n bufs = [];\n yield yield __await(concats);\n }\n else {\n yield yield __await(chunk.slice(pos, pos + len));\n }\n pos += len;\n state = 0;\n }\n break;\n }\n }\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (!_d && !_a && (_b = source_1.return)) yield __await(_b.call(source_1));\n }\n finally { if (e_1) throw e_1.error; }\n }\n });\n}\n","import { TokenErrorResponse } from 'dexie-cloud-common';\n\nexport class TokenErrorResponseError extends Error {\n title: string;\n messageCode:\n | 'INVALID_OTP'\n | 'INVALID_EMAIL'\n | 'LICENSE_LIMIT_REACHED'\n | 'GENERIC_ERROR';\n message: string;\n messageParams?: { [param: string]: string };\n\n constructor({\n title,\n message,\n messageCode,\n messageParams,\n }: TokenErrorResponse) {\n super(message);\n this.name = 'TokenErrorResponseError';\n this.title = title;\n this.messageCode = messageCode;\n this.messageParams = messageParams;\n }\n}\n","import Dexie from 'dexie';\nimport { BehaviorSubject } from 'rxjs';\nimport { take } from 'rxjs/operators';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { DXCAlert } from '../types/DXCAlert';\nimport { DXCInputField } from '../types/DXCInputField';\nimport { DXCUserInteraction } from '../types/DXCUserInteraction';\n\nexport interface DXCUserInteractionRequest {\n type: DXCUserInteraction['type'];\n title: string;\n alerts: DXCAlert[];\n submitLabel?: string;\n cancelLabel?: string | null;\n fields: { [name: string]: DXCInputField };\n}\n\nexport function interactWithUser<T extends DXCUserInteractionRequest>(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n req: T\n): Promise<{\n [P in keyof T['fields']]: string;\n}> {\n let done = false;\n return new Promise<{\n [P in keyof T['fields']]: string;\n }>((resolve, reject) => {\n const interactionProps = {\n submitLabel: 'Submit',\n cancelLabel: 'Cancel',\n ...req,\n onSubmit: (res: {\n [P in keyof T['fields']]: string;\n }) => {\n userInteraction.next(undefined);\n done = true;\n resolve(res);\n },\n onCancel: () => {\n userInteraction.next(undefined);\n done = true;\n reject(new Dexie.AbortError('User cancelled'));\n },\n } as DXCUserInteraction;\n userInteraction.next(interactionProps);\n // Start subscribing for external updates to db.cloud.userInteraction, and if so, cancel this request.\n /*const subscription = userInteraction.subscribe((currentInteractionProps) => {\n if (currentInteractionProps !== interactionProps) {\n if (subscription) subscription.unsubscribe();\n if (!done) {\n reject(new Dexie.AbortError(\"User cancelled\"));\n }\n }\n });*/\n });\n}\n\nexport function alertUser(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n title: string,\n ...alerts: DXCAlert[]\n) {\n return interactWithUser(userInteraction, {\n type: 'message-alert',\n title,\n alerts,\n fields: {},\n submitLabel: 'OK',\n cancelLabel: null,\n });\n}\n\nexport async function promptForEmail(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n title: string,\n emailHint?: string\n) {\n let email = emailHint || '';\n // Regular expression for email validation\n // ^[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10}(\\sas\\s[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10})?$\n //\n // ^[\\w-+.]+ : Matches the start of the string. Allows one or more word characters\n // (a-z, A-Z, 0-9, and underscore), hyphen, plus, or dot.\n //\n // @ : Matches the @ symbol.\n // ([\\w-]+\\.)+ : Matches one or more word characters or hyphens followed by a dot.\n // The plus sign outside the parentheses means this pattern can repeat one or more times,\n // allowing for subdomains.\n // [\\w-]{2,10} : Matches between 2 and 10 word characters or hyphens. This is typically for\n // the domain extension like .com, .net, etc.\n // (\\sas\\s[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10})?$ : This part is optional (due to the ? at the end).\n // If present, it matches \" as \" followed by another valid email address. This allows for the\n // input to be either a single email address or two email addresses separated by \" as \". \n //\n // The use case for \"<email1> as <email2>\"\" is for when a database owner with full access to the\n // database needs to impersonate another user in the database in order to troubleshoot. This\n // format will only be possible to use when email1 is the owner of an API client with GLOBAL_READ\n // and GLOBAL_WRITE permissions on the database. The email will be checked on the server before\n // allowing it and giving out a token for email2, using the OTP sent to email1.\n while (!email || !/^[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10}(\\sas\\s[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10})?$/.test(email)) {\n email = (\n await interactWithUser(userInteraction, {\n type: 'email',\n title,\n alerts: email\n ? [\n {\n type: 'error',\n messageCode: 'INVALID_EMAIL',\n message: 'Please enter a valid email address',\n messageParams: {},\n },\n ]\n : [],\n fields: {\n email: {\n type: 'email',\n placeholder: 'you@somedomain.com',\n },\n },\n })\n ).email;\n }\n return email;\n}\n\nexport async function promptForOTP(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n email: string,\n alert?: DXCAlert\n) {\n const alerts: DXCAlert[] = [\n {\n type: 'info',\n messageCode: 'OTP_SENT',\n message: `A One-Time password has been sent to {email}`,\n messageParams: { email },\n },\n ];\n if (alert) {\n alerts.push(alert);\n }\n const { otp } = await interactWithUser(userInteraction, {\n type: 'otp',\n title: 'Enter OTP',\n alerts,\n fields: {\n otp: {\n type: 'otp',\n label: 'OTP',\n placeholder: 'Paste OTP here',\n },\n },\n });\n return otp;\n}\n\nexport async function confirmLogout(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n currentUserId: string,\n numUnsyncedChanges: number\n) {\n const alerts: DXCAlert[] = [\n {\n type: 'warning',\n messageCode: 'LOGOUT_CONFIRMATION',\n message: `{numUnsyncedChanges} unsynced changes will get lost!\n Logout anyway?`,\n messageParams: {\n currentUserId,\n numUnsyncedChanges: numUnsyncedChanges.toString(),\n }\n },\n ];\n return await interactWithUser(userInteraction, {\n type: 'logout-confirmation',\n title: 'Confirm Logout',\n alerts,\n fields: {},\n submitLabel: 'Confirm logout',\n cancelLabel: 'Cancel'\n })\n .then(() => true)\n .catch(() => false);\n}\n","import Dexie from 'dexie';\nimport type {\n RefreshTokenRequest,\n TokenErrorResponse,\n TokenFinalResponse,\n} from 'dexie-cloud-common';\nimport { b64encode } from 'dreambase-library/dist/common/base64';\nimport { BehaviorSubject } from 'rxjs';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { UserLogin } from '../db/entities/UserLogin';\nimport { DXCAlert } from '../types/DXCAlert';\nimport {\n DXCMessageAlert,\n DXCUserInteraction,\n} from '../types/DXCUserInteraction';\nimport { TokenErrorResponseError } from './TokenErrorResponseError';\nimport { alertUser, interactWithUser } from './interactWithUser';\nimport { InvalidLicenseError } from '../InvalidLicenseError';\nimport { LoginHints } from '../DexieCloudAPI';\n\nexport type FetchTokenCallback = (tokenParams: {\n public_key: string;\n hints?: LoginHints;\n}) => Promise<TokenFinalResponse | TokenErrorResponse>;\n\nexport async function loadAccessToken(\n db: DexieCloudDB\n): Promise<UserLogin | null> {\n const currentUser = await db.getCurrentUser();\n const {\n accessToken,\n accessTokenExpiration,\n refreshToken,\n refreshTokenExpiration,\n claims,\n } = currentUser;\n if (!accessToken) return null;\n const expTime = accessTokenExpiration?.getTime() ?? Infinity;\n if (expTime > Date.now() && (currentUser.license?.status || 'ok') === 'ok') {\n return currentUser;\n }\n if (!refreshToken) {\n throw new Error(`Refresh token missing`);\n }\n const refreshExpTime = refreshTokenExpiration?.getTime() ?? Infinity;\n if (refreshExpTime <= Date.now()) {\n throw new Error(`Refresh token has expired`);\n }\n const refreshedLogin = await refreshAccessToken(\n db.cloud.options!.databaseUrl,\n currentUser\n );\n await db.table('$logins').update(claims.sub, {\n accessToken: refreshedLogin.accessToken,\n accessTokenExpiration: refreshedLogin.accessTokenExpiration,\n claims: refreshedLogin.claims,\n license: refreshedLogin.license,\n data: refreshedLogin.data,\n });\n return refreshedLogin;\n}\n\nexport async function authenticate(\n url: string,\n context: UserLogin,\n fetchToken: FetchTokenCallback,\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n hints?: LoginHints\n): Promise<UserLogin> {\n if (\n context.accessToken &&\n context.accessTokenExpiration!.getTime() > Date.now()\n ) {\n return context;\n } else if (\n context.refreshToken &&\n (!context.refreshTokenExpiration ||\n context.refreshTokenExpiration.getTime() > Date.now())\n ) {\n return await refreshAccessToken(url, context);\n } else {\n return await userAuthenticate(context, fetchToken, userInteraction, hints);\n }\n}\n\nexport async function refreshAccessToken(\n url: string,\n login: UserLogin\n): Promise<UserLogin> {\n if (!login.refreshToken)\n throw new Error(`Cannot refresh token - refresh token is missing.`);\n if (!login.nonExportablePrivateKey)\n throw new Error(\n `login.nonExportablePrivateKey is missing - cannot sign refresh token without a private key.`\n );\n\n const time_stamp = Date.now();\n const signing_algorithm = 'RSASSA-PKCS1-v1_5';\n const textEncoder = new TextEncoder();\n const data = textEncoder.encode(login.refreshToken + time_stamp);\n const binarySignature = await crypto.subtle.sign(\n signing_algorithm,\n login.nonExportablePrivateKey,\n data\n );\n const signature = b64encode(binarySignature);\n\n const tokenRequest: RefreshTokenRequest = {\n grant_type: 'refresh_token',\n refresh_token: login.refreshToken,\n scopes: ['ACCESS_DB'],\n signature,\n signing_algorithm,\n time_stamp,\n };\n const res = await fetch(`${url}/token`, {\n body: JSON.stringify(tokenRequest),\n method: 'post',\n headers: { 'Content-Type': 'application/json' },\n mode: 'cors',\n });\n if (res.status !== 200)\n throw new Error(`RefreshToken: Status ${res.status} from ${url}/token`);\n const response: TokenFinalResponse | TokenErrorResponse = await res.json();\n if (response.type === 'error') {\n throw new TokenErrorResponseError(response);\n }\n login.accessToken = response.accessToken;\n login.accessTokenExpiration = response.accessTokenExpiration\n ? new Date(response.accessTokenExpiration)\n : undefined;\n login.claims = response.claims;\n login.license = {\n type: response.userType,\n status: response.claims.license || 'ok',\n }\n if (response.evalDaysLeft != null) {\n login.license.evalDaysLeft = response.evalDaysLeft;\n }\n if (response.userValidUntil != null) {\n login.license.validUntil = new Date(response.userValidUntil);\n }\n if (response.data) {\n login.data = response.data;\n }\n return login;\n}\n\nasync function userAuthenticate(\n context: UserLogin,\n fetchToken: FetchTokenCallback,\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n hints?: LoginHints\n) {\n if (!crypto.subtle) {\n if (typeof location !== 'undefined' && location.protocol === 'http:') {\n throw new Error(`Dexie Cloud Addon needs to use WebCrypto, but your browser has disabled it due to being served from an insecure location. Please serve it from https or http://localhost:<port> (See https://stackoverflow.com/questions/46670556/how-to-enable-crypto-subtle-for-unsecure-origins-in-chrome/46671627#46671627)`);\n } else {\n throw new Error(`This browser does not support WebCrypto.`);\n }\n }\n const { privateKey, publicKey } = await crypto.subtle.generateKey(\n {\n name: 'RSASSA-PKCS1-v1_5',\n modulusLength: 2048,\n publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n hash: { name: 'SHA-256' },\n },\n false, // Non-exportable...\n ['sign', 'verify']\n );\n if (!privateKey || !publicKey)\n throw new Error(`Could not generate RSA keypair`); // Typings suggest these can be undefined...\n context.nonExportablePrivateKey = privateKey; //...but storable!\n const publicKeySPKI = await crypto.subtle.exportKey('spki', publicKey);\n const publicKeyPEM = spkiToPEM(publicKeySPKI);\n context.publicKey = publicKey;\n\n try {\n const response2 = await fetchToken({\n public_key: publicKeyPEM,\n hints,\n });\n\n if (response2.type === 'error') {\n throw new TokenErrorResponseError(response2);\n }\n\n if (response2.type !== 'tokens')\n throw new Error(\n `Unexpected response type from token endpoint: ${(response2 as any).type}`\n );\n\n /*const licenseStatus = response2.claims.license || 'ok';\n if (licenseStatus !== 'ok') {\n throw new InvalidLicenseError(licenseStatus);\n }*/\n\n context.accessToken = response2.accessToken;\n context.accessTokenExpiration = new Date(response2.accessTokenExpiration);\n context.refreshToken = response2.refreshToken;\n if (response2.refreshTokenExpiration) {\n context.refreshTokenExpiration = new Date(\n response2.refreshTokenExpiration\n );\n }\n context.userId = response2.claims.sub;\n context.email = response2.claims.email;\n context.name = response2.claims.name;\n context.claims = response2.claims;\n context.license = {\n type: response2.userType,\n status: response2.claims.license || 'ok',\n }\n context.data = response2.data;\n if (response2.evalDaysLeft != null) {\n context.license.evalDaysLeft = response2.evalDaysLeft;\n }\n if (response2.userValidUntil != null) {\n context.license.validUntil = new Date(response2.userValidUntil);\n }\n\n if (response2.alerts && response2.alerts.length > 0) {\n await interactWithUser(userInteraction, {\n type: 'message-alert',\n title: 'Authentication Alert',\n fields: {},\n alerts: response2.alerts as DXCAlert[],\n });\n }\n return context;\n } catch (error) {\n if (error instanceof TokenErrorResponseError) {\n await alertUser(userInteraction, error.title, {\n type: 'error',\n messageCode: error.messageCode,\n message: error.message,\n messageParams: {},\n });\n throw error;\n }\n let message = `We're having a problem authenticating right now.`;\n console.error (`Error authenticating`, error);\n if (error instanceof TypeError) {\n const isOffline = typeof navigator !== undefined && !navigator.onLine;\n if (isOffline) {\n message = `You seem to be offline. Please connect to the internet and try again.`;\n } else if (Dexie.debug || (typeof location !== 'undefined' && (location.hostname === 'localhost' || location.hostname === '127.0.0.1'))) {\n // The audience is most likely the developer. Suggest to whitelist the localhost origin:\n message = `Could not connect to server. Please verify that your origin '${location.origin}' is whitelisted using \\`npx dexie-cloud whitelist\\``;\n } else {\n message = `Could not connect to server. Please verify the connection.`;\n }\n await alertUser(userInteraction, 'Authentication Failed', {\n type: 'error',\n messageCode: 'GENERIC_ERROR',\n message,\n messageParams: {},\n }).catch(() => {}); \n }\n\n throw error;\n }\n}\n\nfunction spkiToPEM(keydata: ArrayBuffer) {\n const keydataB64 = b64encode(keydata);\n const keydataB64Pem = formatAsPem(keydataB64);\n return keydataB64Pem;\n}\n\nfunction formatAsPem(str: string) {\n let finalString = '-----BEGIN PUBLIC KEY-----\\n';\n\n while (str.length > 0) {\n finalString += str.substring(0, 64) + '\\n';\n str = str.substring(64);\n }\n\n finalString = finalString + '-----END PUBLIC KEY-----';\n\n return finalString;\n}\n","const { toString: toStr } = {};\nfunction getToStringTag(val) {\n return toStr.call(val).slice(8, -1);\n}\nexport function escapeDollarProps(value) {\n const keys = Object.keys(value);\n let dollarKeys = null;\n for (let i = 0, l = keys.length; i < l; ++i) {\n if (keys[i][0] === \"$\") {\n dollarKeys = dollarKeys || [];\n dollarKeys.push(keys[i]);\n }\n }\n if (!dollarKeys)\n return value;\n const clone = { ...value };\n for (const k of dollarKeys) {\n delete clone[k];\n }\n for (const k of dollarKeys) {\n clone[\"$\" + k] = value[k];\n }\n return clone;\n}\nconst ObjectDef = {\n replace: escapeDollarProps,\n};\nexport function TypesonSimplified(...typeDefsInputs) {\n const typeDefs = typeDefsInputs.reduce((p, c) => ({ ...p, ...c }), typeDefsInputs.reduce((p, c) => ({ ...c, ...p }), {}));\n const protoMap = new WeakMap();\n return {\n stringify(value, alternateChannel, space) {\n const json = JSON.stringify(value, function (key) {\n const realVal = this[key];\n const typeDef = getTypeDef(realVal);\n return typeDef\n ? typeDef.replace(realVal, alternateChannel, typeDefs)\n : realVal;\n }, space);\n return json;\n },\n parse(tson, alternateChannel) {\n const stack = [];\n return JSON.parse(tson, function (key, value) {\n //\n // Parent Part\n //\n const type = value === null || value === void 0 ? void 0 : value.$t;\n if (type) {\n const typeDef = typeDefs[type];\n value = typeDef\n ? typeDef.revive(value, alternateChannel, typeDefs)\n : value;\n }\n let top = stack[stack.length - 1];\n if (top && top[0] === value) {\n // Do what the kid told us to\n // Unescape dollar props\n value = { ...value };\n // Delete keys that children wanted us to delete\n for (const k of top[1])\n delete value[k];\n // Set keys that children wanted us to set\n for (const [k, v] of Object.entries(top[2])) {\n value[k] = v;\n }\n stack.pop();\n }\n //\n // Child part\n //\n if (value === undefined || (key[0] === \"$\" && key !== \"$t\")) {\n top = stack[stack.length - 1];\n let deletes;\n let mods;\n if (top && top[0] === this) {\n deletes = top[1];\n mods = top[2];\n }\n else {\n stack.push([this, (deletes = []), (mods = {})]);\n }\n if (key[0] === \"$\" && key !== \"$t\") {\n // Unescape props (also preserves undefined if this is a combo)\n deletes.push(key);\n mods[key.substr(1)] = value;\n }\n else {\n // Preserve undefined\n mods[key] = undefined;\n }\n }\n return value;\n });\n },\n };\n function getTypeDef(realVal) {\n const type = typeof realVal;\n switch (typeof realVal) {\n case \"object\":\n case \"function\": {\n // \"object\", \"function\", null\n if (realVal === null)\n return null;\n const proto = Object.getPrototypeOf(realVal);\n if (!proto)\n return ObjectDef;\n let typeDef = protoMap.get(proto);\n if (typeDef !== undefined)\n return typeDef; // Null counts to! So the caching of Array.prototype also counts.\n const toStringTag = getToStringTag(realVal);\n const entry = Object.entries(typeDefs).find(([typeName, typeDef]) => { var _a, _b; return (_b = (_a = typeDef === null || typeDef === void 0 ? void 0 : typeDef.test) === null || _a === void 0 ? void 0 : _a.call(typeDef, realVal, toStringTag)) !== null && _b !== void 0 ? _b : typeName === toStringTag; });\n typeDef = entry === null || entry === void 0 ? void 0 : entry[1];\n if (!typeDef) {\n typeDef = Array.isArray(realVal)\n ? null\n : typeof realVal === \"function\"\n ? typeDefs.function || null\n : ObjectDef;\n }\n protoMap.set(proto, typeDef);\n return typeDef;\n }\n default:\n return typeDefs[type];\n }\n }\n}\n","export const BisonBinaryTypes = {\n Blob: {\n test: (blob, toStringTag) => toStringTag === \"Blob\",\n replace: (blob, altChannel) => {\n const i = altChannel.length;\n altChannel.push(blob);\n return {\n $t: \"Blob\",\n mimeType: blob.type,\n i,\n };\n },\n revive: ({ i, mimeType }, altChannel) => new Blob([altChannel[i]], { type: mimeType }),\n },\n};\n","export default {\n number: {\n replace: (num) => {\n switch (true) {\n case isNaN(num):\n return { $t: \"number\", v: \"NaN\" };\n case num === Infinity:\n return { $t: \"number\", v: \"Infinity\" };\n case num === -Infinity:\n return { $t: \"number\", v: \"-Infinity\" };\n default:\n return num;\n }\n },\n revive: ({ v }) => Number(v),\n },\n};\n","const bigIntDef = {\n bigint: {\n replace: (realVal) => {\n return { $t: \"bigint\", v: \"\" + realVal };\n },\n revive: (obj) => BigInt(obj.v),\n },\n};\nexport default bigIntDef;\n","export default {\n Date: {\n replace: (date) => ({\n $t: \"Date\",\n v: isNaN(date.getTime()) ? \"NaN\" : date.toISOString(),\n }),\n revive: ({ v }) => new Date(v === \"NaN\" ? NaN : Date.parse(v)),\n },\n};\n","export default {\n Set: {\n replace: (set) => ({\n $t: \"Set\",\n v: Array.from(set.entries()),\n }),\n revive: ({ v }) => new Set(v),\n },\n};\n","export default {\n Map: {\n replace: (map) => ({\n $t: \"Map\",\n v: Array.from(map.entries()),\n }),\n revive: ({ v }) => new Map(v),\n },\n};\n","export const _global = typeof globalThis !== \"undefined\" // All modern environments (node, bun, deno, browser, workers, webview etc)\n ? globalThis\n : typeof self !== \"undefined\" // Older browsers, workers, webview, window etc\n ? self\n : typeof global !== \"undefined\" // Older versions of node\n ? global\n : undefined; // Unsupported environment. No idea to return 'this' since we are in a module or a function scope anyway.\n","import { _global } from \"../../common/_global.js\";\nexport default [\n \"Int8Array\",\n \"Uint8Array\",\n \"Uint8ClampedArray\",\n \"Int16Array\",\n \"Uint16Array\",\n \"Int32Array\",\n \"Uint32Array\",\n \"Float32Array\",\n \"Float64Array\",\n \"DataView\",\n \"BigInt64Array\",\n \"BigUint64Array\",\n].reduce((specs, typeName) => ({\n ...specs,\n [typeName]: {\n // Replace passes the the typed array into $t, buffer so that\n // the ArrayBuffer typedef takes care of further handling of the buffer:\n // {$t:\"Uint8Array\",buffer:{$t:\"ArrayBuffer\",idx:0}}\n // CHANGED ABOVE! Now shortcutting that for more sparse format of the typed arrays\n // to contain the b64 property directly.\n replace: (a, _, typeDefs) => {\n const result = {\n $t: typeName,\n v: typeDefs.ArrayBuffer.replace(a.byteOffset === 0 && a.byteLength === a.buffer.byteLength\n ? a.buffer\n : a.buffer.slice(a.byteOffset, a.byteOffset + a.byteLength), _, typeDefs).v,\n };\n return result;\n },\n revive: ({ v }, _, typeDefs) => {\n const TypedArray = _global[typeName];\n return (TypedArray &&\n new TypedArray(typeDefs.ArrayBuffer.revive({ v }, _, typeDefs)));\n },\n },\n}), {});\n","import { b64decode, b64encode } from \"./base64.js\";\nexport function b64LexEncode(b) {\n return b64ToLex(b64encode(b));\n}\nexport function b64LexDecode(b64Lex) {\n return b64decode(lexToB64(b64Lex));\n}\nexport function b64ToLex(base64) {\n var encoded = \"\";\n for (var i = 0, length = base64.length; i < length; i++) {\n encoded += ENCODE_TABLE[base64[i]];\n }\n return encoded;\n}\nexport function lexToB64(base64lex) {\n // only accept string input\n if (typeof base64lex !== \"string\") {\n throw new Error(\"invalid decoder input: \" + base64lex);\n }\n var base64 = \"\";\n for (var i = 0, length = base64lex.length; i < length; i++) {\n base64 += DECODE_TABLE[base64lex[i]];\n }\n return base64;\n}\nconst DECODE_TABLE = {\n \"-\": \"=\",\n \"0\": \"A\",\n \"1\": \"B\",\n \"2\": \"C\",\n \"3\": \"D\",\n \"4\": \"E\",\n \"5\": \"F\",\n \"6\": \"G\",\n \"7\": \"H\",\n \"8\": \"I\",\n \"9\": \"J\",\n A: \"K\",\n B: \"L\",\n C: \"M\",\n D: \"N\",\n E: \"O\",\n F: \"P\",\n G: \"Q\",\n H: \"R\",\n I: \"S\",\n J: \"T\",\n K: \"U\",\n L: \"V\",\n M: \"W\",\n N: \"X\",\n O: \"Y\",\n P: \"Z\",\n Q: \"a\",\n R: \"b\",\n S: \"c\",\n T: \"d\",\n U: \"e\",\n V: \"f\",\n W: \"g\",\n X: \"h\",\n Y: \"i\",\n Z: \"j\",\n _: \"k\",\n a: \"l\",\n b: \"m\",\n c: \"n\",\n d: \"o\",\n e: \"p\",\n f: \"q\",\n g: \"r\",\n h: \"s\",\n i: \"t\",\n j: \"u\",\n k: \"v\",\n l: \"w\",\n m: \"x\",\n n: \"y\",\n o: \"z\",\n p: \"0\",\n q: \"1\",\n r: \"2\",\n s: \"3\",\n t: \"4\",\n u: \"5\",\n v: \"6\",\n w: \"7\",\n x: \"8\",\n y: \"9\",\n z: \"+\",\n \"|\": \"/\",\n};\nconst ENCODE_TABLE = {};\nfor (const c of Object.keys(DECODE_TABLE)) {\n ENCODE_TABLE[DECODE_TABLE[c]] = c;\n}\n","import { b64LexDecode, b64LexEncode } from \"../../common/b64lex.js\";\nexport default {\n ArrayBuffer: {\n replace: (ab) => ({\n $t: \"ArrayBuffer\",\n v: b64LexEncode(ab),\n }),\n revive: ({ v }) => {\n const ba = b64LexDecode(v);\n return ba.buffer.byteLength === ba.byteLength\n ? ba.buffer\n : ba.buffer.slice(ba.byteOffset, ba.byteOffset + ba.byteLength);\n },\n },\n};\n","export class FakeBlob {\n constructor(buf, type) {\n this.buf = buf;\n this.type = type;\n }\n}\n","export function readBlobSync(b) {\n const req = new XMLHttpRequest();\n req.overrideMimeType(\"text/plain; charset=x-user-defined\");\n req.open(\"GET\", URL.createObjectURL(b), false); // Sync\n req.send();\n if (req.status !== 200 && req.status !== 0) {\n throw new Error(\"Bad Blob access: \" + req.status);\n }\n return req.responseText;\n}\n","export function string2ArrayBuffer(str) {\n const array = new Uint8Array(str.length);\n for (let i = 0; i < str.length; ++i) {\n array[i] = str.charCodeAt(i); // & 0xff;\n }\n return array.buffer;\n}\nexport function arrayBuffer2String(buf) {\n // TODO: Optimize\n return new Uint8Array(buf).reduce((s, byte) => s + String.fromCharCode(byte), \"\");\n}\n","import { b64decode, b64encode } from \"../../common/base64.js\";\nimport { FakeBlob } from \"../FakeBlob.js\";\nimport { readBlobSync } from \"../readBlobSync.js\";\nimport { string2ArrayBuffer } from \"../string2ArrayBuffer.js\";\nexport default {\n Blob: {\n test: (blob, toStringTag) => toStringTag === \"Blob\" || blob instanceof FakeBlob,\n replace: (blob) => ({\n $t: \"Blob\",\n v: blob instanceof FakeBlob\n ? b64encode(blob.buf)\n : b64encode(string2ArrayBuffer(readBlobSync(blob))),\n type: blob.type,\n }),\n revive: ({ type, v }) => {\n const ab = b64decode(v);\n return typeof Blob !== undefined\n ? new Blob([ab])\n : new FakeBlob(ab.buffer, type);\n },\n },\n};\n","import numberDef from \"../types/number.js\";\nimport bigintDef from \"../types/bigint.js\";\nimport DateDef from \"../types/Date.js\";\nimport SetDef from \"../types/Set.js\";\nimport MapDef from \"../types/Map.js\";\nimport TypedArraysDefs from \"../types/TypedArray.js\";\nimport ArrayBufferDef from \"../types/ArrayBuffer.js\";\nimport BlobDef from \"../types/Blob.js\";\nconst builtin = {\n ...numberDef,\n ...bigintDef,\n ...DateDef,\n ...SetDef,\n ...MapDef,\n ...TypedArraysDefs,\n ...ArrayBufferDef,\n ...BlobDef, // Should be moved to another preset for DOM types (or universal? since it supports node as well with FakeBlob)\n};\nexport default builtin;\n","import { BisonBinaryTypes } from \"./BisonBinaryTypes.js\";\nimport builtin from \"./presets/builtin.js\";\nimport { TypesonSimplified } from \"./TypesonSimplified.js\";\nexport function Bison(...typeDefsInputs) {\n const tson = TypesonSimplified(builtin, BisonBinaryTypes, ...typeDefsInputs);\n return {\n toBinary(value) {\n const [blob, json] = this.stringify(value);\n const lenBuf = new ArrayBuffer(4);\n new DataView(lenBuf).setUint32(0, blob.size);\n return new Blob([lenBuf, blob, json]);\n },\n stringify(value) {\n const binaries = [];\n const json = tson.stringify(value, binaries);\n const blob = new Blob(binaries.map((b) => {\n const lenBuf = new ArrayBuffer(4);\n new DataView(lenBuf).setUint32(0, \"byteLength\" in b ? b.byteLength : b.size);\n return new Blob([lenBuf, b]);\n }));\n return [blob, json];\n },\n async parse(json, binData) {\n let pos = 0;\n const arrayBuffers = [];\n const buf = await readBlobBinary(binData);\n const view = new DataView(buf);\n while (pos < buf.byteLength) {\n const len = view.getUint32(pos);\n pos += 4;\n const ab = buf.slice(pos, pos + len);\n pos += len;\n arrayBuffers.push(ab);\n }\n return tson.parse(json, arrayBuffers);\n },\n async fromBinary(blob) {\n const len = new DataView(await readBlobBinary(blob.slice(0, 4))).getUint32(0);\n const binData = blob.slice(4, len + 4);\n const json = await readBlob(blob.slice(len + 4));\n return await this.parse(json, binData);\n },\n };\n}\nexport function readBlob(blob) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onabort = (ev) => reject(new Error(\"file read aborted\"));\n reader.onerror = (ev) => reject(ev.target.error);\n reader.onload = (ev) => resolve(ev.target.result);\n reader.readAsText(blob);\n });\n}\nexport function readBlobBinary(blob) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onabort = (ev) => reject(new Error(\"file read aborted\"));\n reader.onerror = (ev) => reject(ev.target.error);\n reader.onload = (ev) => resolve(ev.target.result);\n reader.readAsArrayBuffer(blob);\n });\n}\n","/** The undefined type is not part of builtin but can be manually added.\n * The reason for supporting undefined is if the following object should be revived correctly:\n *\n * {foo: undefined}\n *\n * Without including this typedef, the revived object would just be {}.\n * If including this typedef, the revived object would be {foo: undefined}.\n */\nexport default {\n undefined: {\n replace: () => ({\n $t: \"undefined\"\n }),\n revive: () => undefined,\n },\n};\n","import { b64decode, b64encode } from \"../../common/base64.js\";\nimport { readBlobSync } from \"../readBlobSync.js\";\nimport { string2ArrayBuffer } from \"../string2ArrayBuffer.js\";\nexport default {\n File: {\n test: (file, toStringTag) => toStringTag === \"File\",\n replace: (file) => ({\n $t: \"File\",\n v: b64encode(string2ArrayBuffer(readBlobSync(file))),\n type: file.type,\n name: file.name,\n lastModified: new Date(file.lastModified).toISOString(),\n }),\n revive: ({ type, v, name, lastModified }) => {\n const ab = b64decode(v);\n return new File([ab], name, {\n type,\n lastModified: new Date(lastModified).getTime(),\n });\n },\n },\n};\n","import { TypesonSimplified } from 'dreambase-library/dist/typeson-simplified/TypesonSimplified';\nimport { Bison } from 'dreambase-library/dist/typeson-simplified/Bison';\nimport undefinedDef from 'dreambase-library/dist/typeson-simplified/types/undefined.js';\nimport tsonBuiltinDefs from 'dreambase-library/dist/typeson-simplified/presets/builtin.js';\nimport { TypeDefSet } from 'dreambase-library/dist/typeson-simplified/TypeDefSet';\nimport { PropModSpec, PropModification } from 'dexie';\nimport FileDef from \"dreambase-library/dist/typeson-simplified/types/File.js\";\n\n// Since server revisions are stored in bigints, we need to handle clients without\n// bigint support to not fail when serverRevision is passed over to client.\n// We need to not fail when reviving it and we need to somehow store the information.\n// Since the revived version will later on be put into indexedDB we have another\n// issue: When reading it back from indexedDB we will get a poco object that we\n// cannot replace correctly when sending it to server. So we will also need\n// to do an explicit workaround in the protocol where a bigint is supported.\n// The workaround should be there regardless if browser supports BigInt or not, because\n// the serverRev might have been stored in IDB before the browser was upgraded to support bigint.\n//\n// if (typeof serverRev.rev !== \"bigint\")\n// if (hasBigIntSupport)\n// serverRev.rev = bigIntDef.bigint.revive(server.rev)\n// else\n// serverRev.rev = new FakeBigInt(server.rev)\nexport const hasBigIntSupport =\n typeof BigInt === 'function' && typeof BigInt(0) === 'bigint';\n\nfunction getValueOfBigInt(x: bigint | FakeBigInt | string) {\n if (typeof x === 'bigint') {\n return x;\n }\n if (hasBigIntSupport) {\n return typeof x === 'string' ? BigInt(x) : BigInt(x.v);\n } else {\n return typeof x === 'string' ? Number(x) : Number(x.v);\n }\n}\n\nexport function compareBigInts(\n a: bigint | FakeBigInt | string,\n b: bigint | FakeBigInt | string\n) {\n const valA = getValueOfBigInt(a);\n const valB = getValueOfBigInt(b);\n return valA < valB ? -1 : valA > valB ? 1 : 0;\n}\nexport class FakeBigInt {\n v: string;\n toString() {\n return this.v;\n }\n constructor(value: string) {\n this.v = value;\n }\n}\n\nconst bigIntDef = hasBigIntSupport\n ? {}\n : {\n bigint: {\n test: (val: any) => val instanceof FakeBigInt,\n replace: (fakeBigInt: any) => {\n return {\n $t: 'bigint',\n ...fakeBigInt,\n };\n },\n revive: ({ v }: { $t: 'bigint'; v: string }) =>\n new FakeBigInt(v) as any as bigint,\n },\n };\n\nconst defs: TypeDefSet = {\n ...undefinedDef,\n ...bigIntDef,\n ...FileDef,\n PropModification: {\n test: (val: any) => val instanceof PropModification,\n replace: (propModification: any) => {\n return {\n $t: 'PropModification',\n ...propModification['@@propmod'],\n };\n },\n revive: ({\n $t, // strip '$t'\n ...propModSpec // keep the rest\n }: {\n $t: 'PropModification';\n } & PropModSpec) => new PropModification(propModSpec),\n },\n};\n\nexport const TSON = TypesonSimplified(tsonBuiltinDefs, defs);\n\nexport const BISON = Bison(defs);\n","export class HttpError extends Error {\n httpStatus: number;\n constructor(\n res: Response,\n message?: string)\n {\n super(message || `${res.status} ${res.statusText}`);\n this.httpStatus = res.status;\n }\n\n get name() {\n return \"HttpError\";\n }\n}\n","import Dexie, { DBCoreSchema } from 'dexie';\nimport {\n DBInsertOperation,\n DBOperation,\n DBOperationsSet,\n DBOpPrimaryKey,\n} from 'dexie-cloud-common';\nimport { UserLogin } from '../db/entities/UserLogin';\n\nexport function encodeIdsForServer(\n schema: DBCoreSchema,\n currentUser: UserLogin,\n changes: DBOperationsSet\n): DBOperationsSet {\n const rv: DBOperationsSet = [];\n for (let change of changes) {\n const { table, muts } = change;\n const tableSchema = schema.tables.find((t) => t.name === table);\n if (!tableSchema)\n throw new Error(\n `Internal error: table ${table} not found in DBCore schema`\n );\n const { primaryKey } = tableSchema;\n let changeClone = change;\n muts.forEach((mut, mutIndex) => {\n const rewriteValues =\n !primaryKey.outbound &&\n (mut.type === 'upsert' || mut.type === 'insert');\n mut.keys.forEach((key, keyIndex) => {\n if (Array.isArray(key)) {\n // Server only support string keys. Dexie Cloud client support strings or array of strings.\n if (changeClone === change)\n changeClone = cloneChange(change, rewriteValues);\n const mutClone = changeClone.muts[mutIndex];\n const rewrittenKey = JSON.stringify(key);\n mutClone.keys[keyIndex] = rewrittenKey;\n /* Bug (#1777)\n We should not rewrite values. It will fail because the key is array and the value is string.\n Only the keys should be rewritten and it's already done on the server.\n We should take another round of revieweing how key transformations are being done between\n client and server and let the server do the key transformations entirely instead now that\n we have the primary key schema on the server making it possible to do so.\n if (rewriteValues) {\n Dexie.setByKeyPath(\n (mutClone as DBInsertOperation).values[keyIndex],\n primaryKey.keyPath!,\n rewrittenKey\n );\n }*/\n } else if (key[0] === '#') {\n // Private ID - translate!\n if (changeClone === change)\n changeClone = cloneChange(change, rewriteValues);\n const mutClone = changeClone.muts[mutIndex];\n if (!currentUser.isLoggedIn)\n throw new Error(\n `Internal error: Cannot sync private IDs before authenticated`\n );\n const rewrittenKey = `${key}:${currentUser.userId}`;\n mutClone.keys[keyIndex] = rewrittenKey;\n if (rewriteValues) {\n Dexie.setByKeyPath(\n (mutClone as DBInsertOperation).values[keyIndex],\n primaryKey.keyPath!,\n rewrittenKey\n );\n }\n }\n });\n });\n rv.push(changeClone);\n }\n return rv;\n}\n\nfunction cloneChange(change: DBOperationsSet[number], rewriteValues: boolean) {\n // clone on demand:\n return {\n ...change,\n muts: rewriteValues\n ? change.muts.map((m) => {\n return (m.type === 'insert' || m.type === 'upsert') && m.values\n ? {\n ...m,\n keys: m.keys.slice(),\n values: m.values.slice(),\n }\n : {\n ...m,\n keys: m.keys.slice(),\n };\n })\n : change.muts.map((m) => ({ ...m, keys: m.keys.slice() })),\n };\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\n\n// If we get Ratelimit-Limit and Ratelimit-Remaining where Ratelimit-Remaining is below\n// (Ratelimit-Limit / 2), we should delay the next sync by (Ratelimit-Reset / Ratelimit-Remaining)\n// seconds (given that there is a Ratelimit-Reset header).\n\nlet syncRatelimitDelays = new WeakMap<DexieCloudDB, Date>();\n\nexport async function checkSyncRateLimitDelay(db: DexieCloudDB) {\n const delatMilliseconds = (syncRatelimitDelays.get(db)?.getTime() ?? 0) - Date.now();\n if (delatMilliseconds > 0) {\n console.debug(`Stalling sync request ${delatMilliseconds} ms to spare ratelimits`);\n await new Promise(resolve => setTimeout(resolve, delatMilliseconds));\n }\n}\n\nexport function updateSyncRateLimitDelays(db: DexieCloudDB, res: Response) {\n const limit = res.headers.get('Ratelimit-Limit');\n const remaining = res.headers.get('Ratelimit-Remaining');\n const reset = res.headers.get('Ratelimit-Reset');\n if (limit && remaining && reset) {\n const limitNum = Number(limit);\n const remainingNum = Math.max(0, Number(remaining));\n const willResetInSeconds = Number(reset);\n if (remainingNum < limitNum / 2) {\n const delay = Math.ceil(willResetInSeconds / (remainingNum + 1));\n syncRatelimitDelays.set(db, new Date(Date.now() + delay * 1000));\n console.debug(`Sync ratelimit delay set to ${delay} seconds`);\n } else {\n syncRatelimitDelays.delete(db);\n console.debug(`Sync ratelimit delay cleared`);\n }\n }\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { loadAccessToken } from '../authentication/authenticate';\nimport { BISON, TSON } from '../TSON';\nimport { getSyncableTables } from '../helpers/getSyncableTables';\nimport { BaseRevisionMapEntry } from '../db/entities/BaseRevisionMapEntry';\nimport { HttpError } from '../errors/HttpError';\nimport {\n DBOperationsSet,\n DexieCloudSchema,\n SyncRequest,\n SyncResponse,\n YClientMessage,\n} from 'dexie-cloud-common';\nimport { encodeIdsForServer } from './encodeIdsForServer';\nimport { UserLogin } from '../db/entities/UserLogin';\nimport { updateSyncRateLimitDelays } from './ratelimit';\n//import {BisonWebStreamReader} from \"dreambase-library/dist/typeson-simplified/BisonWebStreamReader\";\n\nexport async function syncWithServer(\n changes: DBOperationsSet,\n y: YClientMessage[],\n syncState: PersistedSyncState | undefined,\n baseRevs: BaseRevisionMapEntry[],\n db: DexieCloudDB,\n databaseUrl: string,\n schema: DexieCloudSchema | null,\n clientIdentity: string,\n currentUser: UserLogin\n): Promise<SyncResponse> {\n //\n // Push changes to server using fetch\n //\n const headers: HeadersInit = {\n Accept: 'application/json, application/x-bison, application/x-bison-stream',\n 'Content-Type': 'application/tson',\n };\n const updatedUser = await loadAccessToken(db);\n /*\n if (updatedUser?.license && changes.length > 0) {\n if (updatedUser.license.status === 'expired') {\n throw new Error(`License has expired`);\n }\n if (updatedUser.license.status === 'deactivated') {\n throw new Error(`License deactivated`);\n }\n }\n */\n const accessToken = updatedUser?.accessToken;\n if (accessToken) {\n headers.Authorization = `Bearer ${accessToken}`;\n }\n\n const syncRequest: SyncRequest = {\n v: 2,\n dbID: syncState?.remoteDbId,\n clientIdentity,\n schema: schema || {},\n lastPull: syncState\n ? {\n serverRevision: syncState.serverRevision!,\n yServerRevision: syncState.yServerRevision,\n realms: syncState.realms,\n inviteRealms: syncState.inviteRealms,\n }\n : undefined,\n baseRevs,\n changes: encodeIdsForServer(db.dx.core.schema, currentUser, changes),\n y,\n dxcv: db.cloud.version\n };\n console.debug('Sync request', syncRequest);\n db.syncStateChangedEvent.next({\n phase: 'pushing',\n });\n const body = TSON.stringify(syncRequest);\n const res = await fetch(`${databaseUrl}/sync`, {\n method: 'post',\n headers,\n credentials: 'include', // For Arr Affinity cookie only, for better Rate-Limit counting only.\n body,\n });\n //const contentLength = Number(res.headers.get('content-length'));\n db.syncStateChangedEvent.next({\n phase: 'pulling',\n });\n\n updateSyncRateLimitDelays(db, res);\n\n if (!res.ok) {\n throw new HttpError(res);\n }\n\n switch (res.headers.get('content-type')) {\n case 'application/x-bison':\n return BISON.fromBinary(await res.blob());\n case 'application/x-bison-stream': //return BisonWebStreamReader(BISON, res);\n default:\n case 'application/json': {\n const text = await res.text();\n const syncRes = TSON.parse(text);\n return syncRes;\n }\n }\n}\n","import Dexie from \"dexie\";\n\nexport interface CancelToken {\n cancelled: boolean;\n}\n\nexport function throwIfCancelled(cancelToken?: CancelToken) {\n if (cancelToken?.cancelled) throw new Dexie.AbortError(`Operation was cancelled`);\n}\n","/* Need this because navigator.onLine seems to say \"false\" when it is actually online.\n This function relies initially on navigator.onLine but then uses online and offline events\n which seem to be more reliable.\n*/\nexport let isOnline = false;\nif (typeof self !== 'undefined' && typeof navigator !== 'undefined') {\n isOnline = navigator.onLine;\n self.addEventListener('online', ()=>isOnline = true);\n self.addEventListener('offline', ()=>isOnline = false);\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { DexieCloudSchema, SyncResponse } from 'dexie-cloud-common';\n\nexport async function updateBaseRevs(db: DexieCloudDB, schema: DexieCloudSchema, latestRevisions: { [table: string]: number; }, serverRev: any) {\n await db.$baseRevs.bulkPut(\n Object.keys(schema)\n .filter((table) => schema[table].markedForSync)\n .map((tableName) => {\n const lastClientRevOnPreviousServerRev = latestRevisions[tableName] || 0;\n return {\n tableName,\n clientRev: lastClientRevOnPreviousServerRev + 1,\n serverRev,\n };\n })\n );\n // Clean up baseRevs for tables that do not exist anymore or are no longer marked for sync\n // Resolve #2168 by also cleaning up baseRevs for tables that are not marked for sync\n await db.$baseRevs.where('tableName').noneOf(\n Object.keys(schema).filter((table) => schema[table].markedForSync)\n ).delete();\n}\n","import { DBOperationsSet } from 'dexie-cloud-common';\n\nexport function getLatestRevisionsPerTable(\n clientChangeSet: DBOperationsSet,\n lastRevisions = {} as { [table: string]: number; }) {\n for (const { table, muts } of clientChangeSet) {\n const lastRev = muts.length > 0 ? muts[muts.length - 1].rev : null;\n lastRevisions[table] = lastRev || lastRevisions[table] || 0;\n }\n return lastRevisions;\n}\n","import Dexie, { Table, cmp } from 'dexie';\n\nexport async function bulkUpdate(\n table: Table,\n keys: any[],\n changeSpecs: { [keyPath: string]: any }[]\n) {\n const objs = await table.bulkGet(keys);\n const resultKeys: any[] = [];\n const resultObjs: any[] = [];\n keys.forEach((key, idx) => {\n const obj = objs[idx];\n if (obj) {\n for (const [keyPath, value] of Object.entries(changeSpecs[idx])) {\n if (keyPath === table.schema.primKey.keyPath) {\n if (cmp(value, key) !== 0) {\n throw new Error(`Cannot change primary key`);\n }\n } else {\n Dexie.setByKeyPath(obj, keyPath, value);\n }\n }\n resultKeys.push(key);\n resultObjs.push(obj);\n }\n });\n await (table.schema.primKey.keyPath == null\n ? table.bulkPut(resultObjs, resultKeys)\n : table.bulkPut(resultObjs));\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport Dexie from 'dexie';\nimport { bulkUpdate } from '../helpers/bulkUpdate';\nimport { DBOperationsSet } from 'dexie-cloud-common';\n\nexport async function applyServerChanges(\n changes: DBOperationsSet<string>,\n db: DexieCloudDB\n) {\n console.debug('Applying server changes', changes, Dexie.currentTransaction);\n for (const { table: tableName, muts } of changes) {\n if (!db.dx._allTables[tableName]) {\n console.debug(\n `Server sent changes for table ${tableName} that we don't have. Ignoring.`\n );\n continue;\n }\n const table = db.table(tableName);\n const { primaryKey } = table.core.schema;\n const keyDecoder = (key: string) => {\n switch (key[0]) {\n case '[':\n // Decode JSON array\n if (key.endsWith(']'))\n try {\n // On server, array keys are transformed to JSON string representation\n return JSON.parse(key);\n } catch {}\n return key;\n case '#':\n // Decode private ID (do the opposite from what's done in encodeIdsForServer())\n if (key.endsWith(':' + db.cloud.currentUserId)) {\n return key.substr(\n 0,\n key.length - db.cloud.currentUserId.length - 1\n );\n }\n return key;\n default:\n return key;\n }\n };\n for (const mut of muts) {\n const keys = mut.keys.map(keyDecoder);\n switch (mut.type) {\n case 'insert':\n if (primaryKey.outbound) {\n await table.bulkAdd(mut.values, keys);\n } else {\n keys.forEach((key, i) => {\n // Make sure inbound keys are consistent\n Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath!, key);\n });\n await table.bulkAdd(mut.values);\n }\n break;\n case 'upsert':\n if (primaryKey.outbound) {\n await table.bulkPut(mut.values, keys);\n } else {\n keys.forEach((key, i) => {\n // Make sure inbound keys are consistent\n Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath!, key);\n });\n await table.bulkPut(mut.values);\n }\n break;\n case 'modify':\n if (keys.length === 1) {\n await table.update(keys[0], mut.changeSpec);\n } else {\n await table.where(':id').anyOf(keys).modify(mut.changeSpec);\n }\n break;\n case 'update':\n await bulkUpdate(table, keys, mut.changeSpecs);\n break;\n case 'delete':\n await table.bulkDelete(keys);\n break;\n }\n }\n }\n}\n","\nexport const DEXIE_CLOUD_SYNCER_ID = 'dexie-cloud-syncer';\n","import type { Table } from 'dexie';\nimport type { YUpdateRow } from 'y-dexie';\n\nexport function listUpdatesSince(yTable: Table, sinceIncluding: number): Promise<YUpdateRow[]> {\n return yTable\n .where('i')\n .between(sinceIncluding, Infinity, true)\n .toArray();\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { YTable } from \"./YTable\";\n\nexport function getUpdatesTable(db: DexieCloudDB, table: string, ydocProp: string): YTable | undefined {\n if (!db.dx._allTables[table]) return undefined;\n const utbl = db.table(table)?.schema.yProps?.find(p => p.prop === ydocProp)?.updatesTable;\n if (!utbl) {\n console.debug(`No updatesTable found for ${table}.${ydocProp}`);\n return undefined;\n }\n if (!db.dx._allTables[utbl]) return undefined;\n return db.table(utbl);\n}\n","import { cmp, InsertType } from 'dexie';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { YServerMessage } from 'dexie-cloud-common';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport { getUpdatesTable } from './getUpdatesTable';\nimport { DexieYProvider, YSyncState, YUpdateRow } from 'y-dexie';\n\nexport async function applyYServerMessages(\n yMessages: YServerMessage[],\n db: DexieCloudDB\n): Promise<{\n receivedUntils: { [yTable: string]: number };\n resyncNeeded: boolean;\n yServerRevision?: string;\n}> {\n const receivedUntils: { [yTable: string]: number } = {};\n let resyncNeeded = false;\n let yServerRevision: string | undefined;\n for (const m of yMessages) {\n try {\n switch (m.type) {\n case 'u-s': {\n const utbl = getUpdatesTable(db, m.table, m.prop);\n if (utbl) {\n const updateRow: InsertType<YUpdateRow, 'i'> = {\n k: m.k,\n u: m.u,\n };\n if (m.r) {\n // @ts-ignore\n updateRow.r = m.r;\n yServerRevision = m.r;\n }\n receivedUntils[utbl.name] = await utbl.add(updateRow);\n }\n break;\n }\n case 'u-ack': {\n const utbl = getUpdatesTable(db, m.table, m.prop);\n if (utbl) {\n await db.transaction('rw', utbl, async (tx) => {\n let syncer = (await tx\n .table(utbl.name)\n .get(DEXIE_CLOUD_SYNCER_ID)) as YSyncState | undefined;\n await tx.table(utbl.name).put({\n ...(syncer || { i: DEXIE_CLOUD_SYNCER_ID }),\n unsentFrom: Math.max(syncer?.unsentFrom || 1, m.i + 1),\n } as YSyncState);\n });\n }\n break;\n }\n case 'u-reject': {\n // Acces control or constraint rejected the update.\n // We delete it. It's not going to be sent again.\n // What's missing is a way to notify consumers, such as Tiptap editor, that the update was rejected.\n // This is only an issue when the document is open. We could find the open document and\n // in a perfect world, we should send a reverse update to the open document to undo the change.\n // See my question in https://discuss.yjs.dev/t/generate-an-inverse-update/2765\n console.debug(`Y update rejected. Deleting it.`);\n const utbl = getUpdatesTable(db, m.table, m.prop);\n if (!utbl) break;\n // Delete the rejected update and all local updates since (avoid holes in the CRDT)\n // and destroy it's open document if there is one.\n const primaryKey = (await utbl.get(m.i))?.k;\n if (primaryKey != null) {\n await db.transaction('rw', utbl, (tx) => {\n // @ts-ignore\n tx.idbtrans._rejecting_y_ypdate = true; // Inform ydoc triggers that we delete because of a rejection and not GC\n return utbl\n .where('i')\n .aboveOrEqual(m.i)\n .filter(\n (u) => cmp(u.k, primaryKey) === 0 && ((u.f || 0) & 1) === 1\n )\n .delete();\n });\n // Destroy active doc\n const activeDoc = DexieYProvider.getDocCache(db.dx).find(\n m.table,\n primaryKey,\n m.prop\n );\n if (activeDoc) activeDoc.destroy(); // Destroy the document so that editors don't continue to work on it\n }\n break;\n }\n case 'in-sync': {\n const doc = DexieYProvider.getDocCache(db.dx).find(\n m.table,\n m.k,\n m.prop\n );\n if (doc && !doc.isSynced) {\n doc.emit('sync', [true, doc]);\n }\n break;\n }\n case 'y-complete-sync-done': {\n yServerRevision = m.yServerRev;\n break;\n }\n case 'outdated-server-rev':\n resyncNeeded = true;\n break;\n }\n } catch (e) {\n console.error(`Failed to apply YMessage`, m, e);\n }\n }\n\n return {\n receivedUntils,\n resyncNeeded,\n yServerRevision,\n };\n}\n","import {\n asyncIterablePipeline,\n consumeChunkedBinaryStream,\n getFetchResponseBodyGenerator,\n} from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { TSON } from '../TSON';\nimport { loadAccessToken } from '../authentication/authenticate';\nimport {\n Decoder,\n readUint8,\n readVarString,\n readAny,\n readVarUint8Array,\n hasContent,\n} from 'lib0/decoding';\nimport { getUpdatesTable } from './getUpdatesTable';\nimport Dexie, { InsertType } from 'dexie';\nimport type { YUpdateRow } from 'y-dexie';\n\nconst BINSTREAM_TYPE_REALMID = 1;\nconst BINSTREAM_TYPE_TABLE_AND_PROP = 2;\nconst BINSTREAM_TYPE_DOCUMENT = 3;\n\nexport async function downloadYDocsFromServer(\n db: DexieCloudDB,\n databaseUrl: string,\n { yDownloadedRealms, realms }: PersistedSyncState\n) {\n if (\n yDownloadedRealms &&\n realms &&\n realms.every((realmId) => yDownloadedRealms[realmId] === '*')\n ) {\n return; // Already done!\n }\n console.debug('Downloading Y.Docs from added realms');\n const user = await loadAccessToken(db);\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n Accept: 'application/octet-stream',\n };\n if (user) {\n headers.Authorization = `Bearer ${user.accessToken}`;\n }\n const res = await fetch(`${databaseUrl}/y/download`, {\n body: TSON.stringify({ downloadedRealms: yDownloadedRealms || {} }),\n method: 'POST',\n headers,\n credentials: 'include',\n });\n if (!res.ok) {\n throw new Error(\n `Failed to download Yjs documents from server. Status: ${res.status}`\n );\n }\n await asyncIterablePipeline(\n getFetchResponseBodyGenerator(res),\n consumeChunkedBinaryStream,\n consumeDownloadChunks\n );\n\n async function* consumeDownloadChunks(chunks: AsyncIterable<Uint8Array>) {\n let currentRealmId: string | null = null;\n let currentTable: string | null = null;\n let currentProp: string | null = null;\n let docsToInsert: InsertType<YUpdateRow, 'i'>[] = [];\n\n async function storeCollectedDocs(completedRealm: boolean) {\n const lastDoc = docsToInsert[docsToInsert.length - 1];\n if (docsToInsert.length > 0) {\n if (!currentRealmId || !currentTable || !currentProp) {\n throw new Error(`Protocol error from ${databaseUrl}/y/download`);\n }\n const yTable = getUpdatesTable(db, currentTable, currentProp);\n if (yTable) {\n await yTable.bulkAdd(docsToInsert);\n }\n docsToInsert = [];\n }\n if (\n currentRealmId &&\n ((currentTable && currentProp && lastDoc) || completedRealm)\n ) {\n await db.$syncState.update('syncState', (syncState: PersistedSyncState) => {\n const yDownloadedRealms = syncState.yDownloadedRealms || {};\n yDownloadedRealms[currentRealmId!] = completedRealm\n ? '*'\n : {\n tbl: currentTable!,\n prop: currentProp!,\n key: lastDoc.k!,\n };\n syncState.yDownloadedRealms = yDownloadedRealms;\n });\n }\n }\n\n try {\n for await (const chunk of chunks) {\n const decoder = new Decoder(chunk);\n while (hasContent(decoder)) {\n switch (readUint8(decoder)) {\n case BINSTREAM_TYPE_REALMID:\n await storeCollectedDocs(true);\n currentRealmId = readVarString(decoder);\n break;\n case BINSTREAM_TYPE_TABLE_AND_PROP:\n await storeCollectedDocs(false); // still on same realm\n currentTable = readVarString(decoder);\n currentProp = readVarString(decoder);\n break;\n case BINSTREAM_TYPE_DOCUMENT: {\n const k = readAny(decoder);\n const u = readVarUint8Array(decoder);\n docsToInsert.push({\n k,\n u,\n });\n break;\n }\n }\n }\n await storeCollectedDocs(false); // Chunk full - migth still be on same realm\n }\n await storeCollectedDocs(true); // Everything downloaded - finalize last downloaded realm to \"*\"\n } catch (error) {\n if (!(error instanceof Dexie.DexieError)) {\n // Network error might have happened.\n // Store what we've collected so far:\n await storeCollectedDocs(false);\n }\n throw error;\n }\n }\n}\n","import { __asyncValues } from \"tslib\";\nexport async function asyncIterablePipeline(source, ...stages) {\n var _a, e_1, _b, _c;\n // Chain generators by sending outdata from one to another\n let result = source(); // Start with the source generator\n for (let i = 0; i < stages.length; i++) {\n result = stages[i](result); // Pass on the result to next generator\n }\n try {\n // Start running the machine. If the last stage is a sink, it will consume the data and never emit anything\n // to us here...\n for (var _d = true, result_1 = __asyncValues(result), result_1_1; result_1_1 = await result_1.next(), _a = result_1_1.done, !_a; _d = true) {\n _c = result_1_1.value;\n _d = false;\n const chunk = _c;\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (!_d && !_a && (_b = result_1.return)) await _b.call(result_1);\n }\n finally { if (e_1) throw e_1.error; }\n }\n}\n","import { __asyncGenerator, __await } from \"tslib\";\nexport function getFetchResponseBodyGenerator(res) {\n return function () {\n return __asyncGenerator(this, arguments, function* () {\n if (!res.body)\n throw new Error(\"Response body is not readable\");\n const reader = res.body.getReader();\n try {\n while (true) {\n const { done, value } = yield __await(reader.read());\n if (done)\n return yield __await(void 0);\n yield yield __await(value);\n }\n }\n finally {\n reader.releaseLock();\n }\n });\n };\n}\n","import { getMutationTable } from '../helpers/getMutationTable';\nimport { getSyncableTables } from '../helpers/getSyncableTables';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { listSyncifiedChanges } from './listSyncifiedChanges';\nimport { getTablesToSyncify } from './getTablesToSyncify';\nimport { listClientChanges } from './listClientChanges';\nimport { syncWithServer } from './syncWithServer';\nimport { modifyLocalObjectsWithNewUserId } from './modifyLocalObjectsWithNewUserId';\nimport { throwIfCancelled } from '../helpers/CancelToken';\nimport { DexieCloudOptions } from '../DexieCloudOptions';\nimport { BaseRevisionMapEntry } from '../db/entities/BaseRevisionMapEntry';\nimport { getTableFromMutationTable } from '../helpers/getTableFromMutationTable';\nimport {\n applyOperations,\n DBKeyMutationSet,\n DBOperationsSet,\n DexieCloudSchema,\n randomString,\n subtractChanges,\n SyncResponse,\n toDBOperationSet,\n} from 'dexie-cloud-common';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { isOnline } from './isOnline';\nimport { updateBaseRevs } from './updateBaseRevs';\nimport { getLatestRevisionsPerTable } from './getLatestRevisionsPerTable';\nimport { applyServerChanges } from './applyServerChanges';\nimport { checkSyncRateLimitDelay } from './ratelimit';\nimport { listYClientMessagesAndStateVector } from '../yjs/listYClientMessagesAndStateVector';\nimport { applyYServerMessages } from '../yjs/applyYMessages';\nimport { updateYSyncStates } from '../yjs/updateYSyncStates';\nimport { downloadYDocsFromServer } from '../yjs/downloadYDocsFromServer';\nimport { UpdateSpec } from 'dexie';\n\nexport const CURRENT_SYNC_WORKER = 'currentSyncWorker';\n\nexport interface SyncOptions {\n isInitialSync?: boolean;\n cancelToken?: { cancelled: boolean };\n justCheckIfNeeded?: boolean;\n retryImmediatelyOnFetchError?: boolean;\n purpose?: 'pull' | 'push';\n}\n\nexport function sync(\n db: DexieCloudDB,\n options: DexieCloudOptions,\n schema: DexieCloudSchema,\n syncOptions?: SyncOptions\n): Promise<boolean> {\n return _sync(db, options, schema, syncOptions)\n .then((result) => {\n if (!syncOptions?.justCheckIfNeeded) { // && syncOptions?.purpose !== 'push') {\n db.syncStateChangedEvent.next({\n phase: 'in-sync',\n });\n }\n return result;\n })\n .catch(async (error: any) => {\n if (syncOptions?.justCheckIfNeeded) return Promise.reject(error); // Just rethrow.\n console.debug('Error from _sync', {\n isOnline,\n syncOptions,\n error,\n });\n if (\n isOnline &&\n syncOptions?.retryImmediatelyOnFetchError &&\n error?.name === 'TypeError' &&\n /fetch/.test(error?.message)\n ) {\n db.syncStateChangedEvent.next({\n phase: 'error',\n error,\n });\n // Retry again in 500 ms but if it fails again, don't retry.\n await new Promise((resolve) => setTimeout(resolve, 500));\n return await sync(db, options, schema, {\n ...syncOptions,\n retryImmediatelyOnFetchError: false,\n });\n }\n // Make sure that no matter whether sync() explodes or not,\n // always update the timestamp. Also store the error.\n await db.$syncState.update('syncState', {\n timestamp: new Date(),\n error: '' + error,\n });\n db.syncStateChangedEvent.next({\n phase: isOnline ? 'error' : 'offline',\n error: new Error('' + error?.message || error),\n });\n return Promise.reject(error);\n });\n}\n\nasync function _sync(\n db: DexieCloudDB,\n options: DexieCloudOptions,\n schema: DexieCloudSchema,\n { isInitialSync, cancelToken, justCheckIfNeeded, purpose }: SyncOptions = {\n isInitialSync: false,\n }\n): Promise<boolean> {\n if (!justCheckIfNeeded) {\n console.debug('SYNC STARTED', { isInitialSync, purpose });\n }\n if (!db.cloud.options?.databaseUrl)\n throw new Error(\n `Internal error: sync must not be called when no databaseUrl is configured`\n );\n const { databaseUrl } = options;\n const currentUser = await db.getCurrentUser(); // Keep same value across entire sync flow:\n const tablesToSync = currentUser.isLoggedIn ? getSyncableTables(db) : [];\n\n const mutationTables = tablesToSync.map((tbl) =>\n db.table(getMutationTable(tbl.name))\n );\n\n // If this is not the initial sync,\n // go through tables that were previously not synced but should now be according to\n // logged in state and the sync table whitelist in db.cloud.options.\n //\n // Prepare for syncification by modifying locally unauthorized objects:\n //\n const persistedSyncState = await db.getPersistedSyncState();\n const readyForSyncification = currentUser.isLoggedIn;\n const tablesToSyncify = readyForSyncification\n ? getTablesToSyncify(db, persistedSyncState)\n : [];\n throwIfCancelled(cancelToken);\n const doSyncify = tablesToSyncify.length > 0;\n\n if (doSyncify) {\n if (justCheckIfNeeded) return true;\n //console.debug('sync doSyncify is true');\n await db.transaction('rw', tablesToSyncify, async (tx) => {\n // @ts-ignore\n tx.idbtrans.disableChangeTracking = true;\n // @ts-ignore\n tx.idbtrans.disableAccessControl = true; // TODO: Take care of this flag in access control middleware!\n await modifyLocalObjectsWithNewUserId(\n tablesToSyncify,\n currentUser,\n persistedSyncState?.realms\n );\n });\n throwIfCancelled(cancelToken);\n }\n //\n // List changes to sync\n //\n const [clientChangeSet, syncState, baseRevs, {yMessages, lastUpdateIds}] = await db.transaction(\n 'r',\n db.tables,\n async () => {\n const syncState = await db.getPersistedSyncState();\n let baseRevs = await db.$baseRevs.toArray();\n \n // Resolve #2168\n baseRevs = baseRevs.filter(br => tablesToSync.some(tbl => tbl.name === br.tableName));\n\n let clientChanges = await listClientChanges(mutationTables, db);\n const yResults = await listYClientMessagesAndStateVector(db, tablesToSync);\n throwIfCancelled(cancelToken);\n if (doSyncify) {\n const alreadySyncedRealms = [\n ...(persistedSyncState?.realms || []),\n ...(persistedSyncState?.inviteRealms || []),\n ];\n const syncificationInserts = await listSyncifiedChanges(\n tablesToSyncify,\n currentUser,\n schema!,\n alreadySyncedRealms\n );\n throwIfCancelled(cancelToken);\n clientChanges = clientChanges.concat(syncificationInserts);\n return [clientChanges, syncState, baseRevs, yResults];\n }\n return [clientChanges, syncState, baseRevs, yResults];\n }\n );\n\n const pushSyncIsNeeded = clientChangeSet.some((set) =>\n set.muts.some((mut) => mut.keys.length > 0)\n ) || yMessages.some(m => m.type === 'u-c');\n if (justCheckIfNeeded) {\n console.debug('Sync is needed:', pushSyncIsNeeded);\n return pushSyncIsNeeded;\n }\n if (purpose === 'push' && !pushSyncIsNeeded) {\n // The purpose of this request was to push changes\n return false;\n }\n\n const latestRevisions = getLatestRevisionsPerTable(\n clientChangeSet,\n syncState?.latestRevisions\n );\n\n const clientIdentity = syncState?.clientIdentity || randomString(16);\n\n //\n // Push changes to server\n //\n throwIfCancelled(cancelToken);\n const res = await syncWithServer(\n clientChangeSet,\n yMessages,\n syncState,\n baseRevs,\n db,\n databaseUrl,\n schema,\n clientIdentity,\n currentUser\n );\n console.debug('Sync response', res);\n\n //\n // Apply changes locally and clear old change entries:\n //\n const {done, newSyncState} = await db.transaction('rw', db.tables, async (tx) => {\n // @ts-ignore\n tx.idbtrans.disableChangeTracking = true;\n // @ts-ignore\n tx.idbtrans.disableAccessControl = true; // TODO: Take care of this flag in access control middleware!\n\n // Update db.cloud.schema from server response.\n // Local schema MAY include a subset of tables, so do not force all tables into local schema.\n for (const tableName of Object.keys(schema)) {\n if (res.schema[tableName]) {\n // Write directly into configured schema. This code can only be executed alone.\n schema[tableName] = res.schema[tableName];\n }\n }\n await db.$syncState.put(schema, 'schema');\n\n // List mutations that happened during our exchange with the server:\n const addedClientChanges = await listClientChanges(mutationTables, db, {\n since: latestRevisions,\n });\n\n //\n // Delete changes now as server has return success\n // (but keep changes that haven't reached server yet)\n //\n for (const mutTable of mutationTables) {\n const tableName = getTableFromMutationTable(mutTable.name);\n if (\n !addedClientChanges.some(\n (ch) => ch.table === tableName && ch.muts.length > 0\n )\n ) {\n // No added mutations for this table during the time we sent changes\n // to the server.\n // It is therefore safe to clear all changes (which is faster than\n // deleting a range)\n await Promise.all([\n mutTable.clear(),\n db.$baseRevs.where({ tableName }).delete(),\n ]);\n } else if (latestRevisions[tableName]) {\n const latestRev = latestRevisions[tableName] || 0;\n await Promise.all([\n mutTable.where('rev').belowOrEqual(latestRev).delete(),\n db.$baseRevs\n .where(':id')\n .between(\n [tableName, -Infinity],\n [tableName, latestRev + 1],\n true,\n true\n )\n .reverse()\n .offset(1) // Keep one entry (the one mapping muts that came during fetch --> previous server revision)\n .delete(),\n ]);\n } else {\n // In this case, the mutation table only contains added items after sending empty changeset to server.\n // We should not clear out anything now.\n }\n }\n\n // Update latestRevisions object according to additional changes:\n getLatestRevisionsPerTable(addedClientChanges, latestRevisions);\n\n // Update/add new entries into baseRevs map.\n // * On tables without mutations since last serverRevision,\n // this will update existing entry.\n // * On tables where mutations have been recorded since last\n // serverRevision, this will create a new entry.\n // The purpose of this operation is to mark a start revision (per table)\n // so that all client-mutations that come after this, will be mapped to current\n // server revision.\n await updateBaseRevs(db, schema, latestRevisions, res.serverRevision);\n\n const syncState = await db.getPersistedSyncState();\n\n //\n // Delete objects from removed realms\n //\n await deleteObjectsFromRemovedRealms(db, res, syncState);\n\n //\n // Update syncState\n //\n const newSyncState: PersistedSyncState = syncState || {\n syncedTables: [],\n latestRevisions: {},\n realms: [],\n inviteRealms: [],\n clientIdentity,\n };\n if (readyForSyncification) {\n newSyncState.syncedTables = tablesToSync\n .map((tbl) => tbl.name)\n .concat(tablesToSyncify.map((tbl) => tbl.name));\n }\n newSyncState.latestRevisions = latestRevisions;\n newSyncState.remoteDbId = res.dbId;\n newSyncState.initiallySynced = true;\n newSyncState.realms = res.realms;\n newSyncState.inviteRealms = res.inviteRealms;\n newSyncState.serverRevision = res.serverRevision;\n newSyncState.yServerRevision = res.serverRevision;\n newSyncState.timestamp = new Date();\n delete newSyncState.error;\n\n const filteredChanges = filterServerChangesThroughAddedClientChanges(\n res.changes,\n addedClientChanges\n );\n\n //\n // apply server changes\n //\n await applyServerChanges(filteredChanges, db);\n\n if (res.yMessages) {\n //\n // apply yMessages\n //\n const {receivedUntils, resyncNeeded, yServerRevision} = await applyYServerMessages(res.yMessages, db);\n if (yServerRevision) {\n newSyncState.yServerRevision = yServerRevision;\n }\n\n //\n // update Y SyncStates\n //\n await updateYSyncStates(lastUpdateIds, receivedUntils, db);\n\n if (resyncNeeded) {\n newSyncState.yDownloadedRealms = {}; // Will trigger a full download of Y-documents below...\n }\n }\n\n //\n // Update regular syncState\n //\n db.$syncState.put(newSyncState, 'syncState');\n\n return {\n done: addedClientChanges.length === 0,\n newSyncState\n };\n });\n if (!done) {\n console.debug('MORE SYNC NEEDED. Go for it again!');\n await checkSyncRateLimitDelay(db);\n return await _sync(db, options, schema, { isInitialSync, cancelToken });\n }\n const usingYProps = Object.values(schema).some(tbl => tbl.yProps?.length);\n const serverSupportsYprops = !!res.yMessages;\n if (usingYProps && serverSupportsYprops) {\n try {\n await downloadYDocsFromServer(db, databaseUrl, newSyncState);\n } catch (error) {\n console.error('Failed to download Yjs documents from server', error);\n }\n }\n console.debug('SYNC DONE', { isInitialSync });\n db.syncCompleteEvent.next();\n return false; // Not needed anymore\n}\n\nasync function deleteObjectsFromRemovedRealms(\n db: DexieCloudDB,\n res: SyncResponse,\n syncState: PersistedSyncState | undefined\n) {\n const deletedRealms = new Set<string>();\n const rejectedRealms = new Set<string>();\n const previousRealmSet = syncState ? syncState.realms : [];\n const previousInviteRealmSet = syncState ? syncState.inviteRealms : [];\n const updatedRealmSet = new Set(res.realms);\n const updatedTotalRealmSet = new Set(res.realms.concat(res.inviteRealms));\n for (const realmId of previousRealmSet) {\n if (!updatedRealmSet.has(realmId)) {\n rejectedRealms.add(realmId);\n if (!updatedTotalRealmSet.has(realmId)) {\n deletedRealms.add(realmId);\n }\n }\n }\n for (const realmId of previousInviteRealmSet.concat(previousRealmSet)) {\n if (!updatedTotalRealmSet.has(realmId)) {\n deletedRealms.add(realmId);\n }\n }\n if (deletedRealms.size > 0 || rejectedRealms.size > 0) {\n const tables = getSyncableTables(db);\n for (const table of tables) {\n let realmsToDelete = ['realms', 'members', 'roles'].includes(table.name)\n ? deletedRealms // These tables should spare rejected ones.\n : rejectedRealms; // All other tables shoudl delete rejected+deleted ones\n if (realmsToDelete.size === 0) continue;\n if (\n table.schema.indexes.some(\n (idx) =>\n idx.keyPath === 'realmId' ||\n (Array.isArray(idx.keyPath) && idx.keyPath[0] === 'realmId')\n )\n ) {\n // There's an index to use:\n //console.debug(`REMOVAL: deleting all ${table.name} where realmId anyOf `, JSON.stringify([...realmsToDelete]));\n await table\n .where('realmId')\n .anyOf([...realmsToDelete])\n .delete();\n } else {\n // No index to use:\n //console.debug(`REMOVAL: deleting all ${table.name} where realmId is any of `, JSON.stringify([...realmsToDelete]), realmsToDelete.size);\n await table\n .filter((obj) => !!obj?.realmId && realmsToDelete.has(obj.realmId))\n .delete();\n }\n }\n }\n if (rejectedRealms.size > 0 && syncState?.yDownloadedRealms) {\n // Remove rejected/deleted realms from yDownloadedRealms because of the following use case:\n // 1. User becomes added to the realm\n // 2. User syncs and all documents of the realm is downloaded (downloadYDocsFromServer.ts)\n // 3. User leaves the realm and all docs are deleted locally (built-in-trigger of deleting their rows in this file)\n // 4. User is yet again added to the realm. At this point, we must make sure the docs are not considered already downloaded.\n const updateSpec: UpdateSpec<PersistedSyncState> = {};\n for (const realmId of rejectedRealms) {\n delete syncState.yDownloadedRealms[realmId];\n } \n }\n}\n\nexport function filterServerChangesThroughAddedClientChanges(\n serverChanges: DBOperationsSet<string>,\n addedClientChanges: DBOperationsSet\n): DBOperationsSet<string> {\n const changes: DBKeyMutationSet = {};\n applyOperations(changes, serverChanges);\n const localPostChanges: DBKeyMutationSet = {};\n applyOperations(localPostChanges, addedClientChanges);\n subtractChanges(changes, localPostChanges);\n return toDBOperationSet(changes);\n}\n","import { getSyncableTables } from \"../helpers/getSyncableTables\";\nimport { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { PersistedSyncState } from \"../db/entities/PersistedSyncState\";\n\nexport function getTablesToSyncify(db: DexieCloudDB, syncState: PersistedSyncState | undefined) {\n const syncedTables = syncState?.syncedTables || [];\n const syncableTables = getSyncableTables(db);\n const tablesToSyncify = syncableTables.filter(\n (tbl) => !syncedTables.includes(tbl.name)\n );\n return tablesToSyncify;\n}\n","import { Table } from \"dexie\";\nimport { EntityCommon } from \"../db/entities/EntityCommon\";\nimport { UserLogin } from \"../db/entities/UserLogin\";\nimport { Member } from \"../db/entities/Member\";\nimport { UNAUTHORIZED_USER } from \"../authentication/UNAUTHORIZED_USER\";\nimport { Realm } from \"../db/entities/Realm\";\n\nexport async function modifyLocalObjectsWithNewUserId(\n syncifiedTables: Table<EntityCommon>[],\n currentUser: UserLogin,\n alreadySyncedRealms?: string[]) {\n const ignoredRealms = new Set(alreadySyncedRealms || []);\n for (const table of syncifiedTables) {\n if (table.name === \"members\") {\n // members\n await table.toCollection().modify((member: Member) => {\n if (!ignoredRealms.has(member.realmId) && (!member.userId || member.userId === UNAUTHORIZED_USER.userId)) {\n member.userId = currentUser.userId;\n }\n });\n } else if (table.name === \"roles\") {\n // roles\n // No changes needed.\n } else if (table.name === \"realms\") {\n // realms\n await table.toCollection().modify((realm: Realm) => {\n if (!ignoredRealms.has(realm.realmId) && (realm.owner === undefined || realm.owner === UNAUTHORIZED_USER.userId)) {\n realm.owner = currentUser.userId;\n }\n });\n } else {\n // application entities\n await table.toCollection().modify((obj) => {\n if (!obj.realmId || !ignoredRealms.has(obj.realmId)) {\n if (!obj.owner || obj.owner === UNAUTHORIZED_USER.userId)\n obj.owner = currentUser.userId;\n if (!obj.realmId || obj.realmId === UNAUTHORIZED_USER.userId) {\n obj.realmId = currentUser.userId;\n }\n }\n });\n }\n }\n}\n","import type { Table } from 'dexie';\nimport type { YClientMessage } from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport { listUpdatesSince } from './listUpdatesSince';\nimport * as Y from 'yjs';\nimport { EntityCommon } from '../db/entities/EntityCommon';\nimport type { YSyncState } from 'y-dexie';\n\n/** Queries the local database for YMessages to send to server.\n * \n * There are 2 messages that this function can provide:\n * YUpdateFromClientRequest ( for local updates )\n * YStateVector ( for state vector of foreign updates so that server can reduce the number of udpates to send back )\n *\n * Notice that we do not do a step 1 sync phase here to get a state vector from the server. Reason we can avoid\n * the 2-step sync is that we are client-server and not client-client here and we keep track of the client changes\n * sent to server by letting server acknowledge them. There is always a chance that some client update has already\n * been sent and that the client failed to receive the ack. However, if this happens it does not matter - the change\n * would be sent again and Yjs handles duplicate changes anyway. And it's rare so we earn the cost of roundtrips by\n * avoiding the step1 sync and instead keep track of this in the `unsentFrom` property of the SyncState.\n * \n * @param db \n * @returns \n */\nexport async function listYClientMessagesAndStateVector(\n db: DexieCloudDB,\n tablesToSync: Table<EntityCommon>[]\n): Promise<{yMessages: YClientMessage[], lastUpdateIds: {[yTable: string]: number}}> {\n const result: YClientMessage[] = [];\n const lastUpdateIds: {[yTable: string]: number} = {};\n for (const table of tablesToSync) {\n if (table.schema.yProps) {\n for (const yProp of table.schema.yProps) {\n const yTable = db.table(yProp.updatesTable); // the updates-table for this combo of table+propName\n const syncState = (await yTable.get(DEXIE_CLOUD_SYNCER_ID)) as\n | YSyncState\n | undefined;\n\n // unsentFrom = the `i` value of updates that aren't yet sent to server (or at least not acked by the server yet)\n const unsentFrom = syncState?.unsentFrom || 1;\n // receivedUntil = the `i` value of updates that both we and the server knows we already have (we know it by the outcome from last syncWithServer() because server keep track of its revision numbers\n const receivedUntil = syncState?.receivedUntil || 0;\n // Compute the least value of these two (but since receivedUntil is inclusive we need to add +1 to it)\n const unsyncedFrom = Math.min(unsentFrom, receivedUntil + 1);\n // Query all these updates for all docs of this table+prop combination\n const updates = await listUpdatesSince(yTable, unsyncedFrom);\n if (updates.length > 0) lastUpdateIds[yTable.name] = updates[updates.length -1].i;\n\n // Now sort them by document and whether they are local or not + ignore local updates already sent:\n const perDoc: {\n [docKey: string]: {\n i: number;\n k: any;\n isLocal: boolean;\n u: Uint8Array[];\n };\n } = {};\n for (const update of updates) {\n // Sort updates into buckets of the doc primary key + the flag (whether it's local or foreign)\n const isLocal = ((update.f || 0) & 0x01) === 0x01;\n if (isLocal && update.i < unsentFrom) continue; // This local update has already been sent and acked.\n const docKey = JSON.stringify(update.k) + '/' + isLocal;\n let entry = perDoc[docKey];\n if (!entry) {\n perDoc[docKey] = entry = {\n i: update.i,\n k: update.k,\n isLocal,\n u: [],\n };\n entry.u.push(update.u);\n } else {\n entry.u.push(update.u);\n entry.i = Math.max(update.i, entry.i);\n }\n }\n\n // Now, go through all these and:\n // * For local updates, compute a merged update per document.\n // * For foreign updates, compute a state vector to pass to server, so that server can\n // avoid re-sending updates that we already have (they might have been sent of websocket\n // and when that happens, we do not mark them in any way nor do we update receivedUntil -\n // we only update receivedUntil after a \"full sync\" (syncWithServer()))\n for (const { k, isLocal, u, i } of Object.values(perDoc)) {\n const mergedUpdate = u.length === 1 ? u[0] : Y.mergeUpdatesV2(u);\n if (isLocal) {\n result.push({\n type: 'u-c',\n table: table.name,\n prop: yProp.prop,\n k,\n u: mergedUpdate,\n i,\n });\n } else {\n const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);\n result.push({\n type: 'sv',\n table: table.name,\n prop: yProp.prop,\n k,\n sv: stateVector,\n });\n }\n }\n }\n }\n }\n return {\n yMessages: result,\n lastUpdateIds\n };\n}\n","import { UserLogin } from '../db/entities/UserLogin';\nimport { randomString } from '../helpers/randomString';\nimport { EntityCommon } from '../db/entities/EntityCommon';\nimport { Table } from 'dexie';\nimport {\n DBOperationsSet,\n DBUpsertOperation,\n DexieCloudSchema,\n isValidAtID,\n isValidSyncableID,\n} from 'dexie-cloud-common';\n\nexport async function listSyncifiedChanges(\n tablesToSyncify: Table<EntityCommon>[],\n currentUser: UserLogin,\n schema: DexieCloudSchema,\n alreadySyncedRealms?: string[]\n): Promise<DBOperationsSet> {\n const txid = `upload-${randomString(8)}`;\n if (currentUser.isLoggedIn) {\n if (tablesToSyncify.length > 0) {\n const ignoredRealms = new Set(alreadySyncedRealms || []);\n const upserts = await Promise.all(\n tablesToSyncify.map(async (table) => {\n const { extractKey } = table.core.schema.primaryKey;\n if (!extractKey) return { table: table.name, muts: [] }; // Outbound tables are not synced.\n\n const dexieCloudTableSchema = schema[table.name];\n const query = dexieCloudTableSchema?.generatedGlobalId\n ? table.filter((item) => {\n const id = extractKey(item);\n return (\n !ignoredRealms.has(item.realmId || '') &&\n //(id[0] !== '#' || !!item.$ts) && // Private obj need no sync if not changed\n isValidAtID(extractKey(item), dexieCloudTableSchema?.idPrefix)\n );\n })\n : table.filter((item) => {\n const id = extractKey(item);\n\n return (\n !ignoredRealms.has(item.realmId || '') &&\n //(id[0] !== '#' || !!item.$ts) && // Private obj need no sync if not changed\n isValidSyncableID(id)\n );\n });\n const unsyncedObjects = await query.toArray();\n if (unsyncedObjects.length > 0) {\n const mut: DBUpsertOperation = {\n type: 'upsert',\n values: unsyncedObjects,\n keys: unsyncedObjects.map(extractKey),\n userId: currentUser.userId,\n txid,\n };\n return {\n table: table.name,\n muts: [mut],\n };\n } else {\n return {\n table: table.name,\n muts: [],\n };\n }\n })\n );\n return upserts.filter((op) => op.muts.length > 0);\n }\n }\n return [];\n}\n","import { UpdateSpec } from 'dexie';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport { YDexieCloudSyncState } from './YDexieCloudSyncState';\n\nexport async function updateYSyncStates(\n lastUpdateIdsBeforeSync: { [yTable: string]: number },\n receivedUntilsAfterSync: { [yTable: string]: number },\n db: DexieCloudDB\n) {\n // We want to update unsentFrom for each yTable to the value specified in first argument\n // because we got those values before we synced with server and here we are back from server\n // that has successfully received all those messages - no matter if the last update was a client or server update,\n // we can safely store unsentFrom to a value of the last update + 1 here.\n // We also want to update receivedUntil for each yTable to the value specified in the second argument,\n // because that contains the highest resulted id of each update from server after storing it.\n // We could do these two tasks separately, but that would require two update calls on the same YSyncState, so\n // to optimize the dexie calls, we merge these two maps into a single one so we can do a single update request\n // per yTable.\n const mergedSpec: {\n [yTable: string]: { unsentFrom?: number; receivedUntil?: number };\n } = {};\n for (const [yTable, lastUpdateId] of Object.entries(\n lastUpdateIdsBeforeSync\n )) {\n mergedSpec[yTable] ??= {};\n mergedSpec[yTable].unsentFrom = lastUpdateId + 1;\n }\n for (const [yTable, lastUpdateId] of Object.entries(\n receivedUntilsAfterSync\n )) {\n mergedSpec[yTable] ??= {};\n mergedSpec[yTable].receivedUntil = lastUpdateId;\n }\n\n // Now go through all yTables and update their YSyncStates:\n const allYTables = Object.values(db.dx._dbSchema)\n .filter((tblSchema) => tblSchema.yProps)\n .map((tblSchema) => tblSchema.yProps!.map((yProp) => yProp.updatesTable))\n .flat();\n for (const yTable of allYTables) {\n const mergedEntry = mergedSpec[yTable];\n const unsentFrom = mergedEntry?.unsentFrom ?? 1;\n const receivedUntil =\n mergedEntry?.receivedUntil ?? // If not received anything on this table, pick the current last update id\n // from local because we are in the same parent transaction (in sync.ts) that\n // applied all updates from the server\n ((\n await db\n .table(yTable)\n .where('i')\n .between(1, Infinity) // Because i might be string DEXIE_CLOUD_SYNCER_ID if not a number.\n .reverse()\n .limit(1)\n .primaryKeys()\n )[0] as number) ??\n 0;\n // We're already in a transaction, but for the sake of\n // code readability and correctness, let's launch an atomic sub transaction:\n await db.transaction('rw', yTable, async () => {\n const state: YDexieCloudSyncState | undefined = await db\n .table(yTable)\n .get(DEXIE_CLOUD_SYNCER_ID);\n if (!state) {\n await db.table<YDexieCloudSyncState>(yTable).add({\n i: DEXIE_CLOUD_SYNCER_ID,\n unsentFrom,\n receivedUntil\n });\n } else {\n state.unsentFrom = Math.max(unsentFrom, state.unsentFrom || 1);\n state.receivedUntil = Math.max(receivedUntil, state.receivedUntil || 0);\n await db.table(yTable).put(state);\n }\n });\n }\n}\n","import { setByKeyPath } from '../utils.js';\nexport function subtractChanges(target, // Server change set\nchangesToSubtract // additional mutations on client during syncWithServer()\n) {\n var _a, _b, _c;\n for (const [table, mutationSet] of Object.entries(changesToSubtract)) {\n for (const [key, mut] of Object.entries(mutationSet)) {\n switch (mut.type) {\n case 'ups':\n {\n const targetMut = (_a = target[table]) === null || _a === void 0 ? void 0 : _a[key];\n if (targetMut) {\n switch (targetMut.type) {\n case 'ups':\n delete target[table][key];\n break;\n case 'del':\n // Leave delete operation.\n // (Don't resurrect objects unintenionally (using tx(get, put) pattern locally))\n break;\n case 'upd':\n delete target[table][key];\n break;\n }\n }\n }\n break;\n case 'del':\n (_b = target[table]) === null || _b === void 0 ? true : delete _b[key];\n break;\n case 'upd': {\n const targetMut = (_c = target[table]) === null || _c === void 0 ? void 0 : _c[key];\n if (targetMut) {\n switch (targetMut.type) {\n case 'ups':\n // Adjust the server upsert with locally updated values.\n for (const [propPath, value] of Object.entries(mut.mod)) {\n setByKeyPath(targetMut.val, propPath, value);\n }\n break;\n case 'del':\n // Leave delete.\n break;\n case 'upd':\n // Remove the local update props from the server update mutation.\n for (const propPath of Object.keys(mut.mod)) {\n delete targetMut.mod[propPath];\n }\n break;\n }\n }\n break;\n }\n }\n }\n }\n}\n","import { randomString } from \"../utils.js\";\n/** Convert a DBKeyMutationSet (which is an internal format capable of looking up changes per ID)\n * ...into a DBOperationsSet (which is more optimal for performing DB operations into DB (bulkAdd() etc))\n *\n * @param inSet\n * @returns DBOperationsSet representing inSet\n */\nexport function toDBOperationSet(inSet, txid = \"\") {\n // Fictive transaction:\n if (!txid)\n txid = randomString(16);\n // Convert data into a temporary map to collect mutations of same table and type\n const map = {};\n for (const [table, ops] of Object.entries(inSet)) {\n for (const [key, op] of Object.entries(ops)) {\n const mapEntry = map[table] || (map[table] = {});\n const ops = mapEntry[op.type] || (mapEntry[op.type] = []);\n ops.push(Object.assign({ key }, op)); // DBKeyMutation doesn't contain key, so we need to bring it in.\n }\n }\n // Start computing the resulting format:\n const result = [];\n for (const [table, ops] of Object.entries(map)) {\n const resultEntry = {\n table,\n muts: [],\n };\n for (const [optype, muts] of Object.entries(ops)) {\n switch (optype) {\n case \"ups\": {\n const op = {\n type: \"upsert\",\n keys: muts.map(mut => mut.key),\n values: muts.map(mut => mut.val),\n txid\n };\n resultEntry.muts.push(op);\n break;\n }\n case \"upd\": {\n const op = {\n type: \"update\",\n keys: muts.map(mut => mut.key),\n changeSpecs: muts.map(mut => mut.mod),\n txid\n };\n resultEntry.muts.push(op);\n break;\n }\n case \"del\": {\n const op = {\n type: \"delete\",\n keys: muts.map(mut => mut.key),\n txid,\n };\n resultEntry.muts.push(op);\n break;\n }\n }\n }\n result.push(resultEntry);\n }\n return result;\n}\n","import { BehaviorSubject, firstValueFrom } from 'rxjs';\nimport { filter, take } from 'rxjs/operators';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { WSConnectionMsg } from '../WSObservable';\nimport { triggerSync } from './triggerSync';\nimport Dexie from 'dexie';\nimport { computeRealmSetHash } from '../helpers/computeRealmSetHash';\nimport { DBOperationsSet } from 'dexie-cloud-common';\nimport { getSyncableTables } from '../helpers/getSyncableTables';\nimport { getMutationTable } from '../helpers/getMutationTable';\nimport { listClientChanges } from './listClientChanges';\nimport { filterServerChangesThroughAddedClientChanges } from './sync';\nimport { applyServerChanges } from './applyServerChanges';\nimport { updateBaseRevs } from './updateBaseRevs';\nimport { getLatestRevisionsPerTable } from './getLatestRevisionsPerTable';\nimport { refreshAccessToken } from '../authentication/authenticate';\n\nconst LIMIT_NUM_MESSAGES_PER_TIME = 10; // Allow a maximum of 10 messages per...\nconst TIME_WINDOW = 10_000; // ...10 seconds.\nconst PAUSE_PERIOD = 1_000; // Pause for 1 second if reached\n\nexport type MessagesFromServerConsumer = ReturnType<\n typeof MessagesFromServerConsumer\n>;\n\nexport function MessagesFromServerConsumer(db: DexieCloudDB) {\n const queue: WSConnectionMsg[] = [];\n const readyToServe = new BehaviorSubject(true);\n const event = new BehaviorSubject(null);\n let isWorking = false;\n\n let loopDetection = new Array(LIMIT_NUM_MESSAGES_PER_TIME).fill(0);\n\n event.subscribe(async () => {\n if (isWorking) return;\n if (queue.length > 0) {\n isWorking = true;\n loopDetection.shift();\n loopDetection.push(Date.now());\n readyToServe.next(false);\n try {\n await consumeQueue();\n } finally {\n if (\n loopDetection[loopDetection.length - 1] - loopDetection[0] <\n TIME_WINDOW\n ) {\n // Ten loops within 10 seconds. Slow down!\n // This is a one-time event. Just pause 10 seconds.\n console.warn(`Slowing down websocket loop for ${PAUSE_PERIOD} milliseconds`);\n await new Promise((resolve) => setTimeout(resolve, PAUSE_PERIOD));\n }\n isWorking = false;\n readyToServe.next(true);\n }\n }\n });\n\n function enqueue(msg: WSConnectionMsg) {\n queue.push(msg);\n event.next(null);\n }\n\n async function consumeQueue() {\n while (queue.length > 0) {\n const msg = queue.shift();\n try {\n // If the sync worker or service worker is syncing, wait 'til thei're done.\n // It's no need to have two channels at the same time - even though it wouldnt\n // be a problem - this is an optimization.\n await firstValueFrom(\n db.cloud.syncState.pipe(\n filter(({ phase }) => phase === 'in-sync' || phase === 'error')\n )\n );\n console.debug('processing msg', msg);\n const persistedSyncState = db.cloud.persistedSyncState.value;\n //syncState.\n if (!msg) continue;\n switch (msg.type) {\n case 'token-expired':\n console.debug(\n 'WebSocket observable: Token expired. Refreshing token...'\n );\n const user = db.cloud.currentUser.value;\n // Refresh access token\n const refreshedLogin = await refreshAccessToken(\n db.cloud.options!.databaseUrl,\n user\n );\n // Persist updated access token\n await db.table('$logins').update(user.userId, {\n accessToken: refreshedLogin.accessToken,\n accessTokenExpiration: refreshedLogin.accessTokenExpiration,\n claims: refreshedLogin.claims,\n license: refreshedLogin.license,\n data: refreshedLogin.data,\n });\n // Updating $logins will trigger emission of db.cloud.currentUser observable, which\n // in turn will lead to that connectWebSocket.ts will reconnect the socket with the\n // new token. So we don't need to do anything more here.\n break;\n case 'realm-added':\n if (\n !persistedSyncState?.realms?.includes(msg.realm) &&\n !persistedSyncState?.inviteRealms?.includes(msg.realm)\n ) {\n await db.cloud.sync({ purpose: 'pull', wait: true });\n //triggerSync(db, 'pull');\n }\n break;\n case 'realm-accepted':\n if (!persistedSyncState?.realms?.includes(msg.realm)) {\n await db.cloud.sync({ purpose: 'pull', wait: true });\n //triggerSync(db, 'pull');\n }\n break;\n case 'realm-removed':\n if (\n persistedSyncState?.realms?.includes(msg.realm) ||\n persistedSyncState?.inviteRealms?.includes(msg.realm)\n ) {\n await db.cloud.sync({ purpose: 'pull', wait: true });\n //triggerSync(db, 'pull');\n }\n break;\n case 'realms-changed':\n //triggerSync(db, 'pull');\n await db.cloud.sync({ purpose: 'pull', wait: true });\n break;\n case 'changes':\n console.debug('changes');\n if (db.cloud.syncState.value?.phase === 'error') {\n triggerSync(db, 'pull');\n break;\n }\n await db.transaction('rw', db.dx.tables, async (tx) => {\n // @ts-ignore\n tx.idbtrans.disableChangeTracking = true;\n // @ts-ignore\n tx.idbtrans.disableAccessControl = true;\n const [schema, syncState, currentUser] = await Promise.all([\n db.getSchema(),\n db.getPersistedSyncState(),\n db.getCurrentUser(),\n ]);\n console.debug('ws message queue: in transaction');\n if (!syncState || !schema || !currentUser) {\n console.debug('required vars not present', {\n syncState,\n schema,\n currentUser,\n });\n return; // Initial sync must have taken place - otherwise, ignore this.\n }\n // Verify again in ACID tx that we're on same server revision.\n if (msg.baseRev !== syncState.serverRevision) {\n console.debug(\n `baseRev (${msg.baseRev}) differs from our serverRevision in syncState (${syncState.serverRevision})`\n );\n // Should we trigger a sync now? No. This is a normal case\n // when another local peer (such as the SW or a websocket channel on other tab) has\n // updated syncState from new server information but we are not aware yet. It would\n // be unnescessary to do a sync in that case. Instead, the caller of this consumeQueue()\n // function will do readyToServe.next(true) right after this return, which will lead\n // to a \"ready\" message being sent to server with the new accurate serverRev we have,\n // so that the next message indeed will be correct.\n if (\n typeof msg.baseRev === 'string' && // v2 format\n (typeof syncState.serverRevision === 'bigint' || // v1 format\n typeof syncState.serverRevision === 'object') // v1 format old browser\n ) {\n // The reason for the diff seems to be that server has migrated the revision format.\n // Do a full sync to update revision format.\n // If we don't do a sync request now, we could stuck in an endless loop.\n triggerSync(db, 'pull');\n }\n return; // Ignore message\n }\n // Verify also that the message is based on the exact same set of realms\n const ourRealmSetHash = await Dexie.waitFor(\n // Keep TX in non-IDB work\n computeRealmSetHash(syncState)\n );\n console.debug('ourRealmSetHash', ourRealmSetHash);\n if (ourRealmSetHash !== msg.realmSetHash) {\n console.debug('not same realmSetHash', msg.realmSetHash);\n triggerSync(db, 'pull');\n // The message isn't based on the same realms.\n // Trigger a sync instead to resolve all things up.\n return;\n }\n\n // Get clientChanges\n let clientChanges: DBOperationsSet = [];\n if (currentUser.isLoggedIn) {\n const mutationTables = getSyncableTables(db).map((tbl) =>\n db.table(getMutationTable(tbl.name))\n );\n clientChanges = await listClientChanges(mutationTables, db);\n console.debug('msg queue: client changes', clientChanges);\n }\n if (msg.changes.length > 0) {\n const filteredChanges =\n filterServerChangesThroughAddedClientChanges(\n msg.changes,\n clientChanges\n );\n\n //\n // apply server changes\n //\n console.debug(\n 'applying filtered server changes',\n filteredChanges\n );\n await applyServerChanges(filteredChanges, db);\n }\n\n // Update latest revisions per table in case there are unsynced changes\n // This can be a real case in future when we allow non-eagery sync.\n // And it can actually be realistic now also, but very rare.\n syncState.latestRevisions = getLatestRevisionsPerTable(\n clientChanges,\n syncState.latestRevisions\n );\n\n syncState.serverRevision = msg.newRev;\n\n // Update base revs\n console.debug('Updating baseRefs', syncState.latestRevisions);\n await updateBaseRevs(\n db,\n schema!,\n syncState.latestRevisions,\n msg.newRev\n );\n\n //\n // Update syncState\n //\n console.debug('Updating syncState', syncState);\n await db.$syncState.put(syncState, 'syncState');\n });\n console.debug('msg queue: done with rw transaction');\n break;\n }\n } catch (error) {\n console.error(`Error in msg queue`, error);\n }\n }\n }\n\n return {\n enqueue,\n readyToServe,\n };\n}\n","import Dexie, { Table } from 'dexie';\nimport { GuardedJob } from './entities/GuardedJob';\nimport { UserLogin } from './entities/UserLogin';\nimport { PersistedSyncState } from './entities/PersistedSyncState';\nimport { UNAUTHORIZED_USER } from '../authentication/UNAUTHORIZED_USER';\nimport { DexieCloudOptions } from '../DexieCloudOptions';\nimport { BehaviorSubject, Subject } from 'rxjs';\nimport { BaseRevisionMapEntry } from './entities/BaseRevisionMapEntry';\nimport {\n DBRealm,\n DBRealmMember,\n DBRealmRole,\n DexieCloudSchema,\n} from 'dexie-cloud-common';\nimport { BroadcastedAndLocalEvent } from '../helpers/BroadcastedAndLocalEvent';\nimport { SyncState, SyncStatePhase } from '../types/SyncState';\nimport { MessagesFromServerConsumer } from '../sync/messagesFromServerQueue';\nimport { YClientMessage } from 'dexie-cloud-common';\n\n/*export interface DexieCloudDB extends Dexie {\n table(name: string): Table<any, any>;\n table(name: \"$jobs\"): Table<GuardedJob, string>;\n table(name: \"$logins\"): Table<UserLogin, string>;\n table(name: \"$syncState\"): Table<SyncState, \"syncState\">;\n //table(name: \"$pendingChangesFromServer\"): Table<DBOperationsSet, number>;\n}\n*/\n\nexport interface SyncStateChangedEventData {\n phase: SyncStatePhase;\n error?: Error;\n progress?: number;\n}\n\ntype SyncStateTable = Table<\n PersistedSyncState | DexieCloudSchema | DexieCloudOptions,\n 'syncState' | 'options' | 'schema'\n>;\nexport interface DexieCloudDBBase {\n readonly name: Dexie['name'];\n readonly close: Dexie['close'];\n transaction: Dexie['transaction'];\n table: Dexie['table'];\n readonly tables: Dexie['tables'];\n readonly cloud: Dexie['cloud'];\n readonly $jobs: Table<GuardedJob, string>;\n readonly $logins: Table<UserLogin, string>;\n readonly $syncState: SyncStateTable;\n readonly $baseRevs: Table<BaseRevisionMapEntry, [string, number]>;\n\n readonly realms: Table<DBRealm, string>;\n readonly members: Table<DBRealmMember, string>;\n readonly roles: Table<DBRealmRole, [string, string]>;\n\n readonly localSyncEvent: Subject<{ purpose?: 'pull' | 'push' }>;\n readonly syncStateChangedEvent: BroadcastedAndLocalEvent<SyncStateChangedEventData>;\n readonly syncCompleteEvent: BroadcastedAndLocalEvent<void>;\n readonly dx: Dexie;\n readonly initiallySynced: boolean;\n}\n\nexport interface DexieCloudDB extends DexieCloudDBBase {\n getCurrentUser(): Promise<UserLogin>;\n getSchema(): Promise<DexieCloudSchema | undefined>;\n getOptions(): Promise<DexieCloudOptions | undefined>;\n getPersistedSyncState(): Promise<PersistedSyncState | undefined>;\n setInitiallySynced(initiallySynced: boolean): void;\n reconfigure(): void;\n messageConsumer: MessagesFromServerConsumer;\n messageProducer: Subject<YClientMessage>;\n}\n\nconst wm = new WeakMap<object, DexieCloudDB>();\n\nexport const DEXIE_CLOUD_SCHEMA = {\n members: '@id, [userId+realmId], [email+realmId], realmId',\n roles: '[realmId+name]',\n realms: '@realmId',\n $jobs: '',\n $syncState: '',\n $baseRevs: '[tableName+clientRev]',\n $logins: 'claims.sub, lastLogin',\n};\n\nlet static_counter = 0;\nexport function DexieCloudDB(dx: Dexie): DexieCloudDB {\n if ('vip' in dx) dx = dx['vip']; // Avoid race condition. Always map to a vipped dexie that don't block during db.on.ready().\n let db = wm.get(dx.cloud);\n if (!db) {\n const localSyncEvent = new Subject<{ purpose: 'push' | 'pull' }>();\n let syncStateChangedEvent =\n new BroadcastedAndLocalEvent<SyncStateChangedEventData>(\n `syncstatechanged-${dx.name}`\n );\n let syncCompleteEvent = new BroadcastedAndLocalEvent<void>(\n `synccomplete-${dx.name}`\n );\n localSyncEvent['id'] = ++static_counter;\n let initiallySynced = false;\n db = {\n get name() {\n return dx.name;\n },\n close() {\n return dx.close();\n },\n transaction: dx.transaction.bind(dx),\n table: dx.table.bind(dx),\n get tables() {\n return dx.tables;\n },\n cloud: dx.cloud,\n get $jobs() {\n return dx.table('$jobs') as Table<GuardedJob, string>;\n },\n get $syncState() {\n return dx.table('$syncState') as SyncStateTable;\n },\n get $baseRevs() {\n return dx.table('$baseRevs') as Table<\n BaseRevisionMapEntry,\n [string, number]\n >;\n },\n get $logins() {\n return dx.table('$logins') as Table<UserLogin, string>;\n },\n\n get realms() {\n return dx.realms;\n },\n get members() {\n return dx.members;\n },\n get roles() {\n return dx.roles;\n },\n get initiallySynced() {\n return initiallySynced;\n },\n localSyncEvent,\n get syncStateChangedEvent() {\n return syncStateChangedEvent;\n },\n get syncCompleteEvent() {\n return syncCompleteEvent;\n },\n dx,\n } as DexieCloudDB;\n\n const helperMethods: Partial<DexieCloudDB> = {\n getCurrentUser() {\n return db!.$logins\n .toArray()\n .then(\n (logins) => logins.find((l) => l.isLoggedIn) || UNAUTHORIZED_USER\n );\n },\n getPersistedSyncState() {\n return db!.$syncState.get('syncState') as Promise<\n PersistedSyncState | undefined\n >;\n },\n getSchema() {\n return db!.$syncState.get('schema').then((schema: DexieCloudSchema) => {\n if (schema) {\n for (const table of db!.tables) {\n if (table.schema.primKey && table.schema.primKey.keyPath && schema[table.name]) {\n schema[table.name].primaryKey = nameFromKeyPath(\n table.schema.primKey.keyPath\n );\n }\n }\n }\n return schema;\n }) as Promise<DexieCloudSchema | undefined>;\n },\n getOptions() {\n return db!.$syncState.get('options') as Promise<\n DexieCloudOptions | undefined\n >;\n },\n setInitiallySynced(value) {\n initiallySynced = value;\n },\n reconfigure() {\n syncStateChangedEvent = new BroadcastedAndLocalEvent<SyncState>(\n `syncstatechanged-${dx.name}`\n );\n syncCompleteEvent = new BroadcastedAndLocalEvent<void>(\n `synccomplete-${dx.name}`\n );\n },\n };\n\n Object.assign(db, helperMethods);\n db.messageConsumer = MessagesFromServerConsumer(db);\n db.messageProducer = new Subject<YClientMessage>();\n wm.set(dx.cloud, db);\n }\n return db;\n}\n\nfunction nameFromKeyPath (keyPath?: string | string[]): string {\n return typeof keyPath === 'string' ?\n keyPath :\n keyPath ? ('[' + [].join.call(keyPath, '+') + ']') : \"\";\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { UserLogin } from \"../db/entities/UserLogin\";\n\nexport interface AuthPersistedContext extends UserLogin {\n save(): Promise<void>;\n}\n\n// Emulate true-private property db. Why? So it's not stored in DB.\nconst wm = new WeakMap<AuthPersistedContext, DexieCloudDB>();\n\nexport class AuthPersistedContext {\n constructor(db: DexieCloudDB, userLogin: UserLogin) {\n wm.set(this, db);\n Object.assign(this, userLogin);\n }\n\n static load(db: DexieCloudDB, userId: string) {\n return db\n .table(\"$logins\")\n .get(userId)\n .then(\n (userLogin) => new AuthPersistedContext(db, userLogin || {\n userId,\n claims: {\n sub: userId\n },\n lastLogin: new Date(0)\n })\n );\n }\n\n async save() {\n const db = wm.get(this)!;\n db.table(\"$logins\").put(this);\n }\n}\n","import { filter, firstValueFrom, from, InteropObservable, Observable } from 'rxjs';\n\nexport function waitUntil<T>(\n o: Observable<T> | InteropObservable<T>, // Works with Dexie's liveQuery observables if we'd need that\n predicate: (value: T) => boolean\n) {\n return firstValueFrom(from(o).pipe(\n filter(predicate),\n ));\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { TXExpandos } from '../types/TXExpandos';\nimport { confirmLogout } from './interactWithUser';\nimport { UNAUTHORIZED_USER } from './UNAUTHORIZED_USER';\nimport { waitUntil } from './waitUntil';\n\nexport async function logout(db: DexieCloudDB) {\n const numUnsyncedChanges = await _logout(db);\n if (numUnsyncedChanges) {\n if (\n await confirmLogout(\n db.cloud.userInteraction,\n db.cloud.currentUserId,\n numUnsyncedChanges\n )\n ) {\n await _logout(db, { deleteUnsyncedData: true });\n } else {\n throw new Error(`User cancelled logout due to unsynced changes`);\n }\n }\n}\n\nexport async function _logout(db: DexieCloudDB, { deleteUnsyncedData = false } = {}) {\n // Clear the database without emptying configuration options.\n const [numUnsynced, loggedOut] = await db.dx.transaction('rw', db.dx.tables, async (tx) => {\n // @ts-ignore\n const idbtrans: IDBTransaction & TXExpandos = tx.idbtrans;\n idbtrans.disableChangeTracking = true;\n idbtrans.disableAccessControl = true;\n const mutationTables = tx.storeNames.filter((tableName) =>\n tableName.endsWith('_mutations')\n );\n\n // Count unsynced changes\n const unsyncCounts = await Promise.all(\n mutationTables.map((mutationTable) => tx.table(mutationTable).count())\n );\n const sumUnSynced = unsyncCounts.reduce((a, b) => a + b, 0);\n\n if (sumUnSynced > 0 && !deleteUnsyncedData) {\n // Let caller ask user if they want to delete unsynced data.\n return [sumUnSynced, false];\n }\n \n // Either there are no unsynched changes, or caller provided flag deleteUnsynchedData = true.\n // Clear all tables except $jobs and $syncState (except the persisted sync state which is\n // also cleared because we're going to rebuild it using a fresh sync).\n db.$syncState.delete('syncState');\n for (const table of db.dx.tables) {\n if (table.name !== '$jobs' && table.name !== '$syncState') {\n table.clear();\n }\n }\n return [sumUnSynced, true];\n });\n\n if (loggedOut) {\n // Wait for currentUser observable to emit UNAUTHORIZED_USER\n await waitUntil(db.cloud.currentUser, (user) => user.userId === UNAUTHORIZED_USER.userId);\n // Then perform an initial sync\n await db.cloud.sync({purpose: 'pull', wait: true});\n }\n return numUnsynced;\n}\n","/** A way to log to console in production without terser stripping out\n * it from the release bundle.\n * This should be used very rarely and only in places where it's\n * absolutely necessary to log something in production.\n * \n * @param level \n * @param args \n */\nexport function prodLog(level: 'log' | 'warn' | 'error' | 'debug', ...args: any[]) {\n globalThis[\"con\"+\"sole\"][level](...args);\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { LoginHints } from '../DexieCloudAPI';\nimport { triggerSync } from '../sync/triggerSync';\nimport { authenticate, loadAccessToken } from './authenticate';\nimport { AuthPersistedContext } from './AuthPersistedContext';\nimport { logout } from './logout';\nimport { otpFetchTokenCallback } from './otpFetchTokenCallback';\nimport { setCurrentUser } from './setCurrentUser';\nimport { UNAUTHORIZED_USER } from './UNAUTHORIZED_USER';\n\nexport async function login(\n db: DexieCloudDB,\n hints?: LoginHints\n) {\n const currentUser = await db.getCurrentUser();\n const origUserId = currentUser.userId;\n if (currentUser.isLoggedIn && (!hints || (!hints.email && !hints.userId))) {\n const licenseStatus = currentUser.license?.status || 'ok';\n if (\n licenseStatus === 'ok' &&\n currentUser.accessToken &&\n (!currentUser.accessTokenExpiration ||\n currentUser.accessTokenExpiration.getTime() > Date.now())\n ) {\n // Already authenticated according to given hints. And license is valid.\n return false;\n }\n if (\n currentUser.refreshToken &&\n (!currentUser.refreshTokenExpiration ||\n currentUser.refreshTokenExpiration.getTime() > Date.now())\n ) {\n // Refresh the token\n await loadAccessToken(db);\n return false;\n }\n // No refresh token - must re-authenticate:\n }\n const context = new AuthPersistedContext(db, {\n claims: {},\n lastLogin: new Date(0),\n });\n await authenticate(\n db.cloud.options!.databaseUrl,\n context,\n db.cloud.options!.fetchTokens || otpFetchTokenCallback(db),\n db.cloud.userInteraction,\n hints\n );\n if (\n origUserId !== UNAUTHORIZED_USER.userId &&\n context.userId !== origUserId\n ) {\n // User was logged in before, but now logged in as another user.\n await logout(db);\n }\n\n /*try {\n await context.save();\n } catch (e) {\n try {\n if (e.name === 'DataCloneError') {\n console.debug(`Login context property names:`, Object.keys(context));\n console.debug(`Login context:`, context);\n console.debug(`Login context JSON:`, JSON.stringify(context));\n }\n } catch {}\n throw e;\n }*/\n await setCurrentUser(db, context);\n // Make sure to resync as the new login will be authorized\n // for new realms.\n triggerSync(db, 'pull');\n return context.userId !== origUserId;\n}\n","import {\n DemoTokenRequest,\n OTPTokenRequest1,\n OTPTokenRequest2,\n TokenErrorResponse,\n TokenFinalResponse,\n TokenRequest,\n TokenResponse,\n} from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { HttpError } from '../errors/HttpError';\nimport { FetchTokenCallback } from './authenticate';\nimport { alertUser, promptForEmail, promptForOTP } from './interactWithUser';\n\nexport function otpFetchTokenCallback(db: DexieCloudDB): FetchTokenCallback {\n const { userInteraction } = db.cloud;\n return async function otpAuthenticate({ public_key, hints }) {\n let tokenRequest: TokenRequest;\n const url = db.cloud.options?.databaseUrl;\n if (!url) throw new Error(`No database URL given.`);\n if (hints?.grant_type === 'demo') {\n const demo_user = await promptForEmail(\n userInteraction,\n 'Enter a demo user email',\n hints?.email || hints?.userId\n );\n tokenRequest = {\n demo_user,\n grant_type: 'demo',\n scopes: ['ACCESS_DB'],\n public_key\n } satisfies DemoTokenRequest;\n } else if (hints?.otpId && hints.otp) {\n // User provided OTP ID and OTP code. This means that the OTP email\n // has already gone out and the user may have clicked a magic link\n // in the email with otp and otpId in query and the app has picked\n // up those values and passed them to db.cloud.login().\n tokenRequest = {\n grant_type: 'otp',\n otp_id: hints.otpId,\n otp: hints.otp,\n scopes: ['ACCESS_DB'],\n public_key,\n } satisfies OTPTokenRequest2;\n } else {\n const email = await promptForEmail(\n userInteraction,\n 'Enter email address',\n hints?.email\n );\n if (/@demo.local$/.test(email)) {\n tokenRequest = {\n demo_user: email,\n grant_type: 'demo',\n scopes: ['ACCESS_DB'],\n public_key\n } satisfies DemoTokenRequest;\n } else {\n tokenRequest = {\n email,\n grant_type: 'otp',\n scopes: ['ACCESS_DB'],\n } satisfies OTPTokenRequest1;\n }\n }\n const res1 = await fetch(`${url}/token`, {\n body: JSON.stringify(tokenRequest),\n method: 'post',\n headers: { 'Content-Type': 'application/json', mode: 'cors' },\n });\n if (res1.status !== 200) {\n const errMsg = await res1.text();\n await alertUser(userInteraction, \"Token request failed\", {\n type: 'error',\n messageCode: 'GENERIC_ERROR',\n message: errMsg,\n messageParams: {}\n }).catch(()=>{});\n throw new HttpError(res1, errMsg);\n }\n const response: TokenResponse = await res1.json();\n if (response.type === 'tokens' || response.type === 'error') {\n // Demo user request can get a \"tokens\" response right away\n // Error can also be returned right away.\n return response;\n } else if (tokenRequest.grant_type === 'otp' && 'email' in tokenRequest) {\n if (response.type !== 'otp-sent')\n throw new Error(`Unexpected response from ${url}/token`);\n const otp = await promptForOTP(userInteraction, tokenRequest.email);\n const tokenRequest2 = {\n ...tokenRequest,\n otp: otp || '',\n otp_id: response.otp_id,\n public_key\n } satisfies OTPTokenRequest2;\n\n let res2 = await fetch(`${url}/token`, {\n body: JSON.stringify(tokenRequest2),\n method: 'post',\n headers: { 'Content-Type': 'application/json' },\n mode: 'cors',\n });\n while (res2.status === 401) {\n const errorText = await res2.text();\n tokenRequest2.otp = await promptForOTP(userInteraction, tokenRequest.email, {\n type: 'error',\n messageCode: 'INVALID_OTP',\n message: errorText,\n messageParams: {}\n });\n res2 = await fetch(`${url}/token`, {\n body: JSON.stringify(tokenRequest2),\n method: 'post',\n headers: { 'Content-Type': 'application/json' },\n mode: 'cors',\n });\n }\n if (res2.status !== 200) {\n const errMsg = await res2.text();\n throw new HttpError(res2, errMsg);\n }\n const response2: TokenFinalResponse | TokenErrorResponse = await res2.json();\n return response2;\n } else {\n throw new Error(`Unexpected response from ${url}/token`);\n }\n };\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { prodLog } from '../prodLog';\nimport { AuthPersistedContext } from './AuthPersistedContext';\nimport { waitUntil } from './waitUntil';\n\n/** This function changes or sets the current user as requested.\n *\n * Use cases:\n * * Initially on db.ready after reading the current user from db.$logins.\n * This will make sure that any unsynced operations from the previous user is synced before\n * changing the user.\n * * Upon user request\n *\n * @param db\n * @param newUser\n */\nexport async function setCurrentUser(\n db: DexieCloudDB,\n user: AuthPersistedContext\n) {\n const $logins = db.table('$logins');\n await db.transaction('rw', $logins, async (tx) => {\n const existingLogins = await $logins.toArray();\n await Promise.all(\n existingLogins\n .filter((login) => login.userId !== user.userId && login.isLoggedIn)\n .map((login) => {\n login.isLoggedIn = false;\n return $logins.put(login);\n })\n );\n user.isLoggedIn = true;\n user.lastLogin = new Date();\n try {\n await user.save();\n } catch (e) {\n try {\n if (e.name === 'DataCloneError') {\n // We've seen this buggy behavior in some browsers and in case it happens\n // again we really need to collect the details to understand what's going on.\n prodLog('debug', `Login context property names:`, Object.keys(user));\n prodLog('debug', `Login context property names:`, Object.keys(user));\n prodLog('debug', `Login context:`, user);\n prodLog('debug', `Login context JSON:`, JSON.stringify(user));\n }\n } catch {}\n throw e;\n }\n console.debug('Saved new user', user.email);\n });\n await waitUntil(\n db.cloud.currentUser,\n (currentUser) => currentUser.userId === user.userId\n );\n}\n","// @ts-ignore\nexport const isFirefox = typeof InstallTrigger !== 'undefined';\n","export const isSafari =\n typeof navigator !== 'undefined' &&\n /Safari\\//.test(navigator.userAgent) &&\n !/Chrom(e|ium)\\/|Edge\\//.test(navigator.userAgent);\n\nexport const safariVersion = isSafari\n ? // @ts-ignore\n [].concat(navigator.userAgent.match(/Safari\\/(\\d*)/))[1]\n : NaN;\n","import { isFirefox } from './isFirefox';\nimport { isSafari, safariVersion } from './isSafari';\n\n// What we know: Safari 14.1 (version 605) crashes when using dexie-cloud's service worker.\n// We don't know what exact call is causing this. Have tried safari-14-idb-fix with no luck.\n// Something we do in the service worker is triggering the crash.\n// When next Safari version (606) is out we will start enabling SW again, hoping that the bug is solved.\n// If not, we might increment 605 to 606.\nexport const DISABLE_SERVICEWORKER_STRATEGY =\n (isSafari && safariVersion <= 605) || // Disable for Safari for now.\n isFirefox; // Disable for Firefox for now. Seems to have a bug in reading CryptoKeys from IDB from service workers\n","export const IS_SERVICE_WORKER =\n typeof self !== \"undefined\" && \"clients\" in self && !self.document;\n","import {\n DBCoreAddRequest,\n DBCoreDeleteRequest,\n DBCoreIndex, DBCorePutRequest\n} from 'dexie';\nimport { b64LexEncode } from 'dreambase-library/dist/common/b64lex';\n\nconst { toString } = {};\nexport function toStringTag(o: Object) {\n return toString.call(o).slice(8, -1);\n}\n\nexport function getEffectiveKeys(\n primaryKey: DBCoreIndex,\n req: (Pick<DBCoreAddRequest | DBCorePutRequest, 'type' | 'values'> & {\n keys?: any[];\n }) |\n Pick<DBCoreDeleteRequest, 'keys' | 'type'>\n) {\n if (req.type === 'delete')\n return req.keys;\n return req.keys?.slice() || req.values.map(primaryKey.extractKey!);\n}\nfunction applyToUpperBitFix(orig: string, bits: number) {\n return (\n (bits & 1 ? orig[0].toUpperCase() : orig[0].toLowerCase()) +\n (bits & 2 ? orig[1].toUpperCase() : orig[1].toLowerCase()) +\n (bits & 4 ? orig[2].toUpperCase() : orig[2].toLowerCase())\n );\n}\nconst consonants = /b|c|d|f|g|h|j|k|l|m|n|p|q|r|s|t|v|x|y|z/i;\nfunction isUpperCase(ch: string) {\n return ch >= 'A' && ch <= 'Z';\n}\n\nexport function generateTablePrefix(\n tableName: string,\n allPrefixes: Set<string>\n) {\n let rv = tableName[0].toLocaleLowerCase(); // \"users\" = \"usr\", \"friends\" = \"frn\", \"realms\" = \"rlm\", etc.\n for (let i = 1, l = tableName.length; i < l && rv.length < 3; ++i) {\n if (consonants.test(tableName[i]) || isUpperCase(tableName[i]))\n rv += tableName[i].toLowerCase();\n }\n while (allPrefixes.has(rv)) {\n if (/\\d/g.test(rv)) {\n rv = rv.substr(0, rv.length - 1) + (rv[rv.length - 1] + 1);\n if (rv.length > 3)\n rv = rv.substr(0, 3);\n else\n continue;\n } else if (rv.length < 3) {\n rv = rv + '2';\n continue;\n }\n let bitFix = 1;\n let upperFixed = rv;\n while (allPrefixes.has(upperFixed) && bitFix < 8) {\n upperFixed = applyToUpperBitFix(rv, bitFix);\n ++bitFix;\n }\n if (bitFix < 8)\n rv = upperFixed;\n else {\n let nextChar = (rv.charCodeAt(2) + 1) & 127;\n rv = rv.substr(0, 2) + String.fromCharCode(nextChar);\n // Here, in theory we could get an infinite loop if having 127*8 table names with identical 3 first consonants.\n }\n }\n return rv;\n}\nlet time = 0;\n/**\n *\n * @param prefix A unique 3-letter short-name of the table.\n * @param shardKey 3 last letters from another ID if colocation is requested. Verified on server on inserts - guarantees unique IDs across shards.\n * The shardKey part of the key represent the shardId where it was first created. An object with this\n * primary key can later on be moved to another shard without being altered. The reason for having\n * the origin shardKey as part of the key, is that the server will not need to check uniqueness constraint\n * across all shards on every insert. Updates / moves across shards are already controlled by the server\n * in the sense that the objects needs to be there already - we only need this part for inserts.\n * @returns\n */\nexport function generateKey(prefix: string, shardKey?: string) {\n const a = new Uint8Array(18);\n const timePart = new Uint8Array(a.buffer, 0, 6);\n const now = Date.now(); // Will fit into 6 bytes until year 10 895.\n if (time >= now) {\n // User is bulk-creating objects the same millisecond.\n // Increment the time part by one millisecond for each item.\n // If bulk-creating 1,000,000 rows client-side in 10 seconds,\n // the last time-stamp will be 990 seconds in future, which is no biggie at all.\n // The point is to create a nice order of the generated IDs instead of\n // using random ids.\n ++time;\n } else {\n time = now;\n }\n timePart[0] = time / 1099511627776; // Normal division (no bitwise operator) --> works with >= 32 bits.\n timePart[1] = time / 4294967296;\n timePart[2] = time / 16777216;\n timePart[3] = time / 65536;\n timePart[4] = time / 256;\n timePart[5] = time;\n const randomPart = new Uint8Array(a.buffer, 6);\n crypto.getRandomValues(randomPart);\n const id = new Uint8Array(a.buffer);\n return prefix + b64LexEncode(id) + (shardKey || '');\n}\n","import Dexie, {\n DBCore,\n DBCoreAddRequest,\n DBCoreMutateRequest,\n DBCorePutRequest,\n DBCoreTransaction,\n Middleware,\n} from 'dexie';\nimport { isValidSyncableID } from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport {\n getEffectiveKeys,\n generateKey,\n toStringTag,\n} from '../middleware-helpers/idGenerationHelpers';\nimport { TXExpandos } from '../types/TXExpandos';\n\nexport function createIdGenerationMiddleware(\n db: DexieCloudDB\n): Middleware<DBCore> {\n return {\n stack: 'dbcore',\n name: 'idGenerationMiddleware',\n level: 1,\n create: (core) => {\n return {\n ...core,\n table: (tableName) => {\n const table = core.table(tableName);\n\n function generateOrVerifyAtKeys(\n req: DBCoreAddRequest | DBCorePutRequest,\n idPrefix: string\n ) {\n let valueClones: null | object[] = null;\n const keys = getEffectiveKeys(table.schema.primaryKey, req);\n keys.forEach((key, idx) => {\n if (key === undefined) {\n // Generate the key\n const colocatedId =\n req.values[idx].realmId || db.cloud.currentUserId;\n const shardKey = colocatedId.substr(colocatedId.length - 3);\n keys[idx] = generateKey(idPrefix, shardKey);\n if (!table.schema.primaryKey.outbound) {\n if (!valueClones) valueClones = req.values.slice();\n valueClones[idx] = Dexie.deepClone(valueClones[idx]);\n Dexie.setByKeyPath(\n valueClones[idx],\n table.schema.primaryKey.keyPath!,\n keys[idx]\n );\n }\n } else if (\n typeof key !== 'string' ||\n (!key.startsWith(idPrefix) && !key.startsWith('#' + idPrefix))\n ) {\n // Key was specified by caller. Verify it complies with id prefix.\n throw new Dexie.ConstraintError(\n `The ID \"${key}\" is not valid for table \"${tableName}\". ` +\n `Primary '@' keys requires the key to be prefixed with \"${idPrefix}\" (or \"#${idPrefix}).\\n` +\n `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.`\n );\n }\n });\n return table.mutate({\n ...req,\n keys,\n values: valueClones || req.values,\n });\n }\n\n return {\n ...table,\n mutate: (req) => {\n const idbtrans = req.trans as DBCoreTransaction & IDBTransaction & TXExpandos;\n if (idbtrans.mode === 'versionchange') {\n // Tell all the other middlewares to skip bothering. We're in versionchange mode.\n // dexie-cloud is not initialized yet.\n idbtrans.disableChangeTracking = true;\n idbtrans.disableAccessControl = true;\n }\n if (idbtrans.disableChangeTracking) {\n // Disable ID policy checks and ID generation\n return table.mutate(req);\n }\n if (req.type === 'add' || req.type === 'put') {\n const cloudTableSchema = db.cloud.schema?.[tableName];\n if (!cloudTableSchema?.generatedGlobalId) {\n if (cloudTableSchema?.markedForSync) {\n // Just make sure primary key is of a supported type:\n const keys = getEffectiveKeys(table.schema.primaryKey, req);\n keys.forEach((key, idx) => {\n if (!isValidSyncableID(key)) {\n const type = Array.isArray(key)\n ? key.map(toStringTag).join(',')\n : toStringTag(key);\n throw new Dexie.ConstraintError(\n `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)`\n );\n }\n });\n }\n } else {\n if (db.cloud.options?.databaseUrl && !db.initiallySynced) {\n // A database URL is configured but no initial sync has been performed.\n const keys = getEffectiveKeys(table.schema.primaryKey, req);\n // Check if the operation would yield any INSERT. If so, complain! We never want wrong ID prefixes stored.\n return table\n .getMany({ keys, trans: req.trans, cache: 'immutable' })\n .then((results) => {\n if (results.length < keys.length) {\n // At least one of the given objects would be created. Complain since\n // the generated ID would be based on a locally computed ID prefix only - we wouldn't\n // know if the server would give the same ID prefix until an initial sync has been\n // performed.\n throw new Error(\n `Unable to create new objects without an initial sync having been performed.`\n );\n }\n return table.mutate(req);\n });\n }\n return generateOrVerifyAtKeys(\n req,\n cloudTableSchema.idPrefix!\n );\n }\n }\n return table.mutate(req);\n },\n };\n },\n };\n },\n };\n}\n","import { DBCoreTable, DBCoreTransaction } from \"dexie\";\nimport { allSettled } from \"../helpers/allSettled\";\n\nlet counter = 0;\n\nexport function guardedTable(table: DBCoreTable) {\n const prop = \"$lock\"+ (++counter);\n return {\n ...table,\n count: readLock(table.count, prop),\n get: readLock(table.get, prop),\n getMany: readLock(table.getMany, prop),\n openCursor: readLock(table.openCursor, prop),\n query: readLock(table.query, prop),\n mutate: writeLock(table.mutate, prop),\n };\n}\n\nfunction readLock<TReq extends { trans: DBCoreTransaction }, TRes>(\n fn: (req: TReq) => Promise<TRes>,\n prop: string\n): (req: TReq) => Promise<TRes> {\n return function readLocker(req): Promise<TRes> {\n const {\n readers,\n writers,\n }: { writers: Promise<any>[]; readers: Promise<any>[] } =\n req.trans[prop] || (req.trans[prop] = { writers: [], readers: [] });\n const numWriters = writers.length;\n const promise = (numWriters > 0\n ? writers[numWriters - 1].then(() => fn(req), () => fn(req))\n : fn(req)\n ).finally(() => {readers.splice(readers.indexOf(promise))});\n readers.push(promise);\n return promise;\n };\n}\n\nfunction writeLock<TReq extends { trans: DBCoreTransaction }, TRes>(\n fn: (req: TReq) => Promise<TRes>,\n prop: string\n): (req: TReq) => Promise<TRes> {\n return function writeLocker(req): Promise<TRes> {\n const {\n readers,\n writers,\n }: { writers: Promise<any>[]; readers: Promise<any>[] } =\n req.trans[prop] || (req.trans[prop] = { writers: [], readers: [] });\n let promise = (writers.length > 0\n ? writers[writers.length - 1].then(() => fn(req), () => fn(req))\n : readers.length > 0\n ? allSettled(readers).then(() => fn(req))\n : fn(req)\n ).finally(() => {writers.shift();});\n writers.push(promise);\n return promise;\n };\n}\n","\nexport function allSettled(possiblePromises: any[]) {\n return new Promise(resolve => {\n if (possiblePromises.length === 0) resolve([]);\n let remaining = possiblePromises.length;\n const results = new Array(remaining);\n possiblePromises.forEach((p, i) => Promise.resolve(p).then(\n value => results[i] = {status: \"fulfilled\", value},\n reason => results[i] = {status: \"rejected\", reason})\n .then(()=>--remaining || resolve(results)));\n });\n}\n","import { DBCoreTransaction } from 'dexie';\nimport { BehaviorSubject } from 'rxjs';\nimport { TXExpandos } from '../types/TXExpandos';\n\nexport const outstandingTransactions = new BehaviorSubject<Set<DBCoreTransaction & IDBTransaction & TXExpandos>>(new Set());\n","import { DexieCloudDB } from './db/DexieCloudDB';\n\nexport function isEagerSyncDisabled(db: DexieCloudDB) {\n return (\n db.cloud.options?.disableEagerSync ||\n db.cloud.currentUser.value?.license?.status !== 'ok' ||\n !db.cloud.options?.databaseUrl\n );\n}\n","import {\n DBCore,\n DBCoreAddRequest,\n DBCoreDeleteRequest,\n DBCoreMutateResponse,\n DBCorePutRequest,\n DBCoreTable,\n DBCoreTransaction,\n Middleware,\n RangeSet,\n} from 'dexie';\nimport { DBOperation, DBUpdateOperation } from 'dexie-cloud-common';\nimport { BehaviorSubject } from 'rxjs';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { UserLogin } from '../db/entities/UserLogin';\nimport { getMutationTable } from '../helpers/getMutationTable';\nimport { randomString } from '../helpers/randomString';\nimport { throwVersionIncrementNeeded } from '../helpers/throwVersionIncrementNeeded';\nimport { guardedTable } from '../middleware-helpers/guardedTable';\nimport { registerSyncEvent } from '../sync/registerSyncEvent';\nimport { TXExpandos } from '../types/TXExpandos';\nimport { outstandingTransactions } from './outstandingTransaction';\nimport { isEagerSyncDisabled } from '../isEagerSyncDisabled';\nimport { triggerSync } from '../sync/triggerSync';\n\nexport interface MutationTrackingMiddlewareArgs {\n currentUserObservable: BehaviorSubject<UserLogin>;\n db: DexieCloudDB;\n}\n\n/** Tracks all mutations in the same transaction as the mutations -\n * so it is guaranteed that no mutation goes untracked - and if transaction\n * aborts, the mutations won't be tracked.\n *\n * The sync job will use the tracked mutations as the source of truth when pushing\n * changes to server and cleanup the tracked mutations once the server has\n * ackowledged that it got them.\n */\nexport function createMutationTrackingMiddleware({\n currentUserObservable,\n db,\n}: MutationTrackingMiddlewareArgs): Middleware<DBCore> {\n return {\n stack: 'dbcore',\n name: 'MutationTrackingMiddleware',\n level: 1,\n create: (core) => {\n const allTableNames = new Set(core.schema.tables.map((t) => t.name));\n const ordinaryTables = core.schema.tables.filter(\n (t) => !/^\\$/.test(t.name)\n );\n const mutTableMap = new Map<string, DBCoreTable>();\n for (const tbl of ordinaryTables) {\n const mutationTableName = `$${tbl.name}_mutations`;\n if (allTableNames.has(mutationTableName)) {\n mutTableMap.set(tbl.name, core.table(mutationTableName));\n }\n }\n\n return {\n ...core,\n transaction: (tables, mode) => {\n let tx: DBCoreTransaction & IDBTransaction & TXExpandos;\n if (mode === 'readwrite') {\n const mutationTables = tables\n .filter((tbl) => db.cloud.schema?.[tbl]?.markedForSync)\n .map((tbl) => getMutationTable(tbl));\n tx = core.transaction(\n [...tables, ...mutationTables],\n mode\n ) as DBCoreTransaction & IDBTransaction & TXExpandos;\n } else {\n tx = core.transaction(tables, mode) as DBCoreTransaction &\n IDBTransaction &\n TXExpandos;\n }\n\n if (mode === 'readwrite') {\n // Give each transaction a globally unique id.\n tx.txid = randomString(16);\n tx.opCount = 0;\n // Introduce the concept of current user that lasts through the entire transaction.\n // This is important because the tracked mutations must be connected to the user.\n tx.currentUser = currentUserObservable.value;\n outstandingTransactions.value.add(tx);\n outstandingTransactions.next(outstandingTransactions.value);\n const removeTransaction = () => {\n tx.removeEventListener('complete', txComplete);\n tx.removeEventListener('error', removeTransaction);\n tx.removeEventListener('abort', removeTransaction);\n outstandingTransactions.value.delete(tx);\n outstandingTransactions.next(outstandingTransactions.value);\n };\n const txComplete = () => {\n if (tx.mutationsAdded && !isEagerSyncDisabled(db)) {\n triggerSync(db, 'push');\n }\n removeTransaction();\n };\n tx.addEventListener('complete', txComplete);\n tx.addEventListener('error', removeTransaction);\n tx.addEventListener('abort', removeTransaction);\n }\n return tx;\n },\n table: (tableName) => {\n const table = core.table(tableName);\n if (/^\\$/.test(tableName)) {\n if (tableName.endsWith('_mutations')) {\n // In case application code adds items to ..._mutations tables,\n // make sure to set the mutationsAdded flag on transaction.\n // This is also done in mutateAndLog() as that function talks to a\n // lower level DBCore and wouldn't be catched by this code.\n return {\n ...table,\n mutate: (req) => {\n if (req.type === 'add' || req.type === 'put') {\n (\n req.trans as DBCoreTransaction & TXExpandos\n ).mutationsAdded = true;\n }\n return table.mutate(req);\n },\n };\n } else if (tableName === '$logins') {\n return {\n ...table,\n mutate: (req) => {\n //console.debug('Mutating $logins table', req);\n return table\n .mutate(req)\n .then((res) => {\n //console.debug('Mutating $logins');\n (\n req.trans as DBCoreTransaction & TXExpandos\n ).mutationsAdded = true;\n //console.debug('$logins mutated');\n return res;\n })\n .catch((err) => {\n console.debug('Failed mutation $logins', err);\n return Promise.reject(err);\n });\n },\n };\n } else {\n return table;\n }\n }\n const { schema } = table;\n const mutsTable = mutTableMap.get(tableName)!;\n if (!mutsTable) {\n // We cannot track mutations on this table because there is no mutations table for it.\n // This might happen in upgraders that executes before cloud schema is applied.\n return table; \n }\n return guardedTable({\n ...table,\n mutate: (req) => {\n const trans = req.trans as DBCoreTransaction & TXExpandos;\n if (!trans.txid) return table.mutate(req); // Upgrade transactions not guarded by us.\n if (trans.disableChangeTracking) return table.mutate(req);\n if (!db.cloud.schema?.[tableName]?.markedForSync)\n return table.mutate(req);\n if (!trans.currentUser?.isLoggedIn) {\n // Unauthorized user should not log mutations.\n // Instead, after login all local data should be logged at once.\n return table.mutate(req);\n }\n\n return req.type === 'deleteRange'\n ? table\n // Query the actual keys (needed for server sending correct rollback to us)\n .query({\n query: { range: req.range, index: schema.primaryKey },\n trans: req.trans,\n values: false,\n })\n // Do a delete request instead, but keep the criteria info for the server to execute\n .then((res) => {\n return mutateAndLog({\n type: 'delete',\n keys: res.result,\n trans: req.trans,\n criteria: { index: null, range: req.range },\n });\n })\n : mutateAndLog(req);\n },\n });\n\n function mutateAndLog(\n req: DBCoreDeleteRequest | DBCoreAddRequest | DBCorePutRequest\n ): Promise<DBCoreMutateResponse> {\n const trans = req.trans as DBCoreTransaction & TXExpandos;\n const unsyncedProps =\n db.cloud.options?.unsyncedProperties?.[tableName];\n const {\n txid,\n currentUser: { userId },\n } = trans;\n const { type } = req;\n const opNo = ++trans.opCount;\n\n function stripChangeSpec(changeSpec: { [keyPath: string]: any }) {\n if (!unsyncedProps) return changeSpec;\n let rv = changeSpec;\n for (const keyPath of Object.keys(changeSpec)) {\n if (\n unsyncedProps.some(\n (p) => keyPath === p || keyPath.startsWith(p + '.')\n )\n ) {\n if (rv === changeSpec) rv = { ...changeSpec }; // clone on demand\n delete rv[keyPath];\n }\n }\n return rv;\n }\n\n return table.mutate(req).then((res) => {\n const { numFailures: hasFailures, failures } = res;\n let keys = type === 'delete' ? req.keys! : res.results!;\n let values = 'values' in req ? req.values : [];\n let changeSpec = 'changeSpec' in req ? req.changeSpec : undefined;\n let updates = 'updates' in req ? req.updates : undefined;\n\n if (hasFailures) {\n keys = keys.filter((_, idx) => !failures[idx]);\n values = values.filter((_, idx) => !failures[idx]);\n }\n if (unsyncedProps) {\n // Filter out unsynced properties\n values = values.map((value) => {\n const newValue = { ...value };\n for (const prop of unsyncedProps) {\n delete newValue[prop];\n }\n return newValue;\n });\n if (changeSpec) {\n // modify operation with criteria and changeSpec.\n // We must strip out unsynced properties from changeSpec.\n // We deal with criteria later.\n changeSpec = stripChangeSpec(changeSpec);\n if (Object.keys(changeSpec).length === 0) {\n // Nothing to change on server\n return res;\n }\n }\n if (updates) {\n let strippedChangeSpecs =\n updates.changeSpecs.map(stripChangeSpec);\n let newUpdates: DBCorePutRequest['updates'] = {\n keys: [],\n changeSpecs: [],\n };\n const validKeys = new RangeSet();\n let anyChangeSpecBecameEmpty = false;\n for (let i = 0, l = strippedChangeSpecs.length; i < l; ++i) {\n if (Object.keys(strippedChangeSpecs[i]).length > 0) {\n newUpdates.keys.push(updates.keys[i]);\n newUpdates.changeSpecs.push(strippedChangeSpecs[i]);\n validKeys.addKey(updates.keys[i]);\n } else {\n anyChangeSpecBecameEmpty = true;\n }\n }\n updates = newUpdates;\n if (anyChangeSpecBecameEmpty) {\n // Some keys were stripped. We must also strip them from keys and values\n let newKeys: any[] = [];\n let newValues: any[] = [];\n for (let i = 0, l = keys.length; i < l; ++i) {\n if (validKeys.hasKey(keys[i])) {\n newKeys.push(keys[i]);\n newValues.push(values[i]);\n }\n }\n keys = newKeys;\n values = newValues;\n }\n }\n }\n const ts = Date.now();\n // Canonicalize req.criteria.index to null if it's on the primary key.\n let criteria =\n 'criteria' in req && req.criteria\n ? {\n ...req.criteria,\n index:\n req.criteria.index === schema.primaryKey.keyPath // Use null to inform server that criteria is on primary key\n ? null // This will disable the server from trying to log consistent operations where it shouldnt.\n : req.criteria.index,\n }\n : undefined;\n if (unsyncedProps && criteria?.index) {\n const keyPaths = schema.indexes.find(\n (idx) => idx.name === criteria!.index\n )?.keyPath;\n const involvedProps = keyPaths\n ? typeof keyPaths === 'string'\n ? [keyPaths]\n : keyPaths\n : [];\n if (involvedProps.some((p) => unsyncedProps?.includes(p))) {\n // Don't log criteria on unsynced properties as the server could not test them.\n criteria = undefined;\n }\n }\n\n const mut: DBOperation =\n req.type === 'delete'\n ? {\n type: 'delete',\n ts,\n opNo,\n keys,\n criteria,\n txid,\n userId,\n }\n : req.type === 'add'\n ? {\n type: 'insert',\n ts,\n opNo,\n keys,\n txid,\n userId,\n values,\n }\n : criteria && changeSpec\n ? {\n // Common changeSpec for all keys\n type: 'modify',\n ts,\n opNo,\n keys,\n criteria,\n changeSpec,\n txid,\n userId,\n }\n : changeSpec\n ? {\n // In case criteria involved an unsynced property, we go for keys instead.\n type: 'update',\n ts,\n opNo,\n keys,\n changeSpecs: keys.map(() => changeSpec!),\n txid,\n userId,\n }\n : updates\n ? {\n // One changeSpec per key\n type: 'update',\n ts,\n opNo,\n keys: updates.keys,\n changeSpecs: updates.changeSpecs,\n txid,\n userId,\n }\n : {\n type: 'upsert',\n ts,\n opNo,\n keys,\n values,\n txid,\n userId,\n };\n\n if ('isAdditionalChunk' in req && req.isAdditionalChunk) {\n mut.isAdditionalChunk = true;\n }\n return keys.length > 0 || criteria\n ? mutsTable\n .mutate({ type: 'add', trans, values: [mut] }) // Log entry\n .then(() => {\n trans.mutationsAdded = true; // Mark transaction as having added mutations to trigger eager sync\n return res; // Return original response\n })\n : res;\n });\n }\n },\n };\n },\n };\n}\n","import Dexie, { DbSchema } from 'dexie';\nimport { DEXIE_CLOUD_SCHEMA } from './db/DexieCloudDB';\nimport { generateTablePrefix } from './middleware-helpers/idGenerationHelpers';\n\nexport function overrideParseStoresSpec(origFunc: Function, dexie: Dexie) {\n return function(stores: {[tableName: string]: string}, dbSchema: DbSchema) {\n const storesClone = {\n ...DEXIE_CLOUD_SCHEMA,\n ...stores,\n };\n // Merge indexes of DEXIE_CLOUD_SCHEMA with stores\n Object.keys(DEXIE_CLOUD_SCHEMA).forEach((tableName: keyof typeof DEXIE_CLOUD_SCHEMA) => {\n const schemaSrc = storesClone[tableName];\n // Verify that they don't try to delete a table that is needed for access control of Dexie Cloud\n if (schemaSrc == null) {\n // They try to delete one of the built-in schema tables.\n throw new Error(`Cannot delete table ${tableName} as it is needed for access control of Dexie Cloud`);\n }\n // If not trying to override a built-in table, then we can skip this and continue to next table.\n if (!stores[tableName]) {\n // They haven't tried to declare this table. No need to merge indexes.\n return; // Continue\n }\n\n // They have declared this table. Merge indexes in case they didn't declare all indexes we need.\n const requestedIndexes = schemaSrc.split(',').map(spec => spec.trim());\n const builtInIndexes = DEXIE_CLOUD_SCHEMA[tableName].split(',').map(spec => spec.trim());\n const requestedIndexSet = new Set(requestedIndexes.map(index => index.replace(/([&*]|\\+\\+)/g, \"\")));\n // Verify that primary key is unchanged\n if (requestedIndexes[0] !== builtInIndexes[0]) {\n // Primary key must match exactly\n throw new Error(`Cannot override primary key of table ${tableName}. Please declare it as {${\n tableName}: ${\n JSON.stringify(DEXIE_CLOUD_SCHEMA[tableName])\n }`);\n }\n // Merge indexes\n for (let i=1; i<builtInIndexes.length; ++i) {\n const builtInIndex = builtInIndexes[i];\n if (!requestedIndexSet.has(builtInIndex.replace(/([&*]|\\+\\+)/g, \"\"))) {\n // Add built-in index if not already requested\n storesClone[tableName] += `,${builtInIndex}`;\n }\n }\n });\n\n // Populate dexie.cloud.schema\n const cloudSchema = dexie.cloud.schema || (dexie.cloud.schema = {});\n const allPrefixes = new Set<string>();\n Object.keys(storesClone).forEach(tableName => {\n const schemaSrc = storesClone[tableName];\n const cloudTableSchema = cloudSchema[tableName] || (cloudSchema[tableName] = {});\n if (schemaSrc != null) {\n if (/^\\@/.test(schemaSrc)) {\n storesClone[tableName] = storesClone[tableName].substr(1);\n cloudTableSchema.generatedGlobalId = true;\n cloudTableSchema.idPrefix = generateTablePrefix(tableName, allPrefixes);\n allPrefixes.add(cloudTableSchema.idPrefix);\n }\n if (!/^\\$/.test(tableName)) {\n storesClone[`$${tableName}_mutations`] = '++rev';\n cloudTableSchema.markedForSync = true;\n }\n if (cloudTableSchema.deleted) {\n cloudTableSchema.deleted = false;\n }\n } else {\n cloudTableSchema.deleted = true;\n cloudTableSchema.markedForSync = false;\n storesClone[`$${tableName}_mutations`] = null;\n }\n });\n const rv = origFunc.call(this, storesClone, dbSchema);\n for (const [tableName, spec] of Object.entries(dbSchema)) {\n if (spec.yProps?.length) {\n const cloudTableSchema = cloudSchema[tableName];\n if (cloudTableSchema) {\n cloudTableSchema.yProps = spec.yProps.map((yProp) => yProp.prop);\n }\n }\n }\n return rv;\n }\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\n\nexport function performGuardedJob<T>(\n db: DexieCloudDB,\n jobName: string,\n job: () => Promise<T>\n): Promise<T> {\n if (typeof navigator === 'undefined' || !navigator.locks) {\n // No support for guarding jobs. IE11, node.js, etc.\n return job();\n }\n return navigator.locks.request(db.name + '|' + jobName, () => job());\n}\n","import { BehaviorSubject, fromEvent, merge, of } from 'rxjs';\nimport {\n debounceTime,\n delay,\n distinctUntilChanged,\n filter,\n map,\n skip,\n startWith,\n switchMap,\n tap,\n} from 'rxjs/operators';\n\nconst USER_INACTIVITY_TIMEOUT = 180_000; // 3 minutes\nconst ACTIVE_WAIT_TIME = 0; // For now, it's nicer to react instantly on user activity\nconst INACTIVE_WAIT_TIME = 20_000;\n\n// This observable will be emitted to later down....\nexport const userIsActive = new BehaviorSubject<boolean>(true);\n\n// A refined version that waits before changing state:\n// * Wait another INACTIVE_WAIT_TIME before accepting that the user is inactive.\n// Reason 1: Spare resources - no need to setup the entire websocket flow when\n// switching tabs back and forth.\n// Reason 2: Less flickering for the end user when switching tabs back and forth.\n// * Wait another ACTIVE_WAIT_TIME before accepting that the user is active.\n// Possible reason to have a value here: Sparing resources if users often temporary click the tab\n// for just a short time.\nexport const userIsReallyActive = new BehaviorSubject<boolean>(true);\nuserIsActive\n .pipe(\n switchMap((isActive) => {\n //console.debug('SyncStatus: DUBB: isActive changed to', isActive);\n return isActive\n ? ACTIVE_WAIT_TIME\n ? of(true).pipe(delay(ACTIVE_WAIT_TIME))\n : of(true)\n : INACTIVE_WAIT_TIME\n ? of(false).pipe(delay(INACTIVE_WAIT_TIME))\n : of(false);}\n ),\n distinctUntilChanged()\n )\n .subscribe(userIsReallyActive);\n\n//\n// First create some corner-stone observables to build the flow on\n//\n\n// document.onvisibilitychange:\nexport const visibilityStateIsChanged =\n typeof document !== 'undefined'\n ? fromEvent(document, 'visibilitychange')\n : of({});\n\n// document.onvisibilitychange makes document hidden:\nexport const documentBecomesHidden = visibilityStateIsChanged.pipe(\n filter(() => document.visibilityState === 'hidden')\n);\n\n// document.onvisibilitychange makes document visible\nexport const documentBecomesVisible = visibilityStateIsChanged.pipe(\n filter(() => document.visibilityState === 'visible')\n);\n\n// Any of various user-activity-related events happen:\nexport const userDoesSomething =\n typeof window !== 'undefined'\n ? merge(\n documentBecomesVisible,\n fromEvent(window, 'mousedown'),\n fromEvent(window, 'mousemove'),\n fromEvent(window, 'keydown'),\n fromEvent(window, 'wheel'),\n fromEvent(window, 'touchmove')\n )\n : of({});\n\nif (typeof document !== 'undefined') {\n //\n // Now, create a final observable and start subscribing to it in order\n // to make it emit values to userIsActive BehaviourSubject (which is the\n // most important global hot observable we have here)\n //\n // Live test: https://jsitor.com/LboCDHgbn\n //\n merge(\n of(true), // Make sure something is always emitted from start\n documentBecomesHidden, // so that we can eagerly emit false!\n userDoesSomething\n )\n .pipe(\n // No matter event source, compute whether user is visible using visibilityState:\n map(() => document.visibilityState === 'visible'),\n // Make sure to emit it\n tap((isActive) => {\n if (userIsActive.value !== isActive) {\n // Emit new value unless it already has that value\n userIsActive.next(isActive);\n }\n }),\n // Now, if true was emitted, make sure to set a timeout to emit false\n // unless new user activity things happen (in that case, the timeout will be cancelled!)\n switchMap((isActive) =>\n isActive\n ? of(0).pipe(\n delay(USER_INACTIVITY_TIMEOUT - INACTIVE_WAIT_TIME),\n tap(() => userIsActive.next(false))\n )\n : of(0)\n )\n )\n .subscribe(() => {}); // Unless we subscribe nothing will be propagated to userIsActive observable\n}\n","export class TokenExpiredError extends Error {\n name = \"TokenExpiredError\";\n}\n","import Dexie from \"dexie\";\nimport { type DexieCloudDB } from \"../db/DexieCloudDB\";\n\nexport function getAwarenessLibrary(db: DexieCloudDB): typeof import ('y-protocols/awareness') {\n if (!db.cloud.options?.awarenessProtocol) {\n throw new Dexie.MissingAPIError('awarenessProtocol was not provided to db.cloud.configure(). Please import * as awarenessProtocol from \"y-protocols/awareness\".');\n }\n return db.cloud.options?.awarenessProtocol;\n}\n\nexport const awarenessWeakMap = new WeakMap<any, import('y-protocols/awareness').Awareness>();\n\nexport const getDocAwareness = (doc: any) => awarenessWeakMap.get(doc);\n\n\n","import { Subject } from \"rxjs\";\nimport type * as Y from \"yjs\";\n\nconst wm = new WeakMap<Y.Doc, Subject<void>>();\n\n/** A property (package-private) on Y.Doc that is used\n * to signal that the server wants us to send a 'doc-open' message\n * to the server for this document.\n * \n * @param doc \n * @returns \n */\nexport function getOpenDocSignal(doc: Y.Doc) {\n let signal = wm.get(doc);\n if (!signal) {\n signal = new Subject<void>();\n wm.set(doc, signal);\n }\n return signal;\n}","import { DBOperationsSet } from 'dexie-cloud-common';\nimport { BehaviorSubject, Observable, Subscriber, Subscription, tap } from 'rxjs';\nimport { TokenExpiredError } from './authentication/TokenExpiredError';\nimport { DXCWebSocketStatus } from './DXCWebSocketStatus';\nimport { TSON } from './TSON';\nimport type { YClientMessage, YServerMessage } from 'dexie-cloud-common';\nimport { DexieCloudDB } from './db/DexieCloudDB';\nimport { createYClientUpdateObservable } from './yjs/createYClientUpdateObservable';\nimport { applyYServerMessages } from './yjs/applyYMessages';\nimport { Table } from 'dexie';\nimport { getAwarenessLibrary, getDocAwareness } from './yjs/awareness';\nimport { encodeYMessage, decodeYMessage } from 'dexie-cloud-common';\nimport { UserLogin } from './dexie-cloud-client';\nimport { isEagerSyncDisabled } from './isEagerSyncDisabled';\nimport { getOpenDocSignal } from './yjs/reopenDocSignal';\nimport { getUpdatesTable } from './yjs/getUpdatesTable';\nimport { DEXIE_CLOUD_SYNCER_ID } from './sync/DEXIE_CLOUD_SYNCER_ID';\nimport { DexieYProvider, YSyncState } from 'y-dexie';\n\nconst SERVER_PING_TIMEOUT = 20000;\nconst CLIENT_PING_INTERVAL = 30000;\nconst FAIL_RETRY_WAIT_TIME = 60000;\n\nexport type WSClientToServerMsg = ReadyForChangesMessage | YClientMessage;\nexport interface ReadyForChangesMessage {\n type: 'ready';\n realmSetHash: string;\n rev: string;\n}\n\nexport type WSConnectionMsg =\n | RevisionChangedMessage\n | RealmAddedMessage\n | RealmAcceptedMessage\n | RealmRemovedMessage\n | RealmsChangedMessage\n | ChangesFromServerMessage\n | TokenExpiredMessage;\ninterface PingMessage {\n type: 'ping';\n}\n\ninterface PongMessage {\n type: 'pong';\n}\n\ninterface ErrorMessage {\n type: 'error';\n error: string;\n}\n\nexport interface ChangesFromServerMessage {\n type: 'changes';\n baseRev: string;\n realmSetHash: string;\n newRev: string;\n changes: DBOperationsSet<string>;\n}\nexport interface RevisionChangedMessage {\n type: 'rev';\n rev: string;\n}\n\nexport interface RealmAddedMessage {\n type: 'realm-added';\n realm: string;\n}\n\nexport interface RealmAcceptedMessage {\n type: 'realm-accepted';\n realm: string;\n}\n\nexport interface RealmRemovedMessage {\n type: 'realm-removed';\n realm: string;\n}\n\nexport interface RealmsChangedMessage {\n type: 'realms-changed';\n realmsHash: string;\n}\nexport interface TokenExpiredMessage {\n type: 'token-expired';\n}\n\nexport class WSObservable extends Observable<WSConnectionMsg> {\n constructor(\n db: DexieCloudDB,\n rev: string | undefined,\n yrev: string | undefined,\n realmSetHash: string,\n clientIdentity: string,\n messageProducer: Observable<WSClientToServerMsg>,\n webSocketStatus: BehaviorSubject<DXCWebSocketStatus>,\n user: UserLogin\n ) {\n super(\n (subscriber) =>\n new WSConnection(\n db,\n rev,\n yrev,\n realmSetHash,\n clientIdentity,\n user,\n subscriber,\n messageProducer,\n webSocketStatus\n )\n );\n }\n}\n\nlet counter = 0;\n\nexport class WSConnection extends Subscription {\n db: DexieCloudDB;\n ws: WebSocket | null;\n lastServerActivity: Date;\n lastUserActivity: Date;\n lastPing: Date;\n databaseUrl: string;\n rev: string | undefined;\n yrev: string | undefined;\n realmSetHash: string;\n clientIdentity: string;\n user: UserLogin;\n subscriber: Subscriber<WSConnectionMsg>;\n pauseUntil?: Date;\n messageProducer: Observable<WSClientToServerMsg>;\n webSocketStatus: BehaviorSubject<DXCWebSocketStatus>;\n id = ++counter;\n\n private pinger: any;\n private subscriptions: Set<Subscription> = new Set();\n\n constructor(\n db: DexieCloudDB,\n rev: string | undefined,\n yrev: string | undefined,\n realmSetHash: string,\n clientIdentity: string,\n user: UserLogin,\n subscriber: Subscriber<WSConnectionMsg>,\n messageProducer: Observable<WSClientToServerMsg>,\n webSocketStatus: BehaviorSubject<DXCWebSocketStatus>\n ) {\n super(() => this.teardown());\n console.debug(\n 'New WebSocket Connection',\n this.id,\n user.accessToken ? 'authorized' : 'unauthorized'\n );\n this.db = db;\n this.databaseUrl = db.cloud.options!.databaseUrl;\n this.rev = rev;\n this.yrev = yrev;\n this.realmSetHash = realmSetHash;\n this.clientIdentity = clientIdentity;\n this.user = user;\n this.subscriber = subscriber;\n this.lastUserActivity = new Date();\n this.messageProducer = messageProducer;\n this.webSocketStatus = webSocketStatus;\n this.connect();\n }\n\n private teardown() {\n console.debug('Teardown WebSocket Connection', this.id);\n this.disconnect();\n }\n\n private disconnect() {\n this.webSocketStatus.next('disconnected');\n if (this.pinger) {\n clearInterval(this.pinger);\n this.pinger = null;\n }\n if (this.ws) {\n try {\n this.ws.close();\n } catch {}\n }\n this.ws = null;\n for (const sub of this.subscriptions) {\n sub.unsubscribe();\n }\n this.subscriptions.clear();\n }\n\n reconnecting = false;\n reconnect() {\n if (this.reconnecting) return;\n this.reconnecting = true;\n try {\n this.disconnect();\n } catch {}\n this.connect()\n .catch(() => {})\n .then(() => (this.reconnecting = false)); // finally()\n }\n\n async connect() {\n this.lastServerActivity = new Date();\n if (this.pauseUntil && this.pauseUntil > new Date()) {\n console.debug('WS not reconnecting just yet', {\n id: this.id,\n pauseUntil: this.pauseUntil,\n });\n return;\n }\n if (this.ws) {\n throw new Error(`Called connect() when a connection is already open`);\n }\n if (!this.databaseUrl)\n throw new Error(`Cannot connect without a database URL`);\n if (this.closed) {\n //console.debug('SyncStatus: DUBB: Ooops it was closed!');\n return;\n }\n const tokenExpiration = this.user.accessTokenExpiration;\n if (tokenExpiration && tokenExpiration < new Date()) {\n this.subscriber.error(new TokenExpiredError()); // Will be handled in connectWebSocket.ts.\n return;\n }\n this.webSocketStatus.next('connecting');\n this.pinger = setInterval(async () => {\n // setInterval here causes unnecessary pings when server is proved active anyway.\n // TODO: Use setTimout() here instead. When triggered, check if we really need to ping.\n // In case we've had server activity, we don't need to ping. Then schedule then next ping\n // to the time when we should ping next time (based on lastServerActivity + CLIENT_PING_INTERVAL).\n // Else, ping now and schedule next ping to CLIENT_PING_INTERVAL from now.\n if (this.closed) {\n console.debug('pinger check', this.id, 'CLOSED.');\n this.teardown();\n return;\n }\n if (this.ws) {\n try {\n this.ws.send(JSON.stringify({ type: 'ping' } as PingMessage));\n setTimeout(() => {\n console.debug(\n 'pinger setTimeout',\n this.id,\n this.pinger ? `alive` : 'dead'\n );\n if (!this.pinger) return;\n if (this.closed) {\n console.debug(\n 'pinger setTimeout',\n this.id,\n 'subscription is closed'\n );\n this.teardown();\n return;\n }\n if (\n this.lastServerActivity <\n new Date(Date.now() - SERVER_PING_TIMEOUT)\n ) {\n // Server inactive. Reconnect if user is active.\n console.debug('pinger: server is inactive');\n console.debug('pinger reconnecting');\n this.reconnect();\n } else {\n console.debug('pinger: server still active');\n }\n }, SERVER_PING_TIMEOUT);\n } catch {\n console.debug('pinger catch error', this.id, 'reconnecting');\n this.reconnect();\n }\n } else {\n console.debug('pinger', this.id, 'reconnecting');\n this.reconnect();\n }\n }, CLIENT_PING_INTERVAL);\n\n // The following vars are needed because we must know which callback to ack when server sends it's ack to us.\n const wsUrl = new URL(this.databaseUrl);\n wsUrl.protocol = wsUrl.protocol === 'http:' ? 'ws' : 'wss';\n const searchParams = new URLSearchParams();\n if (this.subscriber.closed) return;\n searchParams.set('v', '2');\n if (this.rev) searchParams.set('rev', this.rev);\n if (this.yrev) searchParams.set('yrev', this.yrev);\n searchParams.set('realmsHash', this.realmSetHash);\n searchParams.set('clientId', this.clientIdentity);\n searchParams.set('dxcv', this.db.cloud.version);\n if (this.user.accessToken) {\n searchParams.set('token', this.user.accessToken);\n }\n\n // Connect the WebSocket to given url:\n console.debug('dexie-cloud WebSocket create');\n const ws = (this.ws = new WebSocket(`${wsUrl}/changes?${searchParams}`));\n ws.binaryType = \"arraybuffer\";\n\n ws.onclose = (event: Event) => {\n if (!this.pinger) return;\n console.debug('dexie-cloud WebSocket onclosed', this.id);\n this.reconnect();\n };\n\n ws.onmessage = (event: MessageEvent) => {\n if (!this.pinger) return;\n\n this.lastServerActivity = new Date();\n try {\n const msg = typeof event.data === 'string'\n ? TSON.parse(event.data) as\n | WSConnectionMsg\n | PongMessage\n | ErrorMessage\n | YServerMessage \n : decodeYMessage(new Uint8Array(event.data)) as\n | YServerMessage;\n console.debug('dexie-cloud WebSocket onmessage', msg.type, msg);\n if (msg.type === 'error') {\n throw new Error(`Error message from dexie-cloud: ${msg.error}`);\n } else if (msg.type === 'aware') {\n const docCache = DexieYProvider.getDocCache(this.db.dx);\n const doc = docCache.find(msg.table, msg.k, msg.prop);\n if (doc) {\n const awareness = getDocAwareness(doc);\n if (awareness) {\n const awap = getAwarenessLibrary(this.db);\n awap.applyAwarenessUpdate(\n awareness,\n msg.u,\n 'server',\n );\n }\n }\n } else if (msg.type === 'pong') {\n // Do nothing\n } else if (msg.type === 'doc-open') {\n const docCache = DexieYProvider.getDocCache(this.db.dx);\n const doc = docCache.find(msg.table, msg.k, msg.prop);\n if (doc) {\n getOpenDocSignal(doc).next(); // Make yHandler reopen the document on server.\n }\n } else if (msg.type === 'u-ack' || msg.type === 'u-reject' || msg.type === 'u-s' || msg.type === 'in-sync' || msg.type === 'outdated-server-rev' || msg.type === 'y-complete-sync-done') {\n applyYServerMessages([msg], this.db).then(async ({resyncNeeded, yServerRevision, receivedUntils}) => {\n if (yServerRevision) {\n await this.db.$syncState.update('syncState', { yServerRevision: yServerRevision });\n }\n if (msg.type === 'u-s' && receivedUntils) {\n const utbl = getUpdatesTable(this.db, msg.table, msg.prop) as any as Table<YSyncState, string>;\n if (utbl) {\n const receivedUntil = receivedUntils[utbl.name];\n if (receivedUntil) {\n await utbl.update(DEXIE_CLOUD_SYNCER_ID, { receivedUntil });\n }\n }\n }\n if (resyncNeeded) {\n await this.db.cloud.sync({ purpose: 'pull', wait: true });\n }\n })\n } else {\n // Forward the request to our subscriber, wich is in messageFromServerQueue.ts (via connectWebSocket's subscribe() at the end!)\n this.subscriber.next(msg);\n }\n } catch (e) {\n this.subscriber.error(e);\n }\n };\n\n try {\n let everConnected = false;\n await new Promise((resolve, reject) => {\n ws.onopen = (event) => {\n console.debug('dexie-cloud WebSocket onopen');\n everConnected = true;\n resolve(null);\n };\n ws.onerror = (event: ErrorEvent) => {\n if (!everConnected) {\n const error = event.error || new Error('WebSocket Error');\n this.subscriber.error(error);\n this.webSocketStatus.next('error');\n reject(error);\n } else {\n this.reconnect();\n }\n };\n });\n this.subscriptions.add(this.messageProducer.subscribe(\n (msg) => {\n if (!this.closed) {\n if (\n msg.type === 'ready' &&\n this.webSocketStatus.value !== 'connected'\n ) {\n this.webSocketStatus.next('connected');\n }\n console.debug('dexie-cloud WebSocket send', msg.type, msg);\n if (msg.type === 'ready') {\n // Ok, we are certain to have stored everything up until revision msg.rev.\n // Update this.rev in case of reconnect - remember where we were and don't just start over!\n this.rev = msg.rev; \n // ... and then send along the request to the server so it would also be updated!\n this.ws?.send(TSON.stringify(msg));\n } else {\n // If it's not a \"ready\" message, it's an YMessage.\n // YMessages can be sent binary encoded.\n this.ws?.send(encodeYMessage(msg));\n }\n }\n }\n ));\n if (this.user.isLoggedIn && !isEagerSyncDisabled(this.db)) {\n this.subscriptions.add(\n createYClientUpdateObservable(this.db).subscribe(\n this.db.messageProducer\n )\n );\n }\n } catch (error) {\n this.pauseUntil = new Date(Date.now() + FAIL_RETRY_WAIT_TIME);\n }\n }\n}\n","import { Decoder, readAny, readBigUint64, readVarString, readVarUint8Array, } from 'lib0/decoding';\nexport function decodeYMessage(a) {\n const decoder = new Decoder(a);\n const type = readVarString(decoder);\n if (type === 'outdated-server-rev') {\n return { type };\n }\n if (type === 'y-complete-sync-done') {\n return { type, yServerRev: readVarString(decoder) };\n }\n const table = readVarString(decoder);\n const prop = readVarString(decoder);\n switch (type) {\n case 'u-ack':\n case 'u-reject':\n return {\n type,\n table,\n prop,\n i: Number(readBigUint64(decoder)),\n };\n default: {\n const k = readAny(decoder);\n switch (type) {\n case 'in-sync':\n return { type, table, prop, k };\n case 'aware':\n return {\n type,\n table,\n prop,\n k,\n u: readVarUint8Array(decoder),\n };\n case 'doc-open':\n return {\n type,\n table,\n prop,\n k,\n serverRev: readAny(decoder),\n sv: readAny(decoder),\n };\n case 'doc-close':\n return { type, table, prop, k };\n case 'sv':\n return {\n type,\n table,\n prop,\n k,\n sv: readVarUint8Array(decoder),\n };\n case 'u-c':\n return {\n type,\n table,\n prop,\n k,\n u: readVarUint8Array(decoder),\n i: Number(readBigUint64(decoder)),\n };\n case 'u-s':\n return {\n type,\n table,\n prop,\n k,\n u: readVarUint8Array(decoder),\n r: (decoder.pos < decoder.arr.length && readVarString(decoder)) || undefined,\n };\n default:\n throw new TypeError(`Unknown message type: ${type}`);\n }\n }\n }\n}\n","import { Encoder, writeVarString, writeBigUint64, writeAny, toUint8Array, writeVarUint8Array, } from 'lib0/encoding';\nexport function encodeYMessage(msg) {\n const encoder = new Encoder();\n writeVarString(encoder, msg.type);\n if ('table' in msg)\n writeVarString(encoder, msg.table);\n if ('prop' in msg)\n writeVarString(encoder, msg.prop);\n switch (msg.type) {\n case 'u-ack':\n case 'u-reject':\n writeBigUint64(encoder, BigInt(msg.i));\n break;\n case 'outdated-server-rev':\n break;\n case 'y-complete-sync-done':\n writeVarString(encoder, msg.yServerRev);\n break;\n default:\n writeAny(encoder, msg.k);\n switch (msg.type) {\n case 'aware':\n writeVarUint8Array(encoder, msg.u);\n break;\n case 'doc-open':\n writeAny(encoder, msg.serverRev);\n writeAny(encoder, msg.sv);\n break;\n case 'doc-close':\n break;\n case 'sv':\n writeVarUint8Array(encoder, msg.sv);\n break;\n case 'u-c':\n writeVarUint8Array(encoder, msg.u);\n writeBigUint64(encoder, BigInt(msg.i));\n break;\n case 'u-s':\n writeVarUint8Array(encoder, msg.u);\n writeVarString(encoder, msg.r || '');\n break;\n case 'in-sync':\n break;\n }\n }\n return toUint8Array(encoder);\n}\n","import { Observable, from, merge, mergeMap, switchMap, tap } from 'rxjs';\nimport { YClientMessage, YUpdateFromClientRequest } from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { flatten } from '../helpers/flatten';\nimport { liveQuery } from 'dexie';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport { listUpdatesSince } from './listUpdatesSince';\nimport { YDexieCloudSyncState } from './YDexieCloudSyncState';\n\nexport function createYClientUpdateObservable(\n db: DexieCloudDB\n): Observable<YClientMessage> {\n const yTableRecords = flatten(\n db.tables\n .filter(\n (table) =>\n db.cloud.schema?.[table.name]?.markedForSync && table.schema.yProps\n )\n .map((table) =>\n table.schema.yProps!.map((p) => ({\n table: table.name,\n ydocProp: p.prop,\n updatesTable: p.updatesTable,\n }))\n )\n );\n return merge(\n ...yTableRecords.map(({ table, ydocProp, updatesTable }) => {\n // Per updates table (table+prop combo), we first read syncer.unsentFrom,\n // and then start listening for updates since that number.\n const yTbl = db.table(updatesTable);\n return from(yTbl.get(DEXIE_CLOUD_SYNCER_ID)).pipe(\n switchMap((syncer: YDexieCloudSyncState) => {\n let currentUnsentFrom = syncer?.unsentFrom || 1;\n return from(\n liveQuery(async () => {\n const addedUpdates = await listUpdatesSince(\n yTbl,\n currentUnsentFrom\n );\n return addedUpdates\n .filter((update) => update.f && update.f & 1) // Only include local updates\n .map((update) => {\n return {\n type: 'u-c',\n table,\n prop: ydocProp,\n k: update.k,\n u: update.u,\n i: update.i,\n } satisfies YUpdateFromClientRequest;\n });\n })\n ).pipe(\n tap((addedUpdates) => {\n // Update currentUnsentFrom to only listen for updates that will be newer than the ones we emitted.\n // (Before, we did this within the liveQuery, but that caused a bug because\n // a cancelled emittion of a liveQuery would update the currentUnsentFrom without\n // emitting anything, leading to that we jumped over some updates. Here we update it\n // after the liveQuery has emitted its updates)\n if (addedUpdates.length > 0) {\n currentUnsentFrom = addedUpdates.at(-1)!.i + 1;\n }\n })\n );\n })\n );\n })\n ).pipe(\n // Flatten the array of messages.\n // If messageProducer emits empty array, nothing is emitted\n // but if messageProducer emits array of messages, they are\n // emitted one by one.\n mergeMap((messages) => messages)\n );\n}\n","export class InvalidLicenseError extends Error {\n name = 'InvalidLicenseError';\n license?: 'expired' | 'deactivated';\n constructor(license?: 'expired' | 'deactivated') {\n super(\n license === 'expired'\n ? `License expired`\n : license === 'deactivated'\n ? `User deactivated`\n : 'Invalid license'\n );\n if (license) {\n this.license = license;\n }\n }\n}\n","import { BehaviorSubject, firstValueFrom, from, Observable, of, throwError, merge } from 'rxjs';\nimport {\n catchError,\n combineLatestAll,\n debounceTime,\n delay,\n distinctUntilChanged,\n filter,\n map,\n mergeMap,\n switchMap,\n take,\n tap,\n} from 'rxjs/operators';\nimport { refreshAccessToken } from '../authentication/authenticate';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { computeRealmSetHash } from '../helpers/computeRealmSetHash';\nimport {\n userDoesSomething,\n userIsActive,\n userIsReallyActive,\n} from '../userIsActive';\nimport {\n ReadyForChangesMessage,\n WSConnectionMsg,\n WSObservable,\n} from '../WSObservable';\nimport { InvalidLicenseError } from '../InvalidLicenseError';\nimport { read } from 'fs';\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function waitAndReconnectWhenUserDoesSomething(error: Error) {\n console.error(\n `WebSocket observable: error but revive when user does some active thing...`,\n error\n );\n // Sleep some seconds...\n await sleep(3000);\n // Wait til user does something (move mouse, tap, scroll, click etc)\n console.debug('waiting for someone to do something');\n await firstValueFrom(userDoesSomething);\n console.debug('someone did something!');\n}\n\nexport function connectWebSocket(db: DexieCloudDB) {\n if (!db.cloud.options?.databaseUrl) {\n throw new Error(`No database URL to connect WebSocket to`);\n }\n\n const readyForChangesMessage = db.messageConsumer.readyToServe.pipe(\n filter((isReady) => isReady), // When consumer is ready for new messages, produce such a message to inform server about it\n switchMap(() => db.getPersistedSyncState()), // We need the info on which server revision we are at:\n filter((syncState) => syncState && syncState.serverRevision), // We wont send anything to server before inital sync has taken place\n switchMap<PersistedSyncState, Promise<ReadyForChangesMessage>>(async (syncState) => ({\n // Produce the message to trigger server to send us new messages to consume:\n type: 'ready',\n rev: syncState.serverRevision,\n realmSetHash: await computeRealmSetHash(syncState)\n } satisfies ReadyForChangesMessage))\n );\n\n const messageProducer = merge(\n readyForChangesMessage,\n db.messageProducer\n );\n\n function createObservable(): Observable<WSConnectionMsg | null> {\n return db.cloud.persistedSyncState.pipe(\n filter((syncState) => syncState?.serverRevision), // Don't connect before there's no initial sync performed.\n take(1), // Don't continue waking up whenever syncState change\n switchMap((syncState) =>\n db.cloud.currentUser.pipe(\n map((userLogin) => [userLogin, syncState] as const)\n )\n ),\n switchMap(([userLogin, syncState]) => {\n /*if (userLogin.license?.status && userLogin.license.status !== 'ok') {\n throw new InvalidLicenseError();\n }*/\n return userIsReallyActive.pipe(\n map((isActive) => [isActive ? userLogin : null, syncState] as const)\n );\n }),\n switchMap(([userLogin, syncState]) => {\n if (userLogin?.isLoggedIn && !syncState?.realms.includes(userLogin.userId!)) {\n // We're in an in-between state when user is logged in but the user's realms are not yet synced.\n // Don't make this change reconnect the websocket just yet. Wait till syncState is updated\n // to iclude the user's realm.\n return db.cloud.persistedSyncState.pipe(\n filter((syncState) => syncState?.realms.includes(userLogin!.userId!) || false),\n take(1),\n map((syncState) => [userLogin, syncState] as const)\n );\n }\n return new BehaviorSubject([userLogin, syncState] as const);\n }),\n switchMap(\n async ([userLogin, syncState]) =>\n [userLogin, await computeRealmSetHash(syncState!)] as const\n ),\n distinctUntilChanged(([prevUser, prevHash], [currUser, currHash]) => prevUser === currUser && prevHash === currHash ),\n switchMap(([userLogin, realmSetHash]) => {\n if (!db.cloud.persistedSyncState?.value) {\n // Restart the flow if persistedSyncState is not yet available.\n return createObservable();\n }\n // Let server end query changes from last entry of same client-ID and forward.\n // If no new entries, server won't bother the client. If new entries, server sends only those\n // and the baseRev of the last from same client-ID.\n if (userLogin) {\n return new WSObservable(\n db,\n db.cloud.persistedSyncState!.value!.serverRevision,\n db.cloud.persistedSyncState!.value!.yServerRevision,\n realmSetHash,\n db.cloud.persistedSyncState!.value!.clientIdentity,\n messageProducer,\n db.cloud.webSocketStatus,\n userLogin\n );\n } else {\n return from([] as WSConnectionMsg[]);\n }}),\n catchError((error) => {\n if (error?.name === 'TokenExpiredError') {\n console.debug(\n 'WebSocket observable: Token expired. Refreshing token...'\n );\n return of(true).pipe(\n switchMap(async () => {\n // Refresh access token\n const user = await db.getCurrentUser();\n const refreshedLogin = await refreshAccessToken(\n db.cloud.options!.databaseUrl,\n user\n );\n // Persist updated access token\n await db.table('$logins').update(user.userId, {\n accessToken: refreshedLogin.accessToken,\n accessTokenExpiration: refreshedLogin.accessTokenExpiration,\n claims: refreshedLogin.claims,\n license: refreshedLogin.license,\n data: refreshedLogin.data\n });\n }),\n switchMap(() => createObservable())\n );\n } else {\n return throwError(()=>error);\n }\n }),\n catchError((error) => {\n db.cloud.webSocketStatus.next(\"error\");\n if (error instanceof InvalidLicenseError) {\n // Don't retry. Just throw and don't try connect again.\n return throwError(() => error);\n }\n return from(waitAndReconnectWhenUserDoesSomething(error)).pipe(\n switchMap(() => createObservable())\n );\n })\n ) as Observable<WSConnectionMsg | null>;\n }\n\n return createObservable().subscribe({\n next: (msg) => {\n if (msg) {\n console.debug('WS got message', msg);\n db.messageConsumer.enqueue(msg);\n }\n },\n error: (error) => {\n console.error('WS got error', error);\n },\n complete: () => {\n console.debug('WS observable completed');\n },\n });\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { sync } from \"./sync\";\n\nexport async function isSyncNeeded(db: DexieCloudDB) {\n return db.cloud.options?.databaseUrl && db.cloud.schema\n ? await sync(db, db.cloud.options, db.cloud.schema, {justCheckIfNeeded: true})\n : false;\n}\n","import { IS_SERVICE_WORKER } from '../helpers/IS_SERVICE_WORKER';\nimport { performGuardedJob } from './performGuardedJob';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { sync, CURRENT_SYNC_WORKER, SyncOptions } from './sync';\nimport { DexieCloudOptions } from '../DexieCloudOptions';\nimport { assert, DexieCloudSchema } from 'dexie-cloud-common';\nimport { checkSyncRateLimitDelay } from './ratelimit';\n\nconst ongoingSyncs = new WeakMap<\n DexieCloudDB,\n { promise: Promise<void>; pull: boolean }\n>();\n\nexport function syncIfPossible(\n db: DexieCloudDB,\n cloudOptions: DexieCloudOptions,\n cloudSchema: DexieCloudSchema,\n options?: SyncOptions\n) {\n const ongoing = ongoingSyncs.get(db);\n if (ongoing) {\n if (ongoing.pull || options?.purpose === 'push') {\n console.debug('syncIfPossible(): returning the ongoing sync promise.');\n return ongoing.promise;\n } else {\n // Ongoing sync may never do anything in case there are no outstanding changes\n // to sync (because its purpose was \"push\" not \"pull\")\n // Now, however, we are asked to do a sync with the purpose of \"pull\"\n // We want to optimize here. We must wait for the ongoing to complete\n // and then, if the ongoing sync never resulted in a sync request,\n // we must redo the sync.\n\n // To inspect what is happening in the ongoing request, let's subscribe\n // to db.cloud.syncState and look for if it is doing any \"pulling\" phase:\n let hasPullTakenPlace = false;\n const subscription = db.cloud.syncState.subscribe((syncState) => {\n if (syncState.phase === 'pulling') {\n hasPullTakenPlace = true;\n }\n });\n // Ok, so now we are watching. At the same time, wait for the ongoing to complete\n // and when it has completed, check if we're all set or if we need to redo\n // the call:\n return (\n ongoing.promise\n // This is a finally block but we are still running tests on\n // browsers that don't support it, so need to do it like this:\n .then(() => {\n subscription.unsubscribe();\n })\n .catch((error) => {\n subscription.unsubscribe();\n return Promise.reject(error);\n })\n .then(() => {\n if (!hasPullTakenPlace) {\n // No pull took place in the ongoing sync but the caller had \"pull\" as\n // an explicit purpose of this call - so we need to redo the call!\n return syncIfPossible(db, cloudOptions, cloudSchema, options);\n }\n })\n );\n }\n }\n\n const promise = _syncIfPossible();\n ongoingSyncs.set(db, { promise, pull: options?.purpose !== 'push' });\n return promise;\n\n async function _syncIfPossible() {\n try {\n // Check if should delay sync due to ratelimit:\n await checkSyncRateLimitDelay(db); \n await performGuardedJob(db, CURRENT_SYNC_WORKER, () =>\n sync(db, cloudOptions, cloudSchema, options)\n );\n ongoingSyncs.delete(db);\n console.debug('Done sync');\n } catch (error) {\n ongoingSyncs.delete(db);\n console.error(`Failed to sync client changes`, error);\n throw error; // Make sure we rethrow error so that sync event is retried.\n // I don't think we should setTimout or so here.\n // Unless server tells us to in some response.\n // Then we could follow that advice but not by waiting here but by registering\n // Something that triggers an event listened to in startPushWorker()\n }\n }\n}\n","export const SECONDS = 1000;\nexport const MINUTES = 60 * SECONDS;\nexport const HOURS = 60 * MINUTES;\nexport const DAYS = 24 * HOURS;\nexport const WEEKS = 7 * DAYS;\n","import { Subscription } from 'rxjs';\nimport { syncIfPossible } from './syncIfPossible';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { SECONDS } from '../helpers/date-constants';\nimport { DexieCloudOptions } from '../DexieCloudOptions';\nimport { DexieCloudSchema } from 'dexie-cloud-common';\n\nexport function LocalSyncWorker(\n db: DexieCloudDB,\n cloudOptions: DexieCloudOptions,\n cloudSchema: DexieCloudSchema\n) {\n let localSyncEventSubscription: Subscription | null = null;\n let cancelToken = { cancelled: false };\n let nextRetryTime = 0;\n let syncStartTime = 0;\n\n function syncAndRetry(retryNum = 1) {\n // Use setTimeout() to get onto a clean stack and\n // break free from possible active transaction:\n setTimeout(() => {\n const purpose = pullSignalled ? 'pull' : 'push';\n syncStartTime = Date.now();\n syncIfPossible(db, cloudOptions, cloudSchema, {\n cancelToken,\n retryImmediatelyOnFetchError: true, // workaround for \"net::ERR_NETWORK_CHANGED\" in chrome.\n purpose,\n }).then(()=>{\n if (cancelToken.cancelled) {\n stop();\n } else {\n if (pullSignalled || pushSignalled) {\n // If we have signalled for more sync, do it now.\n pullSignalled = false;\n pushSignalled = false;\n return syncAndRetry();\n }\n }\n ongoingSync = false;\n nextRetryTime = 0;\n syncStartTime = 0;\n }).catch((error: unknown) => {\n console.error('error in syncIfPossible()', error);\n if (cancelToken.cancelled) {\n stop();\n ongoingSync = false;\n nextRetryTime = 0;\n syncStartTime = 0;\n } else if (retryNum < 5) {\n // Mimic service worker sync event but a bit more eager: retry 4 times\n // * first retry after 20 seconds\n // * second retry 40 seconds later\n // * third retry 5 minutes later\n // * last retry 15 minutes later\n const retryIn = [0, 20, 40, 300, 900][retryNum] * SECONDS\n nextRetryTime = Date.now() + retryIn;\n syncStartTime = 0;\n setTimeout(\n () => syncAndRetry(retryNum + 1),\n retryIn\n );\n } else {\n ongoingSync = false;\n nextRetryTime = 0;\n syncStartTime = 0;\n }\n });\n }, 0);\n }\n\n let pullSignalled = false;\n let pushSignalled = false;\n let ongoingSync = false;\n const consumer = (purpose: 'pull' | 'push') =>{\n if (cancelToken.cancelled) return;\n if (purpose === 'pull') {\n pullSignalled = true;\n }\n if (purpose === 'push') {\n pushSignalled = true;\n }\n if (ongoingSync) {\n if (nextRetryTime) {\n console.debug(`Sync is paused until ${new Date(nextRetryTime).toISOString()} due to error in last sync attempt`);\n } else if (syncStartTime > 0 && Date.now() - syncStartTime > 20 * SECONDS) {\n console.debug(`An existing sync operation is taking more than 20 seconds. Will resync when done.`)\n }\n return;\n }\n ongoingSync = true;\n syncAndRetry();\n };\n\n const start = () => {\n // Sync eagerly whenever a change has happened (+ initially when there's no syncState yet)\n // This initial subscribe will also trigger an sync also now.\n console.debug('Starting LocalSyncWorker', db.localSyncEvent['id']);\n localSyncEventSubscription = db.localSyncEvent.subscribe(({ purpose }) => {\n consumer(purpose || 'pull');\n });\n };\n\n const stop = () => {\n console.debug('Stopping LocalSyncWorker');\n cancelToken.cancelled = true;\n if (localSyncEventSubscription) localSyncEventSubscription.unsubscribe();\n };\n\n return {\n start,\n stop,\n };\n}\n","import { DexieCloudSchema } from \"dexie-cloud-common\";\nimport { DexieCloudOptions } from \"./DexieCloudOptions\";\n\nexport function updateSchemaFromOptions(schema?: DexieCloudSchema | null, options?: DexieCloudOptions | null) {\n if (schema && options) {\n if (options.unsyncedTables) {\n for (const tableName of options.unsyncedTables) {\n if (schema[tableName]) {\n schema[tableName].markedForSync = false;\n }\n }\n }\n }\n}","var n,l,u,i,t,o,r,f={},e=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(n,l){for(var u in l)n[u]=l[u];return n}function a(n){var l=n.parentNode;l&&l.removeChild(n)}function h(l,u,i){var t,o,r,f={};for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return v(l,f,t,o,null)}function v(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u:r};return null==r&&null!=l.vnode&&l.vnode(f),f}function y(){return{current:null}}function p(n){return n.children}function d(n,l){this.props=n,this.context=l}function _(n,l){if(null==l)return n.__?_(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?_(n):null}function k(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return k(n)}}function b(n){(!n.__d&&(n.__d=!0)&&t.push(n)&&!g.__r++||o!==l.debounceRendering)&&((o=l.debounceRendering)||setTimeout)(g)}function g(){for(var n;g.__r=t.length;)n=t.sort(function(n,l){return n.__v.__b-l.__v.__b}),t=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=s({},t)).__v=t.__v+1,j(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?_(t):o,t.__h),z(u,t),t.__e!=o&&k(t)))})}function w(n,l,u,i,t,o,r,c,s,a){var h,y,d,k,b,g,w,x=i&&i.__k||e,C=x.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||\"boolean\"==typeof k?null:\"string\"==typeof k||\"number\"==typeof k||\"bigint\"==typeof k?v(null,k,null,null,k):Array.isArray(k)?v(p,{children:k},null,null,null):k.__b>0?v(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(d=x[h])||d&&k.key==d.key&&k.type===d.type)x[h]=void 0;else for(y=0;y<C;y++){if((d=x[y])&&k.key==d.key&&k.type===d.type){x[y]=void 0;break}d=null}j(n,k,d=d||f,t,o,r,c,s,a),b=k.__e,(y=k.ref)&&d.ref!=y&&(w||(w=[]),d.ref&&w.push(d.ref,null,k),w.push(y,k.__c||b,k)),null!=b?(null==g&&(g=b),\"function\"==typeof k.type&&k.__k===d.__k?k.__d=s=m(k,s,n):s=A(n,k,d,x,b,s),\"function\"==typeof u.type&&(u.__d=s)):s&&d.__e==s&&s.parentNode!=n&&(s=_(d))}for(u.__e=g,h=C;h--;)null!=x[h]&&(\"function\"==typeof u.type&&null!=x[h].__e&&x[h].__e==u.__d&&(u.__d=_(i,h+1)),N(x[h],x[h]));if(w)for(h=0;h<w.length;h++)M(w[h],w[++h],w[++h])}function m(n,l,u){for(var i,t=n.__k,o=0;t&&o<t.length;o++)(i=t[o])&&(i.__=n,l=\"function\"==typeof i.type?m(i,l,u):A(u,i,i,t,i.__e,l));return l}function x(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(Array.isArray(n)?n.some(function(n){x(n,l)}):l.push(n)),l}function A(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else{for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o}return void 0!==r?r:t.nextSibling}function C(n,l,u,i,t){var o;for(o in u)\"children\"===o||\"key\"===o||o in l||H(n,o,null,u[o],i);for(o in l)t&&\"function\"!=typeof l[o]||\"children\"===o||\"key\"===o||\"value\"===o||\"checked\"===o||u[o]===l[o]||H(n,o,l[o],u[o],i)}function $(n,l,u){\"-\"===l[0]?n.setProperty(l,u):n[l]=null==u?\"\":\"number\"!=typeof u||c.test(l)?u:u+\"px\"}function H(n,l,u,i,t){var o;n:if(\"style\"===l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof i&&(n.style.cssText=i=\"\"),i)for(l in i)u&&l in u||$(n.style,l,\"\");if(u)for(l in u)i&&u[l]===i[l]||$(n.style,l,u[l])}else if(\"o\"===l[0]&&\"n\"===l[1])o=l!==(l=l.replace(/Capture$/,\"\")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?T:I,o):n.removeEventListener(l,o?T:I,o);else if(\"dangerouslySetInnerHTML\"!==l){if(t)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"href\"!==l&&\"list\"!==l&&\"form\"!==l&&\"tabIndex\"!==l&&\"download\"!==l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null!=u&&(!1!==u||\"a\"===l[0]&&\"r\"===l[1])?n.setAttribute(l,u):n.removeAttribute(l))}}function I(n){this.l[n.type+!1](l.event?l.event(n):n)}function T(n){this.l[n.type+!0](l.event?l.event(n):n)}function j(n,u,i,t,o,r,f,e,c){var a,h,v,y,_,k,b,g,m,x,A,C,$,H=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=l.__b)&&a(u);try{n:if(\"function\"==typeof H){if(g=u.props,m=(a=H.contextType)&&t[a.__c],x=a?m?m.props.value:a.__:t,i.__c?b=(h=u.__c=i.__c).__=h.__E:(\"prototype\"in H&&H.prototype.render?u.__c=h=new H(g,x):(u.__c=h=new d(g,x),h.constructor=H,h.render=O),m&&m.sub(h),h.props=g,h.state||(h.state={}),h.context=x,h.__n=t,v=h.__d=!0,h.__h=[]),null==h.__s&&(h.__s=h.state),null!=H.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=s({},h.__s)),s(h.__s,H.getDerivedStateFromProps(g,h.__s))),y=h.props,_=h.state,v)null==H.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(null==H.getDerivedStateFromProps&&g!==y&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(g,x),!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(g,h.__s,x)||u.__v===i.__v){h.props=g,h.state=h.__s,u.__v!==i.__v&&(h.__d=!1),h.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u)}),h.__h.length&&f.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(g,h.__s,x),null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(y,_,k)})}if(h.context=x,h.props=g,h.__v=u,h.__P=n,A=l.__r,C=0,\"prototype\"in H&&H.prototype.render)h.state=h.__s,h.__d=!1,A&&A(u),a=h.render(h.props,h.state,h.context);else do{h.__d=!1,A&&A(u),a=h.render(h.props,h.state,h.context),h.state=h.__s}while(h.__d&&++C<25);h.state=h.__s,null!=h.getChildContext&&(t=s(s({},t),h.getChildContext())),v||null==h.getSnapshotBeforeUpdate||(k=h.getSnapshotBeforeUpdate(y,_)),$=null!=a&&a.type===p&&null==a.key?a.props.children:a,w(n,Array.isArray($)?$:[$],u,i,t,o,r,f,e,c),h.base=u.__e,u.__h=null,h.__h.length&&f.push(h),b&&(h.__E=h.__=null),h.__e=!1}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=L(i.__e,u,i,t,o,r,f,c);(a=l.diffed)&&a(u)}catch(n){u.__v=null,(c||null!=r)&&(u.__e=e,u.__h=!!c,r[r.indexOf(e)]=null),l.__e(n,u,i)}}function z(n,u){l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function L(l,u,i,t,o,r,e,c){var s,h,v,y=i.props,p=u.props,d=u.type,k=0;if(\"svg\"===d&&(o=!0),null!=r)for(;k<r.length;k++)if((s=r[k])&&\"setAttribute\"in s==!!d&&(d?s.localName===d:3===s.nodeType)){l=s,r[k]=null;break}if(null==l){if(null===d)return document.createTextNode(p);l=o?document.createElementNS(\"http://www.w3.org/2000/svg\",d):document.createElement(d,p.is&&p),r=null,c=!1}if(null===d)y===p||c&&l.data===p||(l.data=p);else{if(r=r&&n.call(l.childNodes),h=(y=i.props||f).dangerouslySetInnerHTML,v=p.dangerouslySetInnerHTML,!c){if(null!=r)for(y={},k=0;k<l.attributes.length;k++)y[l.attributes[k].name]=l.attributes[k].value;(v||h)&&(v&&(h&&v.__html==h.__html||v.__html===l.innerHTML)||(l.innerHTML=v&&v.__html||\"\"))}if(C(l,p,y,o,c),v)u.__k=[];else if(k=u.props.children,w(l,Array.isArray(k)?k:[k],u,i,t,o&&\"foreignObject\"!==d,r,e,r?r[0]:i.__k&&_(i,0),c),null!=r)for(k=r.length;k--;)null!=r[k]&&a(r[k]);c||(\"value\"in p&&void 0!==(k=p.value)&&(k!==l.value||\"progress\"===d&&!k||\"option\"===d&&k!==y.value)&&H(l,\"value\",k,y.value,!1),\"checked\"in p&&void 0!==(k=p.checked)&&k!==l.checked&&H(l,\"checked\",k,y.checked,!1))}return l}function M(n,u,i){try{\"function\"==typeof n?n(u):n.current=u}catch(n){l.__e(n,i)}}function N(n,u,i){var t,o;if(l.unmount&&l.unmount(n),(t=n.ref)&&(t.current&&t.current!==n.__e||M(t,null,u)),null!=(t=n.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount()}catch(n){l.__e(n,u)}t.base=t.__P=null}if(t=n.__k)for(o=0;o<t.length;o++)t[o]&&N(t[o],u,\"function\"!=typeof n.type);i||null==n.__e||a(n.__e),n.__e=n.__d=void 0}function O(n,l,u){return this.constructor(n,u)}function P(u,i,t){var o,r,e;l.__&&l.__(u,i),r=(o=\"function\"==typeof t)?null:t&&t.__k||i.__k,e=[],j(i,u=(!o&&t||i).__k=h(p,null,[u]),r||f,f,void 0!==i.ownerSVGElement,!o&&t?[t]:r?null:i.firstChild?n.call(i.childNodes):null,e,!o&&t?t:r?r.__e:i.firstChild,o),z(e,u)}function S(n,l){P(n,l,S)}function q(l,u,i){var t,o,r,f=s({},l.props);for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),v(l.type,f,t||l.key,o||l.ref,null)}function B(n,l){var u={__c:l=\"__cC\"+r++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(b)},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=e.slice,l={__e:function(n,l,u,i){for(var t,o,r;l=l.__;)if((t=l.__c)&&!t.__)try{if((o=t.constructor)&&null!=o.getDerivedStateFromError&&(t.setState(o.getDerivedStateFromError(n)),r=t.__d),null!=t.componentDidCatch&&(t.componentDidCatch(n,i||{}),r=t.__d),r)return t.__E=t}catch(l){n=l}throw n}},u=0,i=function(n){return null!=n&&void 0===n.constructor},d.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=s({},this.state),\"function\"==typeof n&&(n=n(s({},u),this.props)),n&&s(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),b(this))},d.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),b(this))},d.prototype.render=p,t=[],g.__r=0,r=0;export{P as render,S as hydrate,h as createElement,h,p as Fragment,y as createRef,i as isValidElement,d as Component,q as cloneElement,B as createContext,x as toChildArray,l as options};\n//# sourceMappingURL=preact.module.js.map\n","export const Styles: { [styleAlias: string]: Partial<CSSStyleDeclaration> | any} = {\n Error: {\n color: \"red\",\n },\n Alert: {\n error: {\n color: \"red\",\n fontWeight: \"bold\"\n },\n warning: {\n color: \"#f80\",\n fontWeight: \"bold\"\n },\n info: {\n color: \"black\"\n }\n },\n Darken: {\n position: \"fixed\",\n top: 0,\n left: 0,\n opacity: 0.5,\n backgroundColor: \"#000\",\n width: \"100vw\",\n height: \"100vh\",\n zIndex: 150,\n webkitBackdropFilter: \"blur(2px)\",\n backdropFilter: \"blur(2px)\",\n },\n DialogOuter: {\n position: \"fixed\",\n top: 0,\n left: 0,\n width: \"100vw\",\n height: \"100vh\",\n zIndex: 150,\n alignItems: \"center\",\n display: \"flex\",\n justifyContent: \"center\",\n },\n DialogInner: {\n position: \"relative\",\n color: \"#222\",\n backgroundColor: \"#fff\",\n padding: \"30px\",\n marginBottom: \"2em\",\n maxWidth: \"90%\",\n maxHeight: \"90%\",\n overflowY: \"auto\",\n border: \"3px solid #3d3d5d\",\n borderRadius: \"8px\",\n boxShadow: \"0 0 80px 10px #666\",\n width: \"auto\",\n fontFamily: \"sans-serif\",\n },\n Input: {\n height: \"35px\",\n width: \"17em\",\n borderColor: \"#ccf4\",\n outline: \"none\",\n fontSize: \"17pt\",\n padding: \"8px\"\n \n }\n};\n","import { Styles } from './Styles';\nimport { ComponentChildren, h } from 'preact';\n\nexport function Dialog({ children, className }: { children?: ComponentChildren, className?: string }) {\n return (\n <div className={className}>\n <div style={Styles.Darken} />\n <div style={Styles.DialogOuter}>\n <div style={Styles.DialogInner}>{children}</div>\n </div>\n </div>\n );\n}\n","import{options as n}from\"preact\";var t,r,u,i,o=0,c=[],f=[],e=n.__b,a=n.__r,v=n.diffed,l=n.__c,m=n.unmount;function d(t,u){n.__h&&n.__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 h(u,i){var o=d(t++,3);!n.__s&&w(o.__H,i)&&(o.__=u,o.i=i,r.__H.__h.push(o))}function s(u,i){var o=d(t++,4);!n.__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 A(n,t,r){o=6,s(function(){return\"function\"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(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 T(n,t){return o=8,F(function(){return n},t)}function q(n){var u=r.context[n.__c],i=d(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function x(t,r){n.useDebugValue&&n.useDebugValue(r?r(t):t)}function V(n){var u=d(t++,10),i=p();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n){u.__&&u.__(n),i[1](n)}),[i[0],function(){i[1](void 0)}]}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=[],n.__e(r,t.__v)}}n.__b=function(n){r=null,e&&e(n)},n.__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},n.diffed=function(t){v&&v(t);var o=t.__c;o&&o.__H&&(o.__H.__h.length&&(1!==c.push(o)&&i===n.requestAnimationFrame||((i=n.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},n.__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=[],n.__e(u,t.__v)}}),l&&l(t,r)},n.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&&n.__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}export{p as useState,y as useReducer,h as useEffect,s as useLayoutEffect,_ as useRef,A as useImperativeHandle,F as useMemo,T as useCallback,q as useContext,x as useDebugValue,V as useErrorBoundary};\n//# sourceMappingURL=hooks.module.js.map\n","import { Dialog } from './Dialog';\nimport { Styles } from './Styles';\nimport { h, Fragment } from 'preact';\nimport { useLayoutEffect, useRef, useState } from 'preact/hooks';\nimport { DXCUserInteraction } from '../types/DXCUserInteraction';\nimport { resolveText } from '../helpers/resolveText';\nimport { DXCInputField } from '../types/DXCInputField';\n\nconst OTP_LENGTH = 8;\n\nexport function LoginDialog({\n title,\n type,\n alerts,\n fields,\n submitLabel,\n cancelLabel,\n onCancel,\n onSubmit,\n}: DXCUserInteraction) {\n const [params, setParams] = useState<{ [param: string]: string }>({});\n\n const firstFieldRef = useRef<HTMLInputElement>(null);\n useLayoutEffect(() => firstFieldRef.current?.focus(), []);\n\n return (\n <Dialog className=\"dxc-login-dlg\">\n <>\n <h3 style={Styles.WindowHeader}>{title}</h3>\n {alerts.map((alert) => (\n <p style={Styles.Alert[alert.type]}>{resolveText(alert)}</p>\n ))}\n <form\n onSubmit={(ev) => {\n ev.preventDefault();\n onSubmit(params);\n }}\n >\n {(Object.entries(fields) as [string, DXCInputField][]).map(\n ([fieldName, { type, label, placeholder }], idx) => (\n <label style={Styles.Label} key={idx}>\n {label ? `${label}: ` : ''}\n <input\n ref={idx === 0 ? firstFieldRef : undefined}\n type={type}\n name={fieldName}\n autoComplete=\"on\"\n style={Styles.Input}\n autoFocus\n placeholder={placeholder}\n value={params[fieldName] || ''}\n onInput={(ev) => {\n const value = valueTransformer(type, ev.target?.['value']);\n let updatedParams = {\n ...params,\n [fieldName]: value,\n };\n setParams(updatedParams);\n if (type === 'otp' && value?.trim().length === OTP_LENGTH) {\n // Auto-submit when OTP is filled in.\n onSubmit(updatedParams);\n }\n }}\n />\n </label>\n )\n )}\n </form>\n </>\n <div style={Styles.ButtonsDiv}>\n <>\n <button\n type=\"submit\"\n style={Styles.Button}\n onClick={() => onSubmit(params)}\n >\n {submitLabel}\n </button>\n {cancelLabel && (\n <button style={Styles.Button} onClick={onCancel}>\n {cancelLabel}\n </button>\n )}\n </>\n </div>\n </Dialog>\n );\n}\n\nfunction valueTransformer(type: string, value: string) {\n switch (type) {\n case 'email':\n return value.toLowerCase();\n case 'otp':\n return value.toUpperCase();\n default:\n return value;\n }\n}\n","import { DXCAlert } from \"../types/DXCAlert\";\n\n/** Resolve a message template with parameters.\n * \n * Example:\n * resolveText({\n * message: \"Hello {name}!\",\n * messageCode: \"HELLO\",\n * messageParams: {name: \"David\"}\n * }) => \"Hello David!\"\n * \n * @param message Template message with {vars} in it.\n * @param messageCode Unique code for the message. Can be used for translation.\n * @param messageParams Parameters to be used in the message.\n * @returns A final message where parameters have been replaced with values.\n */\nexport function resolveText({message, messageCode, messageParams}: DXCAlert) {\n return message.replace(/\\{\\w+\\}/ig, n => messageParams[n.substring(1, n.length-1)]);\n}\n","import Dexie from \"dexie\";\nimport \"../extend-dexie-interface\";\nimport { h, Component } from \"preact\";\nimport { from, Subscription } from \"rxjs\";\nimport { LoginDialog } from './LoginDialog';\nimport { DXCUserInteraction } from \"../types/DXCUserInteraction\";\nimport * as preact from \"preact\";\n\nexport interface Props {\n db: Dexie;\n}\n\ninterface State {\n userInteraction: DXCUserInteraction | undefined;\n}\n\nexport default class LoginGui extends Component<Props, State> {\n subscription?: Subscription;\n observer = (userInteraction: DXCUserInteraction | undefined) => this.setState({userInteraction});\n\n constructor(props: Props) {\n super(props);\n this.state = { userInteraction: undefined };\n }\n\n componentDidMount() {\n this.subscription = from(this.props.db.cloud.userInteraction).subscribe(this.observer);\n }\n\n componentWillUnmount() {\n if (this.subscription) {\n this.subscription.unsubscribe();\n delete this.subscription;\n }\n }\n\n render(props: Props, {userInteraction}: State) {\n if (!userInteraction) return null;\n //if (props.db.cloud.userInteraction.observers.length > 1) return null; // Someone else subscribes.\n return <LoginDialog {...userInteraction} />;\n }\n}\n\nexport function setupDefaultGUI(db: Dexie) {\n let closed = false;\n\n const el = document.createElement('div');\n if (document.body) {\n document.body.appendChild(el);\n preact.render(<LoginGui db={db.vip} />, el);\n } else {\n addEventListener('DOMContentLoaded', ()=>{\n if (!closed) {\n document.body.appendChild(el);\n preact.render(<LoginGui db={db.vip} />, el);\n }\n });\n }\n\n return {\n unsubscribe() {\n try { el.remove(); } catch {}\n closed = true;\n },\n get closed() {\n return closed;\n }\n }\n}\n","export function associate<T extends object,M>(factory: (x: T)=>M): (x: T) => M {\n const wm = new WeakMap<T, M>();\n return (x: T) => {\n let rv = wm.get(x);\n if (!rv) {\n rv = factory(x);\n wm.set(x, rv);\n }\n return rv;\n }\n}\n","import Dexie from \"dexie\";\nimport { BehaviorSubject } from \"rxjs\";\nimport { associate } from \"./associate\";\nimport { UNAUTHORIZED_USER } from \"./authentication/UNAUTHORIZED_USER\";\n\nexport const getCurrentUserEmitter = associate((db: Dexie) => new BehaviorSubject(UNAUTHORIZED_USER));\n","import {\n concat,\n from,\n InteropObservable,\n map,\n Observable,\n ObservableInput,\n share,\n timer,\n} from 'rxjs';\nimport { ObservableWithCurrentValue } from './mapValueObservable';\n\nexport function createSharedValueObservable<T>(\n o: ObservableInput<T>,\n defaultValue: T\n): ObservableWithCurrentValue<T> {\n let currentValue = defaultValue;\n let shared = from(o).pipe(\n map((x) => (currentValue = x)),\n share({ resetOnRefCountZero: () => timer(1000) })\n ) as ObservableWithCurrentValue<T>;\n\n const rv = new Observable((observer) => {\n let didEmit = false;\n const subscription = shared.subscribe({\n next(value) {\n didEmit = true;\n observer.next(value);\n },\n error(error) {\n observer.error(error);\n },\n complete() {\n observer.complete();\n }\n });\n if (!didEmit && !subscription.closed) {\n observer.next(currentValue);\n }\n return subscription;\n }) as ObservableWithCurrentValue<T>;\n\n rv.getValue = () => currentValue;\n return rv;\n}\n","import Dexie, { liveQuery } from 'dexie';\nimport { DBRealmRole } from 'dexie-cloud-common';\nimport { associate } from './associate';\nimport { createSharedValueObservable } from './createSharedValueObservable';\n\nexport const getGlobalRolesObservable = associate((db: Dexie) => {\n return createSharedValueObservable(\n liveQuery(() =>\n db.roles\n .where({ realmId: 'rlm-public' })\n .toArray()\n .then((roles) => {\n const rv: { [roleName: string]: DBRealmRole } = {};\n for (const role of roles\n .slice()\n .sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0))) {\n rv[role.name] = role;\n }\n return rv;\n })\n ),\n {}\n );\n});\n","import Dexie, { liveQuery } from 'dexie';\nimport { DBRealm, DBRealmMember } from 'dexie-cloud-common';\nimport { concat, Observable, timer } from 'rxjs';\nimport { share, switchMap } from 'rxjs/operators';\nimport { associate } from './associate';\nimport { createSharedValueObservable } from './createSharedValueObservable';\nimport { getCurrentUserEmitter } from './currentUserEmitter';\n\nexport type InternalAccessControlData = {\n readonly selfMembers: DBRealmMember[];\n readonly realms: DBRealm[];\n readonly userId: string;\n};\n\nexport const getInternalAccessControlObservable = associate((db: Dexie) => {\n return createSharedValueObservable(\n getCurrentUserEmitter(db._novip).pipe(\n switchMap((currentUser) =>\n liveQuery(() =>\n db.transaction('r', 'realms', 'members', () =>\n Promise.all([\n db.members.where({ userId: currentUser.userId }).toArray(),\n db.realms.toArray(),\n currentUser.userId!,\n ] as const).then(([selfMembers, realms, userId]) => {\n //console.debug(`PERMS: Result from liveQUery():`, JSON.stringify({selfMembers, realms, userId}, null, 2))\n return { selfMembers, realms, userId };\n })\n )\n )\n )\n ), {\n selfMembers: [],\n realms: [],\n get userId() {\n return db.cloud.currentUserId;\n },\n }\n );\n /* let refCount = 0;\n return new Observable(observer => {\n const subscription = o.subscribe(observer);\n console.debug ('PERMS subscribe', ++refCount);\n return {\n unsubscribe() {\n console.debug ('PERMS unsubscribe', --refCount);\n subscription.unsubscribe();\n }\n }\n })*/\n});\n","// TODO: Move to dexie-cloud-common\n\nimport { DBPermissionSet } from 'dexie-cloud-common';\n\nexport function mergePermissions(\n ...permissions: DBPermissionSet[]\n): DBPermissionSet {\n if (permissions.length === 0) return {};\n const reduced = permissions.reduce((result, next) => {\n const ret = { ...result } as DBPermissionSet;\n for (const [verb, rights] of Object.entries(next) as [\n keyof DBPermissionSet,\n DBPermissionSet[keyof DBPermissionSet]\n ][]) {\n if (verb in ret && ret[verb]) {\n if (ret[verb] === '*') continue;\n if (rights === '*') {\n ret[verb] = '*';\n } else if (Array.isArray(rights) && Array.isArray(ret[verb])) {\n // Both are arrays (verb is 'add' or 'manage')\n const r = ret as { [v in typeof verb]?: string[] };\n const retVerb = r[verb]!; // \"!\" because Array.isArray(ret[verb])\n r[verb] = [...new Set([...retVerb, ...rights])];\n } else if (\n typeof rights === 'object' &&\n rights &&\n typeof ret[verb] === 'object'\n ) {\n // Both are objects (verb is 'update')\n const mergedRights = ret[verb] as {\n [tableName: string]: '*' | string[];\n }; // because we've checked that typeof ret[verb] === 'object' and earlier that not ret[verb] === '*'.\n for (const [tableName, tableRights] of Object.entries(rights) as [\n string,\n string[] | '*'\n ][]) {\n if (mergedRights[tableName] === '*') continue;\n if (tableRights === '*') {\n mergedRights[tableName] = '*';\n } else if (\n Array.isArray(mergedRights[tableName]) &&\n Array.isArray(tableRights)\n ) {\n mergedRights[tableName] = [\n ...new Set([...mergedRights[tableName], ...tableRights]),\n ];\n }\n }\n }\n } else {\n /* This compiles without type assertions. Keeping the comment to\n explain why we do tsignore on the next statement.\n if (verb === \"add\") {\n ret[verb] = next[verb];\n } else if (verb === \"update\") {\n ret[verb] = next[verb];\n } else if (verb === \"manage\") {\n ret[verb] = next[verb];\n } else {\n ret[verb] = next[verb];\n }\n */\n //@ts-ignore\n ret[verb] = next[verb];\n }\n }\n return ret;\n });\n return reduced;\n}\n","import Dexie from 'dexie';\nimport { DBPermissionSet, DBRealm, DBRealmMember } from 'dexie-cloud-common';\nimport { combineLatest, Observable } from 'rxjs';\nimport { map, startWith, tap } from 'rxjs/operators';\nimport { associate } from './associate';\nimport { UNAUTHORIZED_USER } from './authentication/UNAUTHORIZED_USER';\nimport { createSharedValueObservable } from './createSharedValueObservable';\nimport { getGlobalRolesObservable } from './getGlobalRolesObservable';\nimport { getInternalAccessControlObservable } from './getInternalAccessControlObservable';\nimport { flatten } from './helpers/flatten';\nimport { mapValueObservable } from './mapValueObservable';\nimport { mergePermissions } from './mergePermissions';\n\nexport type PermissionsLookup = {\n [realmId: string]: DBRealm & { permissions: DBPermissionSet };\n};\n\nexport type PermissionsLookupObservable = Observable<PermissionsLookup> & {\n getValue(): PermissionsLookup;\n};\n\nexport const getPermissionsLookupObservable = associate((db: Dexie) => {\n const o = createSharedValueObservable(\n combineLatest([\n getInternalAccessControlObservable(db._novip),\n getGlobalRolesObservable(db._novip),\n ]).pipe(\n map(([{ selfMembers, realms, userId }, globalRoles]) => ({\n selfMembers,\n realms,\n userId,\n globalRoles,\n }))\n ),\n {\n selfMembers: [],\n realms: [],\n userId: UNAUTHORIZED_USER.userId!,\n globalRoles: {},\n }\n );\n\n return mapValueObservable(\n o,\n ({ selfMembers, realms, userId, globalRoles }) => {\n const rv = realms\n .map((realm) => {\n const selfRealmMembers = selfMembers.filter(\n (m) => m.realmId === realm.realmId\n );\n const directPermissionSets = selfRealmMembers\n .map((m) => m.permissions!)\n .filter((p) => p);\n const rolePermissionSets = flatten(\n selfRealmMembers.map((m) => m.roles!).filter((roleName) => roleName)\n )\n .map((role) => globalRoles[role]!)\n .filter((role) => role)\n .map((role) => role.permissions);\n\n return {\n ...realm,\n permissions:\n realm.owner === userId\n ? ({ manage: '*' } as DBPermissionSet)\n : mergePermissions(\n ...directPermissionSets,\n ...rolePermissionSets\n ),\n };\n })\n .reduce((p, c) => ({ ...p, [c.realmId]: c }), {\n [userId!]: {\n realmId: userId,\n owner: userId,\n name: userId,\n permissions: { manage: '*' },\n } as DBRealm & { permissions: DBPermissionSet },\n });\n return rv;\n }\n );\n});\n","import { map, Observable } from 'rxjs';\n\nexport interface ObservableWithCurrentValue<T> extends Observable<T> {\n getValue(): T;\n}\n\nexport function mapValueObservable<T, R>(\n o: ObservableWithCurrentValue<T>,\n mapper: (x: T) => R\n): ObservableWithCurrentValue<R> {\n let currentValue: R | undefined;\n const rv = o.pipe(\n map((x) => (currentValue = mapper(x)))\n ) as ObservableWithCurrentValue<R>;\n rv.getValue = () =>\n currentValue !== undefined\n ? currentValue\n : (currentValue = mapper(o.getValue()));\n return rv;\n}\n","import { KeyPaths } from 'dexie';\nimport { DBPermissionSet } from 'dexie-cloud-common';\n\ntype TableName<T> = T extends {table: ()=>infer TABLE} ? TABLE extends string ? TABLE : string : string;\n\nexport class PermissionChecker<T, TableNames extends string = TableName<T>> {\n private permissions: DBPermissionSet;\n private tableName: TableNames;\n private isOwner: boolean;\n\n constructor(\n permissions: DBPermissionSet,\n tableName: TableNames,\n isOwner: boolean\n ) {\n this.permissions = permissions || {};\n this.tableName = tableName;\n this.isOwner = isOwner;\n }\n\n add(...tableNames: TableNames[]): boolean {\n // If user can manage the whole realm, return true.\n if (this.permissions.manage === '*') return true;\n // If user can manage given table in realm, return true\n if (this.permissions.manage?.includes(this.tableName)) return true;\n // If user can add any type, return true\n if (this.permissions.add === '*') return true;\n // If user can add objects into given table names in the realm, return true\n if (\n tableNames.every((tableName) => this.permissions.add?.includes(tableName))\n ) {\n return true;\n }\n return false;\n }\n\n update(...props: KeyPaths<T>[]): boolean {\n // If user is owner of this object, or if user can manage the whole realm, return true.\n if (this.isOwner || this.permissions.manage === '*') return true;\n // If user can manage given table in realm, return true\n if (this.permissions.manage?.includes(this.tableName)) return true;\n // If user can update any prop in any table in this realm, return true unless\n // it regards to ownership change:\n if (this.permissions.update === '*') {\n // @ts-ignore\n return props.every((prop) => prop !== 'owner');\n }\n const tablePermissions = this.permissions.update?.[this.tableName];\n // If user can update any prop in table and realm, return true unless\n // accessing special props owner or realmId\n if (tablePermissions === '*')\n return props.every((prop) => prop !== 'owner');\n\n // Explicitely listed properties to allow updates on:\n return props.every((prop) =>\n tablePermissions?.some(\n (permittedProp) =>\n permittedProp === prop || (permittedProp === '*' && prop !== 'owner')\n )\n );\n }\n\n delete(): boolean {\n // If user is owner of this object, or if user can manage the whole realm, return true.\n if (this.isOwner || this.permissions.manage === '*') return true;\n // If user can manage given table in realm, return true\n if (this.permissions.manage?.includes(this.tableName)) return true;\n return false;\n }\n}\n","import { Dexie, liveQuery } from 'dexie';\nimport { DBRealmMember } from 'dexie-cloud-common';\nimport { combineLatest } from 'rxjs';\nimport { map, switchMap } from 'rxjs/operators';\nimport { associate } from './associate';\nimport { createSharedValueObservable } from './createSharedValueObservable';\nimport { getCurrentUserEmitter } from './currentUserEmitter';\nimport { getInternalAccessControlObservable } from './getInternalAccessControlObservable';\nimport { getPermissionsLookupObservable } from './getPermissionsLookupObservable';\nimport { Invite } from './Invite';\nimport { mapValueObservable } from './mapValueObservable';\n\nexport const getInvitesObservable = associate((db: Dexie) => {\n const membersByEmail = getCurrentUserEmitter(db._novip).pipe(\n switchMap((currentUser) =>\n liveQuery(() =>\n db.members.where({ email: currentUser.email || '' }).toArray()\n )\n )\n );\n const permissions = getPermissionsLookupObservable(db._novip);\n const accessControl = getInternalAccessControlObservable(db._novip);\n return createSharedValueObservable(\n combineLatest([membersByEmail, accessControl, permissions]).pipe(\n map(([membersByEmail, accessControl, realmLookup]) => {\n const reducer = (\n result: { [id: string]: Invite },\n m: DBRealmMember\n ) => ({ ...result, [m.id!]: { ...m, realm: realmLookup[m.realmId] } });\n const emailMembersById = membersByEmail.reduce(reducer, {});\n const membersById = accessControl.selfMembers.reduce(\n reducer,\n emailMembersById\n );\n return Object.values(membersById)\n .filter((invite: DBRealmMember) => !invite.accepted)\n .map(\n (invite: DBRealmMember) =>\n ({\n ...invite,\n async accept() {\n await db.members.update(invite.id!, { accepted: new Date() });\n },\n async reject() {\n await db.members.update(invite.id!, { rejected: new Date() });\n },\n } satisfies Invite)\n );\n })\n ),\n []\n );\n});\n","import { cmp, Table } from 'dexie';\nimport type { DexieCloudDB } from '../db/DexieCloudDB';\nimport { getAwarenessLibrary, awarenessWeakMap } from './awareness';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport * as Y from 'yjs';\nimport { combineLatest, startWith } from 'rxjs';\nimport { YDocumentOpen } from 'dexie-cloud-common';\nimport { isEagerSyncDisabled } from '../isEagerSyncDisabled';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { getOpenDocSignal } from './reopenDocSignal';\nimport { DexieYProvider, DexieYDocMeta } from 'y-dexie';\n\nexport function createYHandler(db: DexieCloudDB) {\n return (provider: import('y-dexie').DexieYProvider) => {\n const doc = provider.doc;\n if (!doc) {\n throw new Error(\n 'Internal error: DexieYProvider.createYHandler called without a doc. This is unexpected.'\n );\n }\n const { parentTable } = doc.meta || ({} as DexieYDocMeta);\n if (!db.cloud.schema?.[parentTable].markedForSync) {\n return; // The table that holds the doc is not marked for sync - leave it to dexie. No syncing, no awareness.\n }\n let awareness: import('y-protocols/awareness').Awareness;\n Object.defineProperty(provider, 'awareness', {\n get() {\n if (awareness) return awareness;\n awareness = createAwareness(db, doc, provider);\n awarenessWeakMap.set(doc, awareness);\n return awareness;\n },\n });\n };\n}\n\nfunction createAwareness(\n db: DexieCloudDB,\n doc: Y.Doc,\n provider: DexieYProvider\n) {\n const { parentTable, parentId, parentProp, updatesTable } =\n doc.meta as DexieYDocMeta;\n const awap = getAwarenessLibrary(db);\n const awareness = new awap.Awareness(doc);\n const reopenDocSignal = getOpenDocSignal(doc);\n\n awareness.on('update', ({ added, updated, removed }, origin: any) => {\n // Send the update\n const changedClients = added.concat(updated).concat(removed);\n const user = db.cloud.currentUser.value;\n if (origin !== 'server' && user.isLoggedIn && !isEagerSyncDisabled(db)) {\n const update = awap.encodeAwarenessUpdate(awareness!, changedClients);\n db.messageProducer.next({\n type: 'aware',\n table: parentTable,\n prop: parentProp,\n k: doc.meta.parentId,\n u: update,\n });\n if (provider.destroyed) {\n // We're called from awareness.on('destroy') that did\n // removeAwarenessStates.\n // It's time to also send the doc-close message that dexie-cloud understands\n // and uses to stop subscribing for updates and awareness updates and brings\n // down the cached information in memory on the WS connection for this.\n db.messageProducer.next({\n type: 'doc-close',\n table: parentTable,\n prop: parentProp,\n k: doc.meta.parentId,\n });\n }\n }\n });\n awareness.on('destroy', () => {\n // Signal to server that this provider is destroyed (the update event will be triggered, which\n // in turn will trigger db.messageProducer that will send the message to the server if WS is connected)\n awap.removeAwarenessStates(\n awareness!,\n [doc.clientID],\n 'provider destroyed'\n );\n });\n\n // Open the document on the server\n (async () => {\n if (provider.destroyed) return;\n let connected = false;\n let currentFlowId = 1;\n const subscription = combineLatest([\n db.cloud.webSocketStatus, // Wake up when webSocket status changes\n reopenDocSignal.pipe(startWith(null)), // Wake up when reopenDocSignal emits\n ]).subscribe(([wsStatus]) => {\n if (provider.destroyed) return;\n // Keep \"connected\" state in a variable so we can check it after async operations\n connected = wsStatus === 'connected';\n\n // We are or got connected. Open the document on the server.\n const user = db.cloud.currentUser.value;\n if (\n wsStatus === 'connected' &&\n user.isLoggedIn &&\n !isEagerSyncDisabled(db)\n ) {\n ++currentFlowId;\n openDocumentOnServer().catch((error) => {\n console.warn(`Error catched in createYHandler.ts: ${error}`);\n });\n }\n });\n // Wait until WebSocket is connected\n provider.addCleanupHandler(subscription);\n\n /** Sends an 'doc-open' message to server whenever websocket becomes\n * connected, or if it is already connected.\n * The flow is aborted in case websocket is disconnected while querying\n * information required to compute the state vector. Flow is also\n * aborted in case document or provider has been destroyed during\n * the async parts of the task.\n *\n * The state vector is only computed from the updates that have occured\n * after the last full sync - which could very often be zero - in which\n * case no state vector is sent (then the server already knows us by\n * revision)\n *\n * When server gets the doc-open message, it will authorize us for\n * whether we are allowed to read / write to this document, and then\n * keep the cached information in memory on the WS connection for this\n * particular document, as well as subscribe to updates and awareness updates\n * from other clients on the document.\n */\n async function openDocumentOnServer() {\n const myFlow = currentFlowId; // So we can abort when a new flow is started\n const yTbl = db.table(updatesTable);\n const syncStateTbl = db.$syncState as Table<\n PersistedSyncState,\n 'syncState'\n >;\n const [receivedUntil, yServerRev] = await db.transaction(\n 'r',\n syncStateTbl,\n yTbl,\n async () => {\n const syncState = await yTbl.get(DEXIE_CLOUD_SYNCER_ID);\n const persistedSyncState = await syncStateTbl.get('syncState');\n return [\n syncState?.receivedUntil || 0,\n persistedSyncState?.yServerRevision ||\n persistedSyncState?.serverRevision,\n ];\n }\n );\n\n // After every await, check if we still should be working on this task.\n if (provider.destroyed || currentFlowId !== myFlow || !connected) return;\n\n const docOpenMsg: YDocumentOpen = {\n type: 'doc-open',\n table: parentTable,\n prop: parentProp,\n k: parentId,\n serverRev: yServerRev,\n };\n const serverUpdatesSinceLastSync = await yTbl\n .where('i')\n .between(receivedUntil, Infinity, false)\n .filter(\n (update) =>\n cmp(update.k, parentId) === 0 && // Only updates for this document\n ((update.f || 0) & 1) === 0 // Don't include local changes\n )\n .toArray();\n // After every await, check if we still should be working on this task.\n if (provider.destroyed || currentFlowId !== myFlow || !connected) return;\n\n if (serverUpdatesSinceLastSync.length > 0) {\n const mergedUpdate = Y.mergeUpdatesV2(\n serverUpdatesSinceLastSync.map((update) => update.u)\n );\n const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);\n docOpenMsg.sv = stateVector;\n }\n db.messageProducer.next(docOpenMsg);\n }\n })();\n return awareness;\n}\n","import Dexie, { liveQuery, Subscription, Table } from 'dexie';\nimport {\n DBPermissionSet,\n DBRealmMember,\n getDbNameFromDbUrl,\n} from 'dexie-cloud-common';\nimport { BehaviorSubject, combineLatest, firstValueFrom, from, fromEvent, Subject } from 'rxjs';\nimport { filter, map, skip, startWith, switchMap, take } from 'rxjs/operators';\nimport { login } from './authentication/login';\nimport { UNAUTHORIZED_USER } from './authentication/UNAUTHORIZED_USER';\nimport { DexieCloudDB } from './db/DexieCloudDB';\nimport { PersistedSyncState } from './db/entities/PersistedSyncState';\nimport { DexieCloudOptions } from './DexieCloudOptions';\nimport { DISABLE_SERVICEWORKER_STRATEGY } from './DISABLE_SERVICEWORKER_STRATEGY';\nimport './extend-dexie-interface';\nimport { DexieCloudSyncOptions } from './DexieCloudSyncOptions';\nimport { IS_SERVICE_WORKER } from './helpers/IS_SERVICE_WORKER';\nimport { throwVersionIncrementNeeded } from './helpers/throwVersionIncrementNeeded';\nimport { createIdGenerationMiddleware } from './middlewares/createIdGenerationMiddleware';\nimport { createImplicitPropSetterMiddleware } from './middlewares/createImplicitPropSetterMiddleware';\nimport { createMutationTrackingMiddleware } from './middlewares/createMutationTrackingMiddleware';\n//import { dexieCloudSyncProtocol } from \"./dexieCloudSyncProtocol\";\nimport { overrideParseStoresSpec } from './overrideParseStoresSpec';\nimport { performInitialSync } from './performInitialSync';\nimport { connectWebSocket } from './sync/connectWebSocket';\nimport { isSyncNeeded } from './sync/isSyncNeeded';\nimport { LocalSyncWorker } from './sync/LocalSyncWorker';\nimport {\n registerPeriodicSyncEvent,\n registerSyncEvent,\n} from './sync/registerSyncEvent';\nimport { triggerSync } from './sync/triggerSync';\nimport { DXCUserInteraction } from './types/DXCUserInteraction';\nimport { SyncState } from './types/SyncState';\nimport { updateSchemaFromOptions } from './updateSchemaFromOptions';\nimport { verifySchema } from './verifySchema';\nimport { setupDefaultGUI } from './default-ui';\nimport { DXCWebSocketStatus } from './DXCWebSocketStatus';\nimport { computeSyncState } from './computeSyncState';\nimport { generateKey } from './middleware-helpers/idGenerationHelpers';\nimport { permissions } from './permissions';\nimport { getCurrentUserEmitter } from './currentUserEmitter';\nimport { NewIdOptions } from './types/NewIdOptions';\nimport { getInvitesObservable } from './getInvitesObservable';\nimport { getGlobalRolesObservable } from './getGlobalRolesObservable';\nimport { UserLogin } from './db/entities/UserLogin';\nimport { InvalidLicenseError } from './InvalidLicenseError';\nimport { logout, _logout } from './authentication/logout';\nimport { loadAccessToken } from './authentication/authenticate';\nimport { isEagerSyncDisabled } from './isEagerSyncDisabled';\nimport { createYHandler } from \"./yjs/createYHandler\";\nimport { DexieYProvider } from 'y-dexie';\nexport { DexieCloudTable } from './DexieCloudTable';\nexport * from './getTiedRealmId';\nexport {\n DBRealm,\n DBRealmMember,\n DBRealmRole,\n DBSyncedObject,\n DBPermissionSet,\n} from 'dexie-cloud-common';\nexport { resolveText } from './helpers/resolveText';\nexport { Invite } from './Invite';\nexport type { UserLogin, DXCWebSocketStatus, SyncState };\nexport type { DexieCloudSyncOptions };\nexport type { DexieCloudOptions, PeriodicSyncOptions } from './DexieCloudOptions';\nexport * from './types/DXCAlert';\nexport * from './types/DXCInputField';\nexport * from './types/DXCUserInteraction';\nexport { defineYDocTrigger } from './define-ydoc-trigger';\n\nconst DEFAULT_OPTIONS: Partial<DexieCloudOptions> = {\n nameSuffix: true,\n};\n\nexport function dexieCloud(dexie: Dexie) {\n const origIdbName = dexie.name;\n //\n //\n //\n const currentUserEmitter = getCurrentUserEmitter(dexie);\n const subscriptions: Subscription[] = [];\n let configuredProgramatically = false;\n\n // local sync worker - used when there's no service worker.\n let localSyncWorker: { start: () => void; stop: () => void } | null = null;\n dexie.on(\n 'ready',\n async (dexie: Dexie) => {\n try {\n await onDbReady(dexie);\n } catch (error) {\n console.error(error);\n // Make sure to succeed with database open even if network is down.\n }\n },\n true // true = sticky\n );\n\n /** Void starting subscribers after a close has happened. */\n let closed = false;\n function throwIfClosed() {\n if (closed) throw new Dexie.DatabaseClosedError();\n }\n\n dexie.once('close', () => {\n subscriptions.forEach((subscription) => subscription.unsubscribe());\n subscriptions.splice(0, subscriptions.length);\n closed = true;\n localSyncWorker && localSyncWorker.stop();\n localSyncWorker = null;\n currentUserEmitter.next(UNAUTHORIZED_USER);\n });\n\n const syncComplete = new Subject<void>();\n\n dexie.cloud = {\n // @ts-ignore\n version: __VERSION__,\n options: { ...DEFAULT_OPTIONS } as DexieCloudOptions,\n schema: null,\n get currentUserId() {\n return currentUserEmitter.value.userId || UNAUTHORIZED_USER.userId!;\n },\n currentUser: currentUserEmitter,\n syncState: new BehaviorSubject<SyncState>({\n phase: 'initial',\n status: 'not-started',\n }),\n\n events: {\n syncComplete,\n },\n\n persistedSyncState: new BehaviorSubject<PersistedSyncState | undefined>(\n undefined\n ),\n userInteraction: new BehaviorSubject<DXCUserInteraction | undefined>(\n undefined\n ),\n webSocketStatus: new BehaviorSubject<DXCWebSocketStatus>('not-started'),\n async login(hint) {\n const db = DexieCloudDB(dexie);\n await db.cloud.sync();\n await login(db, hint);\n },\n invites: getInvitesObservable(dexie),\n roles: getGlobalRolesObservable(dexie),\n configure(options: DexieCloudOptions) {\n options = dexie.cloud.options = { ...dexie.cloud.options, ...options };\n configuredProgramatically = true;\n if (options.databaseUrl && options.nameSuffix) {\n // @ts-ignore\n dexie.name = `${origIdbName}-${getDbNameFromDbUrl(\n options.databaseUrl\n )}`;\n DexieCloudDB(dexie).reconfigure(); // Update observable from new dexie.name\n }\n updateSchemaFromOptions(dexie.cloud.schema, dexie.cloud.options);\n },\n async logout({ force } = {}) {\n force\n ? await _logout(DexieCloudDB(dexie), { deleteUnsyncedData: true })\n : await logout(DexieCloudDB(dexie));\n },\n async sync(\n { wait, purpose }: DexieCloudSyncOptions = { wait: true, purpose: 'push' }\n ) {\n if (wait === undefined) wait = true;\n const db = DexieCloudDB(dexie);\n const licenseStatus = db.cloud.currentUser.value.license?.status || 'ok';\n if (licenseStatus !== 'ok') {\n // Refresh access token to check for updated license\n await loadAccessToken(db);\n }\n if (purpose === 'pull') {\n const syncState = db.cloud.persistedSyncState.value;\n triggerSync(db, purpose);\n if (wait) {\n const newSyncState = await firstValueFrom(\n db.cloud.persistedSyncState.pipe(\n filter(\n (newSyncState) =>\n newSyncState?.timestamp != null &&\n (!syncState || newSyncState.timestamp > syncState.timestamp!)\n )\n )\n );\n if (newSyncState?.error) {\n throw new Error(`Sync error: ` + newSyncState.error);\n }\n }\n } else if (await isSyncNeeded(db)) {\n const syncState = db.cloud.persistedSyncState.value;\n triggerSync(db, purpose);\n if (wait) {\n console.debug('db.cloud.login() is waiting for sync completion...');\n await firstValueFrom(\n from(\n liveQuery(async () => {\n const syncNeeded = await isSyncNeeded(db);\n const newSyncState = await db.getPersistedSyncState();\n if (\n newSyncState?.timestamp !== syncState?.timestamp &&\n newSyncState?.error\n )\n throw new Error(`Sync error: ` + newSyncState.error);\n return syncNeeded;\n })\n ).pipe(filter((isNeeded) => !isNeeded))\n );\n console.debug(\n 'Done waiting for sync completion because we have nothing to push anymore'\n );\n }\n }\n },\n permissions(\n obj: { owner: string; realmId: string; table?: () => string },\n tableName?: string\n ) {\n return permissions(dexie._novip, obj, tableName);\n },\n };\n\n dexie.Version.prototype['_parseStoresSpec'] = Dexie.override(\n dexie.Version.prototype['_parseStoresSpec'],\n (origFunc) => overrideParseStoresSpec(origFunc, dexie)\n );\n\n dexie.Table.prototype.newId = function (\n this: Table<any>,\n { colocateWith }: NewIdOptions = {}\n ) {\n const shardKey =\n colocateWith && colocateWith.substr(colocateWith.length - 3);\n return generateKey(dexie.cloud.schema![this.name].idPrefix || '', shardKey);\n };\n\n dexie.Table.prototype.idPrefix = function (this: Table<any>) {\n return this.db.cloud.schema?.[this.name]?.idPrefix || '';\n };\n\n dexie.use(\n createMutationTrackingMiddleware({\n currentUserObservable: dexie.cloud.currentUser,\n db: DexieCloudDB(dexie),\n })\n );\n dexie.use(createImplicitPropSetterMiddleware(DexieCloudDB(dexie)));\n dexie.use(createIdGenerationMiddleware(DexieCloudDB(dexie)));\n\n async function onDbReady(dexie: Dexie) {\n closed = false; // As Dexie calls us, we are not closed anymore. Maybe reopened? Remember db.ready event is registered with sticky flag!\n const db = DexieCloudDB(dexie);\n // Setup default GUI:\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (!db.cloud.options?.customLoginGui) {\n subscriptions.push(setupDefaultGUI(dexie));\n }\n }\n if (!db.cloud.isServiceWorkerDB) {\n subscriptions.push(computeSyncState(db).subscribe(dexie.cloud.syncState));\n }\n\n // Forward db.syncCompleteEvent to be publicly consumable via db.cloud.events.syncComplete:\n subscriptions.push(db.syncCompleteEvent.subscribe(syncComplete));\n\n //verifyConfig(db.cloud.options); Not needed (yet at least!)\n // Verify the user has allowed version increment.\n if (!db.tables.every((table) => table.core)) {\n throwVersionIncrementNeeded();\n }\n const swRegistrations =\n 'serviceWorker' in navigator\n ? await navigator.serviceWorker.getRegistrations()\n : [];\n\n const [initiallySynced, lastSyncedRealms] = await db.transaction(\n 'rw',\n db.$syncState,\n async () => {\n const { options, schema } = db.cloud;\n const [persistedOptions, persistedSchema, persistedSyncState] =\n await Promise.all([\n db.getOptions(),\n db.getSchema(),\n db.getPersistedSyncState(),\n ]);\n if (!configuredProgramatically) {\n // Options not specified programatically (use case for SW!)\n // Take persisted options:\n db.cloud.options = persistedOptions || null;\n } else if (\n !persistedOptions ||\n JSON.stringify(persistedOptions) !== JSON.stringify(options)\n ) {\n // Update persisted options:\n if (!options) throw new Error(`Internal error`); // options cannot be null if configuredProgramatically is set.\n const newPersistedOptions: DexieCloudOptions = {\n ...options,\n };\n delete newPersistedOptions.fetchTokens;\n delete newPersistedOptions.awarenessProtocol;\n await db.$syncState.put(newPersistedOptions, 'options');\n }\n if (\n db.cloud.options?.tryUseServiceWorker &&\n 'serviceWorker' in navigator &&\n swRegistrations.length > 0 &&\n !DISABLE_SERVICEWORKER_STRATEGY\n ) {\n // * Configured for using service worker if available.\n // * Browser supports service workers\n // * There are at least one service worker registration\n console.debug('Dexie Cloud Addon: Using service worker');\n db.cloud.usingServiceWorker = true;\n } else {\n // Not configured for using service worker or no service worker\n // registration exists. Don't rely on service worker to do any job.\n // Use LocalSyncWorker instead.\n if (\n db.cloud.options?.tryUseServiceWorker &&\n !db.cloud.isServiceWorkerDB\n ) {\n console.debug(\n 'dexie-cloud-addon: Not using service worker.',\n swRegistrations.length === 0\n ? 'No SW registrations found.'\n : 'serviceWorker' in navigator && DISABLE_SERVICEWORKER_STRATEGY\n ? 'Avoiding SW background sync and SW periodic bg sync for this browser due to browser bugs.'\n : 'navigator.serviceWorker not present'\n );\n }\n db.cloud.usingServiceWorker = false;\n }\n updateSchemaFromOptions(schema, db.cloud.options);\n updateSchemaFromOptions(persistedSchema, db.cloud.options);\n if (!schema) {\n // Database opened dynamically (use case for SW!)\n // Take persisted schema:\n db.cloud.schema = persistedSchema || null;\n } else if (\n !persistedSchema ||\n JSON.stringify(persistedSchema) !== JSON.stringify(schema)\n ) {\n // Update persisted schema (but don't overwrite table prefixes)\n const newPersistedSchema = persistedSchema || {};\n for (const [table, tblSchema] of Object.entries(schema)) {\n const newTblSchema = newPersistedSchema[table];\n if (!newTblSchema) {\n newPersistedSchema[table] = { ...tblSchema };\n } else {\n newTblSchema.markedForSync = tblSchema.markedForSync;\n tblSchema.deleted = newTblSchema.deleted;\n newTblSchema.generatedGlobalId = tblSchema.generatedGlobalId;\n }\n }\n await db.$syncState.put(newPersistedSchema, 'schema');\n\n // Make sure persisted table prefixes are being used instead of computed ones:\n // Let's assign all props as the newPersistedSchems should be what we should be working with.\n Object.assign(schema, newPersistedSchema);\n }\n return [persistedSyncState?.initiallySynced, persistedSyncState?.realms];\n }\n );\n\n if (initiallySynced) {\n db.setInitiallySynced(true);\n }\n\n verifySchema(db);\n\n // Manage CurrentUser observable:\n throwIfClosed();\n if (!db.cloud.isServiceWorkerDB) {\n subscriptions.push(\n liveQuery(() => db.getCurrentUser()).subscribe(currentUserEmitter)\n );\n // Manage PersistendSyncState observable:\n subscriptions.push(\n liveQuery(() => db.getPersistedSyncState()).subscribe(\n db.cloud.persistedSyncState\n )\n );\n // Wait till currentUser and persistedSyncState gets populated\n // with things from the database and not just the default values.\n // This is so that when db.open() completes, user should be safe\n // to subscribe to these observables and get actual data.\n await firstValueFrom(combineLatest([\n currentUserEmitter.pipe(skip(1), take(1)),\n db.cloud.persistedSyncState.pipe(skip(1), take(1)),\n ]));\n\n const yHandler = createYHandler(db);\n DexieYProvider.on.new.subscribe(yHandler);\n db.dx.once('close', () => {\n DexieYProvider.on.new.unsubscribe(yHandler);\n });\n }\n\n // HERE: If requireAuth, do athentication now.\n let changedUser = false;\n const user = await db.getCurrentUser();\n const requireAuth = db.cloud.options?.requireAuth;\n if (requireAuth) {\n if (db.cloud.isServiceWorkerDB) {\n // If this is a service worker DB, we can't do authentication here,\n // we just wait until the application has done it.\n console.debug('Dexie Cloud Service worker. Waiting for application to authenticate.');\n await firstValueFrom(currentUserEmitter.pipe(filter((user) => !!user.isLoggedIn), take(1)));\n console.debug('Dexie Cloud Service worker. Application has authenticated.');\n } else {\n if (typeof requireAuth === 'object') {\n // requireAuth contains login hints. Check if we already fulfil it:\n if (\n !user.isLoggedIn ||\n (requireAuth.userId && user.userId !== requireAuth.userId) ||\n (requireAuth.email && user.email !== requireAuth.email)\n ) {\n // If not, login the configured user:\n changedUser = await login(db, requireAuth);\n }\n } else if (!user.isLoggedIn) {\n // requireAuth is true and user is not logged in\n changedUser = await login(db);\n }\n }\n }\n if (user.isLoggedIn && (!lastSyncedRealms || !lastSyncedRealms.includes(user.userId!))) {\n // User has been logged in but this is not reflected in the sync state.\n // This can happen if page is reloaded after login but before the sync call following\n // the login was complete.\n // The user is to be viewed as changed becuase current syncState does not reflect the presence\n // of the logged-in user.\n changedUser = true; // Set changedUser to true to trigger a pull-sync later down.\n }\n\n if (localSyncWorker) localSyncWorker.stop();\n localSyncWorker = null;\n throwIfClosed();\n\n const doInitialSync = db.cloud.options?.databaseUrl && (!initiallySynced || changedUser);\n if (doInitialSync) {\n // Do the initial sync directly in the browser thread no matter if we are using service worker or not.\n await performInitialSync(db, db.cloud.options!, db.cloud.schema!);\n db.setInitiallySynced(true);\n }\n\n throwIfClosed();\n if (db.cloud.usingServiceWorker && db.cloud.options?.databaseUrl) {\n if (!doInitialSync) {\n registerSyncEvent(db, 'push').catch(() => {});\n }\n registerPeriodicSyncEvent(db).catch(() => {});\n } else if (\n db.cloud.options?.databaseUrl &&\n db.cloud.schema &&\n !db.cloud.isServiceWorkerDB\n ) {\n // There's no SW. Start SyncWorker instead.\n localSyncWorker = LocalSyncWorker(db, db.cloud.options, db.cloud.schema!);\n localSyncWorker.start();\n if (!doInitialSync) {\n triggerSync(db, 'push');\n }\n }\n\n // Listen to online event and do sync.\n throwIfClosed();\n if (!db.cloud.isServiceWorkerDB) {\n subscriptions.push(\n fromEvent(self, 'online').subscribe(() => {\n console.debug('online!');\n db.syncStateChangedEvent.next({\n phase: 'not-in-sync',\n });\n if (!isEagerSyncDisabled(db)) {\n triggerSync(db, 'push');\n }\n }),\n fromEvent(self, 'offline').subscribe(() => {\n console.debug('offline!');\n db.syncStateChangedEvent.next({\n phase: 'offline',\n });\n })\n );\n }\n\n // Connect WebSocket unless we are in a service worker or websocket is disabled.\n if (\n db.cloud.options?.databaseUrl &&\n !db.cloud.options?.disableWebSocket &&\n !IS_SERVICE_WORKER\n ) {\n subscriptions.push(connectWebSocket(db));\n }\n }\n}\n\n// @ts-ignore\ndexieCloud.version = __VERSION__;\n\nDexie.Cloud = dexieCloud;\n\nexport default dexieCloud;\n","import { combineLatest, Observable, of } from 'rxjs';\nimport { debounceTime, map, startWith, switchMap } from 'rxjs/operators';\nimport { getCurrentUserEmitter } from './currentUserEmitter';\nimport { DexieCloudDB, SyncStateChangedEventData } from './db/DexieCloudDB';\nimport { isOnline } from './sync/isOnline';\nimport { SyncState } from './types/SyncState';\nimport { userIsActive, userIsReallyActive } from './userIsActive';\n\nexport function computeSyncState(db: DexieCloudDB): Observable<SyncState> {\n let _prevStatus = db.cloud.webSocketStatus.value;\n const lazyWebSocketStatus = db.cloud.webSocketStatus.pipe(\n switchMap((status) => {\n const prevStatus = _prevStatus;\n _prevStatus = status;\n const rv = of(status);\n switch (status) {\n // A normal scenario is that the WS reconnects and falls shortly in disconnected-->connection-->connected.\n // Don't distract user with this unless these things take more time than normal:\n\n // Only show disconnected if disconnected more than 500ms, or if we can\n // see that the user is indeed not active.\n case 'disconnected':\n return userIsActive.value ? rv.pipe(debounceTime(500)) : rv;\n\n // Only show connecting if previous state was 'not-started' or 'error', or if\n // the time it takes to connect goes beyond 4 seconds.\n case 'connecting':\n return prevStatus === 'not-started' || prevStatus === 'error'\n ? rv\n : rv.pipe(debounceTime(4000));\n default:\n return rv;\n }\n })\n );\n return combineLatest([\n lazyWebSocketStatus,\n db.syncStateChangedEvent.pipe(startWith({ phase: 'initial' } as SyncStateChangedEventData)),\n getCurrentUserEmitter(db.dx._novip),\n userIsReallyActive\n ]).pipe(\n map(([status, syncState, user, userIsActive]) => {\n if (user.license?.status && user.license.status !== 'ok') {\n return {\n phase: 'offline',\n status: 'offline',\n license: user.license.status\n } satisfies SyncState;\n }\n let { phase, error, progress } = syncState;\n let adjustedStatus = status;\n if (phase === 'error') {\n // Let users only rely on the status property to display an icon.\n // If there's an error in the sync phase, let it show on that\n // status icon also.\n adjustedStatus = 'error';\n }\n if (status === 'not-started') {\n // If websocket isn't yet connected becase we're doing\n // the startup sync, let the icon show the symbol for connecting.\n if (phase === 'pushing' || phase === 'pulling') {\n adjustedStatus = 'connecting';\n }\n } \n const previousPhase = db.cloud.syncState.value.phase;\n //const previousStatus = db.cloud.syncState.value.status;\n if (previousPhase === 'error' && (syncState.phase === 'pushing' || syncState.phase === 'pulling')) {\n // We were in an errored state but is now doing sync. Show \"connecting\" icon.\n adjustedStatus = 'connecting';\n }\n /*if (syncState.phase === 'in-sync' && adjustedStatus === 'connecting') {\n adjustedStatus = 'connected';\n }*/\n \n if (!userIsActive) {\n adjustedStatus = 'disconnected';\n }\n\n const retState: SyncState = {\n phase,\n error,\n progress,\n status: isOnline ? adjustedStatus : 'offline',\n license: 'ok'\n };\n\n return retState;\n })\n );\n}\n","import Dexie from \"dexie\";\n\nexport function throwVersionIncrementNeeded() {\n throw new Dexie.SchemaError(\n `Version increment needed to allow dexie-cloud change tracking`\n );\n}\n","import Dexie from \"dexie\";\nimport { DexieCloudDB } from \"./db/DexieCloudDB\";\n\nexport function verifySchema(db: DexieCloudDB) {\n for (const table of db.tables) {\n if (db.cloud.schema?.[table.name]?.markedForSync) {\n if (table.schema.primKey.auto) {\n throw new Dexie.SchemaError(\n `Table ${table.name} is both autoIncremented and synced. ` +\n `Use db.cloud.configure({unsyncedTables: [${JSON.stringify(\n table.name\n )}]}) to blacklist it from sync`\n );\n }\n if (!table.schema.primKey.keyPath) {\n throw new Dexie.SchemaError(\n `Table ${table.name} cannot be both synced and outbound. ` +\n `Use db.cloud.configure({unsyncedTables: [${JSON.stringify(\n table.name\n )}]}) to blacklist it from sync`\n );\n }\n }\n }\n}\n","import { DexieCloudSchema } from 'dexie-cloud-common';\nimport { DexieCloudDB } from './db/DexieCloudDB';\nimport { DexieCloudOptions } from './DexieCloudOptions';\nimport { CURRENT_SYNC_WORKER, sync } from './sync/sync';\nimport { performGuardedJob } from './sync/performGuardedJob';\n\nexport async function performInitialSync(\n db: DexieCloudDB,\n cloudOptions: DexieCloudOptions,\n cloudSchema: DexieCloudSchema\n) {\n console.debug('Performing initial sync'); \n await performGuardedJob(\n db,\n CURRENT_SYNC_WORKER,\n () => sync(db, cloudOptions, cloudSchema, { isInitialSync: true })\n );\n console.debug('Done initial sync');\n}\n","import Dexie, { DBCore, DBCoreTransaction, Middleware } from 'dexie';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { TXExpandos } from '../types/TXExpandos';\nimport { UNAUTHORIZED_USER } from '../authentication/UNAUTHORIZED_USER';\n\nexport function createImplicitPropSetterMiddleware(\n db: DexieCloudDB\n): Middleware<DBCore> {\n return {\n stack: 'dbcore',\n name: 'implicitPropSetterMiddleware',\n level: 1,\n create: (core) => {\n return {\n ...core,\n table: (tableName) => {\n const table = core.table(tableName);\n return {\n ...table,\n mutate: (req) => {\n const trans = req.trans as DBCoreTransaction & TXExpandos & IDBTransaction;\n\n if (trans.disableChangeTracking) {\n return table.mutate(req);\n }\n\n const currentUserId = trans.currentUser?.userId ?? UNAUTHORIZED_USER.userId;\n\n if (db.cloud.schema?.[tableName]?.markedForSync) {\n if (req.type === 'add' || req.type === 'put') {\n if (tableName === 'members') {\n for (const member of req.values) {\n if (typeof member.email === 'string') {\n // Resolve https://github.com/dexie/dexie-cloud/issues/4\n // If adding a member, make sure email is lowercase and trimmed.\n // This is to avoid issues where the APP does not check this\n // and just allows the user to enter an email address that might\n // have been pasted by the user from a source that had a trailing\n // space or was in uppercase. We want to avoid that the user\n // creates a new member with a different email address than\n // the one he/she intended to create.\n member.email = member.email.trim().toLowerCase();\n }\n }\n }\n // No matter if user is logged in or not, make sure \"owner\" and \"realmId\" props are set properly.\n // If not logged in, this will be changed upon syncification of the tables (next sync after login),\n // however, application code will work better if we can always rely on that the properties realmId\n // and owner are set. Application code may index them and query them based on db.cloud.currentUserId,\n // and expect them to be returned. That scenario must work also when db.cloud.currentUserId === 'unauthorized'.\n for (const obj of req.values) {\n if (!obj.owner) {\n obj.owner = currentUserId;\n }\n if (!obj.realmId) {\n obj.realmId = currentUserId;\n }\n const key = table.schema.primaryKey.extractKey?.(obj);\n if (typeof key === 'string' && key[0] === '#') {\n // Add $ts prop for put operations and\n // disable update operations as well as consistent\n // modify operations. Reason: Server may not have\n // the object. Object should be created on server only\n // if is being updated. An update operation won't create it\n // so we must delete req.changeSpec to degrade operation to\n // an upsert operation with timestamp so that it will be created.\n // We must also degrade from consistent modify operations for the\n // same reason - object might be there on server. Must but put up instead.\n\n // FUTURE: This clumpsy behavior of private IDs could be refined later.\n // Suggestion is to in future, treat private IDs as we treat all objects \n // and sync operations normally. Only that deletions should become soft deletes\n // for them - so that server knows when a private ID has been deleted on server\n // not accept insert/upserts on them.\n if (req.type === 'put') {\n const now = Date.now();\n delete req.criteria;\n delete req.changeSpec;\n delete req.updates;\n obj.$ts = Date.now();\n }\n }\n }\n }\n }\n return table.mutate(req);\n },\n };\n },\n };\n },\n };\n}\n","export function getDbNameFromDbUrl(dbUrl) {\n const url = new URL(dbUrl);\n return url.pathname === \"/\"\n ? url.hostname.split('.')[0]\n : url.pathname.split('/')[1];\n}\n","import Dexie, { liveQuery } from 'dexie';\nimport { DBRealmMember } from 'dexie-cloud-common';\nimport { from, Observable } from 'rxjs';\nimport { map, startWith } from 'rxjs/operators';\nimport { mergePermissions } from './mergePermissions';\nimport {\n getPermissionsLookupObservable,\n PermissionsLookup,\n} from './getPermissionsLookupObservable';\nimport { PermissionChecker } from './PermissionChecker';\nimport './extend-dexie-interface';\n\nexport function permissions(\n dexie: Dexie,\n obj: { owner?: string; realmId?: string; table?: () => string },\n tableName?: string\n): Observable<PermissionChecker<any>> {\n if (!obj)\n throw new TypeError(\n `Cannot check permissions of undefined or null. A Dexie Cloud object with realmId and owner expected.`\n );\n const { owner, realmId } = obj;\n if (!tableName) {\n if (typeof obj.table !== 'function') {\n throw new TypeError(\n `Missing 'table' argument to permissions and table could not be extracted from entity`\n );\n }\n tableName = obj.table();\n }\n const source = getPermissionsLookupObservable(dexie);\n const mapper = (permissionsLookup: PermissionsLookup) => {\n // If realmId is undefined, it can be due to that the object is not yet syncified - it exists\n // locally only as the user might not yet be authenticated. This is ok and we shall treat it\n // as if the realmId is dexie.cloud.currentUserId (which is \"unauthorized\" by the way)\n const realm = permissionsLookup[realmId || dexie.cloud.currentUserId];\n if (!realm)\n return new PermissionChecker(\n {},\n tableName!,\n !owner || owner === dexie.cloud.currentUserId\n );\n return new PermissionChecker(\n realm.permissions,\n tableName!,\n realmId === undefined || realmId === dexie.cloud.currentUserId || owner === dexie.cloud.currentUserId\n );\n };\n const o = source.pipe(map(mapper)) as Observable<PermissionChecker<any>> & {\n getValue: () => PermissionChecker<any>;\n };\n o.getValue = () => mapper(source.getValue());\n return o;\n}\n","import Dexie from 'dexie';\nimport { DexieCloudDB } from './db/DexieCloudDB';\nimport dexieCloud from './dexie-cloud-client';\nimport { DISABLE_SERVICEWORKER_STRATEGY } from './DISABLE_SERVICEWORKER_STRATEGY';\nimport { isSafari, safariVersion } from './isSafari';\nimport { syncIfPossible } from './sync/syncIfPossible';\nimport { SWMessageEvent } from './types/SWMessageEvent';\nimport { SyncEvent } from './types/SWSyncEvent';\n\n// In case the SW lives for a while, let it reuse already opened connections:\nconst managedDBs = new Map<string, DexieCloudDB>();\n\nfunction getDbNameFromTag(tag: string) {\n return tag.startsWith('dexie-cloud:') && tag.split(':')[1];\n}\n\nconst syncDBSemaphore = new Map<string, Promise<void>>();\n\nfunction syncDB(dbName: string, purpose: 'push' | 'pull') {\n // We're taking hight for being double-signalled both\n // via message event and sync event.\n // Which one comes first doesnt matter, just\n // that we return the existing promise if there is\n // an ongoing sync.\n let promise = syncDBSemaphore.get(dbName + '/' + purpose);\n if (!promise) {\n promise = _syncDB(dbName, purpose)\n .then(() => {\n // When legacy enough across browsers, use .finally() instead of then() and catch():\n syncDBSemaphore.delete(dbName + '/' + purpose);\n })\n .catch((error) => {\n syncDBSemaphore.delete(dbName + '/' + purpose);\n return Promise.reject(error);\n });\n syncDBSemaphore.set(dbName + '/' + purpose, promise!);\n }\n return promise!;\n\n async function _syncDB(dbName: string, purpose: 'push' | 'pull') {\n let db = managedDBs.get(dbName);\n\n if (!db) {\n console.debug('Dexie Cloud SW: Creating new Dexie instance for', dbName);\n const dexie = new Dexie(dbName, { addons: [dexieCloud] });\n db = DexieCloudDB(dexie);\n db.cloud.isServiceWorkerDB = true;\n dexie.on('versionchange', stopManagingDB);\n await db.dx.open(); // Makes sure db.cloud.options and db.cloud.schema are read from db,\n if (managedDBs.get(dbName)) {\n // Avoid race conditions.\n db.close();\n return await _syncDB(dbName, purpose);\n }\n managedDBs.set(dbName, db);\n }\n if (!db.cloud.options?.databaseUrl) {\n console.error(`Dexie Cloud: No databaseUrl configured`);\n return; // Nothing to sync.\n }\n if (!db.cloud.schema) {\n console.error(`Dexie Cloud: No schema persisted`);\n return; // Nothing to sync.\n }\n\n function stopManagingDB() {\n db!.dx.on.versionchange.unsubscribe(stopManagingDB);\n if (managedDBs.get(db!.name) === db) {\n // Avoid race conditions.\n managedDBs.delete(db!.name);\n }\n console.debug(`Dexie Cloud SW: Closing Dexie instance for ${dbName}`);\n db!.dx.close();\n return false;\n }\n\n try {\n console.debug('Dexie Cloud SW: Syncing');\n await syncIfPossible(db, db.cloud.options, db.cloud.schema, {\n retryImmediatelyOnFetchError: true,\n purpose,\n });\n console.debug('Dexie Cloud SW: Done Syncing');\n } catch (e) {\n console.error(`Dexie Cloud SW Error`, e);\n // Error occured. Stop managing this DB until we wake up again by a sync event,\n // which will open a new Dexie and start trying to sync it.\n stopManagingDB();\n if (e.name !== Dexie.errnames.NoSuchDatabase) {\n // Unless the error was that DB doesn't exist, rethrow to trigger sync retry.\n throw e; // Throw e to make syncEvent.waitUntil() receive a rejected promis, so it will retry.\n }\n }\n }\n}\n\n// Avoid taking care of events if browser bugs out by using dexie cloud from a service worker.\nif (!DISABLE_SERVICEWORKER_STRATEGY) {\n self.addEventListener('sync', (event: SyncEvent) => {\n console.debug('SW \"sync\" Event', event.tag);\n const dbName = getDbNameFromTag(event.tag);\n if (dbName) {\n event.waitUntil(syncDB(dbName, \"push\")); // The purpose of sync events are \"push\"\n }\n });\n\n self.addEventListener('periodicsync', (event: SyncEvent) => {\n console.debug('SW \"periodicsync\" Event', event.tag);\n const dbName = getDbNameFromTag(event.tag);\n if (dbName) {\n event.waitUntil(syncDB(dbName, \"pull\")); // The purpose of periodic sync events are \"pull\"\n }\n });\n\n self.addEventListener('message', (event: SWMessageEvent) => {\n console.debug('SW \"message\" Event', event.data);\n if (event.data.type === 'dexie-cloud-sync') {\n const { dbName } = event.data;\n // Mimic background sync behavior - retry in X minutes on failure.\n // But lesser timeout and more number of times.\n const syncAndRetry = (num = 1) => {\n return syncDB(dbName, event.data.purpose || \"pull\").catch(async (e) => {\n if (num === 3) throw e;\n await sleep(60_000); // 1 minute\n syncAndRetry(num + 1);\n });\n };\n if ('waitUntil' in event) {\n event.waitUntil(syncAndRetry().catch(error => console.error(error)));\n } else {\n syncAndRetry().catch(error => console.error(error));\n }\n }\n });\n}\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"names":["__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","__values","o","s","Symbol","iterator","m","i","call","length","TypeError","__await","v","this","__asyncGenerator","asyncIterator","g","q","verb","n","a","b","push","resume","r","fulfill","settle","f","shift","__asyncValues","d","UNAUTHORIZED_USER","userId","name","claims","sub","lastLogin","Date","Object","freeze","_a","swHolder","swContainer","self","document","navigator","serviceWorker","ready","registration","addEventListener","ev","_b","data","type","startsWith","matchAll","includeUncontrolled","forEach","client","id","source","postMessage","SWBroadcastChannel","constructor","subscribe","listener","forwarder","message","removeEventListener","active","events","globalThis","Map","BroadcastedAndLocalEvent","Observable","bc","BroadcastChannel","super","subscriber","onCustomEvent","detail","onMessageEvent","unsubscribe","has","get","set","addListener","err","listeners","idx","indexOf","splice","removeListener","dispatch","CustomEvent","hasComplainedAboutSyncEvent","registerSyncEvent","db","purpose","sw","sync","register","Error","dbName","triggerSync","cloud","usingServiceWorker","localSyncEvent","hasArrayBufferFromBase64","Uint8Array","hasArrayBufferToBase64","prototype","b64decode","Buffer","base64","from","fromBase64","binary_string","atob","len","bytes","charCodeAt","b64encode","ArrayBuffer","isView","buffer","byteOffset","byteLength","toString","toBase64","u8a","strs","l","chunk","subarray","String","fromCharCode","btoa","join","computeRealmSetHash","realms","inviteRealms","JSON","stringify","map","realmId","accepted","sort","byteArray","TextEncoder","encode","digestBytes","crypto","subtle","digest","getSyncableTables","entries","schema","filter","markedForSync","tbl","tables","cloudTableSchema","getMutationTable","tableName","getTableFromMutationTable","mutationTable","exec","concat","flatten","listClientChanges","mutationTables_1","db_1","arguments","mutationTables","since","limit","Infinity","sorted","all","lastRevision","query","where","above","toArray","mut","table","txid","opNo","ts","currentEntry","currentTxid","muts","randomString","buf","getRandomValues","Math","floor","random","_hasOwn","hasOwnProperty","setByKeyPath","obj","keyPath","undefined","isFrozen","assert","period","currentKeyPath","substr","remainingKeyPath","Array","isArray","isNaN","parseInt","innerObj","prop","hasOwn","randomFill","bind","simpleRandomFill","alloc","isValidSyncableID","some","key","every","isValidSyncableIDPart","part","applyOperation","target","op","keys","val","values","changeSpec","changeSpecs","entry","propPath","assign","mod","applyOperations","ops","consumeChunkedBinaryStream","e_1","_c","state","sizeBuf","sizeBufPos","bufs","source_1_1","_d","source_1","dw","DataView","pos","slice","getUint32","concats","reduce","p","c","e_1_1","error","return","TokenErrorResponseError","title","messageCode","messageParams","interactWithUser","userInteraction","req","interactionProps","submitLabel","cancelLabel","onSubmit","res","onCancel","Dexie","AbortError","alertUser","alerts","fields","promptForEmail","emailHint","email","test","placeholder","promptForOTP","alert","otp","label","loadAccessToken","currentUser","getCurrentUser","accessToken","accessTokenExpiration","refreshToken","refreshTokenExpiration","getTime","now","license","status","refreshedLogin","refreshAccessToken","options","databaseUrl","update","authenticate","url","context","fetchToken","hints","location","protocol","privateKey","publicKey","generateKey","modulusLength","publicExponent","hash","nonExportablePrivateKey","publicKeyPEM","keydata","keydataB64","str","finalString","substring","formatAsPem","spkiToPEM","exportKey","response2","public_key","userType","evalDaysLeft","userValidUntil","validUntil","onLine","debug","hostname","origin","catch","userAuthenticate","login","time_stamp","signing_algorithm","binarySignature","sign","signature","tokenRequest","grant_type","refresh_token","scopes","fetch","body","method","headers","mode","response","json","toStr","ObjectDef","replace","dollarKeys","clone","k","TypesonSimplified","typeDefsInputs","typeDefs","protoMap","WeakMap","alternateChannel","space","realVal","typeDef","proto","getPrototypeOf","toStringTag","find","typeName","function","getTypeDef","parse","tson","stack","$t","revive","top","pop","deletes","mods","BisonBinaryTypes","Blob","blob","altChannel","mimeType","numberDef","number","num","Number","bigIntDef","bigint","BigInt","DateDef","date","toISOString","NaN","SetDef","Set","MapDef","_global","global","TypedArraysDefs","specs","_","TypedArray","b64LexEncode","encoded","ENCODE_TABLE","b64ToLex","b64LexDecode","b64Lex","base64lex","DECODE_TABLE","lexToB64","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","Q","R","S","T","U","V","W","X","Y","Z","h","j","t","u","w","x","y","z","ArrayBufferDef","ab","ba","FakeBlob","readBlobSync","XMLHttpRequest","overrideMimeType","open","URL","createObjectURL","send","responseText","string2ArrayBuffer","array","BlobDef","builtin","bigintDef","readBlobBinary","reader","FileReader","onabort","onerror","onload","readAsArrayBuffer","undefinedDef","FileDef","File","file","lastModified","hasBigIntSupport","FakeBigInt","fakeBigInt","defs","PropModification","propModification","propModSpec","getOwnPropertySymbols","propertyIsEnumerable","__rest","TSON","tsonBuiltinDefs","BISON","toBinary","lenBuf","setUint32","size","binaries","binData","arrayBuffers","view","fromBinary","readAsText","readBlob","Bison","HttpError","statusText","httpStatus","encodeIdsForServer","changes","rv","change","tableSchema","primaryKey","changeClone","mutIndex","rewriteValues","outbound","keyIndex","cloneChange","mutClone","rewrittenKey","isLoggedIn","syncRatelimitDelays","checkSyncRateLimitDelay","delatMilliseconds","setTimeout","syncWithServer","syncState","baseRevs","clientIdentity","Accept","updatedUser","Authorization","syncRequest","dbID","remoteDbId","lastPull","serverRevision","yServerRevision","dx","core","dxcv","version","syncStateChangedEvent","phase","credentials","remaining","reset","limitNum","remainingNum","max","willResetInSeconds","delay","ceil","delete","updateSyncRateLimitDelays","ok","text","throwIfCancelled","cancelToken","cancelled","isOnline","updateBaseRevs","latestRevisions","serverRev","$baseRevs","bulkPut","clientRev","noneOf","getLatestRevisionsPerTable","clientChangeSet","lastRevisions","lastRev","rev","bulkUpdate","objs","bulkGet","resultKeys","resultObjs","primKey","cmp","applyServerChanges","_allTables","keyDecoder","endsWith","currentUserId","bulkAdd","anyOf","modify","bulkDelete","DEXIE_CLOUD_SYNCER_ID","listUpdatesSince","yTable","sinceIncluding","between","getUpdatesTable","ydocProp","utbl","yProps","updatesTable","applyYServerMessages","yMessages","receivedUntils","resyncNeeded","updateRow","add","transaction","tx","syncer","put","unsentFrom","idbtrans","_rejecting_y_ypdate","aboveOrEqual","activeDoc","DexieYProvider","getDocCache","destroy","doc","isSynced","emit","yServerRev","BINSTREAM_TYPE_REALMID","BINSTREAM_TYPE_TABLE_AND_PROP","BINSTREAM_TYPE_DOCUMENT","downloadYDocsFromServer","databaseUrl_1","yDownloadedRealms","user","downloadedRealms","async","stages","result_1_1","result_1","asyncIterablePipeline","getReader","read","releaseLock","getFetchResponseBodyGenerator","chunks","currentRealmId","currentTable","currentProp","docsToInsert","storeCollectedDocs","completedRealm","lastDoc","$syncState","chunks_1_1","chunks_1","decoder","Decoder","hasContent","readUint8","readVarString","readAny","readVarUint8Array","DexieError","CURRENT_SYNC_WORKER","syncOptions","_sync","justCheckIfNeeded","retryImmediatelyOnFetchError","timestamp","options_1","schema_1","isInitialSync","tablesToSync","persistedSyncState","getPersistedSyncState","readyForSyncification","tablesToSyncify","syncedTables","includes","getTablesToSyncify","doSyncify","disableChangeTracking","disableAccessControl","syncifiedTables","alreadySyncedRealms","ignoredRealms","toCollection","member","realm","owner","modifyLocalObjectsWithNewUserId","lastUpdateIds","br","clientChanges","yResults","yProp","receivedUntil","unsyncedFrom","min","updates","perDoc","isLocal","docKey","mergedUpdate","mergeUpdatesV2","stateVector","encodeStateVectorFromUpdateV2","sv","listYClientMessagesAndStateVector","syncificationInserts","extractKey","dexieCloudTableSchema","generatedGlobalId","item","idPrefix","unsyncedObjects","listSyncifiedChanges","pushSyncIsNeeded","newSyncState","addedClientChanges","mutTable","ch","latestRev","belowOrEqual","reverse","offset","clear","deletedRealms","rejectedRealms","previousRealmSet","previousInviteRealmSet","updatedRealmSet","updatedTotalRealmSet","realmsToDelete","indexes","deleteObjectsFromRemovedRealms","dbId","initiallySynced","filteredChanges","filterServerChangesThroughAddedClientChanges","lastUpdateIdsBeforeSync","receivedUntilsAfterSync","mergedSpec","lastUpdateId","allYTables","_dbSchema","tblSchema","flat","mergedEntry","_e","primaryKeys","updateYSyncStates","usingYProps","serverSupportsYprops","syncCompleteEvent","serverChanges","localPostChanges","changesToSubtract","mutationSet","targetMut","subtractChanges","inSet","mapEntry","resultEntry","optype","toDBOperationSet","LIMIT_NUM_MESSAGES_PER_TIME","TIME_WINDOW","PAUSE_PERIOD","MessagesFromServerConsumer","queue","readyToServe","BehaviorSubject","event","isWorking","loopDetection","fill","msg","firstValueFrom","pipe","wait","_f","getSchema","baseRev","waitFor","realmSetHash","newRev","consumeQueue","enqueue","wm","DEXIE_CLOUD_SCHEMA","members","roles","$jobs","$logins","static_counter","DexieCloudDB","Subject","close","helperMethods","logins","getOptions","setInitiallySynced","reconfigure","messageConsumer","messageProducer","AuthPersistedContext","userLogin","load","save","waitUntil","predicate","logout","numUnsyncedChanges","_logout","confirmLogout","deleteUnsyncedData","numUnsynced","loggedOut","storeNames","sumUnSynced","count","prodLog","level","args","origUserId","fetchTokens","demo_user","otpId","otp_id","res1","errMsg","tokenRequest2","res2","errorText","otpFetchTokenCallback","existingLogins","setCurrentUser","isFirefox","InstallTrigger","isSafari","userAgent","safariVersion","match","DISABLE_SERVICEWORKER_STRATEGY","IS_SERVICE_WORKER","getEffectiveKeys","consonants","time","prefix","shardKey","timePart","randomPart","createIdGenerationMiddleware","create","mutate","trans","getMany","cache","results","valueClones","colocatedId","deepClone","ConstraintError","generateOrVerifyAtKeys","counter","readLock","fn","readers","writers","numWriters","promise","finally","writeLock","possiblePromises","reason","outstandingTransactions","isEagerSyncDisabled","disableEagerSync","createMutationTrackingMiddleware","currentUserObservable","allTableNames","ordinaryTables","mutTableMap","mutationTableName","opCount","removeTransaction","txComplete","mutationsAdded","mutsTable","openCursor","guardedTable","range","index","mutateAndLog","criteria","unsyncedProps","unsyncedProperties","stripChangeSpec","numFailures","hasFailures","failures","newValue","strippedChangeSpecs","newUpdates","validKeys","RangeSet","anyChangeSpecBecameEmpty","addKey","newKeys","newValues","hasKey","keyPaths","isAdditionalChunk","overrideParseStoresSpec","origFunc","dexie","stores","dbSchema","storesClone","schemaSrc","requestedIndexes","split","spec","trim","builtInIndexes","requestedIndexSet","builtInIndex","cloudSchema","allPrefixes","toLocaleLowerCase","toLowerCase","orig","bits","bitFix","upperFixed","toUpperCase","nextChar","generateTablePrefix","deleted","performGuardedJob","jobName","job","locks","request","userIsActive","userIsReallyActive","switchMap","isActive","of","distinctUntilChanged","visibilityStateIsChanged","fromEvent","documentBecomesHidden","visibilityState","documentBecomesVisible","userDoesSomething","window","merge","tap","USER_INACTIVITY_TIMEOUT","TokenExpiredError","getAwarenessLibrary","awarenessProtocol","MissingAPIError","awarenessWeakMap","getOpenDocSignal","signal","WSObservable","yrev","webSocketStatus","WSConnection","Subscription","teardown","subscriptions","reconnecting","lastUserActivity","connect","disconnect","pinger","clearInterval","ws","reconnect","lastServerActivity","pauseUntil","closed","tokenExpiration","setInterval","wsUrl","searchParams","URLSearchParams","WebSocket","binaryType","onclose","onmessage","readBigUint64","arr","decodeYMessage","awareness","getDocAwareness","applyAwarenessUpdate","everConnected","onopen","encoder","Encoder","writeVarString","writeBigUint64","writeAny","writeVarUint8Array","toUint8Array","encodeYMessage","yTableRecords","yTbl","currentUnsentFrom","liveQuery","addedUpdates","at","mergeMap","messages","createYClientUpdateObservable","InvalidLicenseError","waitAndReconnectWhenUserDoesSomething","ms","isSyncNeeded","ongoingSyncs","syncIfPossible","cloudOptions","ongoing","pull","hasPullTakenPlace","subscription","_syncIfPossible","SECONDS","LocalSyncWorker","localSyncEventSubscription","nextRetryTime","syncStartTime","syncAndRetry","retryNum","pullSignalled","stop","pushSignalled","ongoingSync","retryIn","consumer","start","updateSchemaFromOptions","unsyncedTables","parentNode","removeChild","children","defaultProps","props","ref","__k","__","__b","__e","__d","__c","__h","__v","vnode","base","__r","debounceRendering","__P","__n","ownerSVGElement","appendChild","nextSibling","insertBefore","$","setProperty","style","cssText","setAttribute","removeAttribute","contextType","__E","render","__s","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","componentWillUpdate","componentDidUpdate","getChildContext","getSnapshotBeforeUpdate","diffed","localName","nodeType","createTextNode","createElementNS","createElement","is","childNodes","dangerouslySetInnerHTML","attributes","__html","innerHTML","checked","current","unmount","componentWillUnmount","firstChild","getDerivedStateFromError","setState","componentDidCatch","forceUpdate","Styles","color","Alert","fontWeight","warning","info","Darken","position","left","opacity","backgroundColor","width","height","zIndex","webkitBackdropFilter","backdropFilter","DialogOuter","alignItems","display","justifyContent","DialogInner","padding","marginBottom","maxWidth","maxHeight","overflowY","border","borderRadius","boxShadow","fontFamily","Input","borderColor","outline","fontSize","Dialog","className","__H","__V","__N","requestAnimationFrame","clearTimeout","cancelAnimationFrame","LoginDialog","params","setParams","useState","firstFieldRef","useRef","useLayoutEffect","focus","Fragment","WindowHeader","resolveText","preventDefault","fieldName","Label","autoComplete","autoFocus","onInput","valueTransformer","updatedParams","ButtonsDiv","Button","onClick","LoginGui","Component","observer","associate","factory","getCurrentUserEmitter","createSharedValueObservable","defaultValue","currentValue","shared","share","resetOnRefCountZero","timer","didEmit","complete","getValue","getGlobalRolesObservable","role","sortOrder","getInternalAccessControlObservable","_novip","selfMembers","mergePermissions","permissions","reduced","ret","rights","retVerb","mergedRights","tableRights","getPermissionsLookupObservable","mapper","mapValueObservable","combineLatest","globalRoles","selfRealmMembers","directPermissionSets","rolePermissionSets","roleName","manage","PermissionChecker","isOwner","tableNames","tablePermissions","permittedProp","getInvitesObservable","membersByEmail","accessControl","realmLookup","reducer","emailMembersById","membersById","invite","accept","createYHandler","provider","parentTable","meta","defineProperty","parentId","parentProp","awap","Awareness","reopenDocSignal","on","added","updated","removed","changedClients","encodeAwarenessUpdate","destroyed","removeAwarenessStates","clientID","connected","currentFlowId","startWith","wsStatus","openDocumentOnServer","myFlow","syncStateTbl","docOpenMsg","serverUpdatesSinceLastSync","addCleanupHandler","createAwareness","DEFAULT_OPTIONS","nameSuffix","dexieCloud","origIdbName","currentUserEmitter","configuredProgramatically","localSyncWorker","customLoginGui","el","preact.render","vip","remove","setupDefaultGUI","isServiceWorkerDB","_prevStatus","lazyWebSocketStatus","prevStatus","debounceTime","progress","adjustedStatus","computeSyncState","syncComplete","SchemaError","throwVersionIncrementNeeded","swRegistrations","getRegistrations","lastSyncedRealms","persistedOptions","persistedSchema","newPersistedOptions","tryUseServiceWorker","newPersistedSchema","newTblSchema","auto","verifySchema","throwIfClosed","skip","take","yHandler","new","once","changedUser","requireAuth","doInitialSync","performInitialSync","periodicSync","registerPeriodicSyncEvent","_g","disableWebSocket","readyForChangesMessage","isReady","createObservable","prevUser","prevHash","currUser","currHash","catchError","throwError","connectWebSocket","onDbReady","DatabaseClosedError","hint","invites","configure","dbUrl","pathname","getDbNameFromDbUrl","force","syncNeeded","isNeeded","permissionsLookup","Version","override","Table","newId","colocateWith","use","$ts","Cloud","managedDBs","getDbNameFromTag","tag","syncDBSemaphore","syncDB","_syncDB","addons","stopManagingDB","errnames","NoSuchDatabase","versionchange"],"mappings":"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","x_google_ignoreList":[0,6,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,104,107]}
|
|
1
|
+
{"version":3,"file":"service-worker.min.js","sources":["../../../../node_modules/.pnpm/@rollup+plugin-typescript@11.1.5_rollup@4.1.4_tslib@2.4.0_typescript@5.6.3/node_modules/tslib/tslib.es6.js","../../src/authentication/UNAUTHORIZED_USER.ts","../../src/helpers/SWBroadcastChannel.ts","../../src/helpers/BroadcastedAndLocalEvent.ts","../../src/sync/registerSyncEvent.ts","../../src/sync/triggerSync.ts","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/common/base64.js","../../src/helpers/computeRealmSetHash.ts","../../src/helpers/getSyncableTables.ts","../../src/helpers/getMutationTable.ts","../../src/helpers/getTableFromMutationTable.ts","../../src/helpers/flatten.ts","../../src/sync/listClientChanges.ts","../../src/helpers/randomString.ts","../../../../libs/dexie-cloud-common/dist/utils.js","../../../../libs/dexie-cloud-common/dist/validation/isValidSyncableID.js","../../../../libs/dexie-cloud-common/dist/change-processing/applyOperation.js","../../../../libs/dexie-cloud-common/dist/change-processing/applyOperations.js","../../../../libs/dexie-cloud-common/dist/async-generators/consumeChunkedBinaryStream.js","../../src/authentication/TokenErrorResponseError.ts","../../src/authentication/interactWithUser.ts","../../src/authentication/authenticate.ts","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/TypesonSimplified.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/BisonBinaryTypes.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/number.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/bigint.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/Date.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/Set.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/Map.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/common/_global.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/TypedArray.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/common/b64lex.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/ArrayBuffer.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/FakeBlob.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/readBlobSync.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/string2ArrayBuffer.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/Blob.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/presets/builtin.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/Bison.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/undefined.js","../../../../node_modules/.pnpm/dreambase-library@1.0.26/node_modules/dreambase-library/dist/typeson-simplified/types/File.js","../../src/TSON.ts","../../src/errors/HttpError.ts","../../src/sync/encodeIdsForServer.ts","../../src/sync/ratelimit.ts","../../src/sync/syncWithServer.ts","../../src/helpers/CancelToken.ts","../../src/sync/isOnline.ts","../../src/sync/updateBaseRevs.ts","../../src/sync/getLatestRevisionsPerTable.ts","../../src/helpers/bulkUpdate.ts","../../src/sync/applyServerChanges.ts","../../src/sync/DEXIE_CLOUD_SYNCER_ID.ts","../../src/yjs/listUpdatesSince.ts","../../src/yjs/getUpdatesTable.ts","../../src/yjs/applyYMessages.ts","../../src/yjs/downloadYDocsFromServer.ts","../../../../libs/dexie-cloud-common/dist/async-generators/asyncIterablePipeline.js","../../../../libs/dexie-cloud-common/dist/async-generators/getFetchResponseBodyGenerator.js","../../src/sync/sync.ts","../../src/sync/getTablesToSyncify.ts","../../src/sync/modifyLocalObjectsWithNewUserId.ts","../../src/yjs/listYClientMessagesAndStateVector.ts","../../src/sync/listSyncifiedChanges.ts","../../src/yjs/updateYSyncStates.ts","../../../../libs/dexie-cloud-common/dist/change-processing/subtractChanges.js","../../../../libs/dexie-cloud-common/dist/change-processing/toDBOperationSet.js","../../src/sync/messagesFromServerQueue.ts","../../src/db/DexieCloudDB.ts","../../src/authentication/AuthPersistedContext.ts","../../src/authentication/waitUntil.ts","../../src/authentication/logout.ts","../../src/prodLog.ts","../../src/authentication/login.ts","../../src/authentication/otpFetchTokenCallback.ts","../../src/authentication/setCurrentUser.ts","../../src/isFirefox.ts","../../src/isSafari.ts","../../src/DISABLE_SERVICEWORKER_STRATEGY.ts","../../src/helpers/IS_SERVICE_WORKER.ts","../../src/middleware-helpers/idGenerationHelpers.ts","../../src/middlewares/createIdGenerationMiddleware.ts","../../src/middleware-helpers/guardedTable.ts","../../src/helpers/allSettled.ts","../../src/middlewares/outstandingTransaction.ts","../../src/isEagerSyncDisabled.ts","../../src/middlewares/createMutationTrackingMiddleware.ts","../../src/overrideParseStoresSpec.ts","../../src/sync/performGuardedJob.ts","../../src/userIsActive.ts","../../src/authentication/TokenExpiredError.ts","../../src/yjs/awareness.ts","../../src/yjs/reopenDocSignal.ts","../../src/WSObservable.ts","../../../../libs/dexie-cloud-common/dist/yjs/decoding.js","../../../../libs/dexie-cloud-common/dist/yjs/encoding.js","../../src/yjs/createYClientUpdateObservable.ts","../../src/InvalidLicenseError.ts","../../src/sync/connectWebSocket.ts","../../src/sync/isSyncNeeded.ts","../../src/sync/syncIfPossible.ts","../../src/helpers/date-constants.ts","../../src/sync/LocalSyncWorker.ts","../../src/updateSchemaFromOptions.ts","../../../../node_modules/.pnpm/preact@10.10.6/node_modules/preact/dist/preact.module.js","../../src/default-ui/Styles.ts","../../src/default-ui/Dialog.tsx","../../../../node_modules/.pnpm/preact@10.10.6/node_modules/preact/hooks/dist/hooks.module.js","../../src/default-ui/LoginDialog.tsx","../../src/helpers/resolveText.ts","../../src/default-ui/index.tsx","../../src/associate.ts","../../src/currentUserEmitter.ts","../../src/createSharedValueObservable.ts","../../src/getGlobalRolesObservable.ts","../../src/getInternalAccessControlObservable.ts","../../src/mergePermissions.ts","../../src/getPermissionsLookupObservable.ts","../../src/mapValueObservable.ts","../../src/PermissionChecker.ts","../../src/getInvitesObservable.ts","../../src/yjs/createYHandler.ts","../../src/dexie-cloud-client.ts","../../src/computeSyncState.ts","../../src/helpers/throwVersionIncrementNeeded.ts","../../src/verifySchema.ts","../../src/performInitialSync.ts","../../src/middlewares/createImplicitPropSetterMiddleware.ts","../../../../libs/dexie-cloud-common/dist/getDbNameFromDbUrl.js","../../src/permissions.ts","../../src/service-worker.ts"],"sourcesContent":["/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n var desc = Object.getOwnPropertyDescriptor(m, k);\r\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\r\n desc = { enumerable: true, get: function() { return m[k]; } };\r\n }\r\n Object.defineProperty(o, k2, desc);\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n\r\nexport function __classPrivateFieldIn(state, receiver) {\r\n if (receiver === null || (typeof receiver !== \"object\" && typeof receiver !== \"function\")) throw new TypeError(\"Cannot use 'in' operator on non-object\");\r\n return typeof state === \"function\" ? receiver === state : state.has(receiver);\r\n}\r\n","import { UserLogin } from '../db/entities/UserLogin';\n\nexport const UNAUTHORIZED_USER: UserLogin = {\n userId: \"unauthorized\",\n name: \"Unauthorized\",\n claims: {\n sub: \"unauthorized\",\n },\n lastLogin: new Date(0)\n}\n\ntry {\n Object.freeze(UNAUTHORIZED_USER);\n Object.freeze(UNAUTHORIZED_USER.claims);\n} catch {}\n","const swHolder: { registration?: ServiceWorkerRegistration } = {};\nconst swContainer = typeof self !== 'undefined' && self.document && // self.document is to verify we're not the SW ourself\n typeof navigator !== 'undefined' && navigator.serviceWorker; \nif (swContainer)\n swContainer.ready.then(\n (registration) => (swHolder.registration = registration)\n );\n\nif (typeof self !== 'undefined' && 'clients' in self && !self.document) {\n // We are the service worker. Propagate messages to all our clients.\n addEventListener('message', (ev: any) => {\n if (ev.data?.type?.startsWith('sw-broadcast-')) {\n [...self['clients'].matchAll({ includeUncontrolled: true })].forEach(\n (client) => client.id !== ev.source?.id && client.postMessage(ev.data)\n );\n }\n });\n}\n\n/** This class is a fallback for browsers that lacks BroadcastChannel but have\n * service workers (which is Safari versions 11.1 through 15.3).\n * Safari 15.4 with BroadcastChannel was released on 2022-03-14.\n * We might be able to remove this class in a near future as Safari < 15.4 is\n * already very low in market share as of 2023-03-10.\n */\nexport class SWBroadcastChannel {\n name: string;\n constructor(name: string) {\n this.name = name;\n }\n subscribe(listener: (message: any) => void) {\n if (!swContainer) return () => {};\n const forwarder = (ev: MessageEvent) => {\n if (ev.data?.type === `sw-broadcast-${this.name}`) {\n listener(ev.data.message);\n }\n };\n swContainer.addEventListener('message', forwarder);\n return () => swContainer.removeEventListener('message', forwarder);\n }\n postMessage(message: any) {\n if (typeof self['clients'] === 'object') {\n // We're a service worker. Propagate to our browser clients.\n [...self['clients'].matchAll({ includeUncontrolled: true })].forEach(\n (client) =>\n client.postMessage({\n type: `sw-broadcast-${this.name}`,\n message,\n })\n );\n } else if (swHolder.registration) {\n // We're a client (browser window or other worker)\n // Post to SW so it can repost to all its clients and to itself\n swHolder.registration.active?.postMessage({\n type: `sw-broadcast-${this.name}`,\n message,\n });\n }\n }\n}\n","import { Observable } from \"rxjs\";\nimport { SWBroadcastChannel } from \"./SWBroadcastChannel\";\n\nconst events: Map<string, Array<(ev: CustomEvent)=>void>> =\n globalThis['lbc-events'] || (globalThis['lbc-events'] = new Map<string, Array<(ev: CustomEvent)=>void>>());\n\nfunction addListener(name: string, listener: (ev: CustomEvent)=>void) {\n if (events.has(name)) {\n events.get(name)!.push(listener);\n } else {\n events.set(name, [listener]);\n }\n}\nfunction removeListener(name: string, listener: (ev: CustomEvent)=>void) {\n const listeners = events.get(name);\n if (listeners) {\n const idx = listeners.indexOf(listener);\n if (idx !== -1) {\n listeners.splice(idx, 1);\n }\n }\n}\nfunction dispatch(ev: CustomEvent) {\n const listeners = events.get(ev.type);\n if (listeners) {\n listeners.forEach(listener => {\n try {\n listener(ev);\n } catch {\n }\n });\n }\n}\n\nexport class BroadcastedAndLocalEvent<T> extends Observable<T>{\n name: string;\n bc: BroadcastChannel | SWBroadcastChannel\n\n constructor(name: string) {\n const bc = typeof BroadcastChannel === \"undefined\"\n ? new SWBroadcastChannel(name) : new BroadcastChannel(name);\n super(subscriber => {\n function onCustomEvent(ev: CustomEvent) {\n subscriber.next(ev.detail);\n }\n function onMessageEvent(ev: MessageEvent) {\n console.debug(\"BroadcastedAndLocalEvent: onMessageEvent\", ev);\n subscriber.next(ev.data);\n }\n let unsubscribe: ()=>void;\n //self.addEventListener(`lbc-${name}`, onCustomEvent); // Fails in service workers\n addListener(`lbc-${name}`, onCustomEvent); // Works better in service worker\n\n try { \n if (bc instanceof SWBroadcastChannel) {\n unsubscribe = bc.subscribe(message => subscriber.next(message));\n } else {\n console.debug(\"BroadcastedAndLocalEvent: bc.addEventListener()\", name, \"bc is a\", bc);\n bc.addEventListener(\"message\", onMessageEvent);\n }\n } catch (err) {\n // Service workers might fail to subscribe outside its initial script.\n console.warn('Failed to subscribe to broadcast channel', err);\n }\n return () => {\n //self.removeEventListener(`lbc-${name}`, onCustomEvent);\n removeListener(`lbc-${name}`, onCustomEvent);\n if (bc instanceof SWBroadcastChannel) {\n unsubscribe!();\n } else {\n bc.removeEventListener(\"message\", onMessageEvent);\n }\n }\n });\n this.name = name;\n this.bc = bc;\n }\n\n next(message: T) {\n console.debug(\"BroadcastedAndLocalEvent: bc.postMessage()\", {...message}, \"bc is a\", this.bc);\n this.bc.postMessage(message);\n const ev = new CustomEvent(`lbc-${this.name}`, { detail: message });\n //self.dispatchEvent(ev);\n dispatch(ev);\n }\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\n\n//const hasSW = 'serviceWorker' in navigator;\nlet hasComplainedAboutSyncEvent = false;\n\nexport async function registerSyncEvent(db: DexieCloudDB, purpose: \"push\" | \"pull\") {\n try {\n // Send sync event to SW:\n const sw: ServiceWorkerRegistration & {sync?: any} = await navigator.serviceWorker.ready;\n if (purpose === \"push\" && sw.sync) {\n await sw.sync.register(`dexie-cloud:${db.name}`);\n }\n if (sw.active) {\n // Use postMessage for pull syncs and for browsers not supporting sync event (Firefox, Safari).\n // Also chromium based browsers with sw.sync as a fallback for sleepy sync events not taking action for a while.\n sw.active.postMessage({\n type: 'dexie-cloud-sync',\n dbName: db.name,\n purpose\n });\n } else {\n throw new Error(`Failed to trigger sync - there's no active service worker`);\n }\n return;\n } catch (e) {\n if (!hasComplainedAboutSyncEvent) {\n console.debug(`Dexie Cloud: Could not register sync event`, e);\n hasComplainedAboutSyncEvent = true;\n }\n }\n}\n\nexport async function registerPeriodicSyncEvent(db: DexieCloudDB) {\n try {\n // Register periodicSync event to SW:\n // @ts-ignore\n const { periodicSync } = await navigator.serviceWorker.ready;\n if (periodicSync) {\n try {\n await periodicSync.register(\n `dexie-cloud:${db.name}`,\n db.cloud.options?.periodicSync\n );\n console.debug(\n `Dexie Cloud: Successfully registered periodicsync event for ${db.name}`\n );\n } catch (e) {\n console.debug(`Dexie Cloud: Failed to register periodic sync. Your PWA must be installed to allow background sync.`, e);\n }\n } else {\n console.debug(`Dexie Cloud: periodicSync not supported.`);\n }\n } catch (e) {\n console.debug(\n `Dexie Cloud: Could not register periodicSync for ${db.name}`,\n e\n );\n }\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { registerSyncEvent } from \"./registerSyncEvent\";\n\nexport function triggerSync(db: DexieCloudDB, purpose: \"push\" | \"pull\") {\n if (db.cloud.usingServiceWorker) {\n console.debug('registering sync event');\n registerSyncEvent(db, purpose);\n } else {\n db.localSyncEvent.next({purpose});\n }\n}","const hasArrayBufferFromBase64 = \"fromBase64\" in Uint8Array; // https://github.com/tc39/proposal-arraybuffer-base64;\nconst hasArrayBufferToBase64 = \"toBase64\" in Uint8Array.prototype; // https://github.com/tc39/proposal-arraybuffer-base64;\nexport const b64decode = typeof Buffer !== \"undefined\"\n ? (base64) => Buffer.from(base64, \"base64\") // Node\n : hasArrayBufferFromBase64\n ? // @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64\n (base64) => Uint8Array.fromBase64(base64) // Modern javascript standard\n : (base64) => {\n // Legacy DOM workaround\n const binary_string = atob(base64);\n const len = binary_string.length;\n const bytes = new Uint8Array(len);\n for (var i = 0; i < len; i++) {\n bytes[i] = binary_string.charCodeAt(i);\n }\n return bytes;\n };\nexport const b64encode = typeof Buffer !== \"undefined\"\n ? (b) => {\n // Node\n if (ArrayBuffer.isView(b)) {\n return Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString(\"base64\");\n }\n else {\n return Buffer.from(b).toString(\"base64\");\n }\n }\n : hasArrayBufferToBase64\n ? (b) => {\n // Uint8Array.prototype.toBase64 is available in modern browsers\n const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);\n // @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64\n return u8a.toBase64();\n }\n : (b) => {\n // Legacy DOM workaround\n const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);\n const CHUNK_SIZE = 0x1000;\n const strs = [];\n for (let i = 0, l = u8a.length; i < l; i += CHUNK_SIZE) {\n const chunk = u8a.subarray(i, i + CHUNK_SIZE);\n strs.push(String.fromCharCode.apply(null, chunk));\n }\n return btoa(strs.join(\"\"));\n };\n","import { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { b64encode } from 'dreambase-library/dist/common/base64';\n\nexport async function computeRealmSetHash({\n realms,\n inviteRealms,\n}: PersistedSyncState) {\n const data = JSON.stringify(\n [\n ...realms.map((realmId) => ({ realmId, accepted: true })),\n ...inviteRealms.map((realmId) => ({ realmId, accepted: false })),\n ].sort((a, b) =>\n a.realmId < b.realmId ? -1 : a.realmId > b.realmId ? 1 : 0\n )\n );\n const byteArray = new TextEncoder().encode(data);\n const digestBytes = await crypto.subtle.digest('SHA-1', byteArray);\n const base64 = b64encode(digestBytes);\n return base64;\n}\n","import { IndexableType, Table } from \"dexie\";\nimport { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { EntityCommon } from \"../db/entities/EntityCommon\";\n\nexport function getSyncableTables(db: DexieCloudDB): Table<EntityCommon>[] {\n return Object.entries(db.cloud.schema || {})\n .filter(([, { markedForSync }]) => markedForSync)\n .map(([tbl]) => db.tables.filter(({name}) => name === tbl)[0])\n .filter(cloudTableSchema => cloudTableSchema);\n}\n","\n\nexport function getMutationTable(tableName: string) {\n return `$${tableName}_mutations`;\n}\n","\n\nexport function getTableFromMutationTable(mutationTable: string) {\n const tableName = /^\\$(.*)_mutations$/.exec(mutationTable)?.[1];\n if (!tableName) throw new Error(`Given mutationTable ${mutationTable} is not correct`);\n return tableName;\n}\n","const concat = [].concat;\nexport function flatten<T>(a: (T | T[])[]): T[] {\n return concat.apply([], a);\n}\n","import { Table } from 'dexie';\nimport { getTableFromMutationTable } from '../helpers/getTableFromMutationTable';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { DBOperation, DBOperationsSet } from 'dexie-cloud-common';\nimport { flatten } from '../helpers/flatten';\n\nexport async function listClientChanges(\n mutationTables: Table[],\n db: DexieCloudDB,\n { since = {} as { [table: string]: number }, limit = Infinity } = {}\n): Promise<DBOperationsSet> {\n const allMutsOnTables = await Promise.all(\n mutationTables.map(async (mutationTable) => {\n const tableName = getTableFromMutationTable(mutationTable.name);\n const lastRevision = since[tableName];\n\n let query = lastRevision\n ? mutationTable.where('rev').above(lastRevision)\n : mutationTable;\n\n if (limit < Infinity) query = query.limit(limit);\n\n const muts: DBOperation[] = await query.toArray();\n\n //const objTable = db.table(tableName);\n /*for (const mut of muts) {\n if (mut.type === \"insert\" || mut.type === \"upsert\") {\n mut.values = await objTable.bulkGet(mut.keys);\n }\n }*/\n return muts.map((mut) => ({\n table: tableName,\n mut,\n }));\n })\n );\n\n // Sort by time to get a true order of the operations (between tables)\n const sorted = flatten(allMutsOnTables).sort((a, b) => a.mut.txid === b.mut.txid\n ? a.mut.opNo! - b.mut.opNo! // Within same transaction, sort by opNo\n : a.mut.ts! - b.mut.ts! // Different transactions - sort by timestamp when mutation resolved\n );\n const result: DBOperationsSet = [];\n let currentEntry: {\n table: string;\n muts: DBOperation[];\n } | null = null;\n let currentTxid: string | null = null;\n for (const { table, mut } of sorted) {\n if (\n currentEntry &&\n currentEntry.table === table &&\n currentTxid === mut.txid\n ) {\n currentEntry.muts.push(mut);\n } else {\n currentEntry = {\n table,\n muts: [mut],\n };\n currentTxid = mut.txid!;\n result.push(currentEntry);\n }\n }\n\n // Filter out those tables that doesn't have any mutations:\n return result;\n}\n","export function randomString(bytes: number) {\n const buf = new Uint8Array(bytes);\n if (typeof crypto !== 'undefined') {\n crypto.getRandomValues(buf);\n } else {\n for (let i = 0; i < bytes; i++) buf[i] = Math.floor(Math.random() * 256);\n }\n if (typeof Buffer !== 'undefined' && Buffer.from) {\n return Buffer.from(buf).toString('base64');\n } else if (typeof btoa !== 'undefined') {\n return btoa(String.fromCharCode.apply(null, buf));\n } else {\n throw new Error('No btoa or Buffer available');\n }\n}\n","export function assert(b) {\n if (!b)\n throw new Error('Assertion Failed');\n}\nconst _hasOwn = {}.hasOwnProperty;\nexport function hasOwn(obj, prop) {\n return _hasOwn.call(obj, prop);\n}\nexport function setByKeyPath(obj, keyPath, value) {\n if (!obj || keyPath === undefined)\n return;\n if ('isFrozen' in Object && Object.isFrozen(obj))\n return;\n if (typeof keyPath !== 'string' && 'length' in keyPath) {\n assert(typeof value !== 'string' && 'length' in value);\n for (var i = 0, l = keyPath.length; i < l; ++i) {\n setByKeyPath(obj, keyPath[i], value[i]);\n }\n }\n else {\n var period = keyPath.indexOf('.');\n if (period !== -1) {\n var currentKeyPath = keyPath.substr(0, period);\n var remainingKeyPath = keyPath.substr(period + 1);\n if (remainingKeyPath === '')\n if (value === undefined) {\n if (Array.isArray(obj)) {\n if (!isNaN(parseInt(currentKeyPath)))\n obj.splice(parseInt(currentKeyPath), 1);\n }\n else\n delete obj[currentKeyPath];\n // @ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n }\n else\n obj[currentKeyPath] = value;\n else {\n //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n var innerObj = obj[currentKeyPath];\n //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n if (!innerObj || !hasOwn(obj, currentKeyPath))\n innerObj = (obj[currentKeyPath] = {});\n setByKeyPath(innerObj, remainingKeyPath, value);\n }\n }\n else {\n if (value === undefined) {\n if (Array.isArray(obj) && !isNaN(parseInt(keyPath)))\n // @ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n obj.splice(keyPath, 1);\n //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n else\n delete obj[keyPath];\n //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.\n }\n else\n obj[keyPath] = value;\n }\n }\n}\nexport const randomString = typeof self !== 'undefined' && typeof crypto !== 'undefined' ? (bytes, randomFill = crypto.getRandomValues.bind(crypto)) => {\n // Web\n const buf = new Uint8Array(bytes);\n randomFill(buf);\n return self.btoa(String.fromCharCode.apply(null, buf));\n} : typeof Buffer !== 'undefined' ? (bytes, randomFill = simpleRandomFill) => {\n // Node\n const buf = Buffer.alloc(bytes);\n randomFill(buf);\n return buf.toString(\"base64\");\n} : () => { throw new Error(\"No implementation of randomString was found\"); };\nfunction simpleRandomFill(buf) {\n for (let i = 0; i < buf.length; ++i) {\n buf[i] = Math.floor(Math.random() * 256);\n }\n}\n","const validIDTypes = {\n Uint8Array,\n};\n/** Verifies that given primary key is valid.\n * The reason we narrow validity for valid keys are twofold:\n * 1: Make sure to only support types that can be used as an object index in DBKeyMutationSet.\n * For example, ArrayBuffer cannot be used (gives \"object ArrayBuffer\") but Uint8Array can be\n * used (gives comma-delimited list of included bytes).\n * 2: Avoid using plain numbers and Dates as keys when they are synced, as they are not globally unique.\n * 3: Since we store the key as a VARCHAR server side in current version, try not promote types that stringifies to become very long server side.\n *\n * @param id\n * @returns\n */\nexport function isValidSyncableID(id) {\n if (typeof id === \"string\")\n return true;\n //if (validIDTypes[toStringTag(id)]) return true;\n //if (Array.isArray(id)) return id.every((part) => isValidSyncableID(part));\n if (Array.isArray(id) && id.some(key => isValidSyncableID(key)) && id.every(isValidSyncableIDPart))\n return true;\n return false;\n}\n/** Verifies that given key part is valid.\n * 1: Make sure that arrays of this types are stringified correclty and works with DBKeyMutationSet.\n * For example, ArrayBuffer cannot be used (gives \"object ArrayBuffer\") but Uint8Array can be\n * used (gives comma-delimited list of included bytes).\n * 2: Since we store the key as a VARCHAR server side in current version, try not promote types that stringifies to become very long server side.\n*/\nfunction isValidSyncableIDPart(part) {\n return typeof part === \"string\" || typeof part === \"number\" || Array.isArray(part) && part.every(isValidSyncableIDPart);\n}\nexport function isValidAtID(id, idPrefix) {\n return !idPrefix || (typeof id === \"string\" && id.startsWith(idPrefix));\n}\n","import { setByKeyPath } from \"../utils.js\";\nexport function applyOperation(target, table, op) {\n const tbl = target[table] || (target[table] = {});\n const keys = op.keys.map(key => typeof key === 'string' ? key : JSON.stringify(key));\n switch (op.type) {\n case \"insert\":\n // TODO: Don't treat insert and upsert the same?\n case \"upsert\":\n keys.forEach((key, idx) => {\n tbl[key] = {\n type: \"ups\",\n val: op.values[idx],\n };\n });\n break;\n case \"update\":\n case \"modify\": {\n keys.forEach((key, idx) => {\n const changeSpec = op.type === \"update\"\n ? op.changeSpecs[idx]\n : op.changeSpec;\n const entry = tbl[key];\n if (!entry) {\n tbl[key] = {\n type: \"upd\",\n mod: changeSpec,\n };\n }\n else {\n switch (entry.type) {\n case \"ups\":\n // Adjust the existing upsert with additional updates\n for (const [propPath, value] of Object.entries(changeSpec)) {\n setByKeyPath(entry.val, propPath, value);\n }\n break;\n case \"del\":\n // No action.\n break;\n case \"upd\":\n // Adjust existing update with additional updates\n Object.assign(entry.mod, changeSpec); // May work for deep props as well - new keys is added later, right? Does the prop order persist along TSON and all? But it will not be 100% when combined with some server code (seach for \"address.city\": \"Stockholm\" comment)\n break;\n }\n }\n });\n break;\n }\n case \"delete\":\n keys.forEach((key) => {\n tbl[key] = {\n type: \"del\",\n };\n });\n break;\n }\n return target;\n}\n","import { applyOperation } from \"./applyOperation.js\";\nexport function applyOperations(target, ops) {\n for (const { table, muts } of ops) {\n for (const mut of muts) {\n applyOperation(target, table, mut);\n }\n }\n}\n","import { __asyncGenerator, __asyncValues, __await } from \"tslib\";\nexport function consumeChunkedBinaryStream(source) {\n return __asyncGenerator(this, arguments, function* consumeChunkedBinaryStream_1() {\n var _a, e_1, _b, _c;\n let state = 0;\n let sizeBuf = new Uint8Array(4);\n let sizeBufPos = 0;\n let bufs = [];\n let len = 0;\n try {\n for (var _d = true, source_1 = __asyncValues(source), source_1_1; source_1_1 = yield __await(source_1.next()), _a = source_1_1.done, !_a; _d = true) {\n _c = source_1_1.value;\n _d = false;\n const chunk = _c;\n const dw = new DataView(chunk.buffer, chunk.byteOffset, chunk.byteLength);\n let pos = 0;\n while (pos < chunk.byteLength) {\n switch (state) {\n case 0:\n // Beginning of a size header\n if (pos + 4 > chunk.byteLength) {\n for (const b of chunk.slice(pos)) {\n if (sizeBufPos === 4)\n break;\n sizeBuf[sizeBufPos++] = b;\n ++pos;\n }\n if (sizeBufPos < 4) {\n // Need more bytes in order to read length.\n // Will go out from while loop as well because pos is defenitely = chunk.byteLength here.\n break;\n }\n }\n else if (sizeBufPos > 0 && sizeBufPos < 4) {\n for (const b of chunk.slice(pos, pos + 4 - sizeBufPos)) {\n sizeBuf[sizeBufPos++] = b;\n ++pos;\n }\n }\n // Intentional fall-through...\n case 1:\n len =\n sizeBufPos === 4\n ? new DataView(sizeBuf.buffer, 0, 4).getUint32(0, false)\n : dw.getUint32(pos, false);\n if (sizeBufPos)\n sizeBufPos = 0; // in this case pos is already forwarded\n else\n pos += 4; // else pos is not yet forwarded - that's why we do it now\n // Intentional fall-through...\n case 2:\n // Eat the chunk\n if (pos >= chunk.byteLength) {\n state = 2;\n break;\n }\n if (pos + len > chunk.byteLength) {\n bufs.push(chunk.slice(pos));\n len -= (chunk.byteLength - pos);\n state = 2;\n pos = chunk.byteLength; // will break while loop.\n }\n else {\n if (bufs.length > 0) {\n const concats = new Uint8Array(bufs.reduce((p, c) => p + c.byteLength, len));\n let p = 0;\n for (const buf of bufs) {\n concats.set(buf, p);\n p += buf.byteLength;\n }\n concats.set(chunk.slice(pos, pos + len), p);\n bufs = [];\n yield yield __await(concats);\n }\n else {\n yield yield __await(chunk.slice(pos, pos + len));\n }\n pos += len;\n state = 0;\n }\n break;\n }\n }\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (!_d && !_a && (_b = source_1.return)) yield __await(_b.call(source_1));\n }\n finally { if (e_1) throw e_1.error; }\n }\n });\n}\n","import { TokenErrorResponse } from 'dexie-cloud-common';\n\nexport class TokenErrorResponseError extends Error {\n title: string;\n messageCode:\n | 'INVALID_OTP'\n | 'INVALID_EMAIL'\n | 'LICENSE_LIMIT_REACHED'\n | 'GENERIC_ERROR';\n message: string;\n messageParams?: { [param: string]: string };\n\n constructor({\n title,\n message,\n messageCode,\n messageParams,\n }: TokenErrorResponse) {\n super(message);\n this.name = 'TokenErrorResponseError';\n this.title = title;\n this.messageCode = messageCode;\n this.messageParams = messageParams;\n }\n}\n","import Dexie from 'dexie';\nimport { BehaviorSubject } from 'rxjs';\nimport { take } from 'rxjs/operators';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { DXCAlert } from '../types/DXCAlert';\nimport { DXCInputField } from '../types/DXCInputField';\nimport { DXCUserInteraction } from '../types/DXCUserInteraction';\n\nexport interface DXCUserInteractionRequest {\n type: DXCUserInteraction['type'];\n title: string;\n alerts: DXCAlert[];\n submitLabel?: string;\n cancelLabel?: string | null;\n fields: { [name: string]: DXCInputField };\n}\n\nexport function interactWithUser<T extends DXCUserInteractionRequest>(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n req: T\n): Promise<{\n [P in keyof T['fields']]: string;\n}> {\n let done = false;\n return new Promise<{\n [P in keyof T['fields']]: string;\n }>((resolve, reject) => {\n const interactionProps = {\n submitLabel: 'Submit',\n cancelLabel: 'Cancel',\n ...req,\n onSubmit: (res: {\n [P in keyof T['fields']]: string;\n }) => {\n userInteraction.next(undefined);\n done = true;\n resolve(res);\n },\n onCancel: () => {\n userInteraction.next(undefined);\n done = true;\n reject(new Dexie.AbortError('User cancelled'));\n },\n } as DXCUserInteraction;\n userInteraction.next(interactionProps);\n // Start subscribing for external updates to db.cloud.userInteraction, and if so, cancel this request.\n /*const subscription = userInteraction.subscribe((currentInteractionProps) => {\n if (currentInteractionProps !== interactionProps) {\n if (subscription) subscription.unsubscribe();\n if (!done) {\n reject(new Dexie.AbortError(\"User cancelled\"));\n }\n }\n });*/\n });\n}\n\nexport function alertUser(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n title: string,\n ...alerts: DXCAlert[]\n) {\n return interactWithUser(userInteraction, {\n type: 'message-alert',\n title,\n alerts,\n fields: {},\n submitLabel: 'OK',\n cancelLabel: null,\n });\n}\n\nexport async function promptForEmail(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n title: string,\n emailHint?: string\n) {\n let email = emailHint || '';\n // Regular expression for email validation\n // ^[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10}(\\sas\\s[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10})?$\n //\n // ^[\\w-+.]+ : Matches the start of the string. Allows one or more word characters\n // (a-z, A-Z, 0-9, and underscore), hyphen, plus, or dot.\n //\n // @ : Matches the @ symbol.\n // ([\\w-]+\\.)+ : Matches one or more word characters or hyphens followed by a dot.\n // The plus sign outside the parentheses means this pattern can repeat one or more times,\n // allowing for subdomains.\n // [\\w-]{2,10} : Matches between 2 and 10 word characters or hyphens. This is typically for\n // the domain extension like .com, .net, etc.\n // (\\sas\\s[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10})?$ : This part is optional (due to the ? at the end).\n // If present, it matches \" as \" followed by another valid email address. This allows for the\n // input to be either a single email address or two email addresses separated by \" as \". \n //\n // The use case for \"<email1> as <email2>\"\" is for when a database owner with full access to the\n // database needs to impersonate another user in the database in order to troubleshoot. This\n // format will only be possible to use when email1 is the owner of an API client with GLOBAL_READ\n // and GLOBAL_WRITE permissions on the database. The email will be checked on the server before\n // allowing it and giving out a token for email2, using the OTP sent to email1.\n while (!email || !/^[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10}(\\sas\\s[\\w-+.]+@([\\w-]+\\.)+[\\w-]{2,10})?$/.test(email)) {\n email = (\n await interactWithUser(userInteraction, {\n type: 'email',\n title,\n alerts: email\n ? [\n {\n type: 'error',\n messageCode: 'INVALID_EMAIL',\n message: 'Please enter a valid email address',\n messageParams: {},\n },\n ]\n : [],\n fields: {\n email: {\n type: 'email',\n placeholder: 'you@somedomain.com',\n },\n },\n })\n ).email;\n }\n return email;\n}\n\nexport async function promptForOTP(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n email: string,\n alert?: DXCAlert\n) {\n const alerts: DXCAlert[] = [\n {\n type: 'info',\n messageCode: 'OTP_SENT',\n message: `A One-Time password has been sent to {email}`,\n messageParams: { email },\n },\n ];\n if (alert) {\n alerts.push(alert);\n }\n const { otp } = await interactWithUser(userInteraction, {\n type: 'otp',\n title: 'Enter OTP',\n alerts,\n fields: {\n otp: {\n type: 'otp',\n label: 'OTP',\n placeholder: 'Paste OTP here',\n },\n },\n });\n return otp;\n}\n\nexport async function confirmLogout(\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n currentUserId: string,\n numUnsyncedChanges: number\n) {\n const alerts: DXCAlert[] = [\n {\n type: 'warning',\n messageCode: 'LOGOUT_CONFIRMATION',\n message: `{numUnsyncedChanges} unsynced changes will get lost!\n Logout anyway?`,\n messageParams: {\n currentUserId,\n numUnsyncedChanges: numUnsyncedChanges.toString(),\n }\n },\n ];\n return await interactWithUser(userInteraction, {\n type: 'logout-confirmation',\n title: 'Confirm Logout',\n alerts,\n fields: {},\n submitLabel: 'Confirm logout',\n cancelLabel: 'Cancel'\n })\n .then(() => true)\n .catch(() => false);\n}\n","import Dexie from 'dexie';\nimport type {\n RefreshTokenRequest,\n TokenErrorResponse,\n TokenFinalResponse,\n} from 'dexie-cloud-common';\nimport { b64encode } from 'dreambase-library/dist/common/base64';\nimport { BehaviorSubject } from 'rxjs';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { UserLogin } from '../db/entities/UserLogin';\nimport { DXCAlert } from '../types/DXCAlert';\nimport {\n DXCMessageAlert,\n DXCUserInteraction,\n} from '../types/DXCUserInteraction';\nimport { TokenErrorResponseError } from './TokenErrorResponseError';\nimport { alertUser, interactWithUser } from './interactWithUser';\nimport { InvalidLicenseError } from '../InvalidLicenseError';\nimport { LoginHints } from '../DexieCloudAPI';\n\nexport type FetchTokenCallback = (tokenParams: {\n public_key: string;\n hints?: LoginHints;\n}) => Promise<TokenFinalResponse | TokenErrorResponse>;\n\nexport async function loadAccessToken(\n db: DexieCloudDB\n): Promise<UserLogin | null> {\n const currentUser = await db.getCurrentUser();\n const {\n accessToken,\n accessTokenExpiration,\n refreshToken,\n refreshTokenExpiration,\n claims,\n } = currentUser;\n if (!accessToken) return null;\n const expTime = accessTokenExpiration?.getTime() ?? Infinity;\n if (expTime > Date.now() && (currentUser.license?.status || 'ok') === 'ok') {\n return currentUser;\n }\n if (!refreshToken) {\n throw new Error(`Refresh token missing`);\n }\n const refreshExpTime = refreshTokenExpiration?.getTime() ?? Infinity;\n if (refreshExpTime <= Date.now()) {\n throw new Error(`Refresh token has expired`);\n }\n const refreshedLogin = await refreshAccessToken(\n db.cloud.options!.databaseUrl,\n currentUser\n );\n await db.table('$logins').update(claims.sub, {\n accessToken: refreshedLogin.accessToken,\n accessTokenExpiration: refreshedLogin.accessTokenExpiration,\n claims: refreshedLogin.claims,\n license: refreshedLogin.license,\n data: refreshedLogin.data,\n });\n return refreshedLogin;\n}\n\nexport async function authenticate(\n url: string,\n context: UserLogin,\n fetchToken: FetchTokenCallback,\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n hints?: LoginHints\n): Promise<UserLogin> {\n if (\n context.accessToken &&\n context.accessTokenExpiration!.getTime() > Date.now()\n ) {\n return context;\n } else if (\n context.refreshToken &&\n (!context.refreshTokenExpiration ||\n context.refreshTokenExpiration.getTime() > Date.now())\n ) {\n return await refreshAccessToken(url, context);\n } else {\n return await userAuthenticate(context, fetchToken, userInteraction, hints);\n }\n}\n\nexport async function refreshAccessToken(\n url: string,\n login: UserLogin\n): Promise<UserLogin> {\n if (!login.refreshToken)\n throw new Error(`Cannot refresh token - refresh token is missing.`);\n if (!login.nonExportablePrivateKey)\n throw new Error(\n `login.nonExportablePrivateKey is missing - cannot sign refresh token without a private key.`\n );\n\n const time_stamp = Date.now();\n const signing_algorithm = 'RSASSA-PKCS1-v1_5';\n const textEncoder = new TextEncoder();\n const data = textEncoder.encode(login.refreshToken + time_stamp);\n const binarySignature = await crypto.subtle.sign(\n signing_algorithm,\n login.nonExportablePrivateKey,\n data\n );\n const signature = b64encode(binarySignature);\n\n const tokenRequest: RefreshTokenRequest = {\n grant_type: 'refresh_token',\n refresh_token: login.refreshToken,\n scopes: ['ACCESS_DB'],\n signature,\n signing_algorithm,\n time_stamp,\n };\n const res = await fetch(`${url}/token`, {\n body: JSON.stringify(tokenRequest),\n method: 'post',\n headers: { 'Content-Type': 'application/json' },\n mode: 'cors',\n });\n if (res.status !== 200)\n throw new Error(`RefreshToken: Status ${res.status} from ${url}/token`);\n const response: TokenFinalResponse | TokenErrorResponse = await res.json();\n if (response.type === 'error') {\n throw new TokenErrorResponseError(response);\n }\n login.accessToken = response.accessToken;\n login.accessTokenExpiration = response.accessTokenExpiration\n ? new Date(response.accessTokenExpiration)\n : undefined;\n login.claims = response.claims;\n login.license = {\n type: response.userType,\n status: response.claims.license || 'ok',\n }\n if (response.evalDaysLeft != null) {\n login.license.evalDaysLeft = response.evalDaysLeft;\n }\n if (response.userValidUntil != null) {\n login.license.validUntil = new Date(response.userValidUntil);\n }\n if (response.data) {\n login.data = response.data;\n }\n return login;\n}\n\nasync function userAuthenticate(\n context: UserLogin,\n fetchToken: FetchTokenCallback,\n userInteraction: BehaviorSubject<DXCUserInteraction | undefined>,\n hints?: LoginHints\n) {\n if (!crypto.subtle) {\n if (typeof location !== 'undefined' && location.protocol === 'http:') {\n throw new Error(`Dexie Cloud Addon needs to use WebCrypto, but your browser has disabled it due to being served from an insecure location. Please serve it from https or http://localhost:<port> (See https://stackoverflow.com/questions/46670556/how-to-enable-crypto-subtle-for-unsecure-origins-in-chrome/46671627#46671627)`);\n } else {\n throw new Error(`This browser does not support WebCrypto.`);\n }\n }\n const { privateKey, publicKey } = await crypto.subtle.generateKey(\n {\n name: 'RSASSA-PKCS1-v1_5',\n modulusLength: 2048,\n publicExponent: new Uint8Array([0x01, 0x00, 0x01]),\n hash: { name: 'SHA-256' },\n },\n false, // Non-exportable...\n ['sign', 'verify']\n );\n if (!privateKey || !publicKey)\n throw new Error(`Could not generate RSA keypair`); // Typings suggest these can be undefined...\n context.nonExportablePrivateKey = privateKey; //...but storable!\n const publicKeySPKI = await crypto.subtle.exportKey('spki', publicKey);\n const publicKeyPEM = spkiToPEM(publicKeySPKI);\n context.publicKey = publicKey;\n\n try {\n const response2 = await fetchToken({\n public_key: publicKeyPEM,\n hints,\n });\n\n if (response2.type === 'error') {\n throw new TokenErrorResponseError(response2);\n }\n\n if (response2.type !== 'tokens')\n throw new Error(\n `Unexpected response type from token endpoint: ${(response2 as any).type}`\n );\n\n /*const licenseStatus = response2.claims.license || 'ok';\n if (licenseStatus !== 'ok') {\n throw new InvalidLicenseError(licenseStatus);\n }*/\n\n context.accessToken = response2.accessToken;\n context.accessTokenExpiration = new Date(response2.accessTokenExpiration);\n context.refreshToken = response2.refreshToken;\n if (response2.refreshTokenExpiration) {\n context.refreshTokenExpiration = new Date(\n response2.refreshTokenExpiration\n );\n }\n context.userId = response2.claims.sub;\n context.email = response2.claims.email;\n context.name = response2.claims.name;\n context.claims = response2.claims;\n context.license = {\n type: response2.userType,\n status: response2.claims.license || 'ok',\n }\n context.data = response2.data;\n if (response2.evalDaysLeft != null) {\n context.license.evalDaysLeft = response2.evalDaysLeft;\n }\n if (response2.userValidUntil != null) {\n context.license.validUntil = new Date(response2.userValidUntil);\n }\n\n if (response2.alerts && response2.alerts.length > 0) {\n await interactWithUser(userInteraction, {\n type: 'message-alert',\n title: 'Authentication Alert',\n fields: {},\n alerts: response2.alerts as DXCAlert[],\n });\n }\n return context;\n } catch (error) {\n if (error instanceof TokenErrorResponseError) {\n await alertUser(userInteraction, error.title, {\n type: 'error',\n messageCode: error.messageCode,\n message: error.message,\n messageParams: {},\n });\n throw error;\n }\n let message = `We're having a problem authenticating right now.`;\n console.error (`Error authenticating`, error);\n if (error instanceof TypeError) {\n const isOffline = typeof navigator !== undefined && !navigator.onLine;\n if (isOffline) {\n message = `You seem to be offline. Please connect to the internet and try again.`;\n } else if (Dexie.debug || (typeof location !== 'undefined' && (location.hostname === 'localhost' || location.hostname === '127.0.0.1'))) {\n // The audience is most likely the developer. Suggest to whitelist the localhost origin:\n message = `Could not connect to server. Please verify that your origin '${location.origin}' is whitelisted using \\`npx dexie-cloud whitelist\\``;\n } else {\n message = `Could not connect to server. Please verify the connection.`;\n }\n await alertUser(userInteraction, 'Authentication Failed', {\n type: 'error',\n messageCode: 'GENERIC_ERROR',\n message,\n messageParams: {},\n }).catch(() => {}); \n }\n\n throw error;\n }\n}\n\nfunction spkiToPEM(keydata: ArrayBuffer) {\n const keydataB64 = b64encode(keydata);\n const keydataB64Pem = formatAsPem(keydataB64);\n return keydataB64Pem;\n}\n\nfunction formatAsPem(str: string) {\n let finalString = '-----BEGIN PUBLIC KEY-----\\n';\n\n while (str.length > 0) {\n finalString += str.substring(0, 64) + '\\n';\n str = str.substring(64);\n }\n\n finalString = finalString + '-----END PUBLIC KEY-----';\n\n return finalString;\n}\n","const { toString: toStr } = {};\nfunction getToStringTag(val) {\n return toStr.call(val).slice(8, -1);\n}\nexport function escapeDollarProps(value) {\n const keys = Object.keys(value);\n let dollarKeys = null;\n for (let i = 0, l = keys.length; i < l; ++i) {\n if (keys[i][0] === \"$\") {\n dollarKeys = dollarKeys || [];\n dollarKeys.push(keys[i]);\n }\n }\n if (!dollarKeys)\n return value;\n const clone = { ...value };\n for (const k of dollarKeys) {\n delete clone[k];\n }\n for (const k of dollarKeys) {\n clone[\"$\" + k] = value[k];\n }\n return clone;\n}\nconst ObjectDef = {\n replace: escapeDollarProps,\n};\nexport function TypesonSimplified(...typeDefsInputs) {\n const typeDefs = typeDefsInputs.reduce((p, c) => ({ ...p, ...c }), typeDefsInputs.reduce((p, c) => ({ ...c, ...p }), {}));\n const protoMap = new WeakMap();\n return {\n stringify(value, alternateChannel, space) {\n const json = JSON.stringify(value, function (key) {\n const realVal = this[key];\n const typeDef = getTypeDef(realVal);\n return typeDef\n ? typeDef.replace(realVal, alternateChannel, typeDefs)\n : realVal;\n }, space);\n return json;\n },\n parse(tson, alternateChannel) {\n const stack = [];\n return JSON.parse(tson, function (key, value) {\n //\n // Parent Part\n //\n const type = value === null || value === void 0 ? void 0 : value.$t;\n if (type) {\n const typeDef = typeDefs[type];\n value = typeDef\n ? typeDef.revive(value, alternateChannel, typeDefs)\n : value;\n }\n let top = stack[stack.length - 1];\n if (top && top[0] === value) {\n // Do what the kid told us to\n // Unescape dollar props\n value = { ...value };\n // Delete keys that children wanted us to delete\n for (const k of top[1])\n delete value[k];\n // Set keys that children wanted us to set\n for (const [k, v] of Object.entries(top[2])) {\n value[k] = v;\n }\n stack.pop();\n }\n //\n // Child part\n //\n if (value === undefined || (key[0] === \"$\" && key !== \"$t\")) {\n top = stack[stack.length - 1];\n let deletes;\n let mods;\n if (top && top[0] === this) {\n deletes = top[1];\n mods = top[2];\n }\n else {\n stack.push([this, (deletes = []), (mods = {})]);\n }\n if (key[0] === \"$\" && key !== \"$t\") {\n // Unescape props (also preserves undefined if this is a combo)\n deletes.push(key);\n mods[key.substr(1)] = value;\n }\n else {\n // Preserve undefined\n mods[key] = undefined;\n }\n }\n return value;\n });\n },\n };\n function getTypeDef(realVal) {\n const type = typeof realVal;\n switch (typeof realVal) {\n case \"object\":\n case \"function\": {\n // \"object\", \"function\", null\n if (realVal === null)\n return null;\n const proto = Object.getPrototypeOf(realVal);\n if (!proto)\n return ObjectDef;\n let typeDef = protoMap.get(proto);\n if (typeDef !== undefined)\n return typeDef; // Null counts to! So the caching of Array.prototype also counts.\n const toStringTag = getToStringTag(realVal);\n const entry = Object.entries(typeDefs).find(([typeName, typeDef]) => { var _a, _b; return (_b = (_a = typeDef === null || typeDef === void 0 ? void 0 : typeDef.test) === null || _a === void 0 ? void 0 : _a.call(typeDef, realVal, toStringTag)) !== null && _b !== void 0 ? _b : typeName === toStringTag; });\n typeDef = entry === null || entry === void 0 ? void 0 : entry[1];\n if (!typeDef) {\n typeDef = Array.isArray(realVal)\n ? null\n : typeof realVal === \"function\"\n ? typeDefs.function || null\n : ObjectDef;\n }\n protoMap.set(proto, typeDef);\n return typeDef;\n }\n default:\n return typeDefs[type];\n }\n }\n}\n","export const BisonBinaryTypes = {\n Blob: {\n test: (blob, toStringTag) => toStringTag === \"Blob\",\n replace: (blob, altChannel) => {\n const i = altChannel.length;\n altChannel.push(blob);\n return {\n $t: \"Blob\",\n mimeType: blob.type,\n i,\n };\n },\n revive: ({ i, mimeType }, altChannel) => new Blob([altChannel[i]], { type: mimeType }),\n },\n};\n","export default {\n number: {\n replace: (num) => {\n switch (true) {\n case isNaN(num):\n return { $t: \"number\", v: \"NaN\" };\n case num === Infinity:\n return { $t: \"number\", v: \"Infinity\" };\n case num === -Infinity:\n return { $t: \"number\", v: \"-Infinity\" };\n default:\n return num;\n }\n },\n revive: ({ v }) => Number(v),\n },\n};\n","const bigIntDef = {\n bigint: {\n replace: (realVal) => {\n return { $t: \"bigint\", v: \"\" + realVal };\n },\n revive: (obj) => BigInt(obj.v),\n },\n};\nexport default bigIntDef;\n","export default {\n Date: {\n replace: (date) => ({\n $t: \"Date\",\n v: isNaN(date.getTime()) ? \"NaN\" : date.toISOString(),\n }),\n revive: ({ v }) => new Date(v === \"NaN\" ? NaN : Date.parse(v)),\n },\n};\n","export default {\n Set: {\n replace: (set) => ({\n $t: \"Set\",\n v: Array.from(set.entries()),\n }),\n revive: ({ v }) => new Set(v),\n },\n};\n","export default {\n Map: {\n replace: (map) => ({\n $t: \"Map\",\n v: Array.from(map.entries()),\n }),\n revive: ({ v }) => new Map(v),\n },\n};\n","export const _global = typeof globalThis !== \"undefined\" // All modern environments (node, bun, deno, browser, workers, webview etc)\n ? globalThis\n : typeof self !== \"undefined\" // Older browsers, workers, webview, window etc\n ? self\n : typeof global !== \"undefined\" // Older versions of node\n ? global\n : undefined; // Unsupported environment. No idea to return 'this' since we are in a module or a function scope anyway.\n","import { _global } from \"../../common/_global.js\";\nexport default [\n \"Int8Array\",\n \"Uint8Array\",\n \"Uint8ClampedArray\",\n \"Int16Array\",\n \"Uint16Array\",\n \"Int32Array\",\n \"Uint32Array\",\n \"Float32Array\",\n \"Float64Array\",\n \"DataView\",\n \"BigInt64Array\",\n \"BigUint64Array\",\n].reduce((specs, typeName) => ({\n ...specs,\n [typeName]: {\n // Replace passes the the typed array into $t, buffer so that\n // the ArrayBuffer typedef takes care of further handling of the buffer:\n // {$t:\"Uint8Array\",buffer:{$t:\"ArrayBuffer\",idx:0}}\n // CHANGED ABOVE! Now shortcutting that for more sparse format of the typed arrays\n // to contain the b64 property directly.\n replace: (a, _, typeDefs) => {\n const result = {\n $t: typeName,\n v: typeDefs.ArrayBuffer.replace(a.byteOffset === 0 && a.byteLength === a.buffer.byteLength\n ? a.buffer\n : a.buffer.slice(a.byteOffset, a.byteOffset + a.byteLength), _, typeDefs).v,\n };\n return result;\n },\n revive: ({ v }, _, typeDefs) => {\n const TypedArray = _global[typeName];\n return (TypedArray &&\n new TypedArray(typeDefs.ArrayBuffer.revive({ v }, _, typeDefs)));\n },\n },\n}), {});\n","import { b64decode, b64encode } from \"./base64.js\";\nexport function b64LexEncode(b) {\n return b64ToLex(b64encode(b));\n}\nexport function b64LexDecode(b64Lex) {\n return b64decode(lexToB64(b64Lex));\n}\nexport function b64ToLex(base64) {\n var encoded = \"\";\n for (var i = 0, length = base64.length; i < length; i++) {\n encoded += ENCODE_TABLE[base64[i]];\n }\n return encoded;\n}\nexport function lexToB64(base64lex) {\n // only accept string input\n if (typeof base64lex !== \"string\") {\n throw new Error(\"invalid decoder input: \" + base64lex);\n }\n var base64 = \"\";\n for (var i = 0, length = base64lex.length; i < length; i++) {\n base64 += DECODE_TABLE[base64lex[i]];\n }\n return base64;\n}\nconst DECODE_TABLE = {\n \"-\": \"=\",\n \"0\": \"A\",\n \"1\": \"B\",\n \"2\": \"C\",\n \"3\": \"D\",\n \"4\": \"E\",\n \"5\": \"F\",\n \"6\": \"G\",\n \"7\": \"H\",\n \"8\": \"I\",\n \"9\": \"J\",\n A: \"K\",\n B: \"L\",\n C: \"M\",\n D: \"N\",\n E: \"O\",\n F: \"P\",\n G: \"Q\",\n H: \"R\",\n I: \"S\",\n J: \"T\",\n K: \"U\",\n L: \"V\",\n M: \"W\",\n N: \"X\",\n O: \"Y\",\n P: \"Z\",\n Q: \"a\",\n R: \"b\",\n S: \"c\",\n T: \"d\",\n U: \"e\",\n V: \"f\",\n W: \"g\",\n X: \"h\",\n Y: \"i\",\n Z: \"j\",\n _: \"k\",\n a: \"l\",\n b: \"m\",\n c: \"n\",\n d: \"o\",\n e: \"p\",\n f: \"q\",\n g: \"r\",\n h: \"s\",\n i: \"t\",\n j: \"u\",\n k: \"v\",\n l: \"w\",\n m: \"x\",\n n: \"y\",\n o: \"z\",\n p: \"0\",\n q: \"1\",\n r: \"2\",\n s: \"3\",\n t: \"4\",\n u: \"5\",\n v: \"6\",\n w: \"7\",\n x: \"8\",\n y: \"9\",\n z: \"+\",\n \"|\": \"/\",\n};\nconst ENCODE_TABLE = {};\nfor (const c of Object.keys(DECODE_TABLE)) {\n ENCODE_TABLE[DECODE_TABLE[c]] = c;\n}\n","import { b64LexDecode, b64LexEncode } from \"../../common/b64lex.js\";\nexport default {\n ArrayBuffer: {\n replace: (ab) => ({\n $t: \"ArrayBuffer\",\n v: b64LexEncode(ab),\n }),\n revive: ({ v }) => {\n const ba = b64LexDecode(v);\n return ba.buffer.byteLength === ba.byteLength\n ? ba.buffer\n : ba.buffer.slice(ba.byteOffset, ba.byteOffset + ba.byteLength);\n },\n },\n};\n","export class FakeBlob {\n constructor(buf, type) {\n this.buf = buf;\n this.type = type;\n }\n}\n","export function readBlobSync(b) {\n const req = new XMLHttpRequest();\n req.overrideMimeType(\"text/plain; charset=x-user-defined\");\n req.open(\"GET\", URL.createObjectURL(b), false); // Sync\n req.send();\n if (req.status !== 200 && req.status !== 0) {\n throw new Error(\"Bad Blob access: \" + req.status);\n }\n return req.responseText;\n}\n","export function string2ArrayBuffer(str) {\n const array = new Uint8Array(str.length);\n for (let i = 0; i < str.length; ++i) {\n array[i] = str.charCodeAt(i); // & 0xff;\n }\n return array.buffer;\n}\nexport function arrayBuffer2String(buf) {\n // TODO: Optimize\n return new Uint8Array(buf).reduce((s, byte) => s + String.fromCharCode(byte), \"\");\n}\n","import { b64decode, b64encode } from \"../../common/base64.js\";\nimport { FakeBlob } from \"../FakeBlob.js\";\nimport { readBlobSync } from \"../readBlobSync.js\";\nimport { string2ArrayBuffer } from \"../string2ArrayBuffer.js\";\nexport default {\n Blob: {\n test: (blob, toStringTag) => toStringTag === \"Blob\" || blob instanceof FakeBlob,\n replace: (blob) => ({\n $t: \"Blob\",\n v: blob instanceof FakeBlob\n ? b64encode(blob.buf)\n : b64encode(string2ArrayBuffer(readBlobSync(blob))),\n type: blob.type,\n }),\n revive: ({ type, v }) => {\n const ab = b64decode(v);\n return typeof Blob !== undefined\n ? new Blob([ab])\n : new FakeBlob(ab.buffer, type);\n },\n },\n};\n","import numberDef from \"../types/number.js\";\nimport bigintDef from \"../types/bigint.js\";\nimport DateDef from \"../types/Date.js\";\nimport SetDef from \"../types/Set.js\";\nimport MapDef from \"../types/Map.js\";\nimport TypedArraysDefs from \"../types/TypedArray.js\";\nimport ArrayBufferDef from \"../types/ArrayBuffer.js\";\nimport BlobDef from \"../types/Blob.js\";\nconst builtin = {\n ...numberDef,\n ...bigintDef,\n ...DateDef,\n ...SetDef,\n ...MapDef,\n ...TypedArraysDefs,\n ...ArrayBufferDef,\n ...BlobDef, // Should be moved to another preset for DOM types (or universal? since it supports node as well with FakeBlob)\n};\nexport default builtin;\n","import { BisonBinaryTypes } from \"./BisonBinaryTypes.js\";\nimport builtin from \"./presets/builtin.js\";\nimport { TypesonSimplified } from \"./TypesonSimplified.js\";\nexport function Bison(...typeDefsInputs) {\n const tson = TypesonSimplified(builtin, BisonBinaryTypes, ...typeDefsInputs);\n return {\n toBinary(value) {\n const [blob, json] = this.stringify(value);\n const lenBuf = new ArrayBuffer(4);\n new DataView(lenBuf).setUint32(0, blob.size);\n return new Blob([lenBuf, blob, json]);\n },\n stringify(value) {\n const binaries = [];\n const json = tson.stringify(value, binaries);\n const blob = new Blob(binaries.map((b) => {\n const lenBuf = new ArrayBuffer(4);\n new DataView(lenBuf).setUint32(0, \"byteLength\" in b ? b.byteLength : b.size);\n return new Blob([lenBuf, b]);\n }));\n return [blob, json];\n },\n async parse(json, binData) {\n let pos = 0;\n const arrayBuffers = [];\n const buf = await readBlobBinary(binData);\n const view = new DataView(buf);\n while (pos < buf.byteLength) {\n const len = view.getUint32(pos);\n pos += 4;\n const ab = buf.slice(pos, pos + len);\n pos += len;\n arrayBuffers.push(ab);\n }\n return tson.parse(json, arrayBuffers);\n },\n async fromBinary(blob) {\n const len = new DataView(await readBlobBinary(blob.slice(0, 4))).getUint32(0);\n const binData = blob.slice(4, len + 4);\n const json = await readBlob(blob.slice(len + 4));\n return await this.parse(json, binData);\n },\n };\n}\nexport function readBlob(blob) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onabort = (ev) => reject(new Error(\"file read aborted\"));\n reader.onerror = (ev) => reject(ev.target.error);\n reader.onload = (ev) => resolve(ev.target.result);\n reader.readAsText(blob);\n });\n}\nexport function readBlobBinary(blob) {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onabort = (ev) => reject(new Error(\"file read aborted\"));\n reader.onerror = (ev) => reject(ev.target.error);\n reader.onload = (ev) => resolve(ev.target.result);\n reader.readAsArrayBuffer(blob);\n });\n}\n","/** The undefined type is not part of builtin but can be manually added.\n * The reason for supporting undefined is if the following object should be revived correctly:\n *\n * {foo: undefined}\n *\n * Without including this typedef, the revived object would just be {}.\n * If including this typedef, the revived object would be {foo: undefined}.\n */\nexport default {\n undefined: {\n replace: () => ({\n $t: \"undefined\"\n }),\n revive: () => undefined,\n },\n};\n","import { b64decode, b64encode } from \"../../common/base64.js\";\nimport { readBlobSync } from \"../readBlobSync.js\";\nimport { string2ArrayBuffer } from \"../string2ArrayBuffer.js\";\nexport default {\n File: {\n test: (file, toStringTag) => toStringTag === \"File\",\n replace: (file) => ({\n $t: \"File\",\n v: b64encode(string2ArrayBuffer(readBlobSync(file))),\n type: file.type,\n name: file.name,\n lastModified: new Date(file.lastModified).toISOString(),\n }),\n revive: ({ type, v, name, lastModified }) => {\n const ab = b64decode(v);\n return new File([ab], name, {\n type,\n lastModified: new Date(lastModified).getTime(),\n });\n },\n },\n};\n","import { TypesonSimplified } from 'dreambase-library/dist/typeson-simplified/TypesonSimplified';\nimport { Bison } from 'dreambase-library/dist/typeson-simplified/Bison';\nimport undefinedDef from 'dreambase-library/dist/typeson-simplified/types/undefined.js';\nimport tsonBuiltinDefs from 'dreambase-library/dist/typeson-simplified/presets/builtin.js';\nimport { TypeDefSet } from 'dreambase-library/dist/typeson-simplified/TypeDefSet';\nimport { PropModSpec, PropModification } from 'dexie';\nimport FileDef from \"dreambase-library/dist/typeson-simplified/types/File.js\";\n\n// Since server revisions are stored in bigints, we need to handle clients without\n// bigint support to not fail when serverRevision is passed over to client.\n// We need to not fail when reviving it and we need to somehow store the information.\n// Since the revived version will later on be put into indexedDB we have another\n// issue: When reading it back from indexedDB we will get a poco object that we\n// cannot replace correctly when sending it to server. So we will also need\n// to do an explicit workaround in the protocol where a bigint is supported.\n// The workaround should be there regardless if browser supports BigInt or not, because\n// the serverRev might have been stored in IDB before the browser was upgraded to support bigint.\n//\n// if (typeof serverRev.rev !== \"bigint\")\n// if (hasBigIntSupport)\n// serverRev.rev = bigIntDef.bigint.revive(server.rev)\n// else\n// serverRev.rev = new FakeBigInt(server.rev)\nexport const hasBigIntSupport =\n typeof BigInt === 'function' && typeof BigInt(0) === 'bigint';\n\nfunction getValueOfBigInt(x: bigint | FakeBigInt | string) {\n if (typeof x === 'bigint') {\n return x;\n }\n if (hasBigIntSupport) {\n return typeof x === 'string' ? BigInt(x) : BigInt(x.v);\n } else {\n return typeof x === 'string' ? Number(x) : Number(x.v);\n }\n}\n\nexport function compareBigInts(\n a: bigint | FakeBigInt | string,\n b: bigint | FakeBigInt | string\n) {\n const valA = getValueOfBigInt(a);\n const valB = getValueOfBigInt(b);\n return valA < valB ? -1 : valA > valB ? 1 : 0;\n}\nexport class FakeBigInt {\n v: string;\n toString() {\n return this.v;\n }\n constructor(value: string) {\n this.v = value;\n }\n}\n\nconst bigIntDef = hasBigIntSupport\n ? {}\n : {\n bigint: {\n test: (val: any) => val instanceof FakeBigInt,\n replace: (fakeBigInt: any) => {\n return {\n $t: 'bigint',\n ...fakeBigInt,\n };\n },\n revive: ({ v }: { $t: 'bigint'; v: string }) =>\n new FakeBigInt(v) as any as bigint,\n },\n };\n\nconst defs: TypeDefSet = {\n ...undefinedDef,\n ...bigIntDef,\n ...FileDef,\n PropModification: {\n test: (val: any) => val instanceof PropModification,\n replace: (propModification: any) => {\n return {\n $t: 'PropModification',\n ...propModification['@@propmod'],\n };\n },\n revive: ({\n $t, // strip '$t'\n ...propModSpec // keep the rest\n }: {\n $t: 'PropModification';\n } & PropModSpec) => new PropModification(propModSpec),\n },\n};\n\nexport const TSON = TypesonSimplified(tsonBuiltinDefs, defs);\n\nexport const BISON = Bison(defs);\n","export class HttpError extends Error {\n httpStatus: number;\n constructor(\n res: Response,\n message?: string)\n {\n super(message || `${res.status} ${res.statusText}`);\n this.httpStatus = res.status;\n }\n\n get name() {\n return \"HttpError\";\n }\n}\n","import Dexie, { DBCoreSchema } from 'dexie';\nimport {\n DBInsertOperation,\n DBOperation,\n DBOperationsSet,\n DBOpPrimaryKey,\n} from 'dexie-cloud-common';\nimport { UserLogin } from '../db/entities/UserLogin';\n\nexport function encodeIdsForServer(\n schema: DBCoreSchema,\n currentUser: UserLogin,\n changes: DBOperationsSet\n): DBOperationsSet {\n const rv: DBOperationsSet = [];\n for (let change of changes) {\n const { table, muts } = change;\n const tableSchema = schema.tables.find((t) => t.name === table);\n if (!tableSchema)\n throw new Error(\n `Internal error: table ${table} not found in DBCore schema`\n );\n const { primaryKey } = tableSchema;\n let changeClone = change;\n muts.forEach((mut, mutIndex) => {\n const rewriteValues =\n !primaryKey.outbound &&\n (mut.type === 'upsert' || mut.type === 'insert');\n mut.keys.forEach((key, keyIndex) => {\n if (Array.isArray(key)) {\n // Server only support string keys. Dexie Cloud client support strings or array of strings.\n if (changeClone === change)\n changeClone = cloneChange(change, rewriteValues);\n const mutClone = changeClone.muts[mutIndex];\n const rewrittenKey = JSON.stringify(key);\n mutClone.keys[keyIndex] = rewrittenKey;\n /* Bug (#1777)\n We should not rewrite values. It will fail because the key is array and the value is string.\n Only the keys should be rewritten and it's already done on the server.\n We should take another round of revieweing how key transformations are being done between\n client and server and let the server do the key transformations entirely instead now that\n we have the primary key schema on the server making it possible to do so.\n if (rewriteValues) {\n Dexie.setByKeyPath(\n (mutClone as DBInsertOperation).values[keyIndex],\n primaryKey.keyPath!,\n rewrittenKey\n );\n }*/\n } else if (key[0] === '#') {\n // Private ID - translate!\n if (changeClone === change)\n changeClone = cloneChange(change, rewriteValues);\n const mutClone = changeClone.muts[mutIndex];\n if (!currentUser.isLoggedIn)\n throw new Error(\n `Internal error: Cannot sync private IDs before authenticated`\n );\n const rewrittenKey = `${key}:${currentUser.userId}`;\n mutClone.keys[keyIndex] = rewrittenKey;\n if (rewriteValues) {\n Dexie.setByKeyPath(\n (mutClone as DBInsertOperation).values[keyIndex],\n primaryKey.keyPath!,\n rewrittenKey\n );\n }\n }\n });\n });\n rv.push(changeClone);\n }\n return rv;\n}\n\nfunction cloneChange(change: DBOperationsSet[number], rewriteValues: boolean) {\n // clone on demand:\n return {\n ...change,\n muts: rewriteValues\n ? change.muts.map((m) => {\n return (m.type === 'insert' || m.type === 'upsert') && m.values\n ? {\n ...m,\n keys: m.keys.slice(),\n values: m.values.slice(),\n }\n : {\n ...m,\n keys: m.keys.slice(),\n };\n })\n : change.muts.map((m) => ({ ...m, keys: m.keys.slice() })),\n };\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\n\n// If we get Ratelimit-Limit and Ratelimit-Remaining where Ratelimit-Remaining is below\n// (Ratelimit-Limit / 2), we should delay the next sync by (Ratelimit-Reset / Ratelimit-Remaining)\n// seconds (given that there is a Ratelimit-Reset header).\n\nlet syncRatelimitDelays = new WeakMap<DexieCloudDB, Date>();\n\nexport async function checkSyncRateLimitDelay(db: DexieCloudDB) {\n const delatMilliseconds = (syncRatelimitDelays.get(db)?.getTime() ?? 0) - Date.now();\n if (delatMilliseconds > 0) {\n console.debug(`Stalling sync request ${delatMilliseconds} ms to spare ratelimits`);\n await new Promise(resolve => setTimeout(resolve, delatMilliseconds));\n }\n}\n\nexport function updateSyncRateLimitDelays(db: DexieCloudDB, res: Response) {\n const limit = res.headers.get('Ratelimit-Limit');\n const remaining = res.headers.get('Ratelimit-Remaining');\n const reset = res.headers.get('Ratelimit-Reset');\n if (limit && remaining && reset) {\n const limitNum = Number(limit);\n const remainingNum = Math.max(0, Number(remaining));\n const willResetInSeconds = Number(reset);\n if (remainingNum < limitNum / 2) {\n const delay = Math.ceil(willResetInSeconds / (remainingNum + 1));\n syncRatelimitDelays.set(db, new Date(Date.now() + delay * 1000));\n console.debug(`Sync ratelimit delay set to ${delay} seconds`);\n } else {\n syncRatelimitDelays.delete(db);\n console.debug(`Sync ratelimit delay cleared`);\n }\n }\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { loadAccessToken } from '../authentication/authenticate';\nimport { BISON, TSON } from '../TSON';\nimport { getSyncableTables } from '../helpers/getSyncableTables';\nimport { BaseRevisionMapEntry } from '../db/entities/BaseRevisionMapEntry';\nimport { HttpError } from '../errors/HttpError';\nimport {\n DBOperationsSet,\n DexieCloudSchema,\n SyncRequest,\n SyncResponse,\n YClientMessage,\n} from 'dexie-cloud-common';\nimport { encodeIdsForServer } from './encodeIdsForServer';\nimport { UserLogin } from '../db/entities/UserLogin';\nimport { updateSyncRateLimitDelays } from './ratelimit';\n//import {BisonWebStreamReader} from \"dreambase-library/dist/typeson-simplified/BisonWebStreamReader\";\n\nexport async function syncWithServer(\n changes: DBOperationsSet,\n y: YClientMessage[],\n syncState: PersistedSyncState | undefined,\n baseRevs: BaseRevisionMapEntry[],\n db: DexieCloudDB,\n databaseUrl: string,\n schema: DexieCloudSchema | null,\n clientIdentity: string,\n currentUser: UserLogin\n): Promise<SyncResponse> {\n //\n // Push changes to server using fetch\n //\n const headers: HeadersInit = {\n Accept: 'application/json, application/x-bison, application/x-bison-stream',\n 'Content-Type': 'application/tson',\n };\n const updatedUser = await loadAccessToken(db);\n /*\n if (updatedUser?.license && changes.length > 0) {\n if (updatedUser.license.status === 'expired') {\n throw new Error(`License has expired`);\n }\n if (updatedUser.license.status === 'deactivated') {\n throw new Error(`License deactivated`);\n }\n }\n */\n const accessToken = updatedUser?.accessToken;\n if (accessToken) {\n headers.Authorization = `Bearer ${accessToken}`;\n }\n\n const syncRequest: SyncRequest = {\n v: 2,\n dbID: syncState?.remoteDbId,\n clientIdentity,\n schema: schema || {},\n lastPull: syncState\n ? {\n serverRevision: syncState.serverRevision!,\n yServerRevision: syncState.yServerRevision,\n realms: syncState.realms,\n inviteRealms: syncState.inviteRealms,\n }\n : undefined,\n baseRevs,\n changes: encodeIdsForServer(db.dx.core.schema, currentUser, changes),\n y,\n dxcv: db.cloud.version\n };\n console.debug('Sync request', syncRequest);\n db.syncStateChangedEvent.next({\n phase: 'pushing',\n });\n const body = TSON.stringify(syncRequest);\n const res = await fetch(`${databaseUrl}/sync`, {\n method: 'post',\n headers,\n credentials: 'include', // For Arr Affinity cookie only, for better Rate-Limit counting only.\n body,\n });\n //const contentLength = Number(res.headers.get('content-length'));\n db.syncStateChangedEvent.next({\n phase: 'pulling',\n });\n\n updateSyncRateLimitDelays(db, res);\n\n if (!res.ok) {\n throw new HttpError(res);\n }\n\n switch (res.headers.get('content-type')) {\n case 'application/x-bison':\n return BISON.fromBinary(await res.blob());\n case 'application/x-bison-stream': //return BisonWebStreamReader(BISON, res);\n default:\n case 'application/json': {\n const text = await res.text();\n const syncRes = TSON.parse(text);\n return syncRes;\n }\n }\n}\n","import Dexie from \"dexie\";\n\nexport interface CancelToken {\n cancelled: boolean;\n}\n\nexport function throwIfCancelled(cancelToken?: CancelToken) {\n if (cancelToken?.cancelled) throw new Dexie.AbortError(`Operation was cancelled`);\n}\n","/* Need this because navigator.onLine seems to say \"false\" when it is actually online.\n This function relies initially on navigator.onLine but then uses online and offline events\n which seem to be more reliable.\n*/\nexport let isOnline = false;\nif (typeof self !== 'undefined' && typeof navigator !== 'undefined') {\n isOnline = navigator.onLine;\n self.addEventListener('online', ()=>isOnline = true);\n self.addEventListener('offline', ()=>isOnline = false);\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { DexieCloudSchema, SyncResponse } from 'dexie-cloud-common';\n\nexport async function updateBaseRevs(db: DexieCloudDB, schema: DexieCloudSchema, latestRevisions: { [table: string]: number; }, serverRev: any) {\n await db.$baseRevs.bulkPut(\n Object.keys(schema)\n .filter((table) => schema[table].markedForSync)\n .map((tableName) => {\n const lastClientRevOnPreviousServerRev = latestRevisions[tableName] || 0;\n return {\n tableName,\n clientRev: lastClientRevOnPreviousServerRev + 1,\n serverRev,\n };\n })\n );\n // Clean up baseRevs for tables that do not exist anymore or are no longer marked for sync\n // Resolve #2168 by also cleaning up baseRevs for tables that are not marked for sync\n await db.$baseRevs.where('tableName').noneOf(\n Object.keys(schema).filter((table) => schema[table].markedForSync)\n ).delete();\n}\n","import { DBOperationsSet } from 'dexie-cloud-common';\n\nexport function getLatestRevisionsPerTable(\n clientChangeSet: DBOperationsSet,\n lastRevisions = {} as { [table: string]: number; }) {\n for (const { table, muts } of clientChangeSet) {\n const lastRev = muts.length > 0 ? muts[muts.length - 1].rev : null;\n lastRevisions[table] = lastRev || lastRevisions[table] || 0;\n }\n return lastRevisions;\n}\n","import Dexie, { Table, cmp } from 'dexie';\n\nexport async function bulkUpdate(\n table: Table,\n keys: any[],\n changeSpecs: { [keyPath: string]: any }[]\n) {\n const objs = await table.bulkGet(keys);\n const resultKeys: any[] = [];\n const resultObjs: any[] = [];\n keys.forEach((key, idx) => {\n const obj = objs[idx];\n if (obj) {\n for (const [keyPath, value] of Object.entries(changeSpecs[idx])) {\n if (keyPath === table.schema.primKey.keyPath) {\n if (cmp(value, key) !== 0) {\n throw new Error(`Cannot change primary key`);\n }\n } else {\n Dexie.setByKeyPath(obj, keyPath, value);\n }\n }\n resultKeys.push(key);\n resultObjs.push(obj);\n }\n });\n await (table.schema.primKey.keyPath == null\n ? table.bulkPut(resultObjs, resultKeys)\n : table.bulkPut(resultObjs));\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport Dexie from 'dexie';\nimport { bulkUpdate } from '../helpers/bulkUpdate';\nimport { DBOperationsSet } from 'dexie-cloud-common';\n\nexport async function applyServerChanges(\n changes: DBOperationsSet<string>,\n db: DexieCloudDB\n) {\n console.debug('Applying server changes', changes, Dexie.currentTransaction);\n for (const { table: tableName, muts } of changes) {\n if (!db.dx._allTables[tableName]) {\n console.debug(\n `Server sent changes for table ${tableName} that we don't have. Ignoring.`\n );\n continue;\n }\n const table = db.table(tableName);\n const { primaryKey } = table.core.schema;\n const keyDecoder = (key: string) => {\n switch (key[0]) {\n case '[':\n // Decode JSON array\n if (key.endsWith(']'))\n try {\n // On server, array keys are transformed to JSON string representation\n return JSON.parse(key);\n } catch {}\n return key;\n case '#':\n // Decode private ID (do the opposite from what's done in encodeIdsForServer())\n if (key.endsWith(':' + db.cloud.currentUserId)) {\n return key.substr(\n 0,\n key.length - db.cloud.currentUserId.length - 1\n );\n }\n return key;\n default:\n return key;\n }\n };\n for (const mut of muts) {\n const keys = mut.keys.map(keyDecoder);\n switch (mut.type) {\n case 'insert':\n if (primaryKey.outbound) {\n await table.bulkAdd(mut.values, keys);\n } else {\n keys.forEach((key, i) => {\n // Make sure inbound keys are consistent\n Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath!, key);\n });\n await table.bulkAdd(mut.values);\n }\n break;\n case 'upsert':\n if (primaryKey.outbound) {\n await table.bulkPut(mut.values, keys);\n } else {\n keys.forEach((key, i) => {\n // Make sure inbound keys are consistent\n Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath!, key);\n });\n await table.bulkPut(mut.values);\n }\n break;\n case 'modify':\n if (keys.length === 1) {\n await table.update(keys[0], mut.changeSpec);\n } else {\n await table.where(':id').anyOf(keys).modify(mut.changeSpec);\n }\n break;\n case 'update':\n await bulkUpdate(table, keys, mut.changeSpecs);\n break;\n case 'delete':\n await table.bulkDelete(keys);\n break;\n }\n }\n }\n}\n","\nexport const DEXIE_CLOUD_SYNCER_ID = 'dexie-cloud-syncer';\n","import type { Table } from 'dexie';\nimport type { YUpdateRow } from 'y-dexie';\n\nexport function listUpdatesSince(yTable: Table, sinceIncluding: number): Promise<YUpdateRow[]> {\n return yTable\n .where('i')\n .between(sinceIncluding, Infinity, true)\n .toArray();\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { YTable } from \"./YTable\";\n\nexport function getUpdatesTable(db: DexieCloudDB, table: string, ydocProp: string): YTable | undefined {\n if (!db.dx._allTables[table]) return undefined;\n const utbl = db.table(table)?.schema.yProps?.find(p => p.prop === ydocProp)?.updatesTable;\n if (!utbl) {\n console.debug(`No updatesTable found for ${table}.${ydocProp}`);\n return undefined;\n }\n if (!db.dx._allTables[utbl]) return undefined;\n return db.table(utbl);\n}\n","import { cmp, InsertType } from 'dexie';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { YServerMessage } from 'dexie-cloud-common';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport { getUpdatesTable } from './getUpdatesTable';\nimport { DexieYProvider, YSyncState, YUpdateRow } from 'y-dexie';\n\nexport async function applyYServerMessages(\n yMessages: YServerMessage[],\n db: DexieCloudDB\n): Promise<{\n receivedUntils: { [yTable: string]: number };\n resyncNeeded: boolean;\n yServerRevision?: string;\n}> {\n const receivedUntils: { [yTable: string]: number } = {};\n let resyncNeeded = false;\n let yServerRevision: string | undefined;\n for (const m of yMessages) {\n try {\n switch (m.type) {\n case 'u-s': {\n const utbl = getUpdatesTable(db, m.table, m.prop);\n if (utbl) {\n const updateRow: InsertType<YUpdateRow, 'i'> = {\n k: m.k,\n u: m.u,\n };\n if (m.r) {\n // @ts-ignore\n updateRow.r = m.r;\n yServerRevision = m.r;\n }\n receivedUntils[utbl.name] = await utbl.add(updateRow);\n }\n break;\n }\n case 'u-ack': {\n const utbl = getUpdatesTable(db, m.table, m.prop);\n if (utbl) {\n await db.transaction('rw', utbl, async (tx) => {\n let syncer = (await tx\n .table(utbl.name)\n .get(DEXIE_CLOUD_SYNCER_ID)) as YSyncState | undefined;\n await tx.table(utbl.name).put({\n ...(syncer || { i: DEXIE_CLOUD_SYNCER_ID }),\n unsentFrom: Math.max(syncer?.unsentFrom || 1, m.i + 1),\n } as YSyncState);\n });\n }\n break;\n }\n case 'u-reject': {\n // Acces control or constraint rejected the update.\n // We delete it. It's not going to be sent again.\n // What's missing is a way to notify consumers, such as Tiptap editor, that the update was rejected.\n // This is only an issue when the document is open. We could find the open document and\n // in a perfect world, we should send a reverse update to the open document to undo the change.\n // See my question in https://discuss.yjs.dev/t/generate-an-inverse-update/2765\n console.debug(`Y update rejected. Deleting it.`);\n const utbl = getUpdatesTable(db, m.table, m.prop);\n if (!utbl) break;\n // Delete the rejected update and all local updates since (avoid holes in the CRDT)\n // and destroy it's open document if there is one.\n const primaryKey = (await utbl.get(m.i))?.k;\n if (primaryKey != null) {\n await db.transaction('rw', utbl, (tx) => {\n // @ts-ignore\n tx.idbtrans._rejecting_y_ypdate = true; // Inform ydoc triggers that we delete because of a rejection and not GC\n return utbl\n .where('i')\n .aboveOrEqual(m.i)\n .filter(\n (u) => cmp(u.k, primaryKey) === 0 && ((u.f || 0) & 1) === 1\n )\n .delete();\n });\n // Destroy active doc\n const activeDoc = DexieYProvider.getDocCache(db.dx).find(\n m.table,\n primaryKey,\n m.prop\n );\n if (activeDoc) activeDoc.destroy(); // Destroy the document so that editors don't continue to work on it\n }\n break;\n }\n case 'in-sync': {\n const doc = DexieYProvider.getDocCache(db.dx).find(\n m.table,\n m.k,\n m.prop\n );\n if (doc && !doc.isSynced) {\n doc.emit('sync', [true, doc]);\n }\n break;\n }\n case 'y-complete-sync-done': {\n yServerRevision = m.yServerRev;\n break;\n }\n case 'outdated-server-rev':\n resyncNeeded = true;\n break;\n }\n } catch (e) {\n console.error(`Failed to apply YMessage`, m, e);\n }\n }\n\n return {\n receivedUntils,\n resyncNeeded,\n yServerRevision,\n };\n}\n","import {\n asyncIterablePipeline,\n consumeChunkedBinaryStream,\n getFetchResponseBodyGenerator,\n} from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { TSON } from '../TSON';\nimport { loadAccessToken } from '../authentication/authenticate';\nimport {\n Decoder,\n readUint8,\n readVarString,\n readAny,\n readVarUint8Array,\n hasContent,\n} from 'lib0/decoding';\nimport { getUpdatesTable } from './getUpdatesTable';\nimport Dexie, { InsertType } from 'dexie';\nimport type { YUpdateRow } from 'y-dexie';\n\nconst BINSTREAM_TYPE_REALMID = 1;\nconst BINSTREAM_TYPE_TABLE_AND_PROP = 2;\nconst BINSTREAM_TYPE_DOCUMENT = 3;\n\nexport async function downloadYDocsFromServer(\n db: DexieCloudDB,\n databaseUrl: string,\n { yDownloadedRealms, realms }: PersistedSyncState\n) {\n if (\n yDownloadedRealms &&\n realms &&\n realms.every((realmId) => yDownloadedRealms[realmId] === '*')\n ) {\n return; // Already done!\n }\n console.debug('Downloading Y.Docs from added realms');\n const user = await loadAccessToken(db);\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n Accept: 'application/octet-stream',\n };\n if (user) {\n headers.Authorization = `Bearer ${user.accessToken}`;\n }\n const res = await fetch(`${databaseUrl}/y/download`, {\n body: TSON.stringify({ downloadedRealms: yDownloadedRealms || {} }),\n method: 'POST',\n headers,\n credentials: 'include',\n });\n if (!res.ok) {\n throw new Error(\n `Failed to download Yjs documents from server. Status: ${res.status}`\n );\n }\n await asyncIterablePipeline(\n getFetchResponseBodyGenerator(res),\n consumeChunkedBinaryStream,\n consumeDownloadChunks\n );\n\n async function* consumeDownloadChunks(chunks: AsyncIterable<Uint8Array>) {\n let currentRealmId: string | null = null;\n let currentTable: string | null = null;\n let currentProp: string | null = null;\n let docsToInsert: InsertType<YUpdateRow, 'i'>[] = [];\n\n async function storeCollectedDocs(completedRealm: boolean) {\n const lastDoc = docsToInsert[docsToInsert.length - 1];\n if (docsToInsert.length > 0) {\n if (!currentRealmId || !currentTable || !currentProp) {\n throw new Error(`Protocol error from ${databaseUrl}/y/download`);\n }\n const yTable = getUpdatesTable(db, currentTable, currentProp);\n if (yTable) {\n await yTable.bulkAdd(docsToInsert);\n }\n docsToInsert = [];\n }\n if (\n currentRealmId &&\n ((currentTable && currentProp && lastDoc) || completedRealm)\n ) {\n await db.$syncState.update('syncState', (syncState: PersistedSyncState) => {\n const yDownloadedRealms = syncState.yDownloadedRealms || {};\n yDownloadedRealms[currentRealmId!] = completedRealm\n ? '*'\n : {\n tbl: currentTable!,\n prop: currentProp!,\n key: lastDoc.k!,\n };\n syncState.yDownloadedRealms = yDownloadedRealms;\n });\n }\n }\n\n try {\n for await (const chunk of chunks) {\n const decoder = new Decoder(chunk);\n while (hasContent(decoder)) {\n switch (readUint8(decoder)) {\n case BINSTREAM_TYPE_REALMID:\n await storeCollectedDocs(true);\n currentRealmId = readVarString(decoder);\n break;\n case BINSTREAM_TYPE_TABLE_AND_PROP:\n await storeCollectedDocs(false); // still on same realm\n currentTable = readVarString(decoder);\n currentProp = readVarString(decoder);\n break;\n case BINSTREAM_TYPE_DOCUMENT: {\n const k = readAny(decoder);\n const u = readVarUint8Array(decoder);\n docsToInsert.push({\n k,\n u,\n });\n break;\n }\n }\n }\n await storeCollectedDocs(false); // Chunk full - migth still be on same realm\n }\n await storeCollectedDocs(true); // Everything downloaded - finalize last downloaded realm to \"*\"\n } catch (error) {\n if (!(error instanceof Dexie.DexieError)) {\n // Network error might have happened.\n // Store what we've collected so far:\n await storeCollectedDocs(false);\n }\n throw error;\n }\n }\n}\n","import { __asyncValues } from \"tslib\";\nexport async function asyncIterablePipeline(source, ...stages) {\n var _a, e_1, _b, _c;\n // Chain generators by sending outdata from one to another\n let result = source(); // Start with the source generator\n for (let i = 0; i < stages.length; i++) {\n result = stages[i](result); // Pass on the result to next generator\n }\n try {\n // Start running the machine. If the last stage is a sink, it will consume the data and never emit anything\n // to us here...\n for (var _d = true, result_1 = __asyncValues(result), result_1_1; result_1_1 = await result_1.next(), _a = result_1_1.done, !_a; _d = true) {\n _c = result_1_1.value;\n _d = false;\n const chunk = _c;\n }\n }\n catch (e_1_1) { e_1 = { error: e_1_1 }; }\n finally {\n try {\n if (!_d && !_a && (_b = result_1.return)) await _b.call(result_1);\n }\n finally { if (e_1) throw e_1.error; }\n }\n}\n","import { __asyncGenerator, __await } from \"tslib\";\nexport function getFetchResponseBodyGenerator(res) {\n return function () {\n return __asyncGenerator(this, arguments, function* () {\n if (!res.body)\n throw new Error(\"Response body is not readable\");\n const reader = res.body.getReader();\n try {\n while (true) {\n const { done, value } = yield __await(reader.read());\n if (done)\n return yield __await(void 0);\n yield yield __await(value);\n }\n }\n finally {\n reader.releaseLock();\n }\n });\n };\n}\n","import { getMutationTable } from '../helpers/getMutationTable';\nimport { getSyncableTables } from '../helpers/getSyncableTables';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { listSyncifiedChanges } from './listSyncifiedChanges';\nimport { getTablesToSyncify } from './getTablesToSyncify';\nimport { listClientChanges } from './listClientChanges';\nimport { syncWithServer } from './syncWithServer';\nimport { modifyLocalObjectsWithNewUserId } from './modifyLocalObjectsWithNewUserId';\nimport { throwIfCancelled } from '../helpers/CancelToken';\nimport { DexieCloudOptions } from '../DexieCloudOptions';\nimport { BaseRevisionMapEntry } from '../db/entities/BaseRevisionMapEntry';\nimport { getTableFromMutationTable } from '../helpers/getTableFromMutationTable';\nimport {\n applyOperations,\n DBKeyMutationSet,\n DBOperationsSet,\n DexieCloudSchema,\n randomString,\n subtractChanges,\n SyncResponse,\n toDBOperationSet,\n} from 'dexie-cloud-common';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { isOnline } from './isOnline';\nimport { updateBaseRevs } from './updateBaseRevs';\nimport { getLatestRevisionsPerTable } from './getLatestRevisionsPerTable';\nimport { applyServerChanges } from './applyServerChanges';\nimport { checkSyncRateLimitDelay } from './ratelimit';\nimport { listYClientMessagesAndStateVector } from '../yjs/listYClientMessagesAndStateVector';\nimport { applyYServerMessages } from '../yjs/applyYMessages';\nimport { updateYSyncStates } from '../yjs/updateYSyncStates';\nimport { downloadYDocsFromServer } from '../yjs/downloadYDocsFromServer';\nimport { UpdateSpec } from 'dexie';\n\nexport const CURRENT_SYNC_WORKER = 'currentSyncWorker';\n\nexport interface SyncOptions {\n isInitialSync?: boolean;\n cancelToken?: { cancelled: boolean };\n justCheckIfNeeded?: boolean;\n retryImmediatelyOnFetchError?: boolean;\n purpose?: 'pull' | 'push';\n}\n\nexport function sync(\n db: DexieCloudDB,\n options: DexieCloudOptions,\n schema: DexieCloudSchema,\n syncOptions?: SyncOptions\n): Promise<boolean> {\n return _sync(db, options, schema, syncOptions)\n .then((result) => {\n if (!syncOptions?.justCheckIfNeeded) { // && syncOptions?.purpose !== 'push') {\n db.syncStateChangedEvent.next({\n phase: 'in-sync',\n });\n }\n return result;\n })\n .catch(async (error: any) => {\n if (syncOptions?.justCheckIfNeeded) return Promise.reject(error); // Just rethrow.\n console.debug('Error from _sync', {\n isOnline,\n syncOptions,\n error,\n });\n if (\n isOnline &&\n syncOptions?.retryImmediatelyOnFetchError &&\n error?.name === 'TypeError' &&\n /fetch/.test(error?.message)\n ) {\n db.syncStateChangedEvent.next({\n phase: 'error',\n error,\n });\n // Retry again in 500 ms but if it fails again, don't retry.\n await new Promise((resolve) => setTimeout(resolve, 500));\n return await sync(db, options, schema, {\n ...syncOptions,\n retryImmediatelyOnFetchError: false,\n });\n }\n // Make sure that no matter whether sync() explodes or not,\n // always update the timestamp. Also store the error.\n await db.$syncState.update('syncState', {\n timestamp: new Date(),\n error: '' + error,\n });\n db.syncStateChangedEvent.next({\n phase: isOnline ? 'error' : 'offline',\n error: new Error('' + error?.message || error),\n });\n return Promise.reject(error);\n });\n}\n\nasync function _sync(\n db: DexieCloudDB,\n options: DexieCloudOptions,\n schema: DexieCloudSchema,\n { isInitialSync, cancelToken, justCheckIfNeeded, purpose }: SyncOptions = {\n isInitialSync: false,\n }\n): Promise<boolean> {\n if (!justCheckIfNeeded) {\n console.debug('SYNC STARTED', { isInitialSync, purpose });\n }\n if (!db.cloud.options?.databaseUrl)\n throw new Error(\n `Internal error: sync must not be called when no databaseUrl is configured`\n );\n const { databaseUrl } = options;\n const currentUser = await db.getCurrentUser(); // Keep same value across entire sync flow:\n const tablesToSync = currentUser.isLoggedIn ? getSyncableTables(db) : [];\n\n const mutationTables = tablesToSync.map((tbl) =>\n db.table(getMutationTable(tbl.name))\n );\n\n // If this is not the initial sync,\n // go through tables that were previously not synced but should now be according to\n // logged in state and the sync table whitelist in db.cloud.options.\n //\n // Prepare for syncification by modifying locally unauthorized objects:\n //\n const persistedSyncState = await db.getPersistedSyncState();\n const readyForSyncification = currentUser.isLoggedIn;\n const tablesToSyncify = readyForSyncification\n ? getTablesToSyncify(db, persistedSyncState)\n : [];\n throwIfCancelled(cancelToken);\n const doSyncify = tablesToSyncify.length > 0;\n\n if (doSyncify) {\n if (justCheckIfNeeded) return true;\n //console.debug('sync doSyncify is true');\n await db.transaction('rw', tablesToSyncify, async (tx) => {\n // @ts-ignore\n tx.idbtrans.disableChangeTracking = true;\n // @ts-ignore\n tx.idbtrans.disableAccessControl = true; // TODO: Take care of this flag in access control middleware!\n await modifyLocalObjectsWithNewUserId(\n tablesToSyncify,\n currentUser,\n persistedSyncState?.realms\n );\n });\n throwIfCancelled(cancelToken);\n }\n //\n // List changes to sync\n //\n const [clientChangeSet, syncState, baseRevs, {yMessages, lastUpdateIds}] = await db.transaction(\n 'r',\n db.tables,\n async () => {\n const syncState = await db.getPersistedSyncState();\n let baseRevs = await db.$baseRevs.toArray();\n \n // Resolve #2168\n baseRevs = baseRevs.filter(br => tablesToSync.some(tbl => tbl.name === br.tableName));\n\n let clientChanges = await listClientChanges(mutationTables, db);\n const yResults = await listYClientMessagesAndStateVector(db, tablesToSync);\n throwIfCancelled(cancelToken);\n if (doSyncify) {\n const alreadySyncedRealms = [\n ...(persistedSyncState?.realms || []),\n ...(persistedSyncState?.inviteRealms || []),\n ];\n const syncificationInserts = await listSyncifiedChanges(\n tablesToSyncify,\n currentUser,\n schema!,\n alreadySyncedRealms\n );\n throwIfCancelled(cancelToken);\n clientChanges = clientChanges.concat(syncificationInserts);\n return [clientChanges, syncState, baseRevs, yResults];\n }\n return [clientChanges, syncState, baseRevs, yResults];\n }\n );\n\n const pushSyncIsNeeded = clientChangeSet.some((set) =>\n set.muts.some((mut) => mut.keys.length > 0)\n ) || yMessages.some(m => m.type === 'u-c');\n if (justCheckIfNeeded) {\n console.debug('Sync is needed:', pushSyncIsNeeded);\n return pushSyncIsNeeded;\n }\n if (purpose === 'push' && !pushSyncIsNeeded) {\n // The purpose of this request was to push changes\n return false;\n }\n\n const latestRevisions = getLatestRevisionsPerTable(\n clientChangeSet,\n syncState?.latestRevisions\n );\n\n const clientIdentity = syncState?.clientIdentity || randomString(16);\n\n //\n // Push changes to server\n //\n throwIfCancelled(cancelToken);\n const res = await syncWithServer(\n clientChangeSet,\n yMessages,\n syncState,\n baseRevs,\n db,\n databaseUrl,\n schema,\n clientIdentity,\n currentUser\n );\n console.debug('Sync response', res);\n\n //\n // Apply changes locally and clear old change entries:\n //\n const {done, newSyncState} = await db.transaction('rw', db.tables, async (tx) => {\n // @ts-ignore\n tx.idbtrans.disableChangeTracking = true;\n // @ts-ignore\n tx.idbtrans.disableAccessControl = true; // TODO: Take care of this flag in access control middleware!\n\n // Update db.cloud.schema from server response.\n // Local schema MAY include a subset of tables, so do not force all tables into local schema.\n for (const tableName of Object.keys(schema)) {\n if (res.schema[tableName]) {\n // Write directly into configured schema. This code can only be executed alone.\n schema[tableName] = res.schema[tableName];\n }\n }\n await db.$syncState.put(schema, 'schema');\n\n // List mutations that happened during our exchange with the server:\n const addedClientChanges = await listClientChanges(mutationTables, db, {\n since: latestRevisions,\n });\n\n //\n // Delete changes now as server has return success\n // (but keep changes that haven't reached server yet)\n //\n for (const mutTable of mutationTables) {\n const tableName = getTableFromMutationTable(mutTable.name);\n if (\n !addedClientChanges.some(\n (ch) => ch.table === tableName && ch.muts.length > 0\n )\n ) {\n // No added mutations for this table during the time we sent changes\n // to the server.\n // It is therefore safe to clear all changes (which is faster than\n // deleting a range)\n await Promise.all([\n mutTable.clear(),\n db.$baseRevs.where({ tableName }).delete(),\n ]);\n } else if (latestRevisions[tableName]) {\n const latestRev = latestRevisions[tableName] || 0;\n await Promise.all([\n mutTable.where('rev').belowOrEqual(latestRev).delete(),\n db.$baseRevs\n .where(':id')\n .between(\n [tableName, -Infinity],\n [tableName, latestRev + 1],\n true,\n true\n )\n .reverse()\n .offset(1) // Keep one entry (the one mapping muts that came during fetch --> previous server revision)\n .delete(),\n ]);\n } else {\n // In this case, the mutation table only contains added items after sending empty changeset to server.\n // We should not clear out anything now.\n }\n }\n\n // Update latestRevisions object according to additional changes:\n getLatestRevisionsPerTable(addedClientChanges, latestRevisions);\n\n // Update/add new entries into baseRevs map.\n // * On tables without mutations since last serverRevision,\n // this will update existing entry.\n // * On tables where mutations have been recorded since last\n // serverRevision, this will create a new entry.\n // The purpose of this operation is to mark a start revision (per table)\n // so that all client-mutations that come after this, will be mapped to current\n // server revision.\n await updateBaseRevs(db, schema, latestRevisions, res.serverRevision);\n\n const syncState = await db.getPersistedSyncState();\n\n //\n // Delete objects from removed realms\n //\n await deleteObjectsFromRemovedRealms(db, res, syncState);\n\n //\n // Update syncState\n //\n const newSyncState: PersistedSyncState = syncState || {\n syncedTables: [],\n latestRevisions: {},\n realms: [],\n inviteRealms: [],\n clientIdentity,\n };\n if (readyForSyncification) {\n newSyncState.syncedTables = tablesToSync\n .map((tbl) => tbl.name)\n .concat(tablesToSyncify.map((tbl) => tbl.name));\n }\n newSyncState.latestRevisions = latestRevisions;\n newSyncState.remoteDbId = res.dbId;\n newSyncState.initiallySynced = true;\n newSyncState.realms = res.realms;\n newSyncState.inviteRealms = res.inviteRealms;\n newSyncState.serverRevision = res.serverRevision;\n newSyncState.yServerRevision = res.serverRevision;\n newSyncState.timestamp = new Date();\n delete newSyncState.error;\n\n const filteredChanges = filterServerChangesThroughAddedClientChanges(\n res.changes,\n addedClientChanges\n );\n\n //\n // apply server changes\n //\n await applyServerChanges(filteredChanges, db);\n\n if (res.yMessages) {\n //\n // apply yMessages\n //\n const {receivedUntils, resyncNeeded, yServerRevision} = await applyYServerMessages(res.yMessages, db);\n if (yServerRevision) {\n newSyncState.yServerRevision = yServerRevision;\n }\n\n //\n // update Y SyncStates\n //\n await updateYSyncStates(lastUpdateIds, receivedUntils, db);\n\n if (resyncNeeded) {\n newSyncState.yDownloadedRealms = {}; // Will trigger a full download of Y-documents below...\n }\n }\n\n //\n // Update regular syncState\n //\n db.$syncState.put(newSyncState, 'syncState');\n\n return {\n done: addedClientChanges.length === 0,\n newSyncState\n };\n });\n if (!done) {\n console.debug('MORE SYNC NEEDED. Go for it again!');\n await checkSyncRateLimitDelay(db);\n return await _sync(db, options, schema, { isInitialSync, cancelToken });\n }\n const usingYProps = Object.values(schema).some(tbl => tbl.yProps?.length);\n const serverSupportsYprops = !!res.yMessages;\n if (usingYProps && serverSupportsYprops) {\n try {\n await downloadYDocsFromServer(db, databaseUrl, newSyncState);\n } catch (error) {\n console.error('Failed to download Yjs documents from server', error);\n }\n }\n console.debug('SYNC DONE', { isInitialSync });\n db.syncCompleteEvent.next();\n return false; // Not needed anymore\n}\n\nasync function deleteObjectsFromRemovedRealms(\n db: DexieCloudDB,\n res: SyncResponse,\n syncState: PersistedSyncState | undefined\n) {\n const deletedRealms = new Set<string>();\n const rejectedRealms = new Set<string>();\n const previousRealmSet = syncState ? syncState.realms : [];\n const previousInviteRealmSet = syncState ? syncState.inviteRealms : [];\n const updatedRealmSet = new Set(res.realms);\n const updatedTotalRealmSet = new Set(res.realms.concat(res.inviteRealms));\n for (const realmId of previousRealmSet) {\n if (!updatedRealmSet.has(realmId)) {\n rejectedRealms.add(realmId);\n if (!updatedTotalRealmSet.has(realmId)) {\n deletedRealms.add(realmId);\n }\n }\n }\n for (const realmId of previousInviteRealmSet.concat(previousRealmSet)) {\n if (!updatedTotalRealmSet.has(realmId)) {\n deletedRealms.add(realmId);\n }\n }\n if (deletedRealms.size > 0 || rejectedRealms.size > 0) {\n const tables = getSyncableTables(db);\n for (const table of tables) {\n let realmsToDelete = ['realms', 'members', 'roles'].includes(table.name)\n ? deletedRealms // These tables should spare rejected ones.\n : rejectedRealms; // All other tables shoudl delete rejected+deleted ones\n if (realmsToDelete.size === 0) continue;\n if (\n table.schema.indexes.some(\n (idx) =>\n idx.keyPath === 'realmId' ||\n (Array.isArray(idx.keyPath) && idx.keyPath[0] === 'realmId')\n )\n ) {\n // There's an index to use:\n //console.debug(`REMOVAL: deleting all ${table.name} where realmId anyOf `, JSON.stringify([...realmsToDelete]));\n await table\n .where('realmId')\n .anyOf([...realmsToDelete])\n .delete();\n } else {\n // No index to use:\n //console.debug(`REMOVAL: deleting all ${table.name} where realmId is any of `, JSON.stringify([...realmsToDelete]), realmsToDelete.size);\n await table\n .filter((obj) => !!obj?.realmId && realmsToDelete.has(obj.realmId))\n .delete();\n }\n }\n }\n if (rejectedRealms.size > 0 && syncState?.yDownloadedRealms) {\n // Remove rejected/deleted realms from yDownloadedRealms because of the following use case:\n // 1. User becomes added to the realm\n // 2. User syncs and all documents of the realm is downloaded (downloadYDocsFromServer.ts)\n // 3. User leaves the realm and all docs are deleted locally (built-in-trigger of deleting their rows in this file)\n // 4. User is yet again added to the realm. At this point, we must make sure the docs are not considered already downloaded.\n const updateSpec: UpdateSpec<PersistedSyncState> = {};\n for (const realmId of rejectedRealms) {\n delete syncState.yDownloadedRealms[realmId];\n } \n }\n}\n\nexport function filterServerChangesThroughAddedClientChanges(\n serverChanges: DBOperationsSet<string>,\n addedClientChanges: DBOperationsSet\n): DBOperationsSet<string> {\n const changes: DBKeyMutationSet = {};\n applyOperations(changes, serverChanges);\n const localPostChanges: DBKeyMutationSet = {};\n applyOperations(localPostChanges, addedClientChanges);\n subtractChanges(changes, localPostChanges);\n return toDBOperationSet(changes);\n}\n","import { getSyncableTables } from \"../helpers/getSyncableTables\";\nimport { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { PersistedSyncState } from \"../db/entities/PersistedSyncState\";\n\nexport function getTablesToSyncify(db: DexieCloudDB, syncState: PersistedSyncState | undefined) {\n const syncedTables = syncState?.syncedTables || [];\n const syncableTables = getSyncableTables(db);\n const tablesToSyncify = syncableTables.filter(\n (tbl) => !syncedTables.includes(tbl.name)\n );\n return tablesToSyncify;\n}\n","import { Table } from \"dexie\";\nimport { EntityCommon } from \"../db/entities/EntityCommon\";\nimport { UserLogin } from \"../db/entities/UserLogin\";\nimport { Member } from \"../db/entities/Member\";\nimport { UNAUTHORIZED_USER } from \"../authentication/UNAUTHORIZED_USER\";\nimport { Realm } from \"../db/entities/Realm\";\n\nexport async function modifyLocalObjectsWithNewUserId(\n syncifiedTables: Table<EntityCommon>[],\n currentUser: UserLogin,\n alreadySyncedRealms?: string[]) {\n const ignoredRealms = new Set(alreadySyncedRealms || []);\n for (const table of syncifiedTables) {\n if (table.name === \"members\") {\n // members\n await table.toCollection().modify((member: Member) => {\n if (!ignoredRealms.has(member.realmId) && (!member.userId || member.userId === UNAUTHORIZED_USER.userId)) {\n member.userId = currentUser.userId;\n }\n });\n } else if (table.name === \"roles\") {\n // roles\n // No changes needed.\n } else if (table.name === \"realms\") {\n // realms\n await table.toCollection().modify((realm: Realm) => {\n if (!ignoredRealms.has(realm.realmId) && (realm.owner === undefined || realm.owner === UNAUTHORIZED_USER.userId)) {\n realm.owner = currentUser.userId;\n }\n });\n } else {\n // application entities\n await table.toCollection().modify((obj) => {\n if (!obj.realmId || !ignoredRealms.has(obj.realmId)) {\n if (!obj.owner || obj.owner === UNAUTHORIZED_USER.userId)\n obj.owner = currentUser.userId;\n if (!obj.realmId || obj.realmId === UNAUTHORIZED_USER.userId) {\n obj.realmId = currentUser.userId;\n }\n }\n });\n }\n }\n}\n","import type { Table } from 'dexie';\nimport type { YClientMessage } from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport { listUpdatesSince } from './listUpdatesSince';\nimport * as Y from 'yjs';\nimport { EntityCommon } from '../db/entities/EntityCommon';\nimport type { YSyncState } from 'y-dexie';\n\n/** Queries the local database for YMessages to send to server.\n * \n * There are 2 messages that this function can provide:\n * YUpdateFromClientRequest ( for local updates )\n * YStateVector ( for state vector of foreign updates so that server can reduce the number of udpates to send back )\n *\n * Notice that we do not do a step 1 sync phase here to get a state vector from the server. Reason we can avoid\n * the 2-step sync is that we are client-server and not client-client here and we keep track of the client changes\n * sent to server by letting server acknowledge them. There is always a chance that some client update has already\n * been sent and that the client failed to receive the ack. However, if this happens it does not matter - the change\n * would be sent again and Yjs handles duplicate changes anyway. And it's rare so we earn the cost of roundtrips by\n * avoiding the step1 sync and instead keep track of this in the `unsentFrom` property of the SyncState.\n * \n * @param db \n * @returns \n */\nexport async function listYClientMessagesAndStateVector(\n db: DexieCloudDB,\n tablesToSync: Table<EntityCommon>[]\n): Promise<{yMessages: YClientMessage[], lastUpdateIds: {[yTable: string]: number}}> {\n const result: YClientMessage[] = [];\n const lastUpdateIds: {[yTable: string]: number} = {};\n for (const table of tablesToSync) {\n if (table.schema.yProps) {\n for (const yProp of table.schema.yProps) {\n const yTable = db.table(yProp.updatesTable); // the updates-table for this combo of table+propName\n const syncState = (await yTable.get(DEXIE_CLOUD_SYNCER_ID)) as\n | YSyncState\n | undefined;\n\n // unsentFrom = the `i` value of updates that aren't yet sent to server (or at least not acked by the server yet)\n const unsentFrom = syncState?.unsentFrom || 1;\n // receivedUntil = the `i` value of updates that both we and the server knows we already have (we know it by the outcome from last syncWithServer() because server keep track of its revision numbers\n const receivedUntil = syncState?.receivedUntil || 0;\n // Compute the least value of these two (but since receivedUntil is inclusive we need to add +1 to it)\n const unsyncedFrom = Math.min(unsentFrom, receivedUntil + 1);\n // Query all these updates for all docs of this table+prop combination\n const updates = await listUpdatesSince(yTable, unsyncedFrom);\n if (updates.length > 0) lastUpdateIds[yTable.name] = updates[updates.length -1].i;\n\n // Now sort them by document and whether they are local or not + ignore local updates already sent:\n const perDoc: {\n [docKey: string]: {\n i: number;\n k: any;\n isLocal: boolean;\n u: Uint8Array[];\n };\n } = {};\n for (const update of updates) {\n // Sort updates into buckets of the doc primary key + the flag (whether it's local or foreign)\n const isLocal = ((update.f || 0) & 0x01) === 0x01;\n if (isLocal && update.i < unsentFrom) continue; // This local update has already been sent and acked.\n const docKey = JSON.stringify(update.k) + '/' + isLocal;\n let entry = perDoc[docKey];\n if (!entry) {\n perDoc[docKey] = entry = {\n i: update.i,\n k: update.k,\n isLocal,\n u: [],\n };\n entry.u.push(update.u);\n } else {\n entry.u.push(update.u);\n entry.i = Math.max(update.i, entry.i);\n }\n }\n\n // Now, go through all these and:\n // * For local updates, compute a merged update per document.\n // * For foreign updates, compute a state vector to pass to server, so that server can\n // avoid re-sending updates that we already have (they might have been sent of websocket\n // and when that happens, we do not mark them in any way nor do we update receivedUntil -\n // we only update receivedUntil after a \"full sync\" (syncWithServer()))\n for (const { k, isLocal, u, i } of Object.values(perDoc)) {\n const mergedUpdate = u.length === 1 ? u[0] : Y.mergeUpdatesV2(u);\n if (isLocal) {\n result.push({\n type: 'u-c',\n table: table.name,\n prop: yProp.prop,\n k,\n u: mergedUpdate,\n i,\n });\n } else {\n const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);\n result.push({\n type: 'sv',\n table: table.name,\n prop: yProp.prop,\n k,\n sv: stateVector,\n });\n }\n }\n }\n }\n }\n return {\n yMessages: result,\n lastUpdateIds\n };\n}\n","import { UserLogin } from '../db/entities/UserLogin';\nimport { randomString } from '../helpers/randomString';\nimport { EntityCommon } from '../db/entities/EntityCommon';\nimport { Table } from 'dexie';\nimport {\n DBOperationsSet,\n DBUpsertOperation,\n DexieCloudSchema,\n isValidAtID,\n isValidSyncableID,\n} from 'dexie-cloud-common';\n\nexport async function listSyncifiedChanges(\n tablesToSyncify: Table<EntityCommon>[],\n currentUser: UserLogin,\n schema: DexieCloudSchema,\n alreadySyncedRealms?: string[]\n): Promise<DBOperationsSet> {\n const txid = `upload-${randomString(8)}`;\n if (currentUser.isLoggedIn) {\n if (tablesToSyncify.length > 0) {\n const ignoredRealms = new Set(alreadySyncedRealms || []);\n const upserts = await Promise.all(\n tablesToSyncify.map(async (table) => {\n const { extractKey } = table.core.schema.primaryKey;\n if (!extractKey) return { table: table.name, muts: [] }; // Outbound tables are not synced.\n\n const dexieCloudTableSchema = schema[table.name];\n const query = dexieCloudTableSchema?.generatedGlobalId\n ? table.filter((item) => {\n const id = extractKey(item);\n return (\n !ignoredRealms.has(item.realmId || '') &&\n //(id[0] !== '#' || !!item.$ts) && // Private obj need no sync if not changed\n isValidAtID(extractKey(item), dexieCloudTableSchema?.idPrefix)\n );\n })\n : table.filter((item) => {\n const id = extractKey(item);\n\n return (\n !ignoredRealms.has(item.realmId || '') &&\n //(id[0] !== '#' || !!item.$ts) && // Private obj need no sync if not changed\n isValidSyncableID(id)\n );\n });\n const unsyncedObjects = await query.toArray();\n if (unsyncedObjects.length > 0) {\n const mut: DBUpsertOperation = {\n type: 'upsert',\n values: unsyncedObjects,\n keys: unsyncedObjects.map(extractKey),\n userId: currentUser.userId,\n txid,\n };\n return {\n table: table.name,\n muts: [mut],\n };\n } else {\n return {\n table: table.name,\n muts: [],\n };\n }\n })\n );\n return upserts.filter((op) => op.muts.length > 0);\n }\n }\n return [];\n}\n","import { UpdateSpec } from 'dexie';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport { YDexieCloudSyncState } from './YDexieCloudSyncState';\n\nexport async function updateYSyncStates(\n lastUpdateIdsBeforeSync: { [yTable: string]: number },\n receivedUntilsAfterSync: { [yTable: string]: number },\n db: DexieCloudDB\n) {\n // We want to update unsentFrom for each yTable to the value specified in first argument\n // because we got those values before we synced with server and here we are back from server\n // that has successfully received all those messages - no matter if the last update was a client or server update,\n // we can safely store unsentFrom to a value of the last update + 1 here.\n // We also want to update receivedUntil for each yTable to the value specified in the second argument,\n // because that contains the highest resulted id of each update from server after storing it.\n // We could do these two tasks separately, but that would require two update calls on the same YSyncState, so\n // to optimize the dexie calls, we merge these two maps into a single one so we can do a single update request\n // per yTable.\n const mergedSpec: {\n [yTable: string]: { unsentFrom?: number; receivedUntil?: number };\n } = {};\n for (const [yTable, lastUpdateId] of Object.entries(\n lastUpdateIdsBeforeSync\n )) {\n mergedSpec[yTable] ??= {};\n mergedSpec[yTable].unsentFrom = lastUpdateId + 1;\n }\n for (const [yTable, lastUpdateId] of Object.entries(\n receivedUntilsAfterSync\n )) {\n mergedSpec[yTable] ??= {};\n mergedSpec[yTable].receivedUntil = lastUpdateId;\n }\n\n // Now go through all yTables and update their YSyncStates:\n const allYTables = Object.values(db.dx._dbSchema)\n .filter((tblSchema) => tblSchema.yProps)\n .map((tblSchema) => tblSchema.yProps!.map((yProp) => yProp.updatesTable))\n .flat();\n for (const yTable of allYTables) {\n const mergedEntry = mergedSpec[yTable];\n const unsentFrom = mergedEntry?.unsentFrom ?? 1;\n const receivedUntil =\n mergedEntry?.receivedUntil ?? // If not received anything on this table, pick the current last update id\n // from local because we are in the same parent transaction (in sync.ts) that\n // applied all updates from the server\n ((\n await db\n .table(yTable)\n .where('i')\n .between(1, Infinity) // Because i might be string DEXIE_CLOUD_SYNCER_ID if not a number.\n .reverse()\n .limit(1)\n .primaryKeys()\n )[0] as number) ??\n 0;\n // We're already in a transaction, but for the sake of\n // code readability and correctness, let's launch an atomic sub transaction:\n await db.transaction('rw', yTable, async () => {\n const state: YDexieCloudSyncState | undefined = await db\n .table(yTable)\n .get(DEXIE_CLOUD_SYNCER_ID);\n if (!state) {\n await db.table<YDexieCloudSyncState>(yTable).add({\n i: DEXIE_CLOUD_SYNCER_ID,\n unsentFrom,\n receivedUntil\n });\n } else {\n state.unsentFrom = Math.max(unsentFrom, state.unsentFrom || 1);\n state.receivedUntil = Math.max(receivedUntil, state.receivedUntil || 0);\n await db.table(yTable).put(state);\n }\n });\n }\n}\n","import { setByKeyPath } from '../utils.js';\nexport function subtractChanges(target, // Server change set\nchangesToSubtract // additional mutations on client during syncWithServer()\n) {\n var _a, _b, _c;\n for (const [table, mutationSet] of Object.entries(changesToSubtract)) {\n for (const [key, mut] of Object.entries(mutationSet)) {\n switch (mut.type) {\n case 'ups':\n {\n const targetMut = (_a = target[table]) === null || _a === void 0 ? void 0 : _a[key];\n if (targetMut) {\n switch (targetMut.type) {\n case 'ups':\n delete target[table][key];\n break;\n case 'del':\n // Leave delete operation.\n // (Don't resurrect objects unintenionally (using tx(get, put) pattern locally))\n break;\n case 'upd':\n delete target[table][key];\n break;\n }\n }\n }\n break;\n case 'del':\n (_b = target[table]) === null || _b === void 0 ? true : delete _b[key];\n break;\n case 'upd': {\n const targetMut = (_c = target[table]) === null || _c === void 0 ? void 0 : _c[key];\n if (targetMut) {\n switch (targetMut.type) {\n case 'ups':\n // Adjust the server upsert with locally updated values.\n for (const [propPath, value] of Object.entries(mut.mod)) {\n setByKeyPath(targetMut.val, propPath, value);\n }\n break;\n case 'del':\n // Leave delete.\n break;\n case 'upd':\n // Remove the local update props from the server update mutation.\n for (const propPath of Object.keys(mut.mod)) {\n delete targetMut.mod[propPath];\n }\n break;\n }\n }\n break;\n }\n }\n }\n }\n}\n","import { randomString } from \"../utils.js\";\n/** Convert a DBKeyMutationSet (which is an internal format capable of looking up changes per ID)\n * ...into a DBOperationsSet (which is more optimal for performing DB operations into DB (bulkAdd() etc))\n *\n * @param inSet\n * @returns DBOperationsSet representing inSet\n */\nexport function toDBOperationSet(inSet, txid = \"\") {\n // Fictive transaction:\n if (!txid)\n txid = randomString(16);\n // Convert data into a temporary map to collect mutations of same table and type\n const map = {};\n for (const [table, ops] of Object.entries(inSet)) {\n for (const [key, op] of Object.entries(ops)) {\n const mapEntry = map[table] || (map[table] = {});\n const ops = mapEntry[op.type] || (mapEntry[op.type] = []);\n ops.push(Object.assign({ key }, op)); // DBKeyMutation doesn't contain key, so we need to bring it in.\n }\n }\n // Start computing the resulting format:\n const result = [];\n for (const [table, ops] of Object.entries(map)) {\n const resultEntry = {\n table,\n muts: [],\n };\n for (const [optype, muts] of Object.entries(ops)) {\n switch (optype) {\n case \"ups\": {\n const op = {\n type: \"upsert\",\n keys: muts.map(mut => mut.key),\n values: muts.map(mut => mut.val),\n txid\n };\n resultEntry.muts.push(op);\n break;\n }\n case \"upd\": {\n const op = {\n type: \"update\",\n keys: muts.map(mut => mut.key),\n changeSpecs: muts.map(mut => mut.mod),\n txid\n };\n resultEntry.muts.push(op);\n break;\n }\n case \"del\": {\n const op = {\n type: \"delete\",\n keys: muts.map(mut => mut.key),\n txid,\n };\n resultEntry.muts.push(op);\n break;\n }\n }\n }\n result.push(resultEntry);\n }\n return result;\n}\n","import { BehaviorSubject, firstValueFrom } from 'rxjs';\nimport { filter, take } from 'rxjs/operators';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { WSConnectionMsg } from '../WSObservable';\nimport { triggerSync } from './triggerSync';\nimport Dexie from 'dexie';\nimport { computeRealmSetHash } from '../helpers/computeRealmSetHash';\nimport { DBOperationsSet } from 'dexie-cloud-common';\nimport { getSyncableTables } from '../helpers/getSyncableTables';\nimport { getMutationTable } from '../helpers/getMutationTable';\nimport { listClientChanges } from './listClientChanges';\nimport { filterServerChangesThroughAddedClientChanges } from './sync';\nimport { applyServerChanges } from './applyServerChanges';\nimport { updateBaseRevs } from './updateBaseRevs';\nimport { getLatestRevisionsPerTable } from './getLatestRevisionsPerTable';\nimport { refreshAccessToken } from '../authentication/authenticate';\n\nconst LIMIT_NUM_MESSAGES_PER_TIME = 10; // Allow a maximum of 10 messages per...\nconst TIME_WINDOW = 10_000; // ...10 seconds.\nconst PAUSE_PERIOD = 1_000; // Pause for 1 second if reached\n\nexport type MessagesFromServerConsumer = ReturnType<\n typeof MessagesFromServerConsumer\n>;\n\nexport function MessagesFromServerConsumer(db: DexieCloudDB) {\n const queue: WSConnectionMsg[] = [];\n const readyToServe = new BehaviorSubject(true);\n const event = new BehaviorSubject(null);\n let isWorking = false;\n\n let loopDetection = new Array(LIMIT_NUM_MESSAGES_PER_TIME).fill(0);\n\n event.subscribe(async () => {\n if (isWorking) return;\n if (queue.length > 0) {\n isWorking = true;\n loopDetection.shift();\n loopDetection.push(Date.now());\n readyToServe.next(false);\n try {\n await consumeQueue();\n } finally {\n if (\n loopDetection[loopDetection.length - 1] - loopDetection[0] <\n TIME_WINDOW\n ) {\n // Ten loops within 10 seconds. Slow down!\n // This is a one-time event. Just pause 10 seconds.\n console.warn(`Slowing down websocket loop for ${PAUSE_PERIOD} milliseconds`);\n await new Promise((resolve) => setTimeout(resolve, PAUSE_PERIOD));\n }\n isWorking = false;\n readyToServe.next(true);\n }\n }\n });\n\n function enqueue(msg: WSConnectionMsg) {\n queue.push(msg);\n event.next(null);\n }\n\n async function consumeQueue() {\n while (queue.length > 0) {\n const msg = queue.shift();\n try {\n // If the sync worker or service worker is syncing, wait 'til thei're done.\n // It's no need to have two channels at the same time - even though it wouldnt\n // be a problem - this is an optimization.\n await firstValueFrom(\n db.cloud.syncState.pipe(\n filter(({ phase }) => phase === 'in-sync' || phase === 'error')\n )\n );\n console.debug('processing msg', msg);\n const persistedSyncState = db.cloud.persistedSyncState.value;\n //syncState.\n if (!msg) continue;\n switch (msg.type) {\n case 'token-expired':\n console.debug(\n 'WebSocket observable: Token expired. Refreshing token...'\n );\n const user = db.cloud.currentUser.value;\n // Refresh access token\n const refreshedLogin = await refreshAccessToken(\n db.cloud.options!.databaseUrl,\n user\n );\n // Persist updated access token\n await db.table('$logins').update(user.userId, {\n accessToken: refreshedLogin.accessToken,\n accessTokenExpiration: refreshedLogin.accessTokenExpiration,\n claims: refreshedLogin.claims,\n license: refreshedLogin.license,\n data: refreshedLogin.data,\n });\n // Updating $logins will trigger emission of db.cloud.currentUser observable, which\n // in turn will lead to that connectWebSocket.ts will reconnect the socket with the\n // new token. So we don't need to do anything more here.\n break;\n case 'realm-added':\n if (\n !persistedSyncState?.realms?.includes(msg.realm) &&\n !persistedSyncState?.inviteRealms?.includes(msg.realm)\n ) {\n await db.cloud.sync({ purpose: 'pull', wait: true });\n //triggerSync(db, 'pull');\n }\n break;\n case 'realm-accepted':\n if (!persistedSyncState?.realms?.includes(msg.realm)) {\n await db.cloud.sync({ purpose: 'pull', wait: true });\n //triggerSync(db, 'pull');\n }\n break;\n case 'realm-removed':\n if (\n persistedSyncState?.realms?.includes(msg.realm) ||\n persistedSyncState?.inviteRealms?.includes(msg.realm)\n ) {\n await db.cloud.sync({ purpose: 'pull', wait: true });\n //triggerSync(db, 'pull');\n }\n break;\n case 'realms-changed':\n //triggerSync(db, 'pull');\n await db.cloud.sync({ purpose: 'pull', wait: true });\n break;\n case 'changes':\n console.debug('changes');\n if (db.cloud.syncState.value?.phase === 'error') {\n triggerSync(db, 'pull');\n break;\n }\n await db.transaction('rw', db.dx.tables, async (tx) => {\n // @ts-ignore\n tx.idbtrans.disableChangeTracking = true;\n // @ts-ignore\n tx.idbtrans.disableAccessControl = true;\n const [schema, syncState, currentUser] = await Promise.all([\n db.getSchema(),\n db.getPersistedSyncState(),\n db.getCurrentUser(),\n ]);\n console.debug('ws message queue: in transaction');\n if (!syncState || !schema || !currentUser) {\n console.debug('required vars not present', {\n syncState,\n schema,\n currentUser,\n });\n return; // Initial sync must have taken place - otherwise, ignore this.\n }\n // Verify again in ACID tx that we're on same server revision.\n if (msg.baseRev !== syncState.serverRevision) {\n console.debug(\n `baseRev (${msg.baseRev}) differs from our serverRevision in syncState (${syncState.serverRevision})`\n );\n // Should we trigger a sync now? No. This is a normal case\n // when another local peer (such as the SW or a websocket channel on other tab) has\n // updated syncState from new server information but we are not aware yet. It would\n // be unnescessary to do a sync in that case. Instead, the caller of this consumeQueue()\n // function will do readyToServe.next(true) right after this return, which will lead\n // to a \"ready\" message being sent to server with the new accurate serverRev we have,\n // so that the next message indeed will be correct.\n if (\n typeof msg.baseRev === 'string' && // v2 format\n (typeof syncState.serverRevision === 'bigint' || // v1 format\n typeof syncState.serverRevision === 'object') // v1 format old browser\n ) {\n // The reason for the diff seems to be that server has migrated the revision format.\n // Do a full sync to update revision format.\n // If we don't do a sync request now, we could stuck in an endless loop.\n triggerSync(db, 'pull');\n }\n return; // Ignore message\n }\n // Verify also that the message is based on the exact same set of realms\n const ourRealmSetHash = await Dexie.waitFor(\n // Keep TX in non-IDB work\n computeRealmSetHash(syncState)\n );\n console.debug('ourRealmSetHash', ourRealmSetHash);\n if (ourRealmSetHash !== msg.realmSetHash) {\n console.debug('not same realmSetHash', msg.realmSetHash);\n triggerSync(db, 'pull');\n // The message isn't based on the same realms.\n // Trigger a sync instead to resolve all things up.\n return;\n }\n\n // Get clientChanges\n let clientChanges: DBOperationsSet = [];\n if (currentUser.isLoggedIn) {\n const mutationTables = getSyncableTables(db).map((tbl) =>\n db.table(getMutationTable(tbl.name))\n );\n clientChanges = await listClientChanges(mutationTables, db);\n console.debug('msg queue: client changes', clientChanges);\n }\n if (msg.changes.length > 0) {\n const filteredChanges =\n filterServerChangesThroughAddedClientChanges(\n msg.changes,\n clientChanges\n );\n\n //\n // apply server changes\n //\n console.debug(\n 'applying filtered server changes',\n filteredChanges\n );\n await applyServerChanges(filteredChanges, db);\n }\n\n // Update latest revisions per table in case there are unsynced changes\n // This can be a real case in future when we allow non-eagery sync.\n // And it can actually be realistic now also, but very rare.\n syncState.latestRevisions = getLatestRevisionsPerTable(\n clientChanges,\n syncState.latestRevisions\n );\n\n syncState.serverRevision = msg.newRev;\n\n // Update base revs\n console.debug('Updating baseRefs', syncState.latestRevisions);\n await updateBaseRevs(\n db,\n schema!,\n syncState.latestRevisions,\n msg.newRev\n );\n\n //\n // Update syncState\n //\n console.debug('Updating syncState', syncState);\n await db.$syncState.put(syncState, 'syncState');\n });\n console.debug('msg queue: done with rw transaction');\n break;\n }\n } catch (error) {\n console.error(`Error in msg queue`, error);\n }\n }\n }\n\n return {\n enqueue,\n readyToServe,\n };\n}\n","import Dexie, { Table } from 'dexie';\nimport { GuardedJob } from './entities/GuardedJob';\nimport { UserLogin } from './entities/UserLogin';\nimport { PersistedSyncState } from './entities/PersistedSyncState';\nimport { UNAUTHORIZED_USER } from '../authentication/UNAUTHORIZED_USER';\nimport { DexieCloudOptions } from '../DexieCloudOptions';\nimport { BehaviorSubject, Subject } from 'rxjs';\nimport { BaseRevisionMapEntry } from './entities/BaseRevisionMapEntry';\nimport {\n DBRealm,\n DBRealmMember,\n DBRealmRole,\n DexieCloudSchema,\n} from 'dexie-cloud-common';\nimport { BroadcastedAndLocalEvent } from '../helpers/BroadcastedAndLocalEvent';\nimport { SyncState, SyncStatePhase } from '../types/SyncState';\nimport { MessagesFromServerConsumer } from '../sync/messagesFromServerQueue';\nimport { YClientMessage } from 'dexie-cloud-common';\n\n/*export interface DexieCloudDB extends Dexie {\n table(name: string): Table<any, any>;\n table(name: \"$jobs\"): Table<GuardedJob, string>;\n table(name: \"$logins\"): Table<UserLogin, string>;\n table(name: \"$syncState\"): Table<SyncState, \"syncState\">;\n //table(name: \"$pendingChangesFromServer\"): Table<DBOperationsSet, number>;\n}\n*/\n\nexport interface SyncStateChangedEventData {\n phase: SyncStatePhase;\n error?: Error;\n progress?: number;\n}\n\ntype SyncStateTable = Table<\n PersistedSyncState | DexieCloudSchema | DexieCloudOptions,\n 'syncState' | 'options' | 'schema'\n>;\nexport interface DexieCloudDBBase {\n readonly name: Dexie['name'];\n readonly close: Dexie['close'];\n transaction: Dexie['transaction'];\n table: Dexie['table'];\n readonly tables: Dexie['tables'];\n readonly cloud: Dexie['cloud'];\n readonly $jobs: Table<GuardedJob, string>;\n readonly $logins: Table<UserLogin, string>;\n readonly $syncState: SyncStateTable;\n readonly $baseRevs: Table<BaseRevisionMapEntry, [string, number]>;\n\n readonly realms: Table<DBRealm, string>;\n readonly members: Table<DBRealmMember, string>;\n readonly roles: Table<DBRealmRole, [string, string]>;\n\n readonly localSyncEvent: Subject<{ purpose?: 'pull' | 'push' }>;\n readonly syncStateChangedEvent: BroadcastedAndLocalEvent<SyncStateChangedEventData>;\n readonly syncCompleteEvent: BroadcastedAndLocalEvent<void>;\n readonly dx: Dexie;\n readonly initiallySynced: boolean;\n}\n\nexport interface DexieCloudDB extends DexieCloudDBBase {\n getCurrentUser(): Promise<UserLogin>;\n getSchema(): Promise<DexieCloudSchema | undefined>;\n getOptions(): Promise<DexieCloudOptions | undefined>;\n getPersistedSyncState(): Promise<PersistedSyncState | undefined>;\n setInitiallySynced(initiallySynced: boolean): void;\n reconfigure(): void;\n messageConsumer: MessagesFromServerConsumer;\n messageProducer: Subject<YClientMessage>;\n}\n\nconst wm = new WeakMap<object, DexieCloudDB>();\n\nexport const DEXIE_CLOUD_SCHEMA = {\n members: '@id, [userId+realmId], [email+realmId], realmId',\n roles: '[realmId+name]',\n realms: '@realmId',\n $jobs: '',\n $syncState: '',\n $baseRevs: '[tableName+clientRev]',\n $logins: 'claims.sub, lastLogin',\n};\n\nlet static_counter = 0;\nexport function DexieCloudDB(dx: Dexie): DexieCloudDB {\n if ('vip' in dx) dx = dx['vip']; // Avoid race condition. Always map to a vipped dexie that don't block during db.on.ready().\n let db = wm.get(dx.cloud);\n if (!db) {\n const localSyncEvent = new Subject<{ purpose: 'push' | 'pull' }>();\n let syncStateChangedEvent =\n new BroadcastedAndLocalEvent<SyncStateChangedEventData>(\n `syncstatechanged-${dx.name}`\n );\n let syncCompleteEvent = new BroadcastedAndLocalEvent<void>(\n `synccomplete-${dx.name}`\n );\n localSyncEvent['id'] = ++static_counter;\n let initiallySynced = false;\n db = {\n get name() {\n return dx.name;\n },\n close() {\n return dx.close();\n },\n transaction: dx.transaction.bind(dx),\n table: dx.table.bind(dx),\n get tables() {\n return dx.tables;\n },\n cloud: dx.cloud,\n get $jobs() {\n return dx.table('$jobs') as Table<GuardedJob, string>;\n },\n get $syncState() {\n return dx.table('$syncState') as SyncStateTable;\n },\n get $baseRevs() {\n return dx.table('$baseRevs') as Table<\n BaseRevisionMapEntry,\n [string, number]\n >;\n },\n get $logins() {\n return dx.table('$logins') as Table<UserLogin, string>;\n },\n\n get realms() {\n return dx.realms;\n },\n get members() {\n return dx.members;\n },\n get roles() {\n return dx.roles;\n },\n get initiallySynced() {\n return initiallySynced;\n },\n localSyncEvent,\n get syncStateChangedEvent() {\n return syncStateChangedEvent;\n },\n get syncCompleteEvent() {\n return syncCompleteEvent;\n },\n dx,\n } as DexieCloudDB;\n\n const helperMethods: Partial<DexieCloudDB> = {\n getCurrentUser() {\n return db!.$logins\n .toArray()\n .then(\n (logins) => logins.find((l) => l.isLoggedIn) || UNAUTHORIZED_USER\n );\n },\n getPersistedSyncState() {\n return db!.$syncState.get('syncState') as Promise<\n PersistedSyncState | undefined\n >;\n },\n getSchema() {\n return db!.$syncState.get('schema').then((schema: DexieCloudSchema) => {\n if (schema) {\n for (const table of db!.tables) {\n if (table.schema.primKey && table.schema.primKey.keyPath && schema[table.name]) {\n schema[table.name].primaryKey = nameFromKeyPath(\n table.schema.primKey.keyPath\n );\n }\n }\n }\n return schema;\n }) as Promise<DexieCloudSchema | undefined>;\n },\n getOptions() {\n return db!.$syncState.get('options') as Promise<\n DexieCloudOptions | undefined\n >;\n },\n setInitiallySynced(value) {\n initiallySynced = value;\n },\n reconfigure() {\n syncStateChangedEvent = new BroadcastedAndLocalEvent<SyncState>(\n `syncstatechanged-${dx.name}`\n );\n syncCompleteEvent = new BroadcastedAndLocalEvent<void>(\n `synccomplete-${dx.name}`\n );\n },\n };\n\n Object.assign(db, helperMethods);\n db.messageConsumer = MessagesFromServerConsumer(db);\n db.messageProducer = new Subject<YClientMessage>();\n wm.set(dx.cloud, db);\n }\n return db;\n}\n\nfunction nameFromKeyPath (keyPath?: string | string[]): string {\n return typeof keyPath === 'string' ?\n keyPath :\n keyPath ? ('[' + [].join.call(keyPath, '+') + ']') : \"\";\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { UserLogin } from \"../db/entities/UserLogin\";\n\nexport interface AuthPersistedContext extends UserLogin {\n save(): Promise<void>;\n}\n\n// Emulate true-private property db. Why? So it's not stored in DB.\nconst wm = new WeakMap<AuthPersistedContext, DexieCloudDB>();\n\nexport class AuthPersistedContext {\n constructor(db: DexieCloudDB, userLogin: UserLogin) {\n wm.set(this, db);\n Object.assign(this, userLogin);\n }\n\n static load(db: DexieCloudDB, userId: string) {\n return db\n .table(\"$logins\")\n .get(userId)\n .then(\n (userLogin) => new AuthPersistedContext(db, userLogin || {\n userId,\n claims: {\n sub: userId\n },\n lastLogin: new Date(0)\n })\n );\n }\n\n async save() {\n const db = wm.get(this)!;\n db.table(\"$logins\").put(this);\n }\n}\n","import { filter, firstValueFrom, from, InteropObservable, Observable } from 'rxjs';\n\nexport function waitUntil<T>(\n o: Observable<T> | InteropObservable<T>, // Works with Dexie's liveQuery observables if we'd need that\n predicate: (value: T) => boolean\n) {\n return firstValueFrom(from(o).pipe(\n filter(predicate),\n ));\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { TXExpandos } from '../types/TXExpandos';\nimport { confirmLogout } from './interactWithUser';\nimport { UNAUTHORIZED_USER } from './UNAUTHORIZED_USER';\nimport { waitUntil } from './waitUntil';\n\nexport async function logout(db: DexieCloudDB) {\n const numUnsyncedChanges = await _logout(db);\n if (numUnsyncedChanges) {\n if (\n await confirmLogout(\n db.cloud.userInteraction,\n db.cloud.currentUserId,\n numUnsyncedChanges\n )\n ) {\n await _logout(db, { deleteUnsyncedData: true });\n } else {\n throw new Error(`User cancelled logout due to unsynced changes`);\n }\n }\n}\n\nexport async function _logout(db: DexieCloudDB, { deleteUnsyncedData = false } = {}) {\n // Clear the database without emptying configuration options.\n const [numUnsynced, loggedOut] = await db.dx.transaction('rw', db.dx.tables, async (tx) => {\n // @ts-ignore\n const idbtrans: IDBTransaction & TXExpandos = tx.idbtrans;\n idbtrans.disableChangeTracking = true;\n idbtrans.disableAccessControl = true;\n const mutationTables = tx.storeNames.filter((tableName) =>\n tableName.endsWith('_mutations')\n );\n\n // Count unsynced changes\n const unsyncCounts = await Promise.all(\n mutationTables.map((mutationTable) => tx.table(mutationTable).count())\n );\n const sumUnSynced = unsyncCounts.reduce((a, b) => a + b, 0);\n\n if (sumUnSynced > 0 && !deleteUnsyncedData) {\n // Let caller ask user if they want to delete unsynced data.\n return [sumUnSynced, false];\n }\n \n // Either there are no unsynched changes, or caller provided flag deleteUnsynchedData = true.\n // Clear all tables except $jobs and $syncState (except the persisted sync state which is\n // also cleared because we're going to rebuild it using a fresh sync).\n db.$syncState.delete('syncState');\n for (const table of db.dx.tables) {\n if (table.name !== '$jobs' && table.name !== '$syncState') {\n table.clear();\n }\n }\n return [sumUnSynced, true];\n });\n\n if (loggedOut) {\n // Wait for currentUser observable to emit UNAUTHORIZED_USER\n await waitUntil(db.cloud.currentUser, (user) => user.userId === UNAUTHORIZED_USER.userId);\n // Then perform an initial sync\n await db.cloud.sync({purpose: 'pull', wait: true});\n }\n return numUnsynced;\n}\n","/** A way to log to console in production without terser stripping out\n * it from the release bundle.\n * This should be used very rarely and only in places where it's\n * absolutely necessary to log something in production.\n * \n * @param level \n * @param args \n */\nexport function prodLog(level: 'log' | 'warn' | 'error' | 'debug', ...args: any[]) {\n globalThis[\"con\"+\"sole\"][level](...args);\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { LoginHints } from '../DexieCloudAPI';\nimport { triggerSync } from '../sync/triggerSync';\nimport { authenticate, loadAccessToken } from './authenticate';\nimport { AuthPersistedContext } from './AuthPersistedContext';\nimport { logout } from './logout';\nimport { otpFetchTokenCallback } from './otpFetchTokenCallback';\nimport { setCurrentUser } from './setCurrentUser';\nimport { UNAUTHORIZED_USER } from './UNAUTHORIZED_USER';\n\nexport async function login(\n db: DexieCloudDB,\n hints?: LoginHints\n) {\n const currentUser = await db.getCurrentUser();\n const origUserId = currentUser.userId;\n if (currentUser.isLoggedIn && (!hints || (!hints.email && !hints.userId))) {\n const licenseStatus = currentUser.license?.status || 'ok';\n if (\n licenseStatus === 'ok' &&\n currentUser.accessToken &&\n (!currentUser.accessTokenExpiration ||\n currentUser.accessTokenExpiration.getTime() > Date.now())\n ) {\n // Already authenticated according to given hints. And license is valid.\n return false;\n }\n if (\n currentUser.refreshToken &&\n (!currentUser.refreshTokenExpiration ||\n currentUser.refreshTokenExpiration.getTime() > Date.now())\n ) {\n // Refresh the token\n await loadAccessToken(db);\n return false;\n }\n // No refresh token - must re-authenticate:\n }\n const context = new AuthPersistedContext(db, {\n claims: {},\n lastLogin: new Date(0),\n });\n await authenticate(\n db.cloud.options!.databaseUrl,\n context,\n db.cloud.options!.fetchTokens || otpFetchTokenCallback(db),\n db.cloud.userInteraction,\n hints\n );\n if (\n origUserId !== UNAUTHORIZED_USER.userId &&\n context.userId !== origUserId\n ) {\n // User was logged in before, but now logged in as another user.\n await logout(db);\n }\n\n /*try {\n await context.save();\n } catch (e) {\n try {\n if (e.name === 'DataCloneError') {\n console.debug(`Login context property names:`, Object.keys(context));\n console.debug(`Login context:`, context);\n console.debug(`Login context JSON:`, JSON.stringify(context));\n }\n } catch {}\n throw e;\n }*/\n await setCurrentUser(db, context);\n // Make sure to resync as the new login will be authorized\n // for new realms.\n triggerSync(db, 'pull');\n return context.userId !== origUserId;\n}\n","import {\n DemoTokenRequest,\n OTPTokenRequest1,\n OTPTokenRequest2,\n TokenErrorResponse,\n TokenFinalResponse,\n TokenRequest,\n TokenResponse,\n} from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { HttpError } from '../errors/HttpError';\nimport { FetchTokenCallback } from './authenticate';\nimport { alertUser, promptForEmail, promptForOTP } from './interactWithUser';\n\nexport function otpFetchTokenCallback(db: DexieCloudDB): FetchTokenCallback {\n const { userInteraction } = db.cloud;\n return async function otpAuthenticate({ public_key, hints }) {\n let tokenRequest: TokenRequest;\n const url = db.cloud.options?.databaseUrl;\n if (!url) throw new Error(`No database URL given.`);\n if (hints?.grant_type === 'demo') {\n const demo_user = await promptForEmail(\n userInteraction,\n 'Enter a demo user email',\n hints?.email || hints?.userId\n );\n tokenRequest = {\n demo_user,\n grant_type: 'demo',\n scopes: ['ACCESS_DB'],\n public_key\n } satisfies DemoTokenRequest;\n } else if (hints?.otpId && hints.otp) {\n // User provided OTP ID and OTP code. This means that the OTP email\n // has already gone out and the user may have clicked a magic link\n // in the email with otp and otpId in query and the app has picked\n // up those values and passed them to db.cloud.login().\n tokenRequest = {\n grant_type: 'otp',\n otp_id: hints.otpId,\n otp: hints.otp,\n scopes: ['ACCESS_DB'],\n public_key,\n } satisfies OTPTokenRequest2;\n } else {\n const email = await promptForEmail(\n userInteraction,\n 'Enter email address',\n hints?.email\n );\n if (/@demo.local$/.test(email)) {\n tokenRequest = {\n demo_user: email,\n grant_type: 'demo',\n scopes: ['ACCESS_DB'],\n public_key\n } satisfies DemoTokenRequest;\n } else {\n tokenRequest = {\n email,\n grant_type: 'otp',\n scopes: ['ACCESS_DB'],\n } satisfies OTPTokenRequest1;\n }\n }\n const res1 = await fetch(`${url}/token`, {\n body: JSON.stringify(tokenRequest),\n method: 'post',\n headers: { 'Content-Type': 'application/json', mode: 'cors' },\n });\n if (res1.status !== 200) {\n const errMsg = await res1.text();\n await alertUser(userInteraction, \"Token request failed\", {\n type: 'error',\n messageCode: 'GENERIC_ERROR',\n message: errMsg,\n messageParams: {}\n }).catch(()=>{});\n throw new HttpError(res1, errMsg);\n }\n const response: TokenResponse = await res1.json();\n if (response.type === 'tokens' || response.type === 'error') {\n // Demo user request can get a \"tokens\" response right away\n // Error can also be returned right away.\n return response;\n } else if (tokenRequest.grant_type === 'otp' && 'email' in tokenRequest) {\n if (response.type !== 'otp-sent')\n throw new Error(`Unexpected response from ${url}/token`);\n const otp = await promptForOTP(userInteraction, tokenRequest.email);\n const tokenRequest2 = {\n ...tokenRequest,\n otp: otp || '',\n otp_id: response.otp_id,\n public_key\n } satisfies OTPTokenRequest2;\n\n let res2 = await fetch(`${url}/token`, {\n body: JSON.stringify(tokenRequest2),\n method: 'post',\n headers: { 'Content-Type': 'application/json' },\n mode: 'cors',\n });\n while (res2.status === 401) {\n const errorText = await res2.text();\n tokenRequest2.otp = await promptForOTP(userInteraction, tokenRequest.email, {\n type: 'error',\n messageCode: 'INVALID_OTP',\n message: errorText,\n messageParams: {}\n });\n res2 = await fetch(`${url}/token`, {\n body: JSON.stringify(tokenRequest2),\n method: 'post',\n headers: { 'Content-Type': 'application/json' },\n mode: 'cors',\n });\n }\n if (res2.status !== 200) {\n const errMsg = await res2.text();\n throw new HttpError(res2, errMsg);\n }\n const response2: TokenFinalResponse | TokenErrorResponse = await res2.json();\n return response2;\n } else {\n throw new Error(`Unexpected response from ${url}/token`);\n }\n };\n}\n","import { DexieCloudDB } from '../db/DexieCloudDB';\nimport { prodLog } from '../prodLog';\nimport { AuthPersistedContext } from './AuthPersistedContext';\nimport { waitUntil } from './waitUntil';\n\n/** This function changes or sets the current user as requested.\n *\n * Use cases:\n * * Initially on db.ready after reading the current user from db.$logins.\n * This will make sure that any unsynced operations from the previous user is synced before\n * changing the user.\n * * Upon user request\n *\n * @param db\n * @param newUser\n */\nexport async function setCurrentUser(\n db: DexieCloudDB,\n user: AuthPersistedContext\n) {\n const $logins = db.table('$logins');\n await db.transaction('rw', $logins, async (tx) => {\n const existingLogins = await $logins.toArray();\n await Promise.all(\n existingLogins\n .filter((login) => login.userId !== user.userId && login.isLoggedIn)\n .map((login) => {\n login.isLoggedIn = false;\n return $logins.put(login);\n })\n );\n user.isLoggedIn = true;\n user.lastLogin = new Date();\n try {\n await user.save();\n } catch (e) {\n try {\n if (e.name === 'DataCloneError') {\n // We've seen this buggy behavior in some browsers and in case it happens\n // again we really need to collect the details to understand what's going on.\n prodLog('debug', `Login context property names:`, Object.keys(user));\n prodLog('debug', `Login context property names:`, Object.keys(user));\n prodLog('debug', `Login context:`, user);\n prodLog('debug', `Login context JSON:`, JSON.stringify(user));\n }\n } catch {}\n throw e;\n }\n console.debug('Saved new user', user.email);\n });\n await waitUntil(\n db.cloud.currentUser,\n (currentUser) => currentUser.userId === user.userId\n );\n}\n","// @ts-ignore\nexport const isFirefox = typeof InstallTrigger !== 'undefined';\n","export const isSafari =\n typeof navigator !== 'undefined' &&\n /Safari\\//.test(navigator.userAgent) &&\n !/Chrom(e|ium)\\/|Edge\\//.test(navigator.userAgent);\n\nexport const safariVersion = isSafari\n ? // @ts-ignore\n [].concat(navigator.userAgent.match(/Safari\\/(\\d*)/))[1]\n : NaN;\n","import { isFirefox } from './isFirefox';\nimport { isSafari, safariVersion } from './isSafari';\n\n// What we know: Safari 14.1 (version 605) crashes when using dexie-cloud's service worker.\n// We don't know what exact call is causing this. Have tried safari-14-idb-fix with no luck.\n// Something we do in the service worker is triggering the crash.\n// When next Safari version (606) is out we will start enabling SW again, hoping that the bug is solved.\n// If not, we might increment 605 to 606.\nexport const DISABLE_SERVICEWORKER_STRATEGY =\n (isSafari && safariVersion <= 605) || // Disable for Safari for now.\n isFirefox; // Disable for Firefox for now. Seems to have a bug in reading CryptoKeys from IDB from service workers\n","export const IS_SERVICE_WORKER =\n typeof self !== \"undefined\" && \"clients\" in self && !self.document;\n","import {\n DBCoreAddRequest,\n DBCoreDeleteRequest,\n DBCoreIndex, DBCorePutRequest\n} from 'dexie';\nimport { b64LexEncode } from 'dreambase-library/dist/common/b64lex';\n\nconst { toString } = {};\nexport function toStringTag(o: Object) {\n return toString.call(o).slice(8, -1);\n}\n\nexport function getEffectiveKeys(\n primaryKey: DBCoreIndex,\n req: (Pick<DBCoreAddRequest | DBCorePutRequest, 'type' | 'values'> & {\n keys?: any[];\n }) |\n Pick<DBCoreDeleteRequest, 'keys' | 'type'>\n) {\n if (req.type === 'delete')\n return req.keys;\n return req.keys?.slice() || req.values.map(primaryKey.extractKey!);\n}\nfunction applyToUpperBitFix(orig: string, bits: number) {\n return (\n (bits & 1 ? orig[0].toUpperCase() : orig[0].toLowerCase()) +\n (bits & 2 ? orig[1].toUpperCase() : orig[1].toLowerCase()) +\n (bits & 4 ? orig[2].toUpperCase() : orig[2].toLowerCase())\n );\n}\nconst consonants = /b|c|d|f|g|h|j|k|l|m|n|p|q|r|s|t|v|x|y|z/i;\nfunction isUpperCase(ch: string) {\n return ch >= 'A' && ch <= 'Z';\n}\n\nexport function generateTablePrefix(\n tableName: string,\n allPrefixes: Set<string>\n) {\n let rv = tableName[0].toLocaleLowerCase(); // \"users\" = \"usr\", \"friends\" = \"frn\", \"realms\" = \"rlm\", etc.\n for (let i = 1, l = tableName.length; i < l && rv.length < 3; ++i) {\n if (consonants.test(tableName[i]) || isUpperCase(tableName[i]))\n rv += tableName[i].toLowerCase();\n }\n while (allPrefixes.has(rv)) {\n if (/\\d/g.test(rv)) {\n rv = rv.substr(0, rv.length - 1) + (rv[rv.length - 1] + 1);\n if (rv.length > 3)\n rv = rv.substr(0, 3);\n else\n continue;\n } else if (rv.length < 3) {\n rv = rv + '2';\n continue;\n }\n let bitFix = 1;\n let upperFixed = rv;\n while (allPrefixes.has(upperFixed) && bitFix < 8) {\n upperFixed = applyToUpperBitFix(rv, bitFix);\n ++bitFix;\n }\n if (bitFix < 8)\n rv = upperFixed;\n else {\n let nextChar = (rv.charCodeAt(2) + 1) & 127;\n rv = rv.substr(0, 2) + String.fromCharCode(nextChar);\n // Here, in theory we could get an infinite loop if having 127*8 table names with identical 3 first consonants.\n }\n }\n return rv;\n}\nlet time = 0;\n/**\n *\n * @param prefix A unique 3-letter short-name of the table.\n * @param shardKey 3 last letters from another ID if colocation is requested. Verified on server on inserts - guarantees unique IDs across shards.\n * The shardKey part of the key represent the shardId where it was first created. An object with this\n * primary key can later on be moved to another shard without being altered. The reason for having\n * the origin shardKey as part of the key, is that the server will not need to check uniqueness constraint\n * across all shards on every insert. Updates / moves across shards are already controlled by the server\n * in the sense that the objects needs to be there already - we only need this part for inserts.\n * @returns\n */\nexport function generateKey(prefix: string, shardKey?: string) {\n const a = new Uint8Array(18);\n const timePart = new Uint8Array(a.buffer, 0, 6);\n const now = Date.now(); // Will fit into 6 bytes until year 10 895.\n if (time >= now) {\n // User is bulk-creating objects the same millisecond.\n // Increment the time part by one millisecond for each item.\n // If bulk-creating 1,000,000 rows client-side in 10 seconds,\n // the last time-stamp will be 990 seconds in future, which is no biggie at all.\n // The point is to create a nice order of the generated IDs instead of\n // using random ids.\n ++time;\n } else {\n time = now;\n }\n timePart[0] = time / 1099511627776; // Normal division (no bitwise operator) --> works with >= 32 bits.\n timePart[1] = time / 4294967296;\n timePart[2] = time / 16777216;\n timePart[3] = time / 65536;\n timePart[4] = time / 256;\n timePart[5] = time;\n const randomPart = new Uint8Array(a.buffer, 6);\n crypto.getRandomValues(randomPart);\n const id = new Uint8Array(a.buffer);\n return prefix + b64LexEncode(id) + (shardKey || '');\n}\n","import Dexie, {\n DBCore,\n DBCoreAddRequest,\n DBCoreMutateRequest,\n DBCorePutRequest,\n DBCoreTransaction,\n Middleware,\n} from 'dexie';\nimport { isValidSyncableID } from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport {\n getEffectiveKeys,\n generateKey,\n toStringTag,\n} from '../middleware-helpers/idGenerationHelpers';\nimport { TXExpandos } from '../types/TXExpandos';\n\nexport function createIdGenerationMiddleware(\n db: DexieCloudDB\n): Middleware<DBCore> {\n return {\n stack: 'dbcore',\n name: 'idGenerationMiddleware',\n level: 1,\n create: (core) => {\n return {\n ...core,\n table: (tableName) => {\n const table = core.table(tableName);\n\n function generateOrVerifyAtKeys(\n req: DBCoreAddRequest | DBCorePutRequest,\n idPrefix: string\n ) {\n let valueClones: null | object[] = null;\n const keys = getEffectiveKeys(table.schema.primaryKey, req);\n keys.forEach((key, idx) => {\n if (key === undefined) {\n // Generate the key\n const colocatedId =\n req.values[idx].realmId || db.cloud.currentUserId;\n const shardKey = colocatedId.substr(colocatedId.length - 3);\n keys[idx] = generateKey(idPrefix, shardKey);\n if (!table.schema.primaryKey.outbound) {\n if (!valueClones) valueClones = req.values.slice();\n valueClones[idx] = Dexie.deepClone(valueClones[idx]);\n Dexie.setByKeyPath(\n valueClones[idx],\n table.schema.primaryKey.keyPath!,\n keys[idx]\n );\n }\n } else if (\n typeof key !== 'string' ||\n (!key.startsWith(idPrefix) && !key.startsWith('#' + idPrefix))\n ) {\n // Key was specified by caller. Verify it complies with id prefix.\n throw new Dexie.ConstraintError(\n `The ID \"${key}\" is not valid for table \"${tableName}\". ` +\n `Primary '@' keys requires the key to be prefixed with \"${idPrefix}\" (or \"#${idPrefix}).\\n` +\n `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.`\n );\n }\n });\n return table.mutate({\n ...req,\n keys,\n values: valueClones || req.values,\n });\n }\n\n return {\n ...table,\n mutate: (req) => {\n const idbtrans = req.trans as DBCoreTransaction & IDBTransaction & TXExpandos;\n if (idbtrans.mode === 'versionchange') {\n // Tell all the other middlewares to skip bothering. We're in versionchange mode.\n // dexie-cloud is not initialized yet.\n idbtrans.disableChangeTracking = true;\n idbtrans.disableAccessControl = true;\n }\n if (idbtrans.disableChangeTracking) {\n // Disable ID policy checks and ID generation\n return table.mutate(req);\n }\n if (req.type === 'add' || req.type === 'put') {\n const cloudTableSchema = db.cloud.schema?.[tableName];\n if (!cloudTableSchema?.generatedGlobalId) {\n if (cloudTableSchema?.markedForSync) {\n // Just make sure primary key is of a supported type:\n const keys = getEffectiveKeys(table.schema.primaryKey, req);\n keys.forEach((key, idx) => {\n if (!isValidSyncableID(key)) {\n const type = Array.isArray(key)\n ? key.map(toStringTag).join(',')\n : toStringTag(key);\n throw new Dexie.ConstraintError(\n `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)`\n );\n }\n });\n }\n } else {\n if (db.cloud.options?.databaseUrl && !db.initiallySynced) {\n // A database URL is configured but no initial sync has been performed.\n const keys = getEffectiveKeys(table.schema.primaryKey, req);\n // Check if the operation would yield any INSERT. If so, complain! We never want wrong ID prefixes stored.\n return table\n .getMany({ keys, trans: req.trans, cache: 'immutable' })\n .then((results) => {\n if (results.length < keys.length) {\n // At least one of the given objects would be created. Complain since\n // the generated ID would be based on a locally computed ID prefix only - we wouldn't\n // know if the server would give the same ID prefix until an initial sync has been\n // performed.\n throw new Error(\n `Unable to create new objects without an initial sync having been performed.`\n );\n }\n return table.mutate(req);\n });\n }\n return generateOrVerifyAtKeys(\n req,\n cloudTableSchema.idPrefix!\n );\n }\n }\n return table.mutate(req);\n },\n };\n },\n };\n },\n };\n}\n","import { DBCoreTable, DBCoreTransaction } from \"dexie\";\nimport { allSettled } from \"../helpers/allSettled\";\n\nlet counter = 0;\n\nexport function guardedTable(table: DBCoreTable) {\n const prop = \"$lock\"+ (++counter);\n return {\n ...table,\n count: readLock(table.count, prop),\n get: readLock(table.get, prop),\n getMany: readLock(table.getMany, prop),\n openCursor: readLock(table.openCursor, prop),\n query: readLock(table.query, prop),\n mutate: writeLock(table.mutate, prop),\n };\n}\n\nfunction readLock<TReq extends { trans: DBCoreTransaction }, TRes>(\n fn: (req: TReq) => Promise<TRes>,\n prop: string\n): (req: TReq) => Promise<TRes> {\n return function readLocker(req): Promise<TRes> {\n const {\n readers,\n writers,\n }: { writers: Promise<any>[]; readers: Promise<any>[] } =\n req.trans[prop] || (req.trans[prop] = { writers: [], readers: [] });\n const numWriters = writers.length;\n const promise = (numWriters > 0\n ? writers[numWriters - 1].then(() => fn(req), () => fn(req))\n : fn(req)\n ).finally(() => {readers.splice(readers.indexOf(promise))});\n readers.push(promise);\n return promise;\n };\n}\n\nfunction writeLock<TReq extends { trans: DBCoreTransaction }, TRes>(\n fn: (req: TReq) => Promise<TRes>,\n prop: string\n): (req: TReq) => Promise<TRes> {\n return function writeLocker(req): Promise<TRes> {\n const {\n readers,\n writers,\n }: { writers: Promise<any>[]; readers: Promise<any>[] } =\n req.trans[prop] || (req.trans[prop] = { writers: [], readers: [] });\n let promise = (writers.length > 0\n ? writers[writers.length - 1].then(() => fn(req), () => fn(req))\n : readers.length > 0\n ? allSettled(readers).then(() => fn(req))\n : fn(req)\n ).finally(() => {writers.shift();});\n writers.push(promise);\n return promise;\n };\n}\n","\nexport function allSettled(possiblePromises: any[]) {\n return new Promise(resolve => {\n if (possiblePromises.length === 0) resolve([]);\n let remaining = possiblePromises.length;\n const results = new Array(remaining);\n possiblePromises.forEach((p, i) => Promise.resolve(p).then(\n value => results[i] = {status: \"fulfilled\", value},\n reason => results[i] = {status: \"rejected\", reason})\n .then(()=>--remaining || resolve(results)));\n });\n}\n","import { DBCoreTransaction } from 'dexie';\nimport { BehaviorSubject } from 'rxjs';\nimport { TXExpandos } from '../types/TXExpandos';\n\nexport const outstandingTransactions = new BehaviorSubject<Set<DBCoreTransaction & IDBTransaction & TXExpandos>>(new Set());\n","import { DexieCloudDB } from './db/DexieCloudDB';\n\nexport function isEagerSyncDisabled(db: DexieCloudDB) {\n return (\n db.cloud.options?.disableEagerSync ||\n db.cloud.currentUser.value?.license?.status !== 'ok' ||\n !db.cloud.options?.databaseUrl\n );\n}\n","import {\n DBCore,\n DBCoreAddRequest,\n DBCoreDeleteRequest,\n DBCoreMutateResponse,\n DBCorePutRequest,\n DBCoreTable,\n DBCoreTransaction,\n Middleware,\n RangeSet,\n} from 'dexie';\nimport { DBOperation, DBUpdateOperation } from 'dexie-cloud-common';\nimport { BehaviorSubject } from 'rxjs';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { UserLogin } from '../db/entities/UserLogin';\nimport { getMutationTable } from '../helpers/getMutationTable';\nimport { randomString } from '../helpers/randomString';\nimport { throwVersionIncrementNeeded } from '../helpers/throwVersionIncrementNeeded';\nimport { guardedTable } from '../middleware-helpers/guardedTable';\nimport { registerSyncEvent } from '../sync/registerSyncEvent';\nimport { TXExpandos } from '../types/TXExpandos';\nimport { outstandingTransactions } from './outstandingTransaction';\nimport { isEagerSyncDisabled } from '../isEagerSyncDisabled';\nimport { triggerSync } from '../sync/triggerSync';\n\nexport interface MutationTrackingMiddlewareArgs {\n currentUserObservable: BehaviorSubject<UserLogin>;\n db: DexieCloudDB;\n}\n\n/** Tracks all mutations in the same transaction as the mutations -\n * so it is guaranteed that no mutation goes untracked - and if transaction\n * aborts, the mutations won't be tracked.\n *\n * The sync job will use the tracked mutations as the source of truth when pushing\n * changes to server and cleanup the tracked mutations once the server has\n * ackowledged that it got them.\n */\nexport function createMutationTrackingMiddleware({\n currentUserObservable,\n db,\n}: MutationTrackingMiddlewareArgs): Middleware<DBCore> {\n return {\n stack: 'dbcore',\n name: 'MutationTrackingMiddleware',\n level: 1,\n create: (core) => {\n const allTableNames = new Set(core.schema.tables.map((t) => t.name));\n const ordinaryTables = core.schema.tables.filter(\n (t) => !/^\\$/.test(t.name)\n );\n const mutTableMap = new Map<string, DBCoreTable>();\n for (const tbl of ordinaryTables) {\n const mutationTableName = `$${tbl.name}_mutations`;\n if (allTableNames.has(mutationTableName)) {\n mutTableMap.set(tbl.name, core.table(mutationTableName));\n }\n }\n\n return {\n ...core,\n transaction: (tables, mode) => {\n let tx: DBCoreTransaction & IDBTransaction & TXExpandos;\n if (mode === 'readwrite') {\n const mutationTables = tables\n .filter((tbl) => db.cloud.schema?.[tbl]?.markedForSync)\n .map((tbl) => getMutationTable(tbl));\n tx = core.transaction(\n [...tables, ...mutationTables],\n mode\n ) as DBCoreTransaction & IDBTransaction & TXExpandos;\n } else {\n tx = core.transaction(tables, mode) as DBCoreTransaction &\n IDBTransaction &\n TXExpandos;\n }\n\n if (mode === 'readwrite') {\n // Give each transaction a globally unique id.\n tx.txid = randomString(16);\n tx.opCount = 0;\n // Introduce the concept of current user that lasts through the entire transaction.\n // This is important because the tracked mutations must be connected to the user.\n tx.currentUser = currentUserObservable.value;\n outstandingTransactions.value.add(tx);\n outstandingTransactions.next(outstandingTransactions.value);\n const removeTransaction = () => {\n tx.removeEventListener('complete', txComplete);\n tx.removeEventListener('error', removeTransaction);\n tx.removeEventListener('abort', removeTransaction);\n outstandingTransactions.value.delete(tx);\n outstandingTransactions.next(outstandingTransactions.value);\n };\n const txComplete = () => {\n if (tx.mutationsAdded && !isEagerSyncDisabled(db)) {\n triggerSync(db, 'push');\n }\n removeTransaction();\n };\n tx.addEventListener('complete', txComplete);\n tx.addEventListener('error', removeTransaction);\n tx.addEventListener('abort', removeTransaction);\n }\n return tx;\n },\n table: (tableName) => {\n const table = core.table(tableName);\n if (/^\\$/.test(tableName)) {\n if (tableName.endsWith('_mutations')) {\n // In case application code adds items to ..._mutations tables,\n // make sure to set the mutationsAdded flag on transaction.\n // This is also done in mutateAndLog() as that function talks to a\n // lower level DBCore and wouldn't be catched by this code.\n return {\n ...table,\n mutate: (req) => {\n if (req.type === 'add' || req.type === 'put') {\n (\n req.trans as DBCoreTransaction & TXExpandos\n ).mutationsAdded = true;\n }\n return table.mutate(req);\n },\n };\n } else if (tableName === '$logins') {\n return {\n ...table,\n mutate: (req) => {\n //console.debug('Mutating $logins table', req);\n return table\n .mutate(req)\n .then((res) => {\n //console.debug('Mutating $logins');\n (\n req.trans as DBCoreTransaction & TXExpandos\n ).mutationsAdded = true;\n //console.debug('$logins mutated');\n return res;\n })\n .catch((err) => {\n console.debug('Failed mutation $logins', err);\n return Promise.reject(err);\n });\n },\n };\n } else {\n return table;\n }\n }\n const { schema } = table;\n const mutsTable = mutTableMap.get(tableName)!;\n if (!mutsTable) {\n // We cannot track mutations on this table because there is no mutations table for it.\n // This might happen in upgraders that executes before cloud schema is applied.\n return table; \n }\n return guardedTable({\n ...table,\n mutate: (req) => {\n const trans = req.trans as DBCoreTransaction & TXExpandos;\n if (!trans.txid) return table.mutate(req); // Upgrade transactions not guarded by us.\n if (trans.disableChangeTracking) return table.mutate(req);\n if (!db.cloud.schema?.[tableName]?.markedForSync)\n return table.mutate(req);\n if (!trans.currentUser?.isLoggedIn) {\n // Unauthorized user should not log mutations.\n // Instead, after login all local data should be logged at once.\n return table.mutate(req);\n }\n\n return req.type === 'deleteRange'\n ? table\n // Query the actual keys (needed for server sending correct rollback to us)\n .query({\n query: { range: req.range, index: schema.primaryKey },\n trans: req.trans,\n values: false,\n })\n // Do a delete request instead, but keep the criteria info for the server to execute\n .then((res) => {\n return mutateAndLog({\n type: 'delete',\n keys: res.result,\n trans: req.trans,\n criteria: { index: null, range: req.range },\n });\n })\n : mutateAndLog(req);\n },\n });\n\n function mutateAndLog(\n req: DBCoreDeleteRequest | DBCoreAddRequest | DBCorePutRequest\n ): Promise<DBCoreMutateResponse> {\n const trans = req.trans as DBCoreTransaction & TXExpandos;\n const unsyncedProps =\n db.cloud.options?.unsyncedProperties?.[tableName];\n const {\n txid,\n currentUser: { userId },\n } = trans;\n const { type } = req;\n const opNo = ++trans.opCount;\n\n function stripChangeSpec(changeSpec: { [keyPath: string]: any }) {\n if (!unsyncedProps) return changeSpec;\n let rv = changeSpec;\n for (const keyPath of Object.keys(changeSpec)) {\n if (\n unsyncedProps.some(\n (p) => keyPath === p || keyPath.startsWith(p + '.')\n )\n ) {\n if (rv === changeSpec) rv = { ...changeSpec }; // clone on demand\n delete rv[keyPath];\n }\n }\n return rv;\n }\n\n return table.mutate(req).then((res) => {\n const { numFailures: hasFailures, failures } = res;\n let keys = type === 'delete' ? req.keys! : res.results!;\n let values = 'values' in req ? req.values : [];\n let changeSpec = 'changeSpec' in req ? req.changeSpec : undefined;\n let updates = 'updates' in req ? req.updates : undefined;\n\n if (hasFailures) {\n keys = keys.filter((_, idx) => !failures[idx]);\n values = values.filter((_, idx) => !failures[idx]);\n }\n if (unsyncedProps) {\n // Filter out unsynced properties\n values = values.map((value) => {\n const newValue = { ...value };\n for (const prop of unsyncedProps) {\n delete newValue[prop];\n }\n return newValue;\n });\n if (changeSpec) {\n // modify operation with criteria and changeSpec.\n // We must strip out unsynced properties from changeSpec.\n // We deal with criteria later.\n changeSpec = stripChangeSpec(changeSpec);\n if (Object.keys(changeSpec).length === 0) {\n // Nothing to change on server\n return res;\n }\n }\n if (updates) {\n let strippedChangeSpecs =\n updates.changeSpecs.map(stripChangeSpec);\n let newUpdates: DBCorePutRequest['updates'] = {\n keys: [],\n changeSpecs: [],\n };\n const validKeys = new RangeSet();\n let anyChangeSpecBecameEmpty = false;\n for (let i = 0, l = strippedChangeSpecs.length; i < l; ++i) {\n if (Object.keys(strippedChangeSpecs[i]).length > 0) {\n newUpdates.keys.push(updates.keys[i]);\n newUpdates.changeSpecs.push(strippedChangeSpecs[i]);\n validKeys.addKey(updates.keys[i]);\n } else {\n anyChangeSpecBecameEmpty = true;\n }\n }\n updates = newUpdates;\n if (anyChangeSpecBecameEmpty) {\n // Some keys were stripped. We must also strip them from keys and values\n let newKeys: any[] = [];\n let newValues: any[] = [];\n for (let i = 0, l = keys.length; i < l; ++i) {\n if (validKeys.hasKey(keys[i])) {\n newKeys.push(keys[i]);\n newValues.push(values[i]);\n }\n }\n keys = newKeys;\n values = newValues;\n }\n }\n }\n const ts = Date.now();\n // Canonicalize req.criteria.index to null if it's on the primary key.\n let criteria =\n 'criteria' in req && req.criteria\n ? {\n ...req.criteria,\n index:\n req.criteria.index === schema.primaryKey.keyPath // Use null to inform server that criteria is on primary key\n ? null // This will disable the server from trying to log consistent operations where it shouldnt.\n : req.criteria.index,\n }\n : undefined;\n if (unsyncedProps && criteria?.index) {\n const keyPaths = schema.indexes.find(\n (idx) => idx.name === criteria!.index\n )?.keyPath;\n const involvedProps = keyPaths\n ? typeof keyPaths === 'string'\n ? [keyPaths]\n : keyPaths\n : [];\n if (involvedProps.some((p) => unsyncedProps?.includes(p))) {\n // Don't log criteria on unsynced properties as the server could not test them.\n criteria = undefined;\n }\n }\n\n const mut: DBOperation =\n req.type === 'delete'\n ? {\n type: 'delete',\n ts,\n opNo,\n keys,\n criteria,\n txid,\n userId,\n }\n : req.type === 'add'\n ? {\n type: 'insert',\n ts,\n opNo,\n keys,\n txid,\n userId,\n values,\n }\n : criteria && changeSpec\n ? {\n // Common changeSpec for all keys\n type: 'modify',\n ts,\n opNo,\n keys,\n criteria,\n changeSpec,\n txid,\n userId,\n }\n : changeSpec\n ? {\n // In case criteria involved an unsynced property, we go for keys instead.\n type: 'update',\n ts,\n opNo,\n keys,\n changeSpecs: keys.map(() => changeSpec!),\n txid,\n userId,\n }\n : updates\n ? {\n // One changeSpec per key\n type: 'update',\n ts,\n opNo,\n keys: updates.keys,\n changeSpecs: updates.changeSpecs,\n txid,\n userId,\n }\n : {\n type: 'upsert',\n ts,\n opNo,\n keys,\n values,\n txid,\n userId,\n };\n\n if ('isAdditionalChunk' in req && req.isAdditionalChunk) {\n mut.isAdditionalChunk = true;\n }\n return keys.length > 0 || criteria\n ? mutsTable\n .mutate({ type: 'add', trans, values: [mut] }) // Log entry\n .then(() => {\n trans.mutationsAdded = true; // Mark transaction as having added mutations to trigger eager sync\n return res; // Return original response\n })\n : res;\n });\n }\n },\n };\n },\n };\n}\n","import Dexie, { DbSchema } from 'dexie';\nimport { DEXIE_CLOUD_SCHEMA } from './db/DexieCloudDB';\nimport { generateTablePrefix } from './middleware-helpers/idGenerationHelpers';\n\nexport function overrideParseStoresSpec(origFunc: Function, dexie: Dexie) {\n return function(stores: {[tableName: string]: string}, dbSchema: DbSchema) {\n const storesClone = {\n ...DEXIE_CLOUD_SCHEMA,\n ...stores,\n };\n // Merge indexes of DEXIE_CLOUD_SCHEMA with stores\n Object.keys(DEXIE_CLOUD_SCHEMA).forEach((tableName: keyof typeof DEXIE_CLOUD_SCHEMA) => {\n const schemaSrc = storesClone[tableName];\n // Verify that they don't try to delete a table that is needed for access control of Dexie Cloud\n if (schemaSrc == null) {\n // They try to delete one of the built-in schema tables.\n throw new Error(`Cannot delete table ${tableName} as it is needed for access control of Dexie Cloud`);\n }\n // If not trying to override a built-in table, then we can skip this and continue to next table.\n if (!stores[tableName]) {\n // They haven't tried to declare this table. No need to merge indexes.\n return; // Continue\n }\n\n // They have declared this table. Merge indexes in case they didn't declare all indexes we need.\n const requestedIndexes = schemaSrc.split(',').map(spec => spec.trim());\n const builtInIndexes = DEXIE_CLOUD_SCHEMA[tableName].split(',').map(spec => spec.trim());\n const requestedIndexSet = new Set(requestedIndexes.map(index => index.replace(/([&*]|\\+\\+)/g, \"\")));\n // Verify that primary key is unchanged\n if (requestedIndexes[0] !== builtInIndexes[0]) {\n // Primary key must match exactly\n throw new Error(`Cannot override primary key of table ${tableName}. Please declare it as {${\n tableName}: ${\n JSON.stringify(DEXIE_CLOUD_SCHEMA[tableName])\n }`);\n }\n // Merge indexes\n for (let i=1; i<builtInIndexes.length; ++i) {\n const builtInIndex = builtInIndexes[i];\n if (!requestedIndexSet.has(builtInIndex.replace(/([&*]|\\+\\+)/g, \"\"))) {\n // Add built-in index if not already requested\n storesClone[tableName] += `,${builtInIndex}`;\n }\n }\n });\n\n // Populate dexie.cloud.schema\n const cloudSchema = dexie.cloud.schema || (dexie.cloud.schema = {});\n const allPrefixes = new Set<string>();\n Object.keys(storesClone).forEach(tableName => {\n const schemaSrc = storesClone[tableName];\n const cloudTableSchema = cloudSchema[tableName] || (cloudSchema[tableName] = {});\n if (schemaSrc != null) {\n if (/^\\@/.test(schemaSrc)) {\n storesClone[tableName] = storesClone[tableName].substr(1);\n cloudTableSchema.generatedGlobalId = true;\n cloudTableSchema.idPrefix = generateTablePrefix(tableName, allPrefixes);\n allPrefixes.add(cloudTableSchema.idPrefix);\n }\n if (!/^\\$/.test(tableName)) {\n storesClone[`$${tableName}_mutations`] = '++rev';\n cloudTableSchema.markedForSync = true;\n }\n if (cloudTableSchema.deleted) {\n cloudTableSchema.deleted = false;\n }\n } else {\n cloudTableSchema.deleted = true;\n cloudTableSchema.markedForSync = false;\n storesClone[`$${tableName}_mutations`] = null;\n }\n });\n const rv = origFunc.call(this, storesClone, dbSchema);\n for (const [tableName, spec] of Object.entries(dbSchema)) {\n if (spec.yProps?.length) {\n const cloudTableSchema = cloudSchema[tableName];\n if (cloudTableSchema) {\n cloudTableSchema.yProps = spec.yProps.map((yProp) => yProp.prop);\n }\n }\n }\n return rv;\n }\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\n\nexport function performGuardedJob<T>(\n db: DexieCloudDB,\n jobName: string,\n job: () => Promise<T>\n): Promise<T> {\n if (typeof navigator === 'undefined' || !navigator.locks) {\n // No support for guarding jobs. IE11, node.js, etc.\n return job();\n }\n return navigator.locks.request(db.name + '|' + jobName, () => job());\n}\n","import { BehaviorSubject, fromEvent, merge, of } from 'rxjs';\nimport {\n debounceTime,\n delay,\n distinctUntilChanged,\n filter,\n map,\n skip,\n startWith,\n switchMap,\n tap,\n} from 'rxjs/operators';\n\nconst USER_INACTIVITY_TIMEOUT = 180_000; // 3 minutes\nconst ACTIVE_WAIT_TIME = 0; // For now, it's nicer to react instantly on user activity\nconst INACTIVE_WAIT_TIME = 20_000;\n\n// This observable will be emitted to later down....\nexport const userIsActive = new BehaviorSubject<boolean>(true);\n\n// A refined version that waits before changing state:\n// * Wait another INACTIVE_WAIT_TIME before accepting that the user is inactive.\n// Reason 1: Spare resources - no need to setup the entire websocket flow when\n// switching tabs back and forth.\n// Reason 2: Less flickering for the end user when switching tabs back and forth.\n// * Wait another ACTIVE_WAIT_TIME before accepting that the user is active.\n// Possible reason to have a value here: Sparing resources if users often temporary click the tab\n// for just a short time.\nexport const userIsReallyActive = new BehaviorSubject<boolean>(true);\nuserIsActive\n .pipe(\n switchMap((isActive) => {\n //console.debug('SyncStatus: DUBB: isActive changed to', isActive);\n return isActive\n ? ACTIVE_WAIT_TIME\n ? of(true).pipe(delay(ACTIVE_WAIT_TIME))\n : of(true)\n : INACTIVE_WAIT_TIME\n ? of(false).pipe(delay(INACTIVE_WAIT_TIME))\n : of(false);}\n ),\n distinctUntilChanged()\n )\n .subscribe(userIsReallyActive);\n\n//\n// First create some corner-stone observables to build the flow on\n//\n\n// document.onvisibilitychange:\nexport const visibilityStateIsChanged =\n typeof document !== 'undefined'\n ? fromEvent(document, 'visibilitychange')\n : of({});\n\n// document.onvisibilitychange makes document hidden:\nexport const documentBecomesHidden = visibilityStateIsChanged.pipe(\n filter(() => document.visibilityState === 'hidden')\n);\n\n// document.onvisibilitychange makes document visible\nexport const documentBecomesVisible = visibilityStateIsChanged.pipe(\n filter(() => document.visibilityState === 'visible')\n);\n\n// Any of various user-activity-related events happen:\nexport const userDoesSomething =\n typeof window !== 'undefined'\n ? merge(\n documentBecomesVisible,\n fromEvent(window, 'mousedown'),\n fromEvent(window, 'mousemove'),\n fromEvent(window, 'keydown'),\n fromEvent(window, 'wheel'),\n fromEvent(window, 'touchmove')\n )\n : of({});\n\nif (typeof document !== 'undefined') {\n //\n // Now, create a final observable and start subscribing to it in order\n // to make it emit values to userIsActive BehaviourSubject (which is the\n // most important global hot observable we have here)\n //\n // Live test: https://jsitor.com/LboCDHgbn\n //\n merge(\n of(true), // Make sure something is always emitted from start\n documentBecomesHidden, // so that we can eagerly emit false!\n userDoesSomething\n )\n .pipe(\n // No matter event source, compute whether user is visible using visibilityState:\n map(() => document.visibilityState === 'visible'),\n // Make sure to emit it\n tap((isActive) => {\n if (userIsActive.value !== isActive) {\n // Emit new value unless it already has that value\n userIsActive.next(isActive);\n }\n }),\n // Now, if true was emitted, make sure to set a timeout to emit false\n // unless new user activity things happen (in that case, the timeout will be cancelled!)\n switchMap((isActive) =>\n isActive\n ? of(0).pipe(\n delay(USER_INACTIVITY_TIMEOUT - INACTIVE_WAIT_TIME),\n tap(() => userIsActive.next(false))\n )\n : of(0)\n )\n )\n .subscribe(() => {}); // Unless we subscribe nothing will be propagated to userIsActive observable\n}\n","export class TokenExpiredError extends Error {\n name = \"TokenExpiredError\";\n}\n","import type { Awareness } from 'y-protocols/awareness';\n\nexport const awarenessWeakMap = new WeakMap<any, Awareness>();\n\nexport const getDocAwareness = (doc: any) => awarenessWeakMap.get(doc);\n","import { Subject } from \"rxjs\";\nimport type * as Y from \"yjs\";\n\nconst wm = new WeakMap<Y.Doc, Subject<void>>();\n\n/** A property (package-private) on Y.Doc that is used\n * to signal that the server wants us to send a 'doc-open' message\n * to the server for this document.\n * \n * @param doc \n * @returns \n */\nexport function getOpenDocSignal(doc: Y.Doc) {\n let signal = wm.get(doc);\n if (!signal) {\n signal = new Subject<void>();\n wm.set(doc, signal);\n }\n return signal;\n}","import { DBOperationsSet } from 'dexie-cloud-common';\nimport { BehaviorSubject, Observable, Subscriber, Subscription, tap } from 'rxjs';\nimport { TokenExpiredError } from './authentication/TokenExpiredError';\nimport { DXCWebSocketStatus } from './DXCWebSocketStatus';\nimport { TSON } from './TSON';\nimport type { YClientMessage, YServerMessage } from 'dexie-cloud-common';\nimport { DexieCloudDB } from './db/DexieCloudDB';\nimport { createYClientUpdateObservable } from './yjs/createYClientUpdateObservable';\nimport { applyYServerMessages } from './yjs/applyYMessages';\nimport { Table } from 'dexie';\nimport { getDocAwareness } from './yjs/awareness';\nimport * as awap from 'y-protocols/awareness';\nimport { encodeYMessage, decodeYMessage } from 'dexie-cloud-common';\nimport { UserLogin } from './dexie-cloud-client';\nimport { isEagerSyncDisabled } from './isEagerSyncDisabled';\nimport { getOpenDocSignal } from './yjs/reopenDocSignal';\nimport { getUpdatesTable } from './yjs/getUpdatesTable';\nimport { DEXIE_CLOUD_SYNCER_ID } from './sync/DEXIE_CLOUD_SYNCER_ID';\nimport { DexieYProvider, YSyncState } from 'y-dexie';\n\nconst SERVER_PING_TIMEOUT = 20000;\nconst CLIENT_PING_INTERVAL = 30000;\nconst FAIL_RETRY_WAIT_TIME = 60000;\n\nexport type WSClientToServerMsg = ReadyForChangesMessage | YClientMessage;\nexport interface ReadyForChangesMessage {\n type: 'ready';\n realmSetHash: string;\n rev: string;\n}\n\nexport type WSConnectionMsg =\n | RevisionChangedMessage\n | RealmAddedMessage\n | RealmAcceptedMessage\n | RealmRemovedMessage\n | RealmsChangedMessage\n | ChangesFromServerMessage\n | TokenExpiredMessage;\ninterface PingMessage {\n type: 'ping';\n}\n\ninterface PongMessage {\n type: 'pong';\n}\n\ninterface ErrorMessage {\n type: 'error';\n error: string;\n}\n\nexport interface ChangesFromServerMessage {\n type: 'changes';\n baseRev: string;\n realmSetHash: string;\n newRev: string;\n changes: DBOperationsSet<string>;\n}\nexport interface RevisionChangedMessage {\n type: 'rev';\n rev: string;\n}\n\nexport interface RealmAddedMessage {\n type: 'realm-added';\n realm: string;\n}\n\nexport interface RealmAcceptedMessage {\n type: 'realm-accepted';\n realm: string;\n}\n\nexport interface RealmRemovedMessage {\n type: 'realm-removed';\n realm: string;\n}\n\nexport interface RealmsChangedMessage {\n type: 'realms-changed';\n realmsHash: string;\n}\nexport interface TokenExpiredMessage {\n type: 'token-expired';\n}\n\nexport class WSObservable extends Observable<WSConnectionMsg> {\n constructor(\n db: DexieCloudDB,\n rev: string | undefined,\n yrev: string | undefined,\n realmSetHash: string,\n clientIdentity: string,\n messageProducer: Observable<WSClientToServerMsg>,\n webSocketStatus: BehaviorSubject<DXCWebSocketStatus>,\n user: UserLogin\n ) {\n super(\n (subscriber) =>\n new WSConnection(\n db,\n rev,\n yrev,\n realmSetHash,\n clientIdentity,\n user,\n subscriber,\n messageProducer,\n webSocketStatus\n )\n );\n }\n}\n\nlet counter = 0;\n\nexport class WSConnection extends Subscription {\n db: DexieCloudDB;\n ws: WebSocket | null;\n lastServerActivity: Date;\n lastUserActivity: Date;\n lastPing: Date;\n databaseUrl: string;\n rev: string | undefined;\n yrev: string | undefined;\n realmSetHash: string;\n clientIdentity: string;\n user: UserLogin;\n subscriber: Subscriber<WSConnectionMsg>;\n pauseUntil?: Date;\n messageProducer: Observable<WSClientToServerMsg>;\n webSocketStatus: BehaviorSubject<DXCWebSocketStatus>;\n id = ++counter;\n\n private pinger: any;\n private subscriptions: Set<Subscription> = new Set();\n\n constructor(\n db: DexieCloudDB,\n rev: string | undefined,\n yrev: string | undefined,\n realmSetHash: string,\n clientIdentity: string,\n user: UserLogin,\n subscriber: Subscriber<WSConnectionMsg>,\n messageProducer: Observable<WSClientToServerMsg>,\n webSocketStatus: BehaviorSubject<DXCWebSocketStatus>\n ) {\n super(() => this.teardown());\n console.debug(\n 'New WebSocket Connection',\n this.id,\n user.accessToken ? 'authorized' : 'unauthorized'\n );\n this.db = db;\n this.databaseUrl = db.cloud.options!.databaseUrl;\n this.rev = rev;\n this.yrev = yrev;\n this.realmSetHash = realmSetHash;\n this.clientIdentity = clientIdentity;\n this.user = user;\n this.subscriber = subscriber;\n this.lastUserActivity = new Date();\n this.messageProducer = messageProducer;\n this.webSocketStatus = webSocketStatus;\n this.connect();\n }\n\n private teardown() {\n console.debug('Teardown WebSocket Connection', this.id);\n this.disconnect();\n }\n\n private disconnect() {\n this.webSocketStatus.next('disconnected');\n if (this.pinger) {\n clearInterval(this.pinger);\n this.pinger = null;\n }\n if (this.ws) {\n try {\n this.ws.close();\n } catch {}\n }\n this.ws = null;\n for (const sub of this.subscriptions) {\n sub.unsubscribe();\n }\n this.subscriptions.clear();\n }\n\n reconnecting = false;\n reconnect() {\n if (this.reconnecting) return;\n this.reconnecting = true;\n try {\n this.disconnect();\n } catch {}\n this.connect()\n .catch(() => {})\n .then(() => (this.reconnecting = false)); // finally()\n }\n\n async connect() {\n this.lastServerActivity = new Date();\n if (this.pauseUntil && this.pauseUntil > new Date()) {\n console.debug('WS not reconnecting just yet', {\n id: this.id,\n pauseUntil: this.pauseUntil,\n });\n return;\n }\n if (this.ws) {\n throw new Error(`Called connect() when a connection is already open`);\n }\n if (!this.databaseUrl)\n throw new Error(`Cannot connect without a database URL`);\n if (this.closed) {\n //console.debug('SyncStatus: DUBB: Ooops it was closed!');\n return;\n }\n const tokenExpiration = this.user.accessTokenExpiration;\n if (tokenExpiration && tokenExpiration < new Date()) {\n this.subscriber.error(new TokenExpiredError()); // Will be handled in connectWebSocket.ts.\n return;\n }\n this.webSocketStatus.next('connecting');\n this.pinger = setInterval(async () => {\n // setInterval here causes unnecessary pings when server is proved active anyway.\n // TODO: Use setTimout() here instead. When triggered, check if we really need to ping.\n // In case we've had server activity, we don't need to ping. Then schedule then next ping\n // to the time when we should ping next time (based on lastServerActivity + CLIENT_PING_INTERVAL).\n // Else, ping now and schedule next ping to CLIENT_PING_INTERVAL from now.\n if (this.closed) {\n console.debug('pinger check', this.id, 'CLOSED.');\n this.teardown();\n return;\n }\n if (this.ws) {\n try {\n this.ws.send(JSON.stringify({ type: 'ping' } as PingMessage));\n setTimeout(() => {\n console.debug(\n 'pinger setTimeout',\n this.id,\n this.pinger ? `alive` : 'dead'\n );\n if (!this.pinger) return;\n if (this.closed) {\n console.debug(\n 'pinger setTimeout',\n this.id,\n 'subscription is closed'\n );\n this.teardown();\n return;\n }\n if (\n this.lastServerActivity <\n new Date(Date.now() - SERVER_PING_TIMEOUT)\n ) {\n // Server inactive. Reconnect if user is active.\n console.debug('pinger: server is inactive');\n console.debug('pinger reconnecting');\n this.reconnect();\n } else {\n console.debug('pinger: server still active');\n }\n }, SERVER_PING_TIMEOUT);\n } catch {\n console.debug('pinger catch error', this.id, 'reconnecting');\n this.reconnect();\n }\n } else {\n console.debug('pinger', this.id, 'reconnecting');\n this.reconnect();\n }\n }, CLIENT_PING_INTERVAL);\n\n // The following vars are needed because we must know which callback to ack when server sends it's ack to us.\n const wsUrl = new URL(this.databaseUrl);\n wsUrl.protocol = wsUrl.protocol === 'http:' ? 'ws' : 'wss';\n const searchParams = new URLSearchParams();\n if (this.subscriber.closed) return;\n searchParams.set('v', '2');\n if (this.rev) searchParams.set('rev', this.rev);\n if (this.yrev) searchParams.set('yrev', this.yrev);\n searchParams.set('realmsHash', this.realmSetHash);\n searchParams.set('clientId', this.clientIdentity);\n searchParams.set('dxcv', this.db.cloud.version);\n if (this.user.accessToken) {\n searchParams.set('token', this.user.accessToken);\n }\n\n // Connect the WebSocket to given url:\n console.debug('dexie-cloud WebSocket create');\n const ws = (this.ws = new WebSocket(`${wsUrl}/changes?${searchParams}`));\n ws.binaryType = \"arraybuffer\";\n\n ws.onclose = (event: Event) => {\n if (!this.pinger) return;\n console.debug('dexie-cloud WebSocket onclosed', this.id);\n this.reconnect();\n };\n\n ws.onmessage = (event: MessageEvent) => {\n if (!this.pinger) return;\n\n this.lastServerActivity = new Date();\n try {\n const msg = typeof event.data === 'string'\n ? TSON.parse(event.data) as\n | WSConnectionMsg\n | PongMessage\n | ErrorMessage\n | YServerMessage \n : decodeYMessage(new Uint8Array(event.data)) as\n | YServerMessage;\n console.debug('dexie-cloud WebSocket onmessage', msg.type, msg);\n if (msg.type === 'error') {\n throw new Error(`Error message from dexie-cloud: ${msg.error}`);\n } else if (msg.type === 'aware') {\n const docCache = DexieYProvider.getDocCache(this.db.dx);\n const doc = docCache.find(msg.table, msg.k, msg.prop);\n if (doc) {\n const awareness = getDocAwareness(doc);\n if (awareness) {\n awap.applyAwarenessUpdate(\n awareness,\n msg.u,\n 'server',\n );\n }\n }\n } else if (msg.type === 'pong') {\n // Do nothing\n } else if (msg.type === 'doc-open') {\n const docCache = DexieYProvider.getDocCache(this.db.dx);\n const doc = docCache.find(msg.table, msg.k, msg.prop);\n if (doc) {\n getOpenDocSignal(doc).next(); // Make yHandler reopen the document on server.\n }\n } else if (msg.type === 'u-ack' || msg.type === 'u-reject' || msg.type === 'u-s' || msg.type === 'in-sync' || msg.type === 'outdated-server-rev' || msg.type === 'y-complete-sync-done') {\n applyYServerMessages([msg], this.db).then(async ({resyncNeeded, yServerRevision, receivedUntils}) => {\n if (yServerRevision) {\n await this.db.$syncState.update('syncState', { yServerRevision: yServerRevision });\n }\n if (msg.type === 'u-s' && receivedUntils) {\n const utbl = getUpdatesTable(this.db, msg.table, msg.prop) as any as Table<YSyncState, string>;\n if (utbl) {\n const receivedUntil = receivedUntils[utbl.name];\n if (receivedUntil) {\n await utbl.update(DEXIE_CLOUD_SYNCER_ID, { receivedUntil });\n }\n }\n }\n if (resyncNeeded) {\n await this.db.cloud.sync({ purpose: 'pull', wait: true });\n }\n })\n } else {\n // Forward the request to our subscriber, wich is in messageFromServerQueue.ts (via connectWebSocket's subscribe() at the end!)\n this.subscriber.next(msg);\n }\n } catch (e) {\n this.subscriber.error(e);\n }\n };\n\n try {\n let everConnected = false;\n await new Promise((resolve, reject) => {\n ws.onopen = (event) => {\n console.debug('dexie-cloud WebSocket onopen');\n everConnected = true;\n resolve(null);\n };\n ws.onerror = (event: ErrorEvent) => {\n if (!everConnected) {\n const error = event.error || new Error('WebSocket Error');\n this.subscriber.error(error);\n this.webSocketStatus.next('error');\n reject(error);\n } else {\n this.reconnect();\n }\n };\n });\n this.subscriptions.add(this.messageProducer.subscribe(\n (msg) => {\n if (!this.closed) {\n if (\n msg.type === 'ready' &&\n this.webSocketStatus.value !== 'connected'\n ) {\n this.webSocketStatus.next('connected');\n }\n console.debug('dexie-cloud WebSocket send', msg.type, msg);\n if (msg.type === 'ready') {\n // Ok, we are certain to have stored everything up until revision msg.rev.\n // Update this.rev in case of reconnect - remember where we were and don't just start over!\n this.rev = msg.rev; \n // ... and then send along the request to the server so it would also be updated!\n this.ws?.send(TSON.stringify(msg));\n } else {\n // If it's not a \"ready\" message, it's an YMessage.\n // YMessages can be sent binary encoded.\n this.ws?.send(encodeYMessage(msg));\n }\n }\n }\n ));\n if (this.user.isLoggedIn && !isEagerSyncDisabled(this.db)) {\n this.subscriptions.add(\n createYClientUpdateObservable(this.db).subscribe(\n this.db.messageProducer\n )\n );\n }\n } catch (error) {\n this.pauseUntil = new Date(Date.now() + FAIL_RETRY_WAIT_TIME);\n }\n }\n}\n","import { Decoder, readAny, readBigUint64, readVarString, readVarUint8Array, } from 'lib0/decoding';\nexport function decodeYMessage(a) {\n const decoder = new Decoder(a);\n const type = readVarString(decoder);\n if (type === 'outdated-server-rev') {\n return { type };\n }\n if (type === 'y-complete-sync-done') {\n return { type, yServerRev: readVarString(decoder) };\n }\n const table = readVarString(decoder);\n const prop = readVarString(decoder);\n switch (type) {\n case 'u-ack':\n case 'u-reject':\n return {\n type,\n table,\n prop,\n i: Number(readBigUint64(decoder)),\n };\n default: {\n const k = readAny(decoder);\n switch (type) {\n case 'in-sync':\n return { type, table, prop, k };\n case 'aware':\n return {\n type,\n table,\n prop,\n k,\n u: readVarUint8Array(decoder),\n };\n case 'doc-open':\n return {\n type,\n table,\n prop,\n k,\n serverRev: readAny(decoder),\n sv: readAny(decoder),\n };\n case 'doc-close':\n return { type, table, prop, k };\n case 'sv':\n return {\n type,\n table,\n prop,\n k,\n sv: readVarUint8Array(decoder),\n };\n case 'u-c':\n return {\n type,\n table,\n prop,\n k,\n u: readVarUint8Array(decoder),\n i: Number(readBigUint64(decoder)),\n };\n case 'u-s':\n return {\n type,\n table,\n prop,\n k,\n u: readVarUint8Array(decoder),\n r: (decoder.pos < decoder.arr.length && readVarString(decoder)) || undefined,\n };\n default:\n throw new TypeError(`Unknown message type: ${type}`);\n }\n }\n }\n}\n","import { Encoder, writeVarString, writeBigUint64, writeAny, toUint8Array, writeVarUint8Array, } from 'lib0/encoding';\nexport function encodeYMessage(msg) {\n const encoder = new Encoder();\n writeVarString(encoder, msg.type);\n if ('table' in msg)\n writeVarString(encoder, msg.table);\n if ('prop' in msg)\n writeVarString(encoder, msg.prop);\n switch (msg.type) {\n case 'u-ack':\n case 'u-reject':\n writeBigUint64(encoder, BigInt(msg.i));\n break;\n case 'outdated-server-rev':\n break;\n case 'y-complete-sync-done':\n writeVarString(encoder, msg.yServerRev);\n break;\n default:\n writeAny(encoder, msg.k);\n switch (msg.type) {\n case 'aware':\n writeVarUint8Array(encoder, msg.u);\n break;\n case 'doc-open':\n writeAny(encoder, msg.serverRev);\n writeAny(encoder, msg.sv);\n break;\n case 'doc-close':\n break;\n case 'sv':\n writeVarUint8Array(encoder, msg.sv);\n break;\n case 'u-c':\n writeVarUint8Array(encoder, msg.u);\n writeBigUint64(encoder, BigInt(msg.i));\n break;\n case 'u-s':\n writeVarUint8Array(encoder, msg.u);\n writeVarString(encoder, msg.r || '');\n break;\n case 'in-sync':\n break;\n }\n }\n return toUint8Array(encoder);\n}\n","import { Observable, from, merge, mergeMap, switchMap, tap } from 'rxjs';\nimport { YClientMessage, YUpdateFromClientRequest } from 'dexie-cloud-common';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { flatten } from '../helpers/flatten';\nimport { liveQuery } from 'dexie';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport { listUpdatesSince } from './listUpdatesSince';\nimport { YDexieCloudSyncState } from './YDexieCloudSyncState';\n\nexport function createYClientUpdateObservable(\n db: DexieCloudDB\n): Observable<YClientMessage> {\n const yTableRecords = flatten(\n db.tables\n .filter(\n (table) =>\n db.cloud.schema?.[table.name]?.markedForSync && table.schema.yProps\n )\n .map((table) =>\n table.schema.yProps!.map((p) => ({\n table: table.name,\n ydocProp: p.prop,\n updatesTable: p.updatesTable,\n }))\n )\n );\n return merge(\n ...yTableRecords.map(({ table, ydocProp, updatesTable }) => {\n // Per updates table (table+prop combo), we first read syncer.unsentFrom,\n // and then start listening for updates since that number.\n const yTbl = db.table(updatesTable);\n return from(yTbl.get(DEXIE_CLOUD_SYNCER_ID)).pipe(\n switchMap((syncer: YDexieCloudSyncState) => {\n let currentUnsentFrom = syncer?.unsentFrom || 1;\n return from(\n liveQuery(async () => {\n const addedUpdates = await listUpdatesSince(\n yTbl,\n currentUnsentFrom\n );\n return addedUpdates\n .filter((update) => update.f && update.f & 1) // Only include local updates\n .map((update) => {\n return {\n type: 'u-c',\n table,\n prop: ydocProp,\n k: update.k,\n u: update.u,\n i: update.i,\n } satisfies YUpdateFromClientRequest;\n });\n })\n ).pipe(\n tap((addedUpdates) => {\n // Update currentUnsentFrom to only listen for updates that will be newer than the ones we emitted.\n // (Before, we did this within the liveQuery, but that caused a bug because\n // a cancelled emittion of a liveQuery would update the currentUnsentFrom without\n // emitting anything, leading to that we jumped over some updates. Here we update it\n // after the liveQuery has emitted its updates)\n if (addedUpdates.length > 0) {\n currentUnsentFrom = addedUpdates.at(-1)!.i + 1;\n }\n })\n );\n })\n );\n })\n ).pipe(\n // Flatten the array of messages.\n // If messageProducer emits empty array, nothing is emitted\n // but if messageProducer emits array of messages, they are\n // emitted one by one.\n mergeMap((messages) => messages)\n );\n}\n","export class InvalidLicenseError extends Error {\n name = 'InvalidLicenseError';\n license?: 'expired' | 'deactivated';\n constructor(license?: 'expired' | 'deactivated') {\n super(\n license === 'expired'\n ? `License expired`\n : license === 'deactivated'\n ? `User deactivated`\n : 'Invalid license'\n );\n if (license) {\n this.license = license;\n }\n }\n}\n","import { BehaviorSubject, firstValueFrom, from, Observable, of, throwError, merge } from 'rxjs';\nimport {\n catchError,\n combineLatestAll,\n debounceTime,\n delay,\n distinctUntilChanged,\n filter,\n map,\n mergeMap,\n switchMap,\n take,\n tap,\n} from 'rxjs/operators';\nimport { refreshAccessToken } from '../authentication/authenticate';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { computeRealmSetHash } from '../helpers/computeRealmSetHash';\nimport {\n userDoesSomething,\n userIsActive,\n userIsReallyActive,\n} from '../userIsActive';\nimport {\n ReadyForChangesMessage,\n WSConnectionMsg,\n WSObservable,\n} from '../WSObservable';\nimport { InvalidLicenseError } from '../InvalidLicenseError';\nimport { read } from 'fs';\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function waitAndReconnectWhenUserDoesSomething(error: Error) {\n console.error(\n `WebSocket observable: error but revive when user does some active thing...`,\n error\n );\n // Sleep some seconds...\n await sleep(3000);\n // Wait til user does something (move mouse, tap, scroll, click etc)\n console.debug('waiting for someone to do something');\n await firstValueFrom(userDoesSomething);\n console.debug('someone did something!');\n}\n\nexport function connectWebSocket(db: DexieCloudDB) {\n if (!db.cloud.options?.databaseUrl) {\n throw new Error(`No database URL to connect WebSocket to`);\n }\n\n const readyForChangesMessage = db.messageConsumer.readyToServe.pipe(\n filter((isReady) => isReady), // When consumer is ready for new messages, produce such a message to inform server about it\n switchMap(() => db.getPersistedSyncState()), // We need the info on which server revision we are at:\n filter((syncState) => syncState && syncState.serverRevision), // We wont send anything to server before inital sync has taken place\n switchMap<PersistedSyncState, Promise<ReadyForChangesMessage>>(async (syncState) => ({\n // Produce the message to trigger server to send us new messages to consume:\n type: 'ready',\n rev: syncState.serverRevision,\n realmSetHash: await computeRealmSetHash(syncState)\n } satisfies ReadyForChangesMessage))\n );\n\n const messageProducer = merge(\n readyForChangesMessage,\n db.messageProducer\n );\n\n function createObservable(): Observable<WSConnectionMsg | null> {\n return db.cloud.persistedSyncState.pipe(\n filter((syncState) => syncState?.serverRevision), // Don't connect before there's no initial sync performed.\n take(1), // Don't continue waking up whenever syncState change\n switchMap((syncState) =>\n db.cloud.currentUser.pipe(\n map((userLogin) => [userLogin, syncState] as const)\n )\n ),\n switchMap(([userLogin, syncState]) => {\n /*if (userLogin.license?.status && userLogin.license.status !== 'ok') {\n throw new InvalidLicenseError();\n }*/\n return userIsReallyActive.pipe(\n map((isActive) => [isActive ? userLogin : null, syncState] as const)\n );\n }),\n switchMap(([userLogin, syncState]) => {\n if (userLogin?.isLoggedIn && !syncState?.realms.includes(userLogin.userId!)) {\n // We're in an in-between state when user is logged in but the user's realms are not yet synced.\n // Don't make this change reconnect the websocket just yet. Wait till syncState is updated\n // to iclude the user's realm.\n return db.cloud.persistedSyncState.pipe(\n filter((syncState) => syncState?.realms.includes(userLogin!.userId!) || false),\n take(1),\n map((syncState) => [userLogin, syncState] as const)\n );\n }\n return new BehaviorSubject([userLogin, syncState] as const);\n }),\n switchMap(\n async ([userLogin, syncState]) =>\n [userLogin, await computeRealmSetHash(syncState!)] as const\n ),\n distinctUntilChanged(([prevUser, prevHash], [currUser, currHash]) => prevUser === currUser && prevHash === currHash ),\n switchMap(([userLogin, realmSetHash]) => {\n if (!db.cloud.persistedSyncState?.value) {\n // Restart the flow if persistedSyncState is not yet available.\n return createObservable();\n }\n // Let server end query changes from last entry of same client-ID and forward.\n // If no new entries, server won't bother the client. If new entries, server sends only those\n // and the baseRev of the last from same client-ID.\n if (userLogin) {\n return new WSObservable(\n db,\n db.cloud.persistedSyncState!.value!.serverRevision,\n db.cloud.persistedSyncState!.value!.yServerRevision,\n realmSetHash,\n db.cloud.persistedSyncState!.value!.clientIdentity,\n messageProducer,\n db.cloud.webSocketStatus,\n userLogin\n );\n } else {\n return from([] as WSConnectionMsg[]);\n }}),\n catchError((error) => {\n if (error?.name === 'TokenExpiredError') {\n console.debug(\n 'WebSocket observable: Token expired. Refreshing token...'\n );\n return of(true).pipe(\n switchMap(async () => {\n // Refresh access token\n const user = await db.getCurrentUser();\n const refreshedLogin = await refreshAccessToken(\n db.cloud.options!.databaseUrl,\n user\n );\n // Persist updated access token\n await db.table('$logins').update(user.userId, {\n accessToken: refreshedLogin.accessToken,\n accessTokenExpiration: refreshedLogin.accessTokenExpiration,\n claims: refreshedLogin.claims,\n license: refreshedLogin.license,\n data: refreshedLogin.data\n });\n }),\n switchMap(() => createObservable())\n );\n } else {\n return throwError(()=>error);\n }\n }),\n catchError((error) => {\n db.cloud.webSocketStatus.next(\"error\");\n if (error instanceof InvalidLicenseError) {\n // Don't retry. Just throw and don't try connect again.\n return throwError(() => error);\n }\n return from(waitAndReconnectWhenUserDoesSomething(error)).pipe(\n switchMap(() => createObservable())\n );\n })\n ) as Observable<WSConnectionMsg | null>;\n }\n\n return createObservable().subscribe({\n next: (msg) => {\n if (msg) {\n console.debug('WS got message', msg);\n db.messageConsumer.enqueue(msg);\n }\n },\n error: (error) => {\n console.error('WS got error', error);\n },\n complete: () => {\n console.debug('WS observable completed');\n },\n });\n}\n","import { DexieCloudDB } from \"../db/DexieCloudDB\";\nimport { sync } from \"./sync\";\n\nexport async function isSyncNeeded(db: DexieCloudDB) {\n return db.cloud.options?.databaseUrl && db.cloud.schema\n ? await sync(db, db.cloud.options, db.cloud.schema, {justCheckIfNeeded: true})\n : false;\n}\n","import { IS_SERVICE_WORKER } from '../helpers/IS_SERVICE_WORKER';\nimport { performGuardedJob } from './performGuardedJob';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { sync, CURRENT_SYNC_WORKER, SyncOptions } from './sync';\nimport { DexieCloudOptions } from '../DexieCloudOptions';\nimport { assert, DexieCloudSchema } from 'dexie-cloud-common';\nimport { checkSyncRateLimitDelay } from './ratelimit';\n\nconst ongoingSyncs = new WeakMap<\n DexieCloudDB,\n { promise: Promise<void>; pull: boolean }\n>();\n\nexport function syncIfPossible(\n db: DexieCloudDB,\n cloudOptions: DexieCloudOptions,\n cloudSchema: DexieCloudSchema,\n options?: SyncOptions\n) {\n const ongoing = ongoingSyncs.get(db);\n if (ongoing) {\n if (ongoing.pull || options?.purpose === 'push') {\n console.debug('syncIfPossible(): returning the ongoing sync promise.');\n return ongoing.promise;\n } else {\n // Ongoing sync may never do anything in case there are no outstanding changes\n // to sync (because its purpose was \"push\" not \"pull\")\n // Now, however, we are asked to do a sync with the purpose of \"pull\"\n // We want to optimize here. We must wait for the ongoing to complete\n // and then, if the ongoing sync never resulted in a sync request,\n // we must redo the sync.\n\n // To inspect what is happening in the ongoing request, let's subscribe\n // to db.cloud.syncState and look for if it is doing any \"pulling\" phase:\n let hasPullTakenPlace = false;\n const subscription = db.cloud.syncState.subscribe((syncState) => {\n if (syncState.phase === 'pulling') {\n hasPullTakenPlace = true;\n }\n });\n // Ok, so now we are watching. At the same time, wait for the ongoing to complete\n // and when it has completed, check if we're all set or if we need to redo\n // the call:\n return (\n ongoing.promise\n // This is a finally block but we are still running tests on\n // browsers that don't support it, so need to do it like this:\n .then(() => {\n subscription.unsubscribe();\n })\n .catch((error) => {\n subscription.unsubscribe();\n return Promise.reject(error);\n })\n .then(() => {\n if (!hasPullTakenPlace) {\n // No pull took place in the ongoing sync but the caller had \"pull\" as\n // an explicit purpose of this call - so we need to redo the call!\n return syncIfPossible(db, cloudOptions, cloudSchema, options);\n }\n })\n );\n }\n }\n\n const promise = _syncIfPossible();\n ongoingSyncs.set(db, { promise, pull: options?.purpose !== 'push' });\n return promise;\n\n async function _syncIfPossible() {\n try {\n // Check if should delay sync due to ratelimit:\n await checkSyncRateLimitDelay(db); \n await performGuardedJob(db, CURRENT_SYNC_WORKER, () =>\n sync(db, cloudOptions, cloudSchema, options)\n );\n ongoingSyncs.delete(db);\n console.debug('Done sync');\n } catch (error) {\n ongoingSyncs.delete(db);\n console.error(`Failed to sync client changes`, error);\n throw error; // Make sure we rethrow error so that sync event is retried.\n // I don't think we should setTimout or so here.\n // Unless server tells us to in some response.\n // Then we could follow that advice but not by waiting here but by registering\n // Something that triggers an event listened to in startPushWorker()\n }\n }\n}\n","export const SECONDS = 1000;\nexport const MINUTES = 60 * SECONDS;\nexport const HOURS = 60 * MINUTES;\nexport const DAYS = 24 * HOURS;\nexport const WEEKS = 7 * DAYS;\n","import { Subscription } from 'rxjs';\nimport { syncIfPossible } from './syncIfPossible';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { SECONDS } from '../helpers/date-constants';\nimport { DexieCloudOptions } from '../DexieCloudOptions';\nimport { DexieCloudSchema } from 'dexie-cloud-common';\n\nexport function LocalSyncWorker(\n db: DexieCloudDB,\n cloudOptions: DexieCloudOptions,\n cloudSchema: DexieCloudSchema\n) {\n let localSyncEventSubscription: Subscription | null = null;\n let cancelToken = { cancelled: false };\n let nextRetryTime = 0;\n let syncStartTime = 0;\n\n function syncAndRetry(retryNum = 1) {\n // Use setTimeout() to get onto a clean stack and\n // break free from possible active transaction:\n setTimeout(() => {\n const purpose = pullSignalled ? 'pull' : 'push';\n syncStartTime = Date.now();\n syncIfPossible(db, cloudOptions, cloudSchema, {\n cancelToken,\n retryImmediatelyOnFetchError: true, // workaround for \"net::ERR_NETWORK_CHANGED\" in chrome.\n purpose,\n }).then(()=>{\n if (cancelToken.cancelled) {\n stop();\n } else {\n if (pullSignalled || pushSignalled) {\n // If we have signalled for more sync, do it now.\n pullSignalled = false;\n pushSignalled = false;\n return syncAndRetry();\n }\n }\n ongoingSync = false;\n nextRetryTime = 0;\n syncStartTime = 0;\n }).catch((error: unknown) => {\n console.error('error in syncIfPossible()', error);\n if (cancelToken.cancelled) {\n stop();\n ongoingSync = false;\n nextRetryTime = 0;\n syncStartTime = 0;\n } else if (retryNum < 5) {\n // Mimic service worker sync event but a bit more eager: retry 4 times\n // * first retry after 20 seconds\n // * second retry 40 seconds later\n // * third retry 5 minutes later\n // * last retry 15 minutes later\n const retryIn = [0, 20, 40, 300, 900][retryNum] * SECONDS\n nextRetryTime = Date.now() + retryIn;\n syncStartTime = 0;\n setTimeout(\n () => syncAndRetry(retryNum + 1),\n retryIn\n );\n } else {\n ongoingSync = false;\n nextRetryTime = 0;\n syncStartTime = 0;\n }\n });\n }, 0);\n }\n\n let pullSignalled = false;\n let pushSignalled = false;\n let ongoingSync = false;\n const consumer = (purpose: 'pull' | 'push') =>{\n if (cancelToken.cancelled) return;\n if (purpose === 'pull') {\n pullSignalled = true;\n }\n if (purpose === 'push') {\n pushSignalled = true;\n }\n if (ongoingSync) {\n if (nextRetryTime) {\n console.debug(`Sync is paused until ${new Date(nextRetryTime).toISOString()} due to error in last sync attempt`);\n } else if (syncStartTime > 0 && Date.now() - syncStartTime > 20 * SECONDS) {\n console.debug(`An existing sync operation is taking more than 20 seconds. Will resync when done.`)\n }\n return;\n }\n ongoingSync = true;\n syncAndRetry();\n };\n\n const start = () => {\n // Sync eagerly whenever a change has happened (+ initially when there's no syncState yet)\n // This initial subscribe will also trigger an sync also now.\n console.debug('Starting LocalSyncWorker', db.localSyncEvent['id']);\n localSyncEventSubscription = db.localSyncEvent.subscribe(({ purpose }) => {\n consumer(purpose || 'pull');\n });\n };\n\n const stop = () => {\n console.debug('Stopping LocalSyncWorker');\n cancelToken.cancelled = true;\n if (localSyncEventSubscription) localSyncEventSubscription.unsubscribe();\n };\n\n return {\n start,\n stop,\n };\n}\n","import { DexieCloudSchema } from \"dexie-cloud-common\";\nimport { DexieCloudOptions } from \"./DexieCloudOptions\";\n\nexport function updateSchemaFromOptions(schema?: DexieCloudSchema | null, options?: DexieCloudOptions | null) {\n if (schema && options) {\n if (options.unsyncedTables) {\n for (const tableName of options.unsyncedTables) {\n if (schema[tableName]) {\n schema[tableName].markedForSync = false;\n }\n }\n }\n }\n}","var n,l,u,i,t,o,r,f={},e=[],c=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s(n,l){for(var u in l)n[u]=l[u];return n}function a(n){var l=n.parentNode;l&&l.removeChild(n)}function h(l,u,i){var t,o,r,f={};for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),\"function\"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return v(l,f,t,o,null)}function v(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u:r};return null==r&&null!=l.vnode&&l.vnode(f),f}function y(){return{current:null}}function p(n){return n.children}function d(n,l){this.props=n,this.context=l}function _(n,l){if(null==l)return n.__?_(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return\"function\"==typeof n.type?_(n):null}function k(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return k(n)}}function b(n){(!n.__d&&(n.__d=!0)&&t.push(n)&&!g.__r++||o!==l.debounceRendering)&&((o=l.debounceRendering)||setTimeout)(g)}function g(){for(var n;g.__r=t.length;)n=t.sort(function(n,l){return n.__v.__b-l.__v.__b}),t=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=s({},t)).__v=t.__v+1,j(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?_(t):o,t.__h),z(u,t),t.__e!=o&&k(t)))})}function w(n,l,u,i,t,o,r,c,s,a){var h,y,d,k,b,g,w,x=i&&i.__k||e,C=x.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||\"boolean\"==typeof k?null:\"string\"==typeof k||\"number\"==typeof k||\"bigint\"==typeof k?v(null,k,null,null,k):Array.isArray(k)?v(p,{children:k},null,null,null):k.__b>0?v(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(d=x[h])||d&&k.key==d.key&&k.type===d.type)x[h]=void 0;else for(y=0;y<C;y++){if((d=x[y])&&k.key==d.key&&k.type===d.type){x[y]=void 0;break}d=null}j(n,k,d=d||f,t,o,r,c,s,a),b=k.__e,(y=k.ref)&&d.ref!=y&&(w||(w=[]),d.ref&&w.push(d.ref,null,k),w.push(y,k.__c||b,k)),null!=b?(null==g&&(g=b),\"function\"==typeof k.type&&k.__k===d.__k?k.__d=s=m(k,s,n):s=A(n,k,d,x,b,s),\"function\"==typeof u.type&&(u.__d=s)):s&&d.__e==s&&s.parentNode!=n&&(s=_(d))}for(u.__e=g,h=C;h--;)null!=x[h]&&(\"function\"==typeof u.type&&null!=x[h].__e&&x[h].__e==u.__d&&(u.__d=_(i,h+1)),N(x[h],x[h]));if(w)for(h=0;h<w.length;h++)M(w[h],w[++h],w[++h])}function m(n,l,u){for(var i,t=n.__k,o=0;t&&o<t.length;o++)(i=t[o])&&(i.__=n,l=\"function\"==typeof i.type?m(i,l,u):A(u,i,i,t,i.__e,l));return l}function x(n,l){return l=l||[],null==n||\"boolean\"==typeof n||(Array.isArray(n)?n.some(function(n){x(n,l)}):l.push(n)),l}function A(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else{for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o}return void 0!==r?r:t.nextSibling}function C(n,l,u,i,t){var o;for(o in u)\"children\"===o||\"key\"===o||o in l||H(n,o,null,u[o],i);for(o in l)t&&\"function\"!=typeof l[o]||\"children\"===o||\"key\"===o||\"value\"===o||\"checked\"===o||u[o]===l[o]||H(n,o,l[o],u[o],i)}function $(n,l,u){\"-\"===l[0]?n.setProperty(l,u):n[l]=null==u?\"\":\"number\"!=typeof u||c.test(l)?u:u+\"px\"}function H(n,l,u,i,t){var o;n:if(\"style\"===l)if(\"string\"==typeof u)n.style.cssText=u;else{if(\"string\"==typeof i&&(n.style.cssText=i=\"\"),i)for(l in i)u&&l in u||$(n.style,l,\"\");if(u)for(l in u)i&&u[l]===i[l]||$(n.style,l,u[l])}else if(\"o\"===l[0]&&\"n\"===l[1])o=l!==(l=l.replace(/Capture$/,\"\")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?T:I,o):n.removeEventListener(l,o?T:I,o);else if(\"dangerouslySetInnerHTML\"!==l){if(t)l=l.replace(/xlink(H|:h)/,\"h\").replace(/sName$/,\"s\");else if(\"href\"!==l&&\"list\"!==l&&\"form\"!==l&&\"tabIndex\"!==l&&\"download\"!==l&&l in n)try{n[l]=null==u?\"\":u;break n}catch(n){}\"function\"==typeof u||(null!=u&&(!1!==u||\"a\"===l[0]&&\"r\"===l[1])?n.setAttribute(l,u):n.removeAttribute(l))}}function I(n){this.l[n.type+!1](l.event?l.event(n):n)}function T(n){this.l[n.type+!0](l.event?l.event(n):n)}function j(n,u,i,t,o,r,f,e,c){var a,h,v,y,_,k,b,g,m,x,A,C,$,H=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=l.__b)&&a(u);try{n:if(\"function\"==typeof H){if(g=u.props,m=(a=H.contextType)&&t[a.__c],x=a?m?m.props.value:a.__:t,i.__c?b=(h=u.__c=i.__c).__=h.__E:(\"prototype\"in H&&H.prototype.render?u.__c=h=new H(g,x):(u.__c=h=new d(g,x),h.constructor=H,h.render=O),m&&m.sub(h),h.props=g,h.state||(h.state={}),h.context=x,h.__n=t,v=h.__d=!0,h.__h=[]),null==h.__s&&(h.__s=h.state),null!=H.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=s({},h.__s)),s(h.__s,H.getDerivedStateFromProps(g,h.__s))),y=h.props,_=h.state,v)null==H.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else{if(null==H.getDerivedStateFromProps&&g!==y&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(g,x),!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(g,h.__s,x)||u.__v===i.__v){h.props=g,h.state=h.__s,u.__v!==i.__v&&(h.__d=!1),h.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u)}),h.__h.length&&f.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(g,h.__s,x),null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(y,_,k)})}if(h.context=x,h.props=g,h.__v=u,h.__P=n,A=l.__r,C=0,\"prototype\"in H&&H.prototype.render)h.state=h.__s,h.__d=!1,A&&A(u),a=h.render(h.props,h.state,h.context);else do{h.__d=!1,A&&A(u),a=h.render(h.props,h.state,h.context),h.state=h.__s}while(h.__d&&++C<25);h.state=h.__s,null!=h.getChildContext&&(t=s(s({},t),h.getChildContext())),v||null==h.getSnapshotBeforeUpdate||(k=h.getSnapshotBeforeUpdate(y,_)),$=null!=a&&a.type===p&&null==a.key?a.props.children:a,w(n,Array.isArray($)?$:[$],u,i,t,o,r,f,e,c),h.base=u.__e,u.__h=null,h.__h.length&&f.push(h),b&&(h.__E=h.__=null),h.__e=!1}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=L(i.__e,u,i,t,o,r,f,c);(a=l.diffed)&&a(u)}catch(n){u.__v=null,(c||null!=r)&&(u.__e=e,u.__h=!!c,r[r.indexOf(e)]=null),l.__e(n,u,i)}}function z(n,u){l.__c&&l.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u)})}catch(n){l.__e(n,u.__v)}})}function L(l,u,i,t,o,r,e,c){var s,h,v,y=i.props,p=u.props,d=u.type,k=0;if(\"svg\"===d&&(o=!0),null!=r)for(;k<r.length;k++)if((s=r[k])&&\"setAttribute\"in s==!!d&&(d?s.localName===d:3===s.nodeType)){l=s,r[k]=null;break}if(null==l){if(null===d)return document.createTextNode(p);l=o?document.createElementNS(\"http://www.w3.org/2000/svg\",d):document.createElement(d,p.is&&p),r=null,c=!1}if(null===d)y===p||c&&l.data===p||(l.data=p);else{if(r=r&&n.call(l.childNodes),h=(y=i.props||f).dangerouslySetInnerHTML,v=p.dangerouslySetInnerHTML,!c){if(null!=r)for(y={},k=0;k<l.attributes.length;k++)y[l.attributes[k].name]=l.attributes[k].value;(v||h)&&(v&&(h&&v.__html==h.__html||v.__html===l.innerHTML)||(l.innerHTML=v&&v.__html||\"\"))}if(C(l,p,y,o,c),v)u.__k=[];else if(k=u.props.children,w(l,Array.isArray(k)?k:[k],u,i,t,o&&\"foreignObject\"!==d,r,e,r?r[0]:i.__k&&_(i,0),c),null!=r)for(k=r.length;k--;)null!=r[k]&&a(r[k]);c||(\"value\"in p&&void 0!==(k=p.value)&&(k!==l.value||\"progress\"===d&&!k||\"option\"===d&&k!==y.value)&&H(l,\"value\",k,y.value,!1),\"checked\"in p&&void 0!==(k=p.checked)&&k!==l.checked&&H(l,\"checked\",k,y.checked,!1))}return l}function M(n,u,i){try{\"function\"==typeof n?n(u):n.current=u}catch(n){l.__e(n,i)}}function N(n,u,i){var t,o;if(l.unmount&&l.unmount(n),(t=n.ref)&&(t.current&&t.current!==n.__e||M(t,null,u)),null!=(t=n.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount()}catch(n){l.__e(n,u)}t.base=t.__P=null}if(t=n.__k)for(o=0;o<t.length;o++)t[o]&&N(t[o],u,\"function\"!=typeof n.type);i||null==n.__e||a(n.__e),n.__e=n.__d=void 0}function O(n,l,u){return this.constructor(n,u)}function P(u,i,t){var o,r,e;l.__&&l.__(u,i),r=(o=\"function\"==typeof t)?null:t&&t.__k||i.__k,e=[],j(i,u=(!o&&t||i).__k=h(p,null,[u]),r||f,f,void 0!==i.ownerSVGElement,!o&&t?[t]:r?null:i.firstChild?n.call(i.childNodes):null,e,!o&&t?t:r?r.__e:i.firstChild,o),z(e,u)}function S(n,l){P(n,l,S)}function q(l,u,i){var t,o,r,f=s({},l.props);for(r in u)\"key\"==r?t=u[r]:\"ref\"==r?o=u[r]:f[r]=u[r];return arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),v(l.type,f,t||l.key,o||l.ref,null)}function B(n,l){var u={__c:l=\"__cC\"+r++,__:n,Consumer:function(n,l){return n.children(l)},Provider:function(n){var u,i;return this.getChildContext||(u=[],(i={})[l]=this,this.getChildContext=function(){return i},this.shouldComponentUpdate=function(n){this.props.value!==n.value&&u.some(b)},this.sub=function(n){u.push(n);var l=n.componentWillUnmount;n.componentWillUnmount=function(){u.splice(u.indexOf(n),1),l&&l.call(n)}}),n.children}};return u.Provider.__=u.Consumer.contextType=u}n=e.slice,l={__e:function(n,l,u,i){for(var t,o,r;l=l.__;)if((t=l.__c)&&!t.__)try{if((o=t.constructor)&&null!=o.getDerivedStateFromError&&(t.setState(o.getDerivedStateFromError(n)),r=t.__d),null!=t.componentDidCatch&&(t.componentDidCatch(n,i||{}),r=t.__d),r)return t.__E=t}catch(l){n=l}throw n}},u=0,i=function(n){return null!=n&&void 0===n.constructor},d.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=s({},this.state),\"function\"==typeof n&&(n=n(s({},u),this.props)),n&&s(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),b(this))},d.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),b(this))},d.prototype.render=p,t=[],g.__r=0,r=0;export{P as render,S as hydrate,h as createElement,h,p as Fragment,y as createRef,i as isValidElement,d as Component,q as cloneElement,B as createContext,x as toChildArray,l as options};\n//# sourceMappingURL=preact.module.js.map\n","export const Styles: { [styleAlias: string]: Partial<CSSStyleDeclaration> | any} = {\n Error: {\n color: \"red\",\n },\n Alert: {\n error: {\n color: \"red\",\n fontWeight: \"bold\"\n },\n warning: {\n color: \"#f80\",\n fontWeight: \"bold\"\n },\n info: {\n color: \"black\"\n }\n },\n Darken: {\n position: \"fixed\",\n top: 0,\n left: 0,\n opacity: 0.5,\n backgroundColor: \"#000\",\n width: \"100vw\",\n height: \"100vh\",\n zIndex: 150,\n webkitBackdropFilter: \"blur(2px)\",\n backdropFilter: \"blur(2px)\",\n },\n DialogOuter: {\n position: \"fixed\",\n top: 0,\n left: 0,\n width: \"100vw\",\n height: \"100vh\",\n zIndex: 150,\n alignItems: \"center\",\n display: \"flex\",\n justifyContent: \"center\",\n },\n DialogInner: {\n position: \"relative\",\n color: \"#222\",\n backgroundColor: \"#fff\",\n padding: \"30px\",\n marginBottom: \"2em\",\n maxWidth: \"90%\",\n maxHeight: \"90%\",\n overflowY: \"auto\",\n border: \"3px solid #3d3d5d\",\n borderRadius: \"8px\",\n boxShadow: \"0 0 80px 10px #666\",\n width: \"auto\",\n fontFamily: \"sans-serif\",\n },\n Input: {\n height: \"35px\",\n width: \"17em\",\n borderColor: \"#ccf4\",\n outline: \"none\",\n fontSize: \"17pt\",\n padding: \"8px\"\n \n }\n};\n","import { Styles } from './Styles';\nimport { ComponentChildren, h } from 'preact';\n\nexport function Dialog({ children, className }: { children?: ComponentChildren, className?: string }) {\n return (\n <div className={className}>\n <div style={Styles.Darken} />\n <div style={Styles.DialogOuter}>\n <div style={Styles.DialogInner}>{children}</div>\n </div>\n </div>\n );\n}\n","import{options as n}from\"preact\";var t,r,u,i,o=0,c=[],f=[],e=n.__b,a=n.__r,v=n.diffed,l=n.__c,m=n.unmount;function d(t,u){n.__h&&n.__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 h(u,i){var o=d(t++,3);!n.__s&&w(o.__H,i)&&(o.__=u,o.i=i,r.__H.__h.push(o))}function s(u,i){var o=d(t++,4);!n.__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 A(n,t,r){o=6,s(function(){return\"function\"==typeof n?(n(t()),function(){return n(null)}):n?(n.current=t(),function(){return n.current=null}):void 0},null==r?r:r.concat(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 T(n,t){return o=8,F(function(){return n},t)}function q(n){var u=r.context[n.__c],i=d(t++,9);return i.c=n,u?(null==i.__&&(i.__=!0,u.sub(r)),u.props.value):n.__}function x(t,r){n.useDebugValue&&n.useDebugValue(r?r(t):t)}function V(n){var u=d(t++,10),i=p();return u.__=n,r.componentDidCatch||(r.componentDidCatch=function(n){u.__&&u.__(n),i[1](n)}),[i[0],function(){i[1](void 0)}]}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=[],n.__e(r,t.__v)}}n.__b=function(n){r=null,e&&e(n)},n.__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},n.diffed=function(t){v&&v(t);var o=t.__c;o&&o.__H&&(o.__H.__h.length&&(1!==c.push(o)&&i===n.requestAnimationFrame||((i=n.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},n.__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=[],n.__e(u,t.__v)}}),l&&l(t,r)},n.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&&n.__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}export{p as useState,y as useReducer,h as useEffect,s as useLayoutEffect,_ as useRef,A as useImperativeHandle,F as useMemo,T as useCallback,q as useContext,x as useDebugValue,V as useErrorBoundary};\n//# sourceMappingURL=hooks.module.js.map\n","import { Dialog } from './Dialog';\nimport { Styles } from './Styles';\nimport { h, Fragment } from 'preact';\nimport { useLayoutEffect, useRef, useState } from 'preact/hooks';\nimport { DXCUserInteraction } from '../types/DXCUserInteraction';\nimport { resolveText } from '../helpers/resolveText';\nimport { DXCInputField } from '../types/DXCInputField';\n\nconst OTP_LENGTH = 8;\n\nexport function LoginDialog({\n title,\n type,\n alerts,\n fields,\n submitLabel,\n cancelLabel,\n onCancel,\n onSubmit,\n}: DXCUserInteraction) {\n const [params, setParams] = useState<{ [param: string]: string }>({});\n\n const firstFieldRef = useRef<HTMLInputElement>(null);\n useLayoutEffect(() => firstFieldRef.current?.focus(), []);\n\n return (\n <Dialog className=\"dxc-login-dlg\">\n <>\n <h3 style={Styles.WindowHeader}>{title}</h3>\n {alerts.map((alert) => (\n <p style={Styles.Alert[alert.type]}>{resolveText(alert)}</p>\n ))}\n <form\n onSubmit={(ev) => {\n ev.preventDefault();\n onSubmit(params);\n }}\n >\n {(Object.entries(fields) as [string, DXCInputField][]).map(\n ([fieldName, { type, label, placeholder }], idx) => (\n <label style={Styles.Label} key={idx}>\n {label ? `${label}: ` : ''}\n <input\n ref={idx === 0 ? firstFieldRef : undefined}\n type={type}\n name={fieldName}\n autoComplete=\"on\"\n style={Styles.Input}\n autoFocus\n placeholder={placeholder}\n value={params[fieldName] || ''}\n onInput={(ev) => {\n const value = valueTransformer(type, ev.target?.['value']);\n let updatedParams = {\n ...params,\n [fieldName]: value,\n };\n setParams(updatedParams);\n if (type === 'otp' && value?.trim().length === OTP_LENGTH) {\n // Auto-submit when OTP is filled in.\n onSubmit(updatedParams);\n }\n }}\n />\n </label>\n )\n )}\n </form>\n </>\n <div style={Styles.ButtonsDiv}>\n <>\n <button\n type=\"submit\"\n style={Styles.Button}\n onClick={() => onSubmit(params)}\n >\n {submitLabel}\n </button>\n {cancelLabel && (\n <button style={Styles.Button} onClick={onCancel}>\n {cancelLabel}\n </button>\n )}\n </>\n </div>\n </Dialog>\n );\n}\n\nfunction valueTransformer(type: string, value: string) {\n switch (type) {\n case 'email':\n return value.toLowerCase();\n case 'otp':\n return value.toUpperCase();\n default:\n return value;\n }\n}\n","import { DXCAlert } from \"../types/DXCAlert\";\n\n/** Resolve a message template with parameters.\n * \n * Example:\n * resolveText({\n * message: \"Hello {name}!\",\n * messageCode: \"HELLO\",\n * messageParams: {name: \"David\"}\n * }) => \"Hello David!\"\n * \n * @param message Template message with {vars} in it.\n * @param messageCode Unique code for the message. Can be used for translation.\n * @param messageParams Parameters to be used in the message.\n * @returns A final message where parameters have been replaced with values.\n */\nexport function resolveText({message, messageCode, messageParams}: DXCAlert) {\n return message.replace(/\\{\\w+\\}/ig, n => messageParams[n.substring(1, n.length-1)]);\n}\n","import Dexie from \"dexie\";\nimport \"../extend-dexie-interface\";\nimport { h, Component } from \"preact\";\nimport { from, Subscription } from \"rxjs\";\nimport { LoginDialog } from './LoginDialog';\nimport { DXCUserInteraction } from \"../types/DXCUserInteraction\";\nimport * as preact from \"preact\";\n\nexport interface Props {\n db: Dexie;\n}\n\ninterface State {\n userInteraction: DXCUserInteraction | undefined;\n}\n\nexport default class LoginGui extends Component<Props, State> {\n subscription?: Subscription;\n observer = (userInteraction: DXCUserInteraction | undefined) => this.setState({userInteraction});\n\n constructor(props: Props) {\n super(props);\n this.state = { userInteraction: undefined };\n }\n\n componentDidMount() {\n this.subscription = from(this.props.db.cloud.userInteraction).subscribe(this.observer);\n }\n\n componentWillUnmount() {\n if (this.subscription) {\n this.subscription.unsubscribe();\n delete this.subscription;\n }\n }\n\n render(props: Props, {userInteraction}: State) {\n if (!userInteraction) return null;\n //if (props.db.cloud.userInteraction.observers.length > 1) return null; // Someone else subscribes.\n return <LoginDialog {...userInteraction} />;\n }\n}\n\nexport function setupDefaultGUI(db: Dexie) {\n let closed = false;\n\n const el = document.createElement('div');\n if (document.body) {\n document.body.appendChild(el);\n preact.render(<LoginGui db={db.vip} />, el);\n } else {\n addEventListener('DOMContentLoaded', ()=>{\n if (!closed) {\n document.body.appendChild(el);\n preact.render(<LoginGui db={db.vip} />, el);\n }\n });\n }\n\n return {\n unsubscribe() {\n try { el.remove(); } catch {}\n closed = true;\n },\n get closed() {\n return closed;\n }\n }\n}\n","export function associate<T extends object,M>(factory: (x: T)=>M): (x: T) => M {\n const wm = new WeakMap<T, M>();\n return (x: T) => {\n let rv = wm.get(x);\n if (!rv) {\n rv = factory(x);\n wm.set(x, rv);\n }\n return rv;\n }\n}\n","import Dexie from \"dexie\";\nimport { BehaviorSubject } from \"rxjs\";\nimport { associate } from \"./associate\";\nimport { UNAUTHORIZED_USER } from \"./authentication/UNAUTHORIZED_USER\";\n\nexport const getCurrentUserEmitter = associate((db: Dexie) => new BehaviorSubject(UNAUTHORIZED_USER));\n","import {\n concat,\n from,\n InteropObservable,\n map,\n Observable,\n ObservableInput,\n share,\n timer,\n} from 'rxjs';\nimport { ObservableWithCurrentValue } from './mapValueObservable';\n\nexport function createSharedValueObservable<T>(\n o: ObservableInput<T>,\n defaultValue: T\n): ObservableWithCurrentValue<T> {\n let currentValue = defaultValue;\n let shared = from(o).pipe(\n map((x) => (currentValue = x)),\n share({ resetOnRefCountZero: () => timer(1000) })\n ) as ObservableWithCurrentValue<T>;\n\n const rv = new Observable((observer) => {\n let didEmit = false;\n const subscription = shared.subscribe({\n next(value) {\n didEmit = true;\n observer.next(value);\n },\n error(error) {\n observer.error(error);\n },\n complete() {\n observer.complete();\n }\n });\n if (!didEmit && !subscription.closed) {\n observer.next(currentValue);\n }\n return subscription;\n }) as ObservableWithCurrentValue<T>;\n\n rv.getValue = () => currentValue;\n return rv;\n}\n","import Dexie, { liveQuery } from 'dexie';\nimport { DBRealmRole } from 'dexie-cloud-common';\nimport { associate } from './associate';\nimport { createSharedValueObservable } from './createSharedValueObservable';\n\nexport const getGlobalRolesObservable = associate((db: Dexie) => {\n return createSharedValueObservable(\n liveQuery(() =>\n db.roles\n .where({ realmId: 'rlm-public' })\n .toArray()\n .then((roles) => {\n const rv: { [roleName: string]: DBRealmRole } = {};\n for (const role of roles\n .slice()\n .sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0))) {\n rv[role.name] = role;\n }\n return rv;\n })\n ),\n {}\n );\n});\n","import Dexie, { liveQuery } from 'dexie';\nimport { DBRealm, DBRealmMember } from 'dexie-cloud-common';\nimport { concat, Observable, timer } from 'rxjs';\nimport { share, switchMap } from 'rxjs/operators';\nimport { associate } from './associate';\nimport { createSharedValueObservable } from './createSharedValueObservable';\nimport { getCurrentUserEmitter } from './currentUserEmitter';\n\nexport type InternalAccessControlData = {\n readonly selfMembers: DBRealmMember[];\n readonly realms: DBRealm[];\n readonly userId: string;\n};\n\nexport const getInternalAccessControlObservable = associate((db: Dexie) => {\n return createSharedValueObservable(\n getCurrentUserEmitter(db._novip).pipe(\n switchMap((currentUser) =>\n liveQuery(() =>\n db.transaction('r', 'realms', 'members', () =>\n Promise.all([\n db.members.where({ userId: currentUser.userId }).toArray(),\n db.realms.toArray(),\n currentUser.userId!,\n ] as const).then(([selfMembers, realms, userId]) => {\n //console.debug(`PERMS: Result from liveQUery():`, JSON.stringify({selfMembers, realms, userId}, null, 2))\n return { selfMembers, realms, userId };\n })\n )\n )\n )\n ), {\n selfMembers: [],\n realms: [],\n get userId() {\n return db.cloud.currentUserId;\n },\n }\n );\n /* let refCount = 0;\n return new Observable(observer => {\n const subscription = o.subscribe(observer);\n console.debug ('PERMS subscribe', ++refCount);\n return {\n unsubscribe() {\n console.debug ('PERMS unsubscribe', --refCount);\n subscription.unsubscribe();\n }\n }\n })*/\n});\n","// TODO: Move to dexie-cloud-common\n\nimport { DBPermissionSet } from 'dexie-cloud-common';\n\nexport function mergePermissions(\n ...permissions: DBPermissionSet[]\n): DBPermissionSet {\n if (permissions.length === 0) return {};\n const reduced = permissions.reduce((result, next) => {\n const ret = { ...result } as DBPermissionSet;\n for (const [verb, rights] of Object.entries(next) as [\n keyof DBPermissionSet,\n DBPermissionSet[keyof DBPermissionSet]\n ][]) {\n if (verb in ret && ret[verb]) {\n if (ret[verb] === '*') continue;\n if (rights === '*') {\n ret[verb] = '*';\n } else if (Array.isArray(rights) && Array.isArray(ret[verb])) {\n // Both are arrays (verb is 'add' or 'manage')\n const r = ret as { [v in typeof verb]?: string[] };\n const retVerb = r[verb]!; // \"!\" because Array.isArray(ret[verb])\n r[verb] = [...new Set([...retVerb, ...rights])];\n } else if (\n typeof rights === 'object' &&\n rights &&\n typeof ret[verb] === 'object'\n ) {\n // Both are objects (verb is 'update')\n const mergedRights = ret[verb] as {\n [tableName: string]: '*' | string[];\n }; // because we've checked that typeof ret[verb] === 'object' and earlier that not ret[verb] === '*'.\n for (const [tableName, tableRights] of Object.entries(rights) as [\n string,\n string[] | '*'\n ][]) {\n if (mergedRights[tableName] === '*') continue;\n if (tableRights === '*') {\n mergedRights[tableName] = '*';\n } else if (\n Array.isArray(mergedRights[tableName]) &&\n Array.isArray(tableRights)\n ) {\n mergedRights[tableName] = [\n ...new Set([...mergedRights[tableName], ...tableRights]),\n ];\n }\n }\n }\n } else {\n /* This compiles without type assertions. Keeping the comment to\n explain why we do tsignore on the next statement.\n if (verb === \"add\") {\n ret[verb] = next[verb];\n } else if (verb === \"update\") {\n ret[verb] = next[verb];\n } else if (verb === \"manage\") {\n ret[verb] = next[verb];\n } else {\n ret[verb] = next[verb];\n }\n */\n //@ts-ignore\n ret[verb] = next[verb];\n }\n }\n return ret;\n });\n return reduced;\n}\n","import Dexie from 'dexie';\nimport { DBPermissionSet, DBRealm, DBRealmMember } from 'dexie-cloud-common';\nimport { combineLatest, Observable } from 'rxjs';\nimport { map, startWith, tap } from 'rxjs/operators';\nimport { associate } from './associate';\nimport { UNAUTHORIZED_USER } from './authentication/UNAUTHORIZED_USER';\nimport { createSharedValueObservable } from './createSharedValueObservable';\nimport { getGlobalRolesObservable } from './getGlobalRolesObservable';\nimport { getInternalAccessControlObservable } from './getInternalAccessControlObservable';\nimport { flatten } from './helpers/flatten';\nimport { mapValueObservable } from './mapValueObservable';\nimport { mergePermissions } from './mergePermissions';\n\nexport type PermissionsLookup = {\n [realmId: string]: DBRealm & { permissions: DBPermissionSet };\n};\n\nexport type PermissionsLookupObservable = Observable<PermissionsLookup> & {\n getValue(): PermissionsLookup;\n};\n\nexport const getPermissionsLookupObservable = associate((db: Dexie) => {\n const o = createSharedValueObservable(\n combineLatest([\n getInternalAccessControlObservable(db._novip),\n getGlobalRolesObservable(db._novip),\n ]).pipe(\n map(([{ selfMembers, realms, userId }, globalRoles]) => ({\n selfMembers,\n realms,\n userId,\n globalRoles,\n }))\n ),\n {\n selfMembers: [],\n realms: [],\n userId: UNAUTHORIZED_USER.userId!,\n globalRoles: {},\n }\n );\n\n return mapValueObservable(\n o,\n ({ selfMembers, realms, userId, globalRoles }) => {\n const rv = realms\n .map((realm) => {\n const selfRealmMembers = selfMembers.filter(\n (m) => m.realmId === realm.realmId\n );\n const directPermissionSets = selfRealmMembers\n .map((m) => m.permissions!)\n .filter((p) => p);\n const rolePermissionSets = flatten(\n selfRealmMembers.map((m) => m.roles!).filter((roleName) => roleName)\n )\n .map((role) => globalRoles[role]!)\n .filter((role) => role)\n .map((role) => role.permissions);\n\n return {\n ...realm,\n permissions:\n realm.owner === userId\n ? ({ manage: '*' } as DBPermissionSet)\n : mergePermissions(\n ...directPermissionSets,\n ...rolePermissionSets\n ),\n };\n })\n .reduce((p, c) => ({ ...p, [c.realmId]: c }), {\n [userId!]: {\n realmId: userId,\n owner: userId,\n name: userId,\n permissions: { manage: '*' },\n } as DBRealm & { permissions: DBPermissionSet },\n });\n return rv;\n }\n );\n});\n","import { map, Observable } from 'rxjs';\n\nexport interface ObservableWithCurrentValue<T> extends Observable<T> {\n getValue(): T;\n}\n\nexport function mapValueObservable<T, R>(\n o: ObservableWithCurrentValue<T>,\n mapper: (x: T) => R\n): ObservableWithCurrentValue<R> {\n let currentValue: R | undefined;\n const rv = o.pipe(\n map((x) => (currentValue = mapper(x)))\n ) as ObservableWithCurrentValue<R>;\n rv.getValue = () =>\n currentValue !== undefined\n ? currentValue\n : (currentValue = mapper(o.getValue()));\n return rv;\n}\n","import { KeyPaths } from 'dexie';\nimport { DBPermissionSet } from 'dexie-cloud-common';\n\ntype TableName<T> = T extends {table: ()=>infer TABLE} ? TABLE extends string ? TABLE : string : string;\n\nexport class PermissionChecker<T, TableNames extends string = TableName<T>> {\n private permissions: DBPermissionSet;\n private tableName: TableNames;\n private isOwner: boolean;\n\n constructor(\n permissions: DBPermissionSet,\n tableName: TableNames,\n isOwner: boolean\n ) {\n this.permissions = permissions || {};\n this.tableName = tableName;\n this.isOwner = isOwner;\n }\n\n add(...tableNames: TableNames[]): boolean {\n // If user can manage the whole realm, return true.\n if (this.permissions.manage === '*') return true;\n // If user can manage given table in realm, return true\n if (this.permissions.manage?.includes(this.tableName)) return true;\n // If user can add any type, return true\n if (this.permissions.add === '*') return true;\n // If user can add objects into given table names in the realm, return true\n if (\n tableNames.every((tableName) => this.permissions.add?.includes(tableName))\n ) {\n return true;\n }\n return false;\n }\n\n update(...props: KeyPaths<T>[]): boolean {\n // If user is owner of this object, or if user can manage the whole realm, return true.\n if (this.isOwner || this.permissions.manage === '*') return true;\n // If user can manage given table in realm, return true\n if (this.permissions.manage?.includes(this.tableName)) return true;\n // If user can update any prop in any table in this realm, return true unless\n // it regards to ownership change:\n if (this.permissions.update === '*') {\n // @ts-ignore\n return props.every((prop) => prop !== 'owner');\n }\n const tablePermissions = this.permissions.update?.[this.tableName];\n // If user can update any prop in table and realm, return true unless\n // accessing special props owner or realmId\n if (tablePermissions === '*')\n return props.every((prop) => prop !== 'owner');\n\n // Explicitely listed properties to allow updates on:\n return props.every((prop) =>\n tablePermissions?.some(\n (permittedProp) =>\n permittedProp === prop || (permittedProp === '*' && prop !== 'owner')\n )\n );\n }\n\n delete(): boolean {\n // If user is owner of this object, or if user can manage the whole realm, return true.\n if (this.isOwner || this.permissions.manage === '*') return true;\n // If user can manage given table in realm, return true\n if (this.permissions.manage?.includes(this.tableName)) return true;\n return false;\n }\n}\n","import { Dexie, liveQuery } from 'dexie';\nimport { DBRealmMember } from 'dexie-cloud-common';\nimport { combineLatest } from 'rxjs';\nimport { map, switchMap } from 'rxjs/operators';\nimport { associate } from './associate';\nimport { createSharedValueObservable } from './createSharedValueObservable';\nimport { getCurrentUserEmitter } from './currentUserEmitter';\nimport { getInternalAccessControlObservable } from './getInternalAccessControlObservable';\nimport { getPermissionsLookupObservable } from './getPermissionsLookupObservable';\nimport { Invite } from './Invite';\nimport { mapValueObservable } from './mapValueObservable';\n\nexport const getInvitesObservable = associate((db: Dexie) => {\n const membersByEmail = getCurrentUserEmitter(db._novip).pipe(\n switchMap((currentUser) =>\n liveQuery(() =>\n db.members.where({ email: currentUser.email || '' }).toArray()\n )\n )\n );\n const permissions = getPermissionsLookupObservable(db._novip);\n const accessControl = getInternalAccessControlObservable(db._novip);\n return createSharedValueObservable(\n combineLatest([membersByEmail, accessControl, permissions]).pipe(\n map(([membersByEmail, accessControl, realmLookup]) => {\n const reducer = (\n result: { [id: string]: Invite },\n m: DBRealmMember\n ) => ({ ...result, [m.id!]: { ...m, realm: realmLookup[m.realmId] } });\n const emailMembersById = membersByEmail.reduce(reducer, {});\n const membersById = accessControl.selfMembers.reduce(\n reducer,\n emailMembersById\n );\n return Object.values(membersById)\n .filter((invite: DBRealmMember) => !invite.accepted)\n .map(\n (invite: DBRealmMember) =>\n ({\n ...invite,\n async accept() {\n await db.members.update(invite.id!, { accepted: new Date() });\n },\n async reject() {\n await db.members.update(invite.id!, { rejected: new Date() });\n },\n } satisfies Invite)\n );\n })\n ),\n []\n );\n});\n","import { cmp, Table } from 'dexie';\nimport type { DexieCloudDB } from '../db/DexieCloudDB';\nimport { awarenessWeakMap } from './awareness';\nimport * as awap from 'y-protocols/awareness';\nimport { DEXIE_CLOUD_SYNCER_ID } from '../sync/DEXIE_CLOUD_SYNCER_ID';\nimport * as Y from 'yjs';\nimport { combineLatest, startWith } from 'rxjs';\nimport { YDocumentOpen } from 'dexie-cloud-common';\nimport { isEagerSyncDisabled } from '../isEagerSyncDisabled';\nimport { PersistedSyncState } from '../db/entities/PersistedSyncState';\nimport { getOpenDocSignal } from './reopenDocSignal';\nimport { DexieYProvider, DexieYDocMeta } from 'y-dexie';\n\nexport function createYHandler(db: DexieCloudDB) {\n return (provider: import('y-dexie').DexieYProvider) => {\n const doc = provider.doc;\n if (!doc) {\n throw new Error(\n 'Internal error: DexieYProvider.createYHandler called without a doc. This is unexpected.'\n );\n }\n const { parentTable } = doc.meta || ({} as DexieYDocMeta);\n if (!db.cloud.schema?.[parentTable].markedForSync) {\n return; // The table that holds the doc is not marked for sync - leave it to dexie. No syncing, no awareness.\n }\n let awareness: import('y-protocols/awareness').Awareness;\n Object.defineProperty(provider, 'awareness', {\n get() {\n if (awareness) return awareness;\n awareness = createAwareness(db, doc, provider);\n awarenessWeakMap.set(doc, awareness);\n return awareness;\n },\n });\n };\n}\n\nfunction createAwareness(\n db: DexieCloudDB,\n doc: Y.Doc,\n provider: DexieYProvider\n) {\n const { parentTable, parentId, parentProp, updatesTable } =\n doc.meta as DexieYDocMeta;\n const awareness = new awap.Awareness(doc);\n const reopenDocSignal = getOpenDocSignal(doc);\n\n awareness.on('update', ({ added, updated, removed }, origin: any) => {\n // Send the update\n const changedClients = added.concat(updated).concat(removed);\n const user = db.cloud.currentUser.value;\n if (origin !== 'server' && user.isLoggedIn && !isEagerSyncDisabled(db)) {\n const update = awap.encodeAwarenessUpdate(awareness!, changedClients);\n db.messageProducer.next({\n type: 'aware',\n table: parentTable,\n prop: parentProp,\n k: doc.meta.parentId,\n u: update,\n });\n if (provider.destroyed) {\n // We're called from awareness.on('destroy') that did\n // removeAwarenessStates.\n // It's time to also send the doc-close message that dexie-cloud understands\n // and uses to stop subscribing for updates and awareness updates and brings\n // down the cached information in memory on the WS connection for this.\n db.messageProducer.next({\n type: 'doc-close',\n table: parentTable,\n prop: parentProp,\n k: doc.meta.parentId,\n });\n }\n }\n });\n awareness.on('destroy', () => {\n // Signal to server that this provider is destroyed (the update event will be triggered, which\n // in turn will trigger db.messageProducer that will send the message to the server if WS is connected)\n awap.removeAwarenessStates(\n awareness!,\n [doc.clientID],\n 'provider destroyed'\n );\n });\n\n // Open the document on the server\n (async () => {\n if (provider.destroyed) return;\n let connected = false;\n let currentFlowId = 1;\n const subscription = combineLatest([\n db.cloud.webSocketStatus, // Wake up when webSocket status changes\n reopenDocSignal.pipe(startWith(null)), // Wake up when reopenDocSignal emits\n ]).subscribe(([wsStatus]) => {\n if (provider.destroyed) return;\n // Keep \"connected\" state in a variable so we can check it after async operations\n connected = wsStatus === 'connected';\n\n // We are or got connected. Open the document on the server.\n const user = db.cloud.currentUser.value;\n if (\n wsStatus === 'connected' &&\n user.isLoggedIn &&\n !isEagerSyncDisabled(db)\n ) {\n ++currentFlowId;\n openDocumentOnServer().catch((error) => {\n console.warn(`Error catched in createYHandler.ts: ${error}`);\n });\n }\n });\n // Wait until WebSocket is connected\n provider.addCleanupHandler(subscription);\n\n /** Sends an 'doc-open' message to server whenever websocket becomes\n * connected, or if it is already connected.\n * The flow is aborted in case websocket is disconnected while querying\n * information required to compute the state vector. Flow is also\n * aborted in case document or provider has been destroyed during\n * the async parts of the task.\n *\n * The state vector is only computed from the updates that have occured\n * after the last full sync - which could very often be zero - in which\n * case no state vector is sent (then the server already knows us by\n * revision)\n *\n * When server gets the doc-open message, it will authorize us for\n * whether we are allowed to read / write to this document, and then\n * keep the cached information in memory on the WS connection for this\n * particular document, as well as subscribe to updates and awareness updates\n * from other clients on the document.\n */\n async function openDocumentOnServer() {\n const myFlow = currentFlowId; // So we can abort when a new flow is started\n const yTbl = db.table(updatesTable);\n const syncStateTbl = db.$syncState as Table<\n PersistedSyncState,\n 'syncState'\n >;\n const [receivedUntil, yServerRev] = await db.transaction(\n 'r',\n syncStateTbl,\n yTbl,\n async () => {\n const syncState = await yTbl.get(DEXIE_CLOUD_SYNCER_ID);\n const persistedSyncState = await syncStateTbl.get('syncState');\n return [\n syncState?.receivedUntil || 0,\n persistedSyncState?.yServerRevision ||\n persistedSyncState?.serverRevision,\n ];\n }\n );\n\n // After every await, check if we still should be working on this task.\n if (provider.destroyed || currentFlowId !== myFlow || !connected) return;\n\n const docOpenMsg: YDocumentOpen = {\n type: 'doc-open',\n table: parentTable,\n prop: parentProp,\n k: parentId,\n serverRev: yServerRev,\n };\n const serverUpdatesSinceLastSync = await yTbl\n .where('i')\n .between(receivedUntil, Infinity, false)\n .filter(\n (update) =>\n cmp(update.k, parentId) === 0 && // Only updates for this document\n ((update.f || 0) & 1) === 0 // Don't include local changes\n )\n .toArray();\n // After every await, check if we still should be working on this task.\n if (provider.destroyed || currentFlowId !== myFlow || !connected) return;\n\n if (serverUpdatesSinceLastSync.length > 0) {\n const mergedUpdate = Y.mergeUpdatesV2(\n serverUpdatesSinceLastSync.map((update) => update.u)\n );\n const stateVector = Y.encodeStateVectorFromUpdateV2(mergedUpdate);\n docOpenMsg.sv = stateVector;\n }\n db.messageProducer.next(docOpenMsg);\n }\n })();\n return awareness;\n}\n","import Dexie, { liveQuery, Subscription, Table } from 'dexie';\nimport {\n DBPermissionSet,\n DBRealmMember,\n getDbNameFromDbUrl,\n} from 'dexie-cloud-common';\nimport { BehaviorSubject, combineLatest, firstValueFrom, from, fromEvent, Subject } from 'rxjs';\nimport { filter, map, skip, startWith, switchMap, take } from 'rxjs/operators';\nimport { login } from './authentication/login';\nimport { UNAUTHORIZED_USER } from './authentication/UNAUTHORIZED_USER';\nimport { DexieCloudDB } from './db/DexieCloudDB';\nimport { PersistedSyncState } from './db/entities/PersistedSyncState';\nimport { DexieCloudOptions } from './DexieCloudOptions';\nimport { DISABLE_SERVICEWORKER_STRATEGY } from './DISABLE_SERVICEWORKER_STRATEGY';\nimport './extend-dexie-interface';\nimport { DexieCloudSyncOptions } from './DexieCloudSyncOptions';\nimport { IS_SERVICE_WORKER } from './helpers/IS_SERVICE_WORKER';\nimport { throwVersionIncrementNeeded } from './helpers/throwVersionIncrementNeeded';\nimport { createIdGenerationMiddleware } from './middlewares/createIdGenerationMiddleware';\nimport { createImplicitPropSetterMiddleware } from './middlewares/createImplicitPropSetterMiddleware';\nimport { createMutationTrackingMiddleware } from './middlewares/createMutationTrackingMiddleware';\n//import { dexieCloudSyncProtocol } from \"./dexieCloudSyncProtocol\";\nimport { overrideParseStoresSpec } from './overrideParseStoresSpec';\nimport { performInitialSync } from './performInitialSync';\nimport { connectWebSocket } from './sync/connectWebSocket';\nimport { isSyncNeeded } from './sync/isSyncNeeded';\nimport { LocalSyncWorker } from './sync/LocalSyncWorker';\nimport {\n registerPeriodicSyncEvent,\n registerSyncEvent,\n} from './sync/registerSyncEvent';\nimport { triggerSync } from './sync/triggerSync';\nimport { DXCUserInteraction } from './types/DXCUserInteraction';\nimport { SyncState } from './types/SyncState';\nimport { updateSchemaFromOptions } from './updateSchemaFromOptions';\nimport { verifySchema } from './verifySchema';\nimport { setupDefaultGUI } from './default-ui';\nimport { DXCWebSocketStatus } from './DXCWebSocketStatus';\nimport { computeSyncState } from './computeSyncState';\nimport { generateKey } from './middleware-helpers/idGenerationHelpers';\nimport { permissions } from './permissions';\nimport { getCurrentUserEmitter } from './currentUserEmitter';\nimport { NewIdOptions } from './types/NewIdOptions';\nimport { getInvitesObservable } from './getInvitesObservable';\nimport { getGlobalRolesObservable } from './getGlobalRolesObservable';\nimport { UserLogin } from './db/entities/UserLogin';\nimport { InvalidLicenseError } from './InvalidLicenseError';\nimport { logout, _logout } from './authentication/logout';\nimport { loadAccessToken } from './authentication/authenticate';\nimport { isEagerSyncDisabled } from './isEagerSyncDisabled';\nimport { createYHandler } from \"./yjs/createYHandler\";\nimport { DexieYProvider } from 'y-dexie';\nexport { DexieCloudTable } from './DexieCloudTable';\nexport * from './getTiedRealmId';\nexport {\n DBRealm,\n DBRealmMember,\n DBRealmRole,\n DBSyncedObject,\n DBPermissionSet,\n} from 'dexie-cloud-common';\nexport { resolveText } from './helpers/resolveText';\nexport { Invite } from './Invite';\nexport type { UserLogin, DXCWebSocketStatus, SyncState };\nexport type { DexieCloudSyncOptions };\nexport type { DexieCloudOptions, PeriodicSyncOptions } from './DexieCloudOptions';\nexport * from './types/DXCAlert';\nexport * from './types/DXCInputField';\nexport * from './types/DXCUserInteraction';\nexport { defineYDocTrigger } from './define-ydoc-trigger';\n\nconst DEFAULT_OPTIONS: Partial<DexieCloudOptions> = {\n nameSuffix: true,\n};\n\nexport function dexieCloud(dexie: Dexie) {\n const origIdbName = dexie.name;\n //\n //\n //\n const currentUserEmitter = getCurrentUserEmitter(dexie);\n const subscriptions: Subscription[] = [];\n let configuredProgramatically = false;\n\n // local sync worker - used when there's no service worker.\n let localSyncWorker: { start: () => void; stop: () => void } | null = null;\n dexie.on(\n 'ready',\n async (dexie: Dexie) => {\n try {\n await onDbReady(dexie);\n } catch (error) {\n console.error(error);\n // Make sure to succeed with database open even if network is down.\n }\n },\n true // true = sticky\n );\n\n /** Void starting subscribers after a close has happened. */\n let closed = false;\n function throwIfClosed() {\n if (closed) throw new Dexie.DatabaseClosedError();\n }\n\n dexie.once('close', () => {\n subscriptions.forEach((subscription) => subscription.unsubscribe());\n subscriptions.splice(0, subscriptions.length);\n closed = true;\n localSyncWorker && localSyncWorker.stop();\n localSyncWorker = null;\n currentUserEmitter.next(UNAUTHORIZED_USER);\n });\n\n const syncComplete = new Subject<void>();\n\n dexie.cloud = {\n // @ts-ignore\n version: __VERSION__,\n options: { ...DEFAULT_OPTIONS } as DexieCloudOptions,\n schema: null,\n get currentUserId() {\n return currentUserEmitter.value.userId || UNAUTHORIZED_USER.userId!;\n },\n currentUser: currentUserEmitter,\n syncState: new BehaviorSubject<SyncState>({\n phase: 'initial',\n status: 'not-started',\n }),\n\n events: {\n syncComplete,\n },\n\n persistedSyncState: new BehaviorSubject<PersistedSyncState | undefined>(\n undefined\n ),\n userInteraction: new BehaviorSubject<DXCUserInteraction | undefined>(\n undefined\n ),\n webSocketStatus: new BehaviorSubject<DXCWebSocketStatus>('not-started'),\n async login(hint) {\n const db = DexieCloudDB(dexie);\n await db.cloud.sync();\n await login(db, hint);\n },\n invites: getInvitesObservable(dexie),\n roles: getGlobalRolesObservable(dexie),\n configure(options: DexieCloudOptions) {\n options = dexie.cloud.options = { ...dexie.cloud.options, ...options };\n configuredProgramatically = true;\n if (options.databaseUrl && options.nameSuffix) {\n // @ts-ignore\n dexie.name = `${origIdbName}-${getDbNameFromDbUrl(\n options.databaseUrl\n )}`;\n DexieCloudDB(dexie).reconfigure(); // Update observable from new dexie.name\n }\n updateSchemaFromOptions(dexie.cloud.schema, dexie.cloud.options);\n },\n async logout({ force } = {}) {\n force\n ? await _logout(DexieCloudDB(dexie), { deleteUnsyncedData: true })\n : await logout(DexieCloudDB(dexie));\n },\n async sync(\n { wait, purpose }: DexieCloudSyncOptions = { wait: true, purpose: 'push' }\n ) {\n if (wait === undefined) wait = true;\n const db = DexieCloudDB(dexie);\n const licenseStatus = db.cloud.currentUser.value.license?.status || 'ok';\n if (licenseStatus !== 'ok') {\n // Refresh access token to check for updated license\n await loadAccessToken(db);\n }\n if (purpose === 'pull') {\n const syncState = db.cloud.persistedSyncState.value;\n triggerSync(db, purpose);\n if (wait) {\n const newSyncState = await firstValueFrom(\n db.cloud.persistedSyncState.pipe(\n filter(\n (newSyncState) =>\n newSyncState?.timestamp != null &&\n (!syncState || newSyncState.timestamp > syncState.timestamp!)\n )\n )\n );\n if (newSyncState?.error) {\n throw new Error(`Sync error: ` + newSyncState.error);\n }\n }\n } else if (await isSyncNeeded(db)) {\n const syncState = db.cloud.persistedSyncState.value;\n triggerSync(db, purpose);\n if (wait) {\n console.debug('db.cloud.login() is waiting for sync completion...');\n await firstValueFrom(\n from(\n liveQuery(async () => {\n const syncNeeded = await isSyncNeeded(db);\n const newSyncState = await db.getPersistedSyncState();\n if (\n newSyncState?.timestamp !== syncState?.timestamp &&\n newSyncState?.error\n )\n throw new Error(`Sync error: ` + newSyncState.error);\n return syncNeeded;\n })\n ).pipe(filter((isNeeded) => !isNeeded))\n );\n console.debug(\n 'Done waiting for sync completion because we have nothing to push anymore'\n );\n }\n }\n },\n permissions(\n obj: { owner: string; realmId: string; table?: () => string },\n tableName?: string\n ) {\n return permissions(dexie._novip, obj, tableName);\n },\n };\n\n dexie.Version.prototype['_parseStoresSpec'] = Dexie.override(\n dexie.Version.prototype['_parseStoresSpec'],\n (origFunc) => overrideParseStoresSpec(origFunc, dexie)\n );\n\n dexie.Table.prototype.newId = function (\n this: Table<any>,\n { colocateWith }: NewIdOptions = {}\n ) {\n const shardKey =\n colocateWith && colocateWith.substr(colocateWith.length - 3);\n return generateKey(dexie.cloud.schema![this.name].idPrefix || '', shardKey);\n };\n\n dexie.Table.prototype.idPrefix = function (this: Table<any>) {\n return this.db.cloud.schema?.[this.name]?.idPrefix || '';\n };\n\n dexie.use(\n createMutationTrackingMiddleware({\n currentUserObservable: dexie.cloud.currentUser,\n db: DexieCloudDB(dexie),\n })\n );\n dexie.use(createImplicitPropSetterMiddleware(DexieCloudDB(dexie)));\n dexie.use(createIdGenerationMiddleware(DexieCloudDB(dexie)));\n\n async function onDbReady(dexie: Dexie) {\n closed = false; // As Dexie calls us, we are not closed anymore. Maybe reopened? Remember db.ready event is registered with sticky flag!\n const db = DexieCloudDB(dexie);\n // Setup default GUI:\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n if (!db.cloud.options?.customLoginGui) {\n subscriptions.push(setupDefaultGUI(dexie));\n }\n }\n if (!db.cloud.isServiceWorkerDB) {\n subscriptions.push(computeSyncState(db).subscribe(dexie.cloud.syncState));\n }\n\n // Forward db.syncCompleteEvent to be publicly consumable via db.cloud.events.syncComplete:\n subscriptions.push(db.syncCompleteEvent.subscribe(syncComplete));\n\n //verifyConfig(db.cloud.options); Not needed (yet at least!)\n // Verify the user has allowed version increment.\n if (!db.tables.every((table) => table.core)) {\n throwVersionIncrementNeeded();\n }\n const swRegistrations =\n 'serviceWorker' in navigator\n ? await navigator.serviceWorker.getRegistrations()\n : [];\n\n const [initiallySynced, lastSyncedRealms] = await db.transaction(\n 'rw',\n db.$syncState,\n async () => {\n const { options, schema } = db.cloud;\n const [persistedOptions, persistedSchema, persistedSyncState] =\n await Promise.all([\n db.getOptions(),\n db.getSchema(),\n db.getPersistedSyncState(),\n ]);\n if (!configuredProgramatically) {\n // Options not specified programatically (use case for SW!)\n // Take persisted options:\n db.cloud.options = persistedOptions || null;\n } else if (\n !persistedOptions ||\n JSON.stringify(persistedOptions) !== JSON.stringify(options)\n ) {\n // Update persisted options:\n if (!options) throw new Error(`Internal error`); // options cannot be null if configuredProgramatically is set.\n const newPersistedOptions: DexieCloudOptions = {\n ...options,\n };\n delete newPersistedOptions.fetchTokens;\n delete newPersistedOptions.awarenessProtocol;\n await db.$syncState.put(newPersistedOptions, 'options');\n }\n if (\n db.cloud.options?.tryUseServiceWorker &&\n 'serviceWorker' in navigator &&\n swRegistrations.length > 0 &&\n !DISABLE_SERVICEWORKER_STRATEGY\n ) {\n // * Configured for using service worker if available.\n // * Browser supports service workers\n // * There are at least one service worker registration\n console.debug('Dexie Cloud Addon: Using service worker');\n db.cloud.usingServiceWorker = true;\n } else {\n // Not configured for using service worker or no service worker\n // registration exists. Don't rely on service worker to do any job.\n // Use LocalSyncWorker instead.\n if (\n db.cloud.options?.tryUseServiceWorker &&\n !db.cloud.isServiceWorkerDB\n ) {\n console.debug(\n 'dexie-cloud-addon: Not using service worker.',\n swRegistrations.length === 0\n ? 'No SW registrations found.'\n : 'serviceWorker' in navigator && DISABLE_SERVICEWORKER_STRATEGY\n ? 'Avoiding SW background sync and SW periodic bg sync for this browser due to browser bugs.'\n : 'navigator.serviceWorker not present'\n );\n }\n db.cloud.usingServiceWorker = false;\n }\n updateSchemaFromOptions(schema, db.cloud.options);\n updateSchemaFromOptions(persistedSchema, db.cloud.options);\n if (!schema) {\n // Database opened dynamically (use case for SW!)\n // Take persisted schema:\n db.cloud.schema = persistedSchema || null;\n } else if (\n !persistedSchema ||\n JSON.stringify(persistedSchema) !== JSON.stringify(schema)\n ) {\n // Update persisted schema (but don't overwrite table prefixes)\n const newPersistedSchema = persistedSchema || {};\n for (const [table, tblSchema] of Object.entries(schema)) {\n const newTblSchema = newPersistedSchema[table];\n if (!newTblSchema) {\n newPersistedSchema[table] = { ...tblSchema };\n } else {\n newTblSchema.markedForSync = tblSchema.markedForSync;\n tblSchema.deleted = newTblSchema.deleted;\n newTblSchema.generatedGlobalId = tblSchema.generatedGlobalId;\n }\n }\n await db.$syncState.put(newPersistedSchema, 'schema');\n\n // Make sure persisted table prefixes are being used instead of computed ones:\n // Let's assign all props as the newPersistedSchems should be what we should be working with.\n Object.assign(schema, newPersistedSchema);\n }\n return [persistedSyncState?.initiallySynced, persistedSyncState?.realms];\n }\n );\n\n if (initiallySynced) {\n db.setInitiallySynced(true);\n }\n\n verifySchema(db);\n\n // Manage CurrentUser observable:\n throwIfClosed();\n if (!db.cloud.isServiceWorkerDB) {\n subscriptions.push(\n liveQuery(() => db.getCurrentUser()).subscribe(currentUserEmitter)\n );\n // Manage PersistendSyncState observable:\n subscriptions.push(\n liveQuery(() => db.getPersistedSyncState()).subscribe(\n db.cloud.persistedSyncState\n )\n );\n // Wait till currentUser and persistedSyncState gets populated\n // with things from the database and not just the default values.\n // This is so that when db.open() completes, user should be safe\n // to subscribe to these observables and get actual data.\n await firstValueFrom(combineLatest([\n currentUserEmitter.pipe(skip(1), take(1)),\n db.cloud.persistedSyncState.pipe(skip(1), take(1)),\n ]));\n\n const yHandler = createYHandler(db);\n DexieYProvider.on.new.subscribe(yHandler);\n db.dx.once('close', () => {\n DexieYProvider.on.new.unsubscribe(yHandler);\n });\n }\n\n // HERE: If requireAuth, do athentication now.\n let changedUser = false;\n const user = await db.getCurrentUser();\n const requireAuth = db.cloud.options?.requireAuth;\n if (requireAuth) {\n if (db.cloud.isServiceWorkerDB) {\n // If this is a service worker DB, we can't do authentication here,\n // we just wait until the application has done it.\n console.debug('Dexie Cloud Service worker. Waiting for application to authenticate.');\n await firstValueFrom(currentUserEmitter.pipe(filter((user) => !!user.isLoggedIn), take(1)));\n console.debug('Dexie Cloud Service worker. Application has authenticated.');\n } else {\n if (typeof requireAuth === 'object') {\n // requireAuth contains login hints. Check if we already fulfil it:\n if (\n !user.isLoggedIn ||\n (requireAuth.userId && user.userId !== requireAuth.userId) ||\n (requireAuth.email && user.email !== requireAuth.email)\n ) {\n // If not, login the configured user:\n changedUser = await login(db, requireAuth);\n }\n } else if (!user.isLoggedIn) {\n // requireAuth is true and user is not logged in\n changedUser = await login(db);\n }\n }\n }\n if (user.isLoggedIn && (!lastSyncedRealms || !lastSyncedRealms.includes(user.userId!))) {\n // User has been logged in but this is not reflected in the sync state.\n // This can happen if page is reloaded after login but before the sync call following\n // the login was complete.\n // The user is to be viewed as changed becuase current syncState does not reflect the presence\n // of the logged-in user.\n changedUser = true; // Set changedUser to true to trigger a pull-sync later down.\n }\n\n if (localSyncWorker) localSyncWorker.stop();\n localSyncWorker = null;\n throwIfClosed();\n\n const doInitialSync = db.cloud.options?.databaseUrl && (!initiallySynced || changedUser);\n if (doInitialSync) {\n // Do the initial sync directly in the browser thread no matter if we are using service worker or not.\n await performInitialSync(db, db.cloud.options!, db.cloud.schema!);\n db.setInitiallySynced(true);\n }\n\n throwIfClosed();\n if (db.cloud.usingServiceWorker && db.cloud.options?.databaseUrl) {\n if (!doInitialSync) {\n registerSyncEvent(db, 'push').catch(() => {});\n }\n registerPeriodicSyncEvent(db).catch(() => {});\n } else if (\n db.cloud.options?.databaseUrl &&\n db.cloud.schema &&\n !db.cloud.isServiceWorkerDB\n ) {\n // There's no SW. Start SyncWorker instead.\n localSyncWorker = LocalSyncWorker(db, db.cloud.options, db.cloud.schema!);\n localSyncWorker.start();\n if (!doInitialSync) {\n triggerSync(db, 'push');\n }\n }\n\n // Listen to online event and do sync.\n throwIfClosed();\n if (!db.cloud.isServiceWorkerDB) {\n subscriptions.push(\n fromEvent(self, 'online').subscribe(() => {\n console.debug('online!');\n db.syncStateChangedEvent.next({\n phase: 'not-in-sync',\n });\n if (!isEagerSyncDisabled(db)) {\n triggerSync(db, 'push');\n }\n }),\n fromEvent(self, 'offline').subscribe(() => {\n console.debug('offline!');\n db.syncStateChangedEvent.next({\n phase: 'offline',\n });\n })\n );\n }\n\n // Connect WebSocket unless we are in a service worker or websocket is disabled.\n if (\n db.cloud.options?.databaseUrl &&\n !db.cloud.options?.disableWebSocket &&\n !IS_SERVICE_WORKER\n ) {\n subscriptions.push(connectWebSocket(db));\n }\n }\n}\n\n// @ts-ignore\ndexieCloud.version = __VERSION__;\n\nDexie.Cloud = dexieCloud;\n\nexport default dexieCloud;\n","import { combineLatest, Observable, of } from 'rxjs';\nimport { debounceTime, map, startWith, switchMap } from 'rxjs/operators';\nimport { getCurrentUserEmitter } from './currentUserEmitter';\nimport { DexieCloudDB, SyncStateChangedEventData } from './db/DexieCloudDB';\nimport { isOnline } from './sync/isOnline';\nimport { SyncState } from './types/SyncState';\nimport { userIsActive, userIsReallyActive } from './userIsActive';\n\nexport function computeSyncState(db: DexieCloudDB): Observable<SyncState> {\n let _prevStatus = db.cloud.webSocketStatus.value;\n const lazyWebSocketStatus = db.cloud.webSocketStatus.pipe(\n switchMap((status) => {\n const prevStatus = _prevStatus;\n _prevStatus = status;\n const rv = of(status);\n switch (status) {\n // A normal scenario is that the WS reconnects and falls shortly in disconnected-->connection-->connected.\n // Don't distract user with this unless these things take more time than normal:\n\n // Only show disconnected if disconnected more than 500ms, or if we can\n // see that the user is indeed not active.\n case 'disconnected':\n return userIsActive.value ? rv.pipe(debounceTime(500)) : rv;\n\n // Only show connecting if previous state was 'not-started' or 'error', or if\n // the time it takes to connect goes beyond 4 seconds.\n case 'connecting':\n return prevStatus === 'not-started' || prevStatus === 'error'\n ? rv\n : rv.pipe(debounceTime(4000));\n default:\n return rv;\n }\n })\n );\n return combineLatest([\n lazyWebSocketStatus,\n db.syncStateChangedEvent.pipe(startWith({ phase: 'initial' } as SyncStateChangedEventData)),\n getCurrentUserEmitter(db.dx._novip),\n userIsReallyActive\n ]).pipe(\n map(([status, syncState, user, userIsActive]) => {\n if (user.license?.status && user.license.status !== 'ok') {\n return {\n phase: 'offline',\n status: 'offline',\n license: user.license.status\n } satisfies SyncState;\n }\n let { phase, error, progress } = syncState;\n let adjustedStatus = status;\n if (phase === 'error') {\n // Let users only rely on the status property to display an icon.\n // If there's an error in the sync phase, let it show on that\n // status icon also.\n adjustedStatus = 'error';\n }\n if (status === 'not-started') {\n // If websocket isn't yet connected becase we're doing\n // the startup sync, let the icon show the symbol for connecting.\n if (phase === 'pushing' || phase === 'pulling') {\n adjustedStatus = 'connecting';\n }\n } \n const previousPhase = db.cloud.syncState.value.phase;\n //const previousStatus = db.cloud.syncState.value.status;\n if (previousPhase === 'error' && (syncState.phase === 'pushing' || syncState.phase === 'pulling')) {\n // We were in an errored state but is now doing sync. Show \"connecting\" icon.\n adjustedStatus = 'connecting';\n }\n /*if (syncState.phase === 'in-sync' && adjustedStatus === 'connecting') {\n adjustedStatus = 'connected';\n }*/\n \n if (!userIsActive) {\n adjustedStatus = 'disconnected';\n }\n\n const retState: SyncState = {\n phase,\n error,\n progress,\n status: isOnline ? adjustedStatus : 'offline',\n license: 'ok'\n };\n\n return retState;\n })\n );\n}\n","import Dexie from \"dexie\";\n\nexport function throwVersionIncrementNeeded() {\n throw new Dexie.SchemaError(\n `Version increment needed to allow dexie-cloud change tracking`\n );\n}\n","import Dexie from \"dexie\";\nimport { DexieCloudDB } from \"./db/DexieCloudDB\";\n\nexport function verifySchema(db: DexieCloudDB) {\n for (const table of db.tables) {\n if (db.cloud.schema?.[table.name]?.markedForSync) {\n if (table.schema.primKey.auto) {\n throw new Dexie.SchemaError(\n `Table ${table.name} is both autoIncremented and synced. ` +\n `Use db.cloud.configure({unsyncedTables: [${JSON.stringify(\n table.name\n )}]}) to blacklist it from sync`\n );\n }\n if (!table.schema.primKey.keyPath) {\n throw new Dexie.SchemaError(\n `Table ${table.name} cannot be both synced and outbound. ` +\n `Use db.cloud.configure({unsyncedTables: [${JSON.stringify(\n table.name\n )}]}) to blacklist it from sync`\n );\n }\n }\n }\n}\n","import { DexieCloudSchema } from 'dexie-cloud-common';\nimport { DexieCloudDB } from './db/DexieCloudDB';\nimport { DexieCloudOptions } from './DexieCloudOptions';\nimport { CURRENT_SYNC_WORKER, sync } from './sync/sync';\nimport { performGuardedJob } from './sync/performGuardedJob';\n\nexport async function performInitialSync(\n db: DexieCloudDB,\n cloudOptions: DexieCloudOptions,\n cloudSchema: DexieCloudSchema\n) {\n console.debug('Performing initial sync'); \n await performGuardedJob(\n db,\n CURRENT_SYNC_WORKER,\n () => sync(db, cloudOptions, cloudSchema, { isInitialSync: true })\n );\n console.debug('Done initial sync');\n}\n","import Dexie, { DBCore, DBCoreTransaction, Middleware } from 'dexie';\nimport { DexieCloudDB } from '../db/DexieCloudDB';\nimport { TXExpandos } from '../types/TXExpandos';\nimport { UNAUTHORIZED_USER } from '../authentication/UNAUTHORIZED_USER';\n\nexport function createImplicitPropSetterMiddleware(\n db: DexieCloudDB\n): Middleware<DBCore> {\n return {\n stack: 'dbcore',\n name: 'implicitPropSetterMiddleware',\n level: 1,\n create: (core) => {\n return {\n ...core,\n table: (tableName) => {\n const table = core.table(tableName);\n return {\n ...table,\n mutate: (req) => {\n const trans = req.trans as DBCoreTransaction & TXExpandos & IDBTransaction;\n\n if (trans.disableChangeTracking) {\n return table.mutate(req);\n }\n\n const currentUserId = trans.currentUser?.userId ?? UNAUTHORIZED_USER.userId;\n\n if (db.cloud.schema?.[tableName]?.markedForSync) {\n if (req.type === 'add' || req.type === 'put') {\n if (tableName === 'members') {\n for (const member of req.values) {\n if (typeof member.email === 'string') {\n // Resolve https://github.com/dexie/dexie-cloud/issues/4\n // If adding a member, make sure email is lowercase and trimmed.\n // This is to avoid issues where the APP does not check this\n // and just allows the user to enter an email address that might\n // have been pasted by the user from a source that had a trailing\n // space or was in uppercase. We want to avoid that the user\n // creates a new member with a different email address than\n // the one he/she intended to create.\n member.email = member.email.trim().toLowerCase();\n }\n }\n }\n // No matter if user is logged in or not, make sure \"owner\" and \"realmId\" props are set properly.\n // If not logged in, this will be changed upon syncification of the tables (next sync after login),\n // however, application code will work better if we can always rely on that the properties realmId\n // and owner are set. Application code may index them and query them based on db.cloud.currentUserId,\n // and expect them to be returned. That scenario must work also when db.cloud.currentUserId === 'unauthorized'.\n for (const obj of req.values) {\n if (!obj.owner) {\n obj.owner = currentUserId;\n }\n if (!obj.realmId) {\n obj.realmId = currentUserId;\n }\n const key = table.schema.primaryKey.extractKey?.(obj);\n if (typeof key === 'string' && key[0] === '#') {\n // Add $ts prop for put operations and\n // disable update operations as well as consistent\n // modify operations. Reason: Server may not have\n // the object. Object should be created on server only\n // if is being updated. An update operation won't create it\n // so we must delete req.changeSpec to degrade operation to\n // an upsert operation with timestamp so that it will be created.\n // We must also degrade from consistent modify operations for the\n // same reason - object might be there on server. Must but put up instead.\n\n // FUTURE: This clumpsy behavior of private IDs could be refined later.\n // Suggestion is to in future, treat private IDs as we treat all objects \n // and sync operations normally. Only that deletions should become soft deletes\n // for them - so that server knows when a private ID has been deleted on server\n // not accept insert/upserts on them.\n if (req.type === 'put') {\n const now = Date.now();\n delete req.criteria;\n delete req.changeSpec;\n delete req.updates;\n obj.$ts = Date.now();\n }\n }\n }\n }\n }\n return table.mutate(req);\n },\n };\n },\n };\n },\n };\n}\n","export function getDbNameFromDbUrl(dbUrl) {\n const url = new URL(dbUrl);\n return url.pathname === \"/\"\n ? url.hostname.split('.')[0]\n : url.pathname.split('/')[1];\n}\n","import Dexie, { liveQuery } from 'dexie';\nimport { DBRealmMember } from 'dexie-cloud-common';\nimport { from, Observable } from 'rxjs';\nimport { map, startWith } from 'rxjs/operators';\nimport { mergePermissions } from './mergePermissions';\nimport {\n getPermissionsLookupObservable,\n PermissionsLookup,\n} from './getPermissionsLookupObservable';\nimport { PermissionChecker } from './PermissionChecker';\nimport './extend-dexie-interface';\n\nexport function permissions(\n dexie: Dexie,\n obj: { owner?: string; realmId?: string; table?: () => string },\n tableName?: string\n): Observable<PermissionChecker<any>> {\n if (!obj)\n throw new TypeError(\n `Cannot check permissions of undefined or null. A Dexie Cloud object with realmId and owner expected.`\n );\n const { owner, realmId } = obj;\n if (!tableName) {\n if (typeof obj.table !== 'function') {\n throw new TypeError(\n `Missing 'table' argument to permissions and table could not be extracted from entity`\n );\n }\n tableName = obj.table();\n }\n const source = getPermissionsLookupObservable(dexie);\n const mapper = (permissionsLookup: PermissionsLookup) => {\n // If realmId is undefined, it can be due to that the object is not yet syncified - it exists\n // locally only as the user might not yet be authenticated. This is ok and we shall treat it\n // as if the realmId is dexie.cloud.currentUserId (which is \"unauthorized\" by the way)\n const realm = permissionsLookup[realmId || dexie.cloud.currentUserId];\n if (!realm)\n return new PermissionChecker(\n {},\n tableName!,\n !owner || owner === dexie.cloud.currentUserId\n );\n return new PermissionChecker(\n realm.permissions,\n tableName!,\n realmId === undefined || realmId === dexie.cloud.currentUserId || owner === dexie.cloud.currentUserId\n );\n };\n const o = source.pipe(map(mapper)) as Observable<PermissionChecker<any>> & {\n getValue: () => PermissionChecker<any>;\n };\n o.getValue = () => mapper(source.getValue());\n return o;\n}\n","import Dexie from 'dexie';\nimport { DexieCloudDB } from './db/DexieCloudDB';\nimport dexieCloud from './dexie-cloud-client';\nimport { DISABLE_SERVICEWORKER_STRATEGY } from './DISABLE_SERVICEWORKER_STRATEGY';\nimport { isSafari, safariVersion } from './isSafari';\nimport { syncIfPossible } from './sync/syncIfPossible';\nimport { SWMessageEvent } from './types/SWMessageEvent';\nimport { SyncEvent } from './types/SWSyncEvent';\n\n// In case the SW lives for a while, let it reuse already opened connections:\nconst managedDBs = new Map<string, DexieCloudDB>();\n\nfunction getDbNameFromTag(tag: string) {\n return tag.startsWith('dexie-cloud:') && tag.split(':')[1];\n}\n\nconst syncDBSemaphore = new Map<string, Promise<void>>();\n\nfunction syncDB(dbName: string, purpose: 'push' | 'pull') {\n // We're taking hight for being double-signalled both\n // via message event and sync event.\n // Which one comes first doesnt matter, just\n // that we return the existing promise if there is\n // an ongoing sync.\n let promise = syncDBSemaphore.get(dbName + '/' + purpose);\n if (!promise) {\n promise = _syncDB(dbName, purpose)\n .then(() => {\n // When legacy enough across browsers, use .finally() instead of then() and catch():\n syncDBSemaphore.delete(dbName + '/' + purpose);\n })\n .catch((error) => {\n syncDBSemaphore.delete(dbName + '/' + purpose);\n return Promise.reject(error);\n });\n syncDBSemaphore.set(dbName + '/' + purpose, promise!);\n }\n return promise!;\n\n async function _syncDB(dbName: string, purpose: 'push' | 'pull') {\n let db = managedDBs.get(dbName);\n\n if (!db) {\n console.debug('Dexie Cloud SW: Creating new Dexie instance for', dbName);\n const dexie = new Dexie(dbName, { addons: [dexieCloud] });\n db = DexieCloudDB(dexie);\n db.cloud.isServiceWorkerDB = true;\n dexie.on('versionchange', stopManagingDB);\n await db.dx.open(); // Makes sure db.cloud.options and db.cloud.schema are read from db,\n if (managedDBs.get(dbName)) {\n // Avoid race conditions.\n db.close();\n return await _syncDB(dbName, purpose);\n }\n managedDBs.set(dbName, db);\n }\n if (!db.cloud.options?.databaseUrl) {\n console.error(`Dexie Cloud: No databaseUrl configured`);\n return; // Nothing to sync.\n }\n if (!db.cloud.schema) {\n console.error(`Dexie Cloud: No schema persisted`);\n return; // Nothing to sync.\n }\n\n function stopManagingDB() {\n db!.dx.on.versionchange.unsubscribe(stopManagingDB);\n if (managedDBs.get(db!.name) === db) {\n // Avoid race conditions.\n managedDBs.delete(db!.name);\n }\n console.debug(`Dexie Cloud SW: Closing Dexie instance for ${dbName}`);\n db!.dx.close();\n return false;\n }\n\n try {\n console.debug('Dexie Cloud SW: Syncing');\n await syncIfPossible(db, db.cloud.options, db.cloud.schema, {\n retryImmediatelyOnFetchError: true,\n purpose,\n });\n console.debug('Dexie Cloud SW: Done Syncing');\n } catch (e) {\n console.error(`Dexie Cloud SW Error`, e);\n // Error occured. Stop managing this DB until we wake up again by a sync event,\n // which will open a new Dexie and start trying to sync it.\n stopManagingDB();\n if (e.name !== Dexie.errnames.NoSuchDatabase) {\n // Unless the error was that DB doesn't exist, rethrow to trigger sync retry.\n throw e; // Throw e to make syncEvent.waitUntil() receive a rejected promis, so it will retry.\n }\n }\n }\n}\n\n// Avoid taking care of events if browser bugs out by using dexie cloud from a service worker.\nif (!DISABLE_SERVICEWORKER_STRATEGY) {\n self.addEventListener('sync', (event: SyncEvent) => {\n console.debug('SW \"sync\" Event', event.tag);\n const dbName = getDbNameFromTag(event.tag);\n if (dbName) {\n event.waitUntil(syncDB(dbName, \"push\")); // The purpose of sync events are \"push\"\n }\n });\n\n self.addEventListener('periodicsync', (event: SyncEvent) => {\n console.debug('SW \"periodicsync\" Event', event.tag);\n const dbName = getDbNameFromTag(event.tag);\n if (dbName) {\n event.waitUntil(syncDB(dbName, \"pull\")); // The purpose of periodic sync events are \"pull\"\n }\n });\n\n self.addEventListener('message', (event: SWMessageEvent) => {\n console.debug('SW \"message\" Event', event.data);\n if (event.data.type === 'dexie-cloud-sync') {\n const { dbName } = event.data;\n // Mimic background sync behavior - retry in X minutes on failure.\n // But lesser timeout and more number of times.\n const syncAndRetry = (num = 1) => {\n return syncDB(dbName, event.data.purpose || \"pull\").catch(async (e) => {\n if (num === 3) throw e;\n await sleep(60_000); // 1 minute\n syncAndRetry(num + 1);\n });\n };\n if ('waitUntil' in event) {\n event.waitUntil(syncAndRetry().catch(error => console.error(error)));\n } else {\n syncAndRetry().catch(error => console.error(error));\n }\n }\n });\n}\n\nfunction sleep(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"names":["__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","apply","__values","o","s","Symbol","iterator","m","i","call","length","TypeError","__await","v","this","__asyncGenerator","asyncIterator","g","q","verb","n","a","b","push","resume","r","fulfill","settle","f","shift","__asyncValues","d","UNAUTHORIZED_USER","userId","name","claims","sub","lastLogin","Date","Object","freeze","_a","swHolder","swContainer","self","document","navigator","serviceWorker","ready","registration","addEventListener","ev","_b","data","type","startsWith","matchAll","includeUncontrolled","forEach","client","id","source","postMessage","SWBroadcastChannel","constructor","subscribe","listener","forwarder","message","removeEventListener","active","events","globalThis","Map","BroadcastedAndLocalEvent","Observable","bc","BroadcastChannel","super","subscriber","onCustomEvent","detail","onMessageEvent","unsubscribe","has","get","set","addListener","err","listeners","idx","indexOf","splice","removeListener","dispatch","CustomEvent","hasComplainedAboutSyncEvent","registerSyncEvent","db","purpose","sw","sync","register","Error","dbName","triggerSync","cloud","usingServiceWorker","localSyncEvent","hasArrayBufferFromBase64","Uint8Array","hasArrayBufferToBase64","prototype","b64decode","Buffer","base64","from","fromBase64","binary_string","atob","len","bytes","charCodeAt","b64encode","ArrayBuffer","isView","buffer","byteOffset","byteLength","toString","toBase64","u8a","strs","l","chunk","subarray","String","fromCharCode","btoa","join","computeRealmSetHash","realms","inviteRealms","JSON","stringify","map","realmId","accepted","sort","byteArray","TextEncoder","encode","digestBytes","crypto","subtle","digest","getSyncableTables","entries","schema","filter","markedForSync","tbl","tables","cloudTableSchema","getMutationTable","tableName","getTableFromMutationTable","mutationTable","exec","concat","flatten","listClientChanges","mutationTables_1","db_1","arguments","mutationTables","since","limit","Infinity","sorted","all","lastRevision","query","where","above","toArray","mut","table","txid","opNo","ts","currentEntry","currentTxid","muts","randomString","buf","getRandomValues","Math","floor","random","_hasOwn","hasOwnProperty","setByKeyPath","obj","keyPath","undefined","isFrozen","assert","period","currentKeyPath","substr","remainingKeyPath","Array","isArray","isNaN","parseInt","innerObj","prop","hasOwn","randomFill","bind","simpleRandomFill","alloc","isValidSyncableID","some","key","every","isValidSyncableIDPart","part","applyOperation","target","op","keys","val","values","changeSpec","changeSpecs","entry","propPath","assign","mod","applyOperations","ops","consumeChunkedBinaryStream","e_1","_c","state","sizeBuf","sizeBufPos","bufs","source_1_1","_d","source_1","dw","DataView","pos","slice","getUint32","concats","reduce","p","c","e_1_1","error","return","TokenErrorResponseError","title","messageCode","messageParams","interactWithUser","userInteraction","req","interactionProps","submitLabel","cancelLabel","onSubmit","res","onCancel","Dexie","AbortError","alertUser","alerts","fields","promptForEmail","emailHint","email","test","placeholder","promptForOTP","alert","otp","label","loadAccessToken","currentUser","getCurrentUser","accessToken","accessTokenExpiration","refreshToken","refreshTokenExpiration","getTime","now","license","status","refreshedLogin","refreshAccessToken","options","databaseUrl","update","authenticate","url","context","fetchToken","hints","location","protocol","privateKey","publicKey","generateKey","modulusLength","publicExponent","hash","nonExportablePrivateKey","publicKeyPEM","keydata","keydataB64","str","finalString","substring","formatAsPem","spkiToPEM","exportKey","response2","public_key","userType","evalDaysLeft","userValidUntil","validUntil","onLine","debug","hostname","origin","catch","userAuthenticate","login","time_stamp","signing_algorithm","binarySignature","sign","signature","tokenRequest","grant_type","refresh_token","scopes","fetch","body","method","headers","mode","response","json","toStr","ObjectDef","replace","dollarKeys","clone","k","TypesonSimplified","typeDefsInputs","typeDefs","protoMap","WeakMap","alternateChannel","space","realVal","typeDef","proto","getPrototypeOf","toStringTag","find","typeName","function","getTypeDef","parse","tson","stack","$t","revive","top","pop","deletes","mods","BisonBinaryTypes","Blob","blob","altChannel","mimeType","numberDef","number","num","Number","bigIntDef","bigint","BigInt","DateDef","date","toISOString","NaN","SetDef","Set","MapDef","_global","global","TypedArraysDefs","specs","_","TypedArray","b64LexEncode","encoded","ENCODE_TABLE","b64ToLex","b64LexDecode","b64Lex","base64lex","DECODE_TABLE","lexToB64","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","Q","R","S","T","U","V","W","X","Y","Z","h","j","t","u","w","x","y","z","ArrayBufferDef","ab","ba","FakeBlob","readBlobSync","XMLHttpRequest","overrideMimeType","open","URL","createObjectURL","send","responseText","string2ArrayBuffer","array","BlobDef","builtin","bigintDef","readBlobBinary","reader","FileReader","onabort","onerror","onload","readAsArrayBuffer","undefinedDef","FileDef","File","file","lastModified","hasBigIntSupport","FakeBigInt","fakeBigInt","defs","PropModification","propModification","propModSpec","getOwnPropertySymbols","propertyIsEnumerable","__rest","TSON","tsonBuiltinDefs","BISON","toBinary","lenBuf","setUint32","size","binaries","binData","arrayBuffers","view","fromBinary","readAsText","readBlob","Bison","HttpError","statusText","httpStatus","encodeIdsForServer","changes","rv","change","tableSchema","primaryKey","changeClone","mutIndex","rewriteValues","outbound","keyIndex","cloneChange","mutClone","rewrittenKey","isLoggedIn","syncRatelimitDelays","checkSyncRateLimitDelay","delatMilliseconds","setTimeout","syncWithServer","syncState","baseRevs","clientIdentity","Accept","updatedUser","Authorization","syncRequest","dbID","remoteDbId","lastPull","serverRevision","yServerRevision","dx","core","dxcv","version","syncStateChangedEvent","phase","credentials","remaining","reset","limitNum","remainingNum","max","willResetInSeconds","delay","ceil","delete","updateSyncRateLimitDelays","ok","text","throwIfCancelled","cancelToken","cancelled","isOnline","updateBaseRevs","latestRevisions","serverRev","$baseRevs","bulkPut","clientRev","noneOf","getLatestRevisionsPerTable","clientChangeSet","lastRevisions","lastRev","rev","bulkUpdate","objs","bulkGet","resultKeys","resultObjs","primKey","cmp","applyServerChanges","_allTables","keyDecoder","endsWith","currentUserId","bulkAdd","anyOf","modify","bulkDelete","DEXIE_CLOUD_SYNCER_ID","listUpdatesSince","yTable","sinceIncluding","between","getUpdatesTable","ydocProp","utbl","yProps","updatesTable","applyYServerMessages","yMessages","receivedUntils","resyncNeeded","updateRow","add","transaction","tx","syncer","put","unsentFrom","idbtrans","_rejecting_y_ypdate","aboveOrEqual","activeDoc","DexieYProvider","getDocCache","destroy","doc","isSynced","emit","yServerRev","BINSTREAM_TYPE_REALMID","BINSTREAM_TYPE_TABLE_AND_PROP","BINSTREAM_TYPE_DOCUMENT","downloadYDocsFromServer","databaseUrl_1","yDownloadedRealms","user","downloadedRealms","async","stages","result_1_1","result_1","asyncIterablePipeline","getReader","read","releaseLock","getFetchResponseBodyGenerator","chunks","currentRealmId","currentTable","currentProp","docsToInsert","storeCollectedDocs","completedRealm","lastDoc","$syncState","chunks_1_1","chunks_1","decoder","Decoder","hasContent","readUint8","readVarString","readAny","readVarUint8Array","DexieError","CURRENT_SYNC_WORKER","syncOptions","_sync","justCheckIfNeeded","retryImmediatelyOnFetchError","timestamp","options_1","schema_1","isInitialSync","tablesToSync","persistedSyncState","getPersistedSyncState","readyForSyncification","tablesToSyncify","syncedTables","includes","getTablesToSyncify","doSyncify","disableChangeTracking","disableAccessControl","syncifiedTables","alreadySyncedRealms","ignoredRealms","toCollection","member","realm","owner","modifyLocalObjectsWithNewUserId","lastUpdateIds","br","clientChanges","yResults","yProp","receivedUntil","unsyncedFrom","min","updates","perDoc","isLocal","docKey","mergedUpdate","mergeUpdatesV2","stateVector","encodeStateVectorFromUpdateV2","sv","listYClientMessagesAndStateVector","syncificationInserts","extractKey","dexieCloudTableSchema","generatedGlobalId","item","idPrefix","unsyncedObjects","listSyncifiedChanges","pushSyncIsNeeded","newSyncState","addedClientChanges","mutTable","ch","latestRev","belowOrEqual","reverse","offset","clear","deletedRealms","rejectedRealms","previousRealmSet","previousInviteRealmSet","updatedRealmSet","updatedTotalRealmSet","realmsToDelete","indexes","deleteObjectsFromRemovedRealms","dbId","initiallySynced","filteredChanges","filterServerChangesThroughAddedClientChanges","lastUpdateIdsBeforeSync","receivedUntilsAfterSync","mergedSpec","lastUpdateId","allYTables","_dbSchema","tblSchema","flat","mergedEntry","_e","primaryKeys","updateYSyncStates","usingYProps","serverSupportsYprops","syncCompleteEvent","serverChanges","localPostChanges","changesToSubtract","mutationSet","targetMut","subtractChanges","inSet","mapEntry","resultEntry","optype","toDBOperationSet","LIMIT_NUM_MESSAGES_PER_TIME","TIME_WINDOW","PAUSE_PERIOD","MessagesFromServerConsumer","queue","readyToServe","BehaviorSubject","event","isWorking","loopDetection","fill","msg","firstValueFrom","pipe","wait","_f","getSchema","baseRev","waitFor","realmSetHash","newRev","consumeQueue","enqueue","wm","DEXIE_CLOUD_SCHEMA","members","roles","$jobs","$logins","static_counter","DexieCloudDB","Subject","close","helperMethods","logins","getOptions","setInitiallySynced","reconfigure","messageConsumer","messageProducer","AuthPersistedContext","userLogin","load","save","waitUntil","predicate","logout","numUnsyncedChanges","_logout","confirmLogout","deleteUnsyncedData","numUnsynced","loggedOut","storeNames","sumUnSynced","count","prodLog","level","args","origUserId","fetchTokens","demo_user","otpId","otp_id","res1","errMsg","tokenRequest2","res2","errorText","otpFetchTokenCallback","existingLogins","setCurrentUser","isFirefox","InstallTrigger","isSafari","userAgent","safariVersion","match","DISABLE_SERVICEWORKER_STRATEGY","IS_SERVICE_WORKER","getEffectiveKeys","consonants","time","prefix","shardKey","timePart","randomPart","createIdGenerationMiddleware","create","mutate","trans","getMany","cache","results","valueClones","colocatedId","deepClone","ConstraintError","generateOrVerifyAtKeys","counter","readLock","fn","readers","writers","numWriters","promise","finally","writeLock","possiblePromises","reason","outstandingTransactions","isEagerSyncDisabled","disableEagerSync","createMutationTrackingMiddleware","currentUserObservable","allTableNames","ordinaryTables","mutTableMap","mutationTableName","opCount","removeTransaction","txComplete","mutationsAdded","mutsTable","openCursor","guardedTable","range","index","mutateAndLog","criteria","unsyncedProps","unsyncedProperties","stripChangeSpec","numFailures","hasFailures","failures","newValue","strippedChangeSpecs","newUpdates","validKeys","RangeSet","anyChangeSpecBecameEmpty","addKey","newKeys","newValues","hasKey","keyPaths","isAdditionalChunk","overrideParseStoresSpec","origFunc","dexie","stores","dbSchema","storesClone","schemaSrc","requestedIndexes","split","spec","trim","builtInIndexes","requestedIndexSet","builtInIndex","cloudSchema","allPrefixes","toLocaleLowerCase","toLowerCase","orig","bits","bitFix","upperFixed","toUpperCase","nextChar","generateTablePrefix","deleted","performGuardedJob","jobName","job","locks","request","userIsActive","userIsReallyActive","switchMap","isActive","of","distinctUntilChanged","visibilityStateIsChanged","fromEvent","documentBecomesHidden","visibilityState","documentBecomesVisible","userDoesSomething","window","merge","tap","USER_INACTIVITY_TIMEOUT","TokenExpiredError","awarenessWeakMap","getOpenDocSignal","signal","WSObservable","yrev","webSocketStatus","WSConnection","Subscription","teardown","subscriptions","reconnecting","lastUserActivity","connect","disconnect","pinger","clearInterval","ws","reconnect","lastServerActivity","pauseUntil","closed","tokenExpiration","setInterval","wsUrl","searchParams","URLSearchParams","WebSocket","binaryType","onclose","onmessage","readBigUint64","arr","decodeYMessage","awareness","getDocAwareness","awap","applyAwarenessUpdate","everConnected","onopen","encoder","Encoder","writeVarString","writeBigUint64","writeAny","writeVarUint8Array","toUint8Array","encodeYMessage","yTableRecords","yTbl","currentUnsentFrom","liveQuery","addedUpdates","at","mergeMap","messages","createYClientUpdateObservable","InvalidLicenseError","waitAndReconnectWhenUserDoesSomething","ms","isSyncNeeded","ongoingSyncs","syncIfPossible","cloudOptions","ongoing","pull","hasPullTakenPlace","subscription","_syncIfPossible","SECONDS","LocalSyncWorker","localSyncEventSubscription","nextRetryTime","syncStartTime","syncAndRetry","retryNum","pullSignalled","stop","pushSignalled","ongoingSync","retryIn","consumer","start","updateSchemaFromOptions","unsyncedTables","parentNode","removeChild","children","defaultProps","props","ref","__k","__","__b","__e","__d","__c","__h","__v","vnode","base","__r","debounceRendering","__P","__n","ownerSVGElement","appendChild","nextSibling","insertBefore","$","setProperty","style","cssText","setAttribute","removeAttribute","contextType","__E","render","__s","getDerivedStateFromProps","componentWillMount","componentDidMount","componentWillReceiveProps","shouldComponentUpdate","componentWillUpdate","componentDidUpdate","getChildContext","getSnapshotBeforeUpdate","diffed","localName","nodeType","createTextNode","createElementNS","createElement","is","childNodes","dangerouslySetInnerHTML","attributes","__html","innerHTML","checked","current","unmount","componentWillUnmount","firstChild","getDerivedStateFromError","setState","componentDidCatch","forceUpdate","Styles","color","Alert","fontWeight","warning","info","Darken","position","left","opacity","backgroundColor","width","height","zIndex","webkitBackdropFilter","backdropFilter","DialogOuter","alignItems","display","justifyContent","DialogInner","padding","marginBottom","maxWidth","maxHeight","overflowY","border","borderRadius","boxShadow","fontFamily","Input","borderColor","outline","fontSize","Dialog","className","__H","__V","__N","requestAnimationFrame","clearTimeout","cancelAnimationFrame","LoginDialog","params","setParams","useState","firstFieldRef","useRef","useLayoutEffect","focus","Fragment","WindowHeader","resolveText","preventDefault","fieldName","Label","autoComplete","autoFocus","onInput","valueTransformer","updatedParams","ButtonsDiv","Button","onClick","LoginGui","Component","observer","associate","factory","getCurrentUserEmitter","createSharedValueObservable","defaultValue","currentValue","shared","share","resetOnRefCountZero","timer","didEmit","complete","getValue","getGlobalRolesObservable","role","sortOrder","getInternalAccessControlObservable","_novip","selfMembers","mergePermissions","permissions","reduced","ret","rights","retVerb","mergedRights","tableRights","getPermissionsLookupObservable","mapper","mapValueObservable","combineLatest","globalRoles","selfRealmMembers","directPermissionSets","rolePermissionSets","roleName","manage","PermissionChecker","isOwner","tableNames","tablePermissions","permittedProp","getInvitesObservable","membersByEmail","accessControl","realmLookup","reducer","emailMembersById","membersById","invite","accept","createYHandler","provider","parentTable","meta","defineProperty","parentId","parentProp","Awareness","reopenDocSignal","on","added","updated","removed","changedClients","encodeAwarenessUpdate","destroyed","removeAwarenessStates","clientID","connected","currentFlowId","startWith","wsStatus","openDocumentOnServer","myFlow","syncStateTbl","docOpenMsg","serverUpdatesSinceLastSync","addCleanupHandler","createAwareness","DEFAULT_OPTIONS","nameSuffix","dexieCloud","origIdbName","currentUserEmitter","configuredProgramatically","localSyncWorker","customLoginGui","el","preact.render","vip","remove","setupDefaultGUI","isServiceWorkerDB","_prevStatus","lazyWebSocketStatus","prevStatus","debounceTime","progress","adjustedStatus","computeSyncState","syncComplete","SchemaError","throwVersionIncrementNeeded","swRegistrations","getRegistrations","lastSyncedRealms","persistedOptions","persistedSchema","newPersistedOptions","awarenessProtocol","tryUseServiceWorker","newPersistedSchema","newTblSchema","auto","verifySchema","throwIfClosed","skip","take","yHandler","new","once","changedUser","requireAuth","doInitialSync","performInitialSync","periodicSync","registerPeriodicSyncEvent","_g","disableWebSocket","readyForChangesMessage","isReady","createObservable","prevUser","prevHash","currUser","currHash","catchError","throwError","connectWebSocket","onDbReady","DatabaseClosedError","hint","invites","configure","dbUrl","pathname","getDbNameFromDbUrl","force","syncNeeded","isNeeded","permissionsLookup","Version","override","Table","newId","colocateWith","use","$ts","Cloud","managedDBs","getDbNameFromTag","tag","syncDBSemaphore","syncDB","_syncDB","addons","stopManagingDB","errnames","NoSuchDatabase","versionchange"],"mappings":"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","x_google_ignoreList":[0,6,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,104,107]}
|