dexie-cloud-addon 4.4.5 → 4.4.7
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/DXCWebSocketStatus.d.ts +1 -1
- package/dist/modern/DexieCloudAPI.d.ts +1 -1
- package/dist/modern/authentication/AuthPersistedContext.d.ts +2 -2
- package/dist/modern/currentUserEmitter.d.ts +3 -3
- package/dist/modern/db/entities/Member.d.ts +3 -3
- package/dist/modern/db/entities/PersistedSyncState.d.ts +1 -1
- package/dist/modern/db/entities/Role.d.ts +3 -3
- package/dist/modern/default-ui/Dialog.d.ts +1 -1
- package/dist/modern/default-ui/index.d.ts +5 -5
- package/dist/modern/dexie-cloud-addon.js +646 -526
- 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/dexie-cloud-client.d.ts +1 -1
- package/dist/modern/helpers/BroadcastedAndLocalEvent.d.ts +2 -2
- package/dist/modern/helpers/getSyncableTables.d.ts +3 -3
- package/dist/modern/helpers/resolveText.d.ts +1 -1
- package/dist/modern/middleware-helpers/guardedTable.d.ts +1 -1
- package/dist/modern/service-worker.js +648 -528
- 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/sync/BlobDownloadTracker.d.ts +2 -2
- package/dist/modern/sync/extractRealm.d.ts +1 -1
- package/dist/modern/sync/getTablesToSyncify.d.ts +2 -2
- package/dist/modern/sync/isSyncNeeded.d.ts +1 -1
- package/dist/modern/sync/messageConsumerIsReady.d.ts +1 -1
- package/dist/modern/sync/modifyLocalObjectsWithNewUserId.d.ts +3 -3
- package/dist/modern/sync/numUnsyncedMutations.d.ts +1 -1
- package/dist/modern/sync/performGuardedJob.d.ts +1 -1
- package/dist/modern/sync/registerSyncEvent.d.ts +1 -1
- package/dist/modern/sync/triggerSync.d.ts +2 -2
- package/dist/modern/types/DXCUserInteraction.d.ts +2 -2
- package/dist/modern/types/SyncState.d.ts +2 -2
- package/dist/modern/types/TXExpandos.d.ts +1 -1
- package/dist/modern/updateSchemaFromOptions.d.ts +2 -2
- package/dist/modern/verifyConfig.d.ts +1 -1
- package/dist/modern/verifySchema.d.ts +1 -1
- package/dist/modern/yjs/YTable.d.ts +3 -3
- package/dist/modern/yjs/getUpdatesTable.d.ts +2 -2
- package/dist/modern/yjs/reopenDocSignal.d.ts +2 -2
- package/dist/umd/dexie-cloud-addon.js +654 -534
- 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 +656 -536
- 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/package.json +3 -3
- package/dist/modern/default-ui/AuthProviderButton.d.ts +0 -21
- package/dist/modern/default-ui/ProviderSelectionDialog.d.ts +0 -7
- package/dist/modern/default-ui/SelectDialog.d.ts +0 -10
- package/dist/modern/dexie-cloud-addon.min.js.gz +0 -0
- package/dist/umd/DISABLE_SERVICEWORKER_STRATEGY.d.ts +0 -1
- package/dist/umd/DXCWebSocketStatus.d.ts +0 -1
- package/dist/umd/DexieCloudAPI.d.ts +0 -75
- package/dist/umd/DexieCloudOptions.d.ts +0 -27
- package/dist/umd/DexieCloudSyncOptions.d.ts +0 -4
- package/dist/umd/DexieCloudTable.d.ts +0 -18
- package/dist/umd/InvalidLicenseError.d.ts +0 -5
- package/dist/umd/Invite.d.ts +0 -8
- package/dist/umd/PermissionChecker.d.ts +0 -15
- package/dist/umd/TSON.d.ts +0 -17
- package/dist/umd/WSObservable.d.ts +0 -72
- package/dist/umd/associate.d.ts +0 -1
- package/dist/umd/authentication/AuthPersistedContext.d.ts +0 -9
- package/dist/umd/authentication/TokenErrorResponseError.d.ts +0 -10
- package/dist/umd/authentication/TokenExpiredError.d.ts +0 -3
- package/dist/umd/authentication/UNAUTHORIZED_USER.d.ts +0 -2
- package/dist/umd/authentication/authenticate.d.ts +0 -13
- package/dist/umd/authentication/currentUserObservable.d.ts +0 -1
- package/dist/umd/authentication/interactWithUser.d.ts +0 -21
- package/dist/umd/authentication/login.d.ts +0 -3
- package/dist/umd/authentication/logout.d.ts +0 -5
- package/dist/umd/authentication/otpFetchTokenCallback.d.ts +0 -3
- package/dist/umd/authentication/setCurrentUser.d.ts +0 -14
- package/dist/umd/authentication/waitUntil.d.ts +0 -3
- package/dist/umd/computeSyncState.d.ts +0 -4
- package/dist/umd/createSharedValueObservable.d.ts +0 -3
- package/dist/umd/currentUserEmitter.d.ts +0 -3
- package/dist/umd/db/DexieCloudDB.d.ts +0 -61
- package/dist/umd/db/entities/BaseRevisionMapEntry.d.ts +0 -5
- package/dist/umd/db/entities/EntityCommon.d.ts +0 -5
- package/dist/umd/db/entities/GuardedJob.d.ts +0 -5
- package/dist/umd/db/entities/Member.d.ts +0 -19
- package/dist/umd/db/entities/PersistedSyncState.d.ts +0 -22
- package/dist/umd/db/entities/Realm.d.ts +0 -14
- package/dist/umd/db/entities/Role.d.ts +0 -11
- package/dist/umd/db/entities/UserLogin.d.ts +0 -23
- package/dist/umd/default-ui/Dialog.d.ts +0 -5
- package/dist/umd/default-ui/LoginDialog.d.ts +0 -3
- package/dist/umd/default-ui/Styles.d.ts +0 -3
- package/dist/umd/default-ui/index.d.ts +0 -24
- package/dist/umd/define-ydoc-trigger.d.ts +0 -3
- package/dist/umd/dexie-cloud-addon.d.ts +0 -3
- package/dist/umd/dexie-cloud-addon.js.gz +0 -0
- package/dist/umd/dexie-cloud-addon.min.js.gz +0 -0
- package/dist/umd/dexie-cloud-client.d.ts +0 -23
- package/dist/umd/errors/HttpError.d.ts +0 -5
- package/dist/umd/extend-dexie-interface.d.ts +0 -23
- package/dist/umd/getGlobalRolesObservable.d.ts +0 -5
- package/dist/umd/getInternalAccessControlObservable.d.ts +0 -12
- package/dist/umd/getInvitesObservable.d.ts +0 -23
- package/dist/umd/getPermissionsLookupObservable.d.ts +0 -16
- package/dist/umd/getTiedRealmId.d.ts +0 -2
- package/dist/umd/helpers/BroadcastedAndLocalEvent.d.ts +0 -8
- package/dist/umd/helpers/CancelToken.d.ts +0 -4
- package/dist/umd/helpers/IS_SERVICE_WORKER.d.ts +0 -1
- package/dist/umd/helpers/SWBroadcastChannel.d.ts +0 -12
- package/dist/umd/helpers/allSettled.d.ts +0 -1
- package/dist/umd/helpers/bulkUpdate.d.ts +0 -4
- package/dist/umd/helpers/computeRealmSetHash.d.ts +0 -2
- package/dist/umd/helpers/date-constants.d.ts +0 -5
- package/dist/umd/helpers/flatten.d.ts +0 -1
- package/dist/umd/helpers/getMutationTable.d.ts +0 -1
- package/dist/umd/helpers/getSyncableTables.d.ts +0 -4
- package/dist/umd/helpers/getTableFromMutationTable.d.ts +0 -1
- package/dist/umd/helpers/makeArray.d.ts +0 -1
- package/dist/umd/helpers/randomString.d.ts +0 -1
- package/dist/umd/helpers/resolveText.d.ts +0 -16
- package/dist/umd/helpers/throwVersionIncrementNeeded.d.ts +0 -1
- package/dist/umd/helpers/visibilityState.d.ts +0 -1
- package/dist/umd/isEagerSyncDisabled.d.ts +0 -2
- package/dist/umd/isFirefox.d.ts +0 -1
- package/dist/umd/isSafari.d.ts +0 -2
- package/dist/umd/mapValueObservable.d.ts +0 -5
- package/dist/umd/mergePermissions.d.ts +0 -2
- package/dist/umd/middleware-helpers/guardedTable.d.ts +0 -11
- package/dist/umd/middleware-helpers/idGenerationHelpers.d.ts +0 -18
- package/dist/umd/middlewares/createIdGenerationMiddleware.d.ts +0 -3
- package/dist/umd/middlewares/createImplicitPropSetterMiddleware.d.ts +0 -3
- package/dist/umd/middlewares/createMutationTrackingMiddleware.d.ts +0 -17
- package/dist/umd/middlewares/outstandingTransaction.d.ts +0 -4
- package/dist/umd/overrideParseStoresSpec.d.ts +0 -4
- package/dist/umd/performInitialSync.d.ts +0 -4
- package/dist/umd/permissions.d.ts +0 -9
- package/dist/umd/prodLog.d.ts +0 -9
- package/dist/umd/service-worker.d.ts +0 -1
- package/dist/umd/sync/DEXIE_CLOUD_SYNCER_ID.d.ts +0 -1
- package/dist/umd/sync/LocalSyncWorker.d.ts +0 -7
- package/dist/umd/sync/SyncRequiredError.d.ts +0 -3
- package/dist/umd/sync/applyServerChanges.d.ts +0 -3
- package/dist/umd/sync/connectWebSocket.d.ts +0 -2
- package/dist/umd/sync/encodeIdsForServer.d.ts +0 -4
- package/dist/umd/sync/extractRealm.d.ts +0 -2
- package/dist/umd/sync/getLatestRevisionsPerTable.d.ts +0 -6
- package/dist/umd/sync/getTablesToSyncify.d.ts +0 -3
- package/dist/umd/sync/isOnline.d.ts +0 -1
- package/dist/umd/sync/isSyncNeeded.d.ts +0 -2
- package/dist/umd/sync/listClientChanges.d.ts +0 -9
- package/dist/umd/sync/listSyncifiedChanges.d.ts +0 -5
- package/dist/umd/sync/messageConsumerIsReady.d.ts +0 -2
- package/dist/umd/sync/messagesFromServerQueue.d.ts +0 -8
- package/dist/umd/sync/modifyLocalObjectsWithNewUserId.d.ts +0 -4
- package/dist/umd/sync/myId.d.ts +0 -1
- package/dist/umd/sync/numUnsyncedMutations.d.ts +0 -2
- package/dist/umd/sync/old_startSyncingClientChanges.d.ts +0 -39
- package/dist/umd/sync/performGuardedJob.d.ts +0 -2
- package/dist/umd/sync/ratelimit.d.ts +0 -3
- package/dist/umd/sync/registerSyncEvent.d.ts +0 -3
- package/dist/umd/sync/sync.d.ts +0 -15
- package/dist/umd/sync/syncIfPossible.d.ts +0 -5
- package/dist/umd/sync/syncWithServer.d.ts +0 -6
- package/dist/umd/sync/triggerSync.d.ts +0 -2
- package/dist/umd/sync/updateBaseRevs.d.ts +0 -5
- package/dist/umd/types/DXCAlert.d.ts +0 -25
- package/dist/umd/types/DXCInputField.d.ts +0 -11
- package/dist/umd/types/DXCUserInteraction.d.ts +0 -93
- package/dist/umd/types/NewIdOptions.d.ts +0 -3
- package/dist/umd/types/SWMessageEvent.d.ts +0 -3
- package/dist/umd/types/SWSyncEvent.d.ts +0 -4
- package/dist/umd/types/SyncState.d.ts +0 -9
- package/dist/umd/types/TXExpandos.d.ts +0 -11
- package/dist/umd/updateSchemaFromOptions.d.ts +0 -3
- package/dist/umd/userIsActive.d.ts +0 -7
- package/dist/umd/verifyConfig.d.ts +0 -2
- package/dist/umd/verifySchema.d.ts +0 -2
- package/dist/umd/yjs/YDexieCloudSyncState.d.ts +0 -3
- package/dist/umd/yjs/YTable.d.ts +0 -3
- package/dist/umd/yjs/applyYMessages.d.ts +0 -9
- package/dist/umd/yjs/awareness.d.ts +0 -3
- package/dist/umd/yjs/createYClientUpdateObservable.d.ts +0 -4
- package/dist/umd/yjs/createYHandler.d.ts +0 -2
- package/dist/umd/yjs/downloadYDocsFromServer.d.ts +0 -3
- package/dist/umd/yjs/getUpdatesTable.d.ts +0 -3
- package/dist/umd/yjs/listUpdatesSince.d.ts +0 -3
- package/dist/umd/yjs/listYClientMessagesAndStateVector.d.ts +0 -26
- package/dist/umd/yjs/reopenDocSignal.d.ts +0 -10
- package/dist/umd/yjs/updateYSyncStates.d.ts +0 -6
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* ==========================================================================
|
|
10
10
|
*
|
|
11
|
-
* Version 4.4.
|
|
11
|
+
* Version 4.4.7, Fri Mar 27 2026
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -111,7 +111,7 @@
|
|
|
111
111
|
const keys = Object.keys(value);
|
|
112
112
|
let dollarKeys = null;
|
|
113
113
|
for (let i = 0, l = keys.length; i < l; ++i) {
|
|
114
|
-
if (keys[i][0] ===
|
|
114
|
+
if (keys[i][0] === '$') {
|
|
115
115
|
dollarKeys = dollarKeys || [];
|
|
116
116
|
dollarKeys.push(keys[i]);
|
|
117
117
|
}
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
delete clone[k];
|
|
124
124
|
}
|
|
125
125
|
for (const k of dollarKeys) {
|
|
126
|
-
clone[
|
|
126
|
+
clone['$' + k] = value[k];
|
|
127
127
|
}
|
|
128
128
|
return clone;
|
|
129
129
|
}
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
//
|
|
175
175
|
// Child part
|
|
176
176
|
//
|
|
177
|
-
if (value === undefined || (key[0] ===
|
|
177
|
+
if (value === undefined || (key[0] === '$' && key !== '$t')) {
|
|
178
178
|
top = stack[stack.length - 1];
|
|
179
179
|
let deletes;
|
|
180
180
|
let mods;
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
else {
|
|
186
186
|
stack.push([this, (deletes = []), (mods = {})]);
|
|
187
187
|
}
|
|
188
|
-
if (key[0] ===
|
|
188
|
+
if (key[0] === '$' && key !== '$t') {
|
|
189
189
|
// Unescape props (also preserves undefined if this is a combo)
|
|
190
190
|
deletes.push(key);
|
|
191
191
|
mods[key.substr(1)] = value;
|
|
@@ -202,8 +202,8 @@
|
|
|
202
202
|
function getTypeDef(realVal) {
|
|
203
203
|
const type = typeof realVal;
|
|
204
204
|
switch (typeof realVal) {
|
|
205
|
-
case
|
|
206
|
-
case
|
|
205
|
+
case 'object':
|
|
206
|
+
case 'function': {
|
|
207
207
|
// "object", "function", null
|
|
208
208
|
if (realVal === null)
|
|
209
209
|
return null;
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
if (!typeDef) {
|
|
220
220
|
typeDef = Array.isArray(realVal)
|
|
221
221
|
? null
|
|
222
|
-
: typeof realVal ===
|
|
222
|
+
: typeof realVal === 'function'
|
|
223
223
|
? typeDefs.function || null
|
|
224
224
|
: ObjectDef;
|
|
225
225
|
}
|
|
@@ -395,13 +395,13 @@
|
|
|
395
395
|
|
|
396
396
|
function readBlobSync(b) {
|
|
397
397
|
const req = new XMLHttpRequest();
|
|
398
|
-
req.overrideMimeType(
|
|
398
|
+
req.overrideMimeType('text/plain; charset=x-user-defined');
|
|
399
399
|
const url = URL.createObjectURL(b);
|
|
400
400
|
try {
|
|
401
|
-
req.open(
|
|
401
|
+
req.open('GET', url, false); // Sync
|
|
402
402
|
req.send();
|
|
403
403
|
if (req.status !== 200 && req.status !== 0) {
|
|
404
|
-
throw new Error(
|
|
404
|
+
throw new Error('Bad Blob access: ' + req.status);
|
|
405
405
|
}
|
|
406
406
|
return req.responseText;
|
|
407
407
|
}
|
|
@@ -415,11 +415,11 @@
|
|
|
415
415
|
replace: (num) => {
|
|
416
416
|
switch (true) {
|
|
417
417
|
case isNaN(num):
|
|
418
|
-
return { $t:
|
|
418
|
+
return { $t: 'number', v: 'NaN' };
|
|
419
419
|
case num === Infinity:
|
|
420
|
-
return { $t:
|
|
420
|
+
return { $t: 'number', v: 'Infinity' };
|
|
421
421
|
case num === -Infinity:
|
|
422
|
-
return { $t:
|
|
422
|
+
return { $t: 'number', v: '-Infinity' };
|
|
423
423
|
default:
|
|
424
424
|
return num;
|
|
425
425
|
}
|
|
@@ -431,17 +431,17 @@
|
|
|
431
431
|
const dateTypeDef = {
|
|
432
432
|
Date: {
|
|
433
433
|
replace: (date) => ({
|
|
434
|
-
$t:
|
|
435
|
-
v: isNaN(date.getTime()) ?
|
|
434
|
+
$t: 'Date',
|
|
435
|
+
v: isNaN(date.getTime()) ? 'NaN' : date.toISOString(),
|
|
436
436
|
}),
|
|
437
|
-
revive: ({ v }) => new Date(v ===
|
|
437
|
+
revive: ({ v }) => new Date(v === 'NaN' ? NaN : Date.parse(v)),
|
|
438
438
|
},
|
|
439
439
|
};
|
|
440
440
|
|
|
441
441
|
const setTypeDef = {
|
|
442
442
|
Set: {
|
|
443
443
|
replace: (set) => ({
|
|
444
|
-
$t:
|
|
444
|
+
$t: 'Set',
|
|
445
445
|
v: Array.from(set),
|
|
446
446
|
}),
|
|
447
447
|
revive: ({ v }) => new Set(v),
|
|
@@ -451,34 +451,34 @@
|
|
|
451
451
|
const mapTypeDef = {
|
|
452
452
|
Map: {
|
|
453
453
|
replace: (map) => ({
|
|
454
|
-
$t:
|
|
454
|
+
$t: 'Map',
|
|
455
455
|
v: Array.from(map.entries()),
|
|
456
456
|
}),
|
|
457
457
|
revive: ({ v }) => new Map(v),
|
|
458
458
|
},
|
|
459
459
|
};
|
|
460
460
|
|
|
461
|
-
const _global = typeof globalThis !==
|
|
461
|
+
const _global = typeof globalThis !== 'undefined' // All modern environments (node, bun, deno, browser, workers, webview etc)
|
|
462
462
|
? globalThis
|
|
463
|
-
: typeof self !==
|
|
463
|
+
: typeof self !== 'undefined' // Older browsers, workers, webview, window etc
|
|
464
464
|
? self
|
|
465
|
-
: typeof global !==
|
|
465
|
+
: typeof global !== 'undefined' // Older versions of node
|
|
466
466
|
? global
|
|
467
467
|
: undefined; // Unsupported environment. No idea to return 'this' since we are in a module or a function scope anyway.
|
|
468
468
|
|
|
469
469
|
const typedArrayTypeDefs = [
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
470
|
+
'Int8Array',
|
|
471
|
+
'Uint8Array',
|
|
472
|
+
'Uint8ClampedArray',
|
|
473
|
+
'Int16Array',
|
|
474
|
+
'Uint16Array',
|
|
475
|
+
'Int32Array',
|
|
476
|
+
'Uint32Array',
|
|
477
|
+
'Float32Array',
|
|
478
|
+
'Float64Array',
|
|
479
|
+
'DataView',
|
|
480
|
+
'BigInt64Array',
|
|
481
|
+
'BigUint64Array',
|
|
482
482
|
].reduce((specs, typeName) => ({
|
|
483
483
|
...specs,
|
|
484
484
|
[typeName]: {
|
|
@@ -506,10 +506,10 @@
|
|
|
506
506
|
},
|
|
507
507
|
}), {});
|
|
508
508
|
|
|
509
|
-
const hasArrayBufferFromBase64 =
|
|
510
|
-
const hasArrayBufferToBase64 =
|
|
511
|
-
const b64decode = typeof Buffer !==
|
|
512
|
-
? (base64) => Buffer.from(base64,
|
|
509
|
+
const hasArrayBufferFromBase64 = 'fromBase64' in Uint8Array; // https://github.com/tc39/proposal-arraybuffer-base64;
|
|
510
|
+
const hasArrayBufferToBase64 = 'toBase64' in Uint8Array.prototype; // https://github.com/tc39/proposal-arraybuffer-base64;
|
|
511
|
+
const b64decode = typeof Buffer !== 'undefined'
|
|
512
|
+
? (base64) => Buffer.from(base64, 'base64') // Node
|
|
513
513
|
: hasArrayBufferFromBase64
|
|
514
514
|
? // @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64
|
|
515
515
|
(base64) => Uint8Array.fromBase64(base64) // Modern javascript standard
|
|
@@ -523,14 +523,14 @@
|
|
|
523
523
|
}
|
|
524
524
|
return bytes;
|
|
525
525
|
};
|
|
526
|
-
const b64encode = typeof Buffer !==
|
|
526
|
+
const b64encode = typeof Buffer !== 'undefined'
|
|
527
527
|
? (b) => {
|
|
528
528
|
// Node
|
|
529
529
|
if (ArrayBuffer.isView(b)) {
|
|
530
|
-
return Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString(
|
|
530
|
+
return Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString('base64');
|
|
531
531
|
}
|
|
532
532
|
else {
|
|
533
|
-
return Buffer.from(b).toString(
|
|
533
|
+
return Buffer.from(b).toString('base64');
|
|
534
534
|
}
|
|
535
535
|
}
|
|
536
536
|
: hasArrayBufferToBase64
|
|
@@ -549,7 +549,7 @@
|
|
|
549
549
|
const chunk = u8a.subarray(i, i + CHUNK_SIZE);
|
|
550
550
|
strs.push(String.fromCharCode.apply(null, Array.from(chunk)));
|
|
551
551
|
}
|
|
552
|
-
return btoa(strs.join(
|
|
552
|
+
return btoa(strs.join(''));
|
|
553
553
|
};
|
|
554
554
|
|
|
555
555
|
function b64LexEncode(b) {
|
|
@@ -559,7 +559,7 @@
|
|
|
559
559
|
return b64decode(lexToB64(b64Lex));
|
|
560
560
|
}
|
|
561
561
|
function b64ToLex(base64) {
|
|
562
|
-
var encoded =
|
|
562
|
+
var encoded = '';
|
|
563
563
|
for (var i = 0, length = base64.length; i < length; i++) {
|
|
564
564
|
encoded += ENCODE_TABLE[base64[i]];
|
|
565
565
|
}
|
|
@@ -567,81 +567,81 @@
|
|
|
567
567
|
}
|
|
568
568
|
function lexToB64(base64lex) {
|
|
569
569
|
// only accept string input
|
|
570
|
-
if (typeof base64lex !==
|
|
571
|
-
throw new Error(
|
|
570
|
+
if (typeof base64lex !== 'string') {
|
|
571
|
+
throw new Error('invalid decoder input: ' + base64lex);
|
|
572
572
|
}
|
|
573
|
-
var base64 =
|
|
573
|
+
var base64 = '';
|
|
574
574
|
for (var i = 0, length = base64lex.length; i < length; i++) {
|
|
575
575
|
base64 += DECODE_TABLE[base64lex[i]];
|
|
576
576
|
}
|
|
577
577
|
return base64;
|
|
578
578
|
}
|
|
579
579
|
const DECODE_TABLE = {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
A:
|
|
592
|
-
B:
|
|
593
|
-
C:
|
|
594
|
-
D:
|
|
595
|
-
E:
|
|
596
|
-
F:
|
|
597
|
-
G:
|
|
598
|
-
H:
|
|
599
|
-
I:
|
|
600
|
-
J:
|
|
601
|
-
K:
|
|
602
|
-
L:
|
|
603
|
-
M:
|
|
604
|
-
N:
|
|
605
|
-
O:
|
|
606
|
-
P:
|
|
607
|
-
Q:
|
|
608
|
-
R:
|
|
609
|
-
S:
|
|
610
|
-
T:
|
|
611
|
-
U:
|
|
612
|
-
V:
|
|
613
|
-
W:
|
|
614
|
-
X:
|
|
615
|
-
Y:
|
|
616
|
-
Z:
|
|
617
|
-
_:
|
|
618
|
-
a:
|
|
619
|
-
b:
|
|
620
|
-
c:
|
|
621
|
-
d:
|
|
622
|
-
e:
|
|
623
|
-
f:
|
|
624
|
-
g:
|
|
625
|
-
h:
|
|
626
|
-
i:
|
|
627
|
-
j:
|
|
628
|
-
k:
|
|
629
|
-
l:
|
|
630
|
-
m:
|
|
631
|
-
n:
|
|
632
|
-
o:
|
|
633
|
-
p:
|
|
634
|
-
q:
|
|
635
|
-
r:
|
|
636
|
-
s:
|
|
637
|
-
t:
|
|
638
|
-
u:
|
|
639
|
-
v:
|
|
640
|
-
w:
|
|
641
|
-
x:
|
|
642
|
-
y:
|
|
643
|
-
z:
|
|
644
|
-
|
|
580
|
+
'-': '=',
|
|
581
|
+
'0': 'A',
|
|
582
|
+
'1': 'B',
|
|
583
|
+
'2': 'C',
|
|
584
|
+
'3': 'D',
|
|
585
|
+
'4': 'E',
|
|
586
|
+
'5': 'F',
|
|
587
|
+
'6': 'G',
|
|
588
|
+
'7': 'H',
|
|
589
|
+
'8': 'I',
|
|
590
|
+
'9': 'J',
|
|
591
|
+
A: 'K',
|
|
592
|
+
B: 'L',
|
|
593
|
+
C: 'M',
|
|
594
|
+
D: 'N',
|
|
595
|
+
E: 'O',
|
|
596
|
+
F: 'P',
|
|
597
|
+
G: 'Q',
|
|
598
|
+
H: 'R',
|
|
599
|
+
I: 'S',
|
|
600
|
+
J: 'T',
|
|
601
|
+
K: 'U',
|
|
602
|
+
L: 'V',
|
|
603
|
+
M: 'W',
|
|
604
|
+
N: 'X',
|
|
605
|
+
O: 'Y',
|
|
606
|
+
P: 'Z',
|
|
607
|
+
Q: 'a',
|
|
608
|
+
R: 'b',
|
|
609
|
+
S: 'c',
|
|
610
|
+
T: 'd',
|
|
611
|
+
U: 'e',
|
|
612
|
+
V: 'f',
|
|
613
|
+
W: 'g',
|
|
614
|
+
X: 'h',
|
|
615
|
+
Y: 'i',
|
|
616
|
+
Z: 'j',
|
|
617
|
+
_: 'k',
|
|
618
|
+
a: 'l',
|
|
619
|
+
b: 'm',
|
|
620
|
+
c: 'n',
|
|
621
|
+
d: 'o',
|
|
622
|
+
e: 'p',
|
|
623
|
+
f: 'q',
|
|
624
|
+
g: 'r',
|
|
625
|
+
h: 's',
|
|
626
|
+
i: 't',
|
|
627
|
+
j: 'u',
|
|
628
|
+
k: 'v',
|
|
629
|
+
l: 'w',
|
|
630
|
+
m: 'x',
|
|
631
|
+
n: 'y',
|
|
632
|
+
o: 'z',
|
|
633
|
+
p: '0',
|
|
634
|
+
q: '1',
|
|
635
|
+
r: '2',
|
|
636
|
+
s: '3',
|
|
637
|
+
t: '4',
|
|
638
|
+
u: '5',
|
|
639
|
+
v: '6',
|
|
640
|
+
w: '7',
|
|
641
|
+
x: '8',
|
|
642
|
+
y: '9',
|
|
643
|
+
z: '+',
|
|
644
|
+
'|': '/',
|
|
645
645
|
};
|
|
646
646
|
const ENCODE_TABLE = {};
|
|
647
647
|
for (const c of Object.keys(DECODE_TABLE)) {
|
|
@@ -651,7 +651,7 @@
|
|
|
651
651
|
const arrayBufferTypeDef = {
|
|
652
652
|
ArrayBuffer: {
|
|
653
653
|
replace: (ab) => ({
|
|
654
|
-
$t:
|
|
654
|
+
$t: 'ArrayBuffer',
|
|
655
655
|
v: b64LexEncode(ab),
|
|
656
656
|
}),
|
|
657
657
|
revive: ({ v }) => {
|
|
@@ -674,9 +674,9 @@
|
|
|
674
674
|
|
|
675
675
|
const blobTypeDef = {
|
|
676
676
|
Blob: {
|
|
677
|
-
test: (blob, toStringTag) => toStringTag ===
|
|
677
|
+
test: (blob, toStringTag) => toStringTag === 'Blob' || blob instanceof FakeBlob,
|
|
678
678
|
replace: (blob) => ({
|
|
679
|
-
$t:
|
|
679
|
+
$t: 'Blob',
|
|
680
680
|
v: blob instanceof FakeBlob
|
|
681
681
|
? b64encode(blob.buf)
|
|
682
682
|
: b64encode(string2ArrayBuffer(readBlobSync(blob))),
|
|
@@ -687,7 +687,7 @@
|
|
|
687
687
|
const buf = ab.buffer.byteLength === ab.byteLength
|
|
688
688
|
? ab.buffer
|
|
689
689
|
: ab.buffer.slice(ab.byteOffset, ab.byteOffset + ab.byteLength);
|
|
690
|
-
return typeof Blob !==
|
|
690
|
+
return typeof Blob !== 'undefined'
|
|
691
691
|
? new Blob([new Uint8Array(buf)], { type })
|
|
692
692
|
: new FakeBlob(buf, type);
|
|
693
693
|
},
|
|
@@ -706,15 +706,15 @@
|
|
|
706
706
|
|
|
707
707
|
const fileTypeDef = {
|
|
708
708
|
File: {
|
|
709
|
-
test: (file, toStringTag) => toStringTag ===
|
|
709
|
+
test: (file, toStringTag) => toStringTag === 'File',
|
|
710
710
|
replace: (file) => ({
|
|
711
|
-
$t:
|
|
711
|
+
$t: 'File',
|
|
712
712
|
v: b64encode(string2ArrayBuffer(readBlobSync(file))),
|
|
713
713
|
type: file.type,
|
|
714
714
|
name: file.name,
|
|
715
715
|
lastModified: new Date(file.lastModified).toISOString(),
|
|
716
716
|
}),
|
|
717
|
-
revive: ({ type, v, name, lastModified }) => {
|
|
717
|
+
revive: ({ type, v, name, lastModified, }) => {
|
|
718
718
|
const ab = b64decode(v);
|
|
719
719
|
const buf = ab.buffer.byteLength === ab.byteLength
|
|
720
720
|
? ab.buffer
|
|
@@ -738,13 +738,13 @@
|
|
|
738
738
|
const undefinedTypeDef = {
|
|
739
739
|
undefined: {
|
|
740
740
|
replace: () => ({
|
|
741
|
-
$t:
|
|
741
|
+
$t: 'undefined',
|
|
742
742
|
}),
|
|
743
743
|
revive: () => undefined,
|
|
744
744
|
},
|
|
745
745
|
};
|
|
746
746
|
|
|
747
|
-
const getRandomValues$1 = typeof crypto !==
|
|
747
|
+
const getRandomValues$1 = typeof crypto !== 'undefined'
|
|
748
748
|
? crypto.getRandomValues.bind(crypto)
|
|
749
749
|
: (buf) => {
|
|
750
750
|
for (let i = 0; i < buf.length; ++i) {
|
|
@@ -845,7 +845,7 @@
|
|
|
845
845
|
var innerObj = obj[currentKeyPath];
|
|
846
846
|
//@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.
|
|
847
847
|
if (!innerObj || !hasOwn(obj, currentKeyPath))
|
|
848
|
-
innerObj =
|
|
848
|
+
innerObj = obj[currentKeyPath] = {};
|
|
849
849
|
setByKeyPath(innerObj, remainingKeyPath, value);
|
|
850
850
|
}
|
|
851
851
|
}
|
|
@@ -864,17 +864,23 @@
|
|
|
864
864
|
}
|
|
865
865
|
}
|
|
866
866
|
}
|
|
867
|
-
const randomString$1 = typeof self !== 'undefined' && typeof crypto !== 'undefined'
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
867
|
+
const randomString$1 = typeof self !== 'undefined' && typeof crypto !== 'undefined'
|
|
868
|
+
? (bytes, randomFill = crypto.getRandomValues.bind(crypto)) => {
|
|
869
|
+
// Web
|
|
870
|
+
const buf = new Uint8Array(bytes);
|
|
871
|
+
randomFill(buf);
|
|
872
|
+
return self.btoa(String.fromCharCode.apply(null, buf));
|
|
873
|
+
}
|
|
874
|
+
: typeof Buffer !== 'undefined'
|
|
875
|
+
? (bytes, randomFill = simpleRandomFill) => {
|
|
876
|
+
// Node
|
|
877
|
+
const buf = Buffer.alloc(bytes);
|
|
878
|
+
randomFill(buf);
|
|
879
|
+
return buf.toString('base64');
|
|
880
|
+
}
|
|
881
|
+
: () => {
|
|
882
|
+
throw new Error('No implementation of randomString was found');
|
|
883
|
+
};
|
|
878
884
|
function simpleRandomFill(buf) {
|
|
879
885
|
for (let i = 0; i < buf.length; ++i) {
|
|
880
886
|
buf[i] = Math.floor(Math.random() * 256);
|
|
@@ -893,11 +899,13 @@
|
|
|
893
899
|
* @returns
|
|
894
900
|
*/
|
|
895
901
|
function isValidSyncableID(id) {
|
|
896
|
-
if (typeof id ===
|
|
902
|
+
if (typeof id === 'string')
|
|
897
903
|
return true;
|
|
898
904
|
//if (validIDTypes[toStringTag(id)]) return true;
|
|
899
905
|
//if (Array.isArray(id)) return id.every((part) => isValidSyncableID(part));
|
|
900
|
-
if (Array.isArray(id) &&
|
|
906
|
+
if (Array.isArray(id) &&
|
|
907
|
+
id.some((key) => isValidSyncableID(key)) &&
|
|
908
|
+
id.every(isValidSyncableIDPart))
|
|
901
909
|
return true;
|
|
902
910
|
return false;
|
|
903
911
|
}
|
|
@@ -906,53 +914,53 @@
|
|
|
906
914
|
* For example, ArrayBuffer cannot be used (gives "object ArrayBuffer") but Uint8Array can be
|
|
907
915
|
* used (gives comma-delimited list of included bytes).
|
|
908
916
|
* 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.
|
|
909
|
-
|
|
917
|
+
*/
|
|
910
918
|
function isValidSyncableIDPart(part) {
|
|
911
|
-
return typeof part ===
|
|
919
|
+
return (typeof part === 'string' ||
|
|
920
|
+
typeof part === 'number' ||
|
|
921
|
+
(Array.isArray(part) && part.every(isValidSyncableIDPart)));
|
|
912
922
|
}
|
|
913
923
|
function isValidAtID(id, idPrefix) {
|
|
914
|
-
return !idPrefix || (typeof id ===
|
|
924
|
+
return !idPrefix || (typeof id === 'string' && id.startsWith(idPrefix));
|
|
915
925
|
}
|
|
916
926
|
|
|
917
927
|
function applyOperation(target, table, op) {
|
|
918
928
|
const tbl = target[table] || (target[table] = {});
|
|
919
|
-
const keys = op.keys.map(key => typeof key === 'string' ? key : JSON.stringify(key));
|
|
929
|
+
const keys = op.keys.map((key) => typeof key === 'string' ? key : JSON.stringify(key));
|
|
920
930
|
switch (op.type) {
|
|
921
|
-
case
|
|
931
|
+
case 'insert':
|
|
922
932
|
// TODO: Don't treat insert and upsert the same?
|
|
923
|
-
case
|
|
933
|
+
case 'upsert':
|
|
924
934
|
keys.forEach((key, idx) => {
|
|
925
935
|
tbl[key] = {
|
|
926
|
-
type:
|
|
936
|
+
type: 'ups',
|
|
927
937
|
val: op.values[idx],
|
|
928
938
|
};
|
|
929
939
|
});
|
|
930
940
|
break;
|
|
931
|
-
case
|
|
932
|
-
case
|
|
941
|
+
case 'update':
|
|
942
|
+
case 'modify': {
|
|
933
943
|
keys.forEach((key, idx) => {
|
|
934
|
-
const changeSpec = op.type ===
|
|
935
|
-
? op.changeSpecs[idx]
|
|
936
|
-
: op.changeSpec;
|
|
944
|
+
const changeSpec = op.type === 'update' ? op.changeSpecs[idx] : op.changeSpec;
|
|
937
945
|
const entry = tbl[key];
|
|
938
946
|
if (!entry) {
|
|
939
947
|
tbl[key] = {
|
|
940
|
-
type:
|
|
948
|
+
type: 'upd',
|
|
941
949
|
mod: changeSpec,
|
|
942
950
|
};
|
|
943
951
|
}
|
|
944
952
|
else {
|
|
945
953
|
switch (entry.type) {
|
|
946
|
-
case
|
|
954
|
+
case 'ups':
|
|
947
955
|
// Adjust the existing upsert with additional updates
|
|
948
956
|
for (const [propPath, value] of Object.entries(changeSpec)) {
|
|
949
957
|
setByKeyPath(entry.val, propPath, value);
|
|
950
958
|
}
|
|
951
959
|
break;
|
|
952
|
-
case
|
|
960
|
+
case 'del':
|
|
953
961
|
// No action.
|
|
954
962
|
break;
|
|
955
|
-
case
|
|
963
|
+
case 'upd':
|
|
956
964
|
// Adjust existing update with additional updates
|
|
957
965
|
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)
|
|
958
966
|
break;
|
|
@@ -961,10 +969,10 @@
|
|
|
961
969
|
});
|
|
962
970
|
break;
|
|
963
971
|
}
|
|
964
|
-
case
|
|
972
|
+
case 'delete':
|
|
965
973
|
keys.forEach((key) => {
|
|
966
974
|
tbl[key] = {
|
|
967
|
-
type:
|
|
975
|
+
type: 'del',
|
|
968
976
|
};
|
|
969
977
|
});
|
|
970
978
|
break;
|
|
@@ -1061,30 +1069,30 @@
|
|
|
1061
1069
|
};
|
|
1062
1070
|
for (const [optype, muts] of Object.entries(ops)) {
|
|
1063
1071
|
switch (optype) {
|
|
1064
|
-
case
|
|
1072
|
+
case 'ups': {
|
|
1065
1073
|
const op = {
|
|
1066
|
-
type:
|
|
1067
|
-
keys: muts.map(mut => mut.key),
|
|
1068
|
-
values: muts.map(mut => mut.val),
|
|
1069
|
-
txid
|
|
1074
|
+
type: 'upsert',
|
|
1075
|
+
keys: muts.map((mut) => mut.key),
|
|
1076
|
+
values: muts.map((mut) => mut.val),
|
|
1077
|
+
txid,
|
|
1070
1078
|
};
|
|
1071
1079
|
resultEntry.muts.push(op);
|
|
1072
1080
|
break;
|
|
1073
1081
|
}
|
|
1074
|
-
case
|
|
1082
|
+
case 'upd': {
|
|
1075
1083
|
const op = {
|
|
1076
|
-
type:
|
|
1077
|
-
keys: muts.map(mut => mut.key),
|
|
1078
|
-
changeSpecs: muts.map(mut => mut.mod),
|
|
1079
|
-
txid
|
|
1084
|
+
type: 'update',
|
|
1085
|
+
keys: muts.map((mut) => mut.key),
|
|
1086
|
+
changeSpecs: muts.map((mut) => mut.mod),
|
|
1087
|
+
txid,
|
|
1080
1088
|
};
|
|
1081
1089
|
resultEntry.muts.push(op);
|
|
1082
1090
|
break;
|
|
1083
1091
|
}
|
|
1084
|
-
case
|
|
1092
|
+
case 'del': {
|
|
1085
1093
|
const op = {
|
|
1086
|
-
type:
|
|
1087
|
-
keys: muts.map(mut => mut.key),
|
|
1094
|
+
type: 'delete',
|
|
1095
|
+
keys: muts.map((mut) => mut.key),
|
|
1088
1096
|
txid,
|
|
1089
1097
|
};
|
|
1090
1098
|
resultEntry.muts.push(op);
|
|
@@ -1099,7 +1107,7 @@
|
|
|
1099
1107
|
|
|
1100
1108
|
function getDbNameFromDbUrl(dbUrl) {
|
|
1101
1109
|
const url = new URL(dbUrl);
|
|
1102
|
-
return url.pathname ===
|
|
1110
|
+
return url.pathname === '/'
|
|
1103
1111
|
? url.hostname.split('.')[0]
|
|
1104
1112
|
: url.pathname.split('/')[1];
|
|
1105
1113
|
}
|
|
@@ -2520,7 +2528,8 @@
|
|
|
2520
2528
|
prop,
|
|
2521
2529
|
k,
|
|
2522
2530
|
u: readVarUint8Array(decoder),
|
|
2523
|
-
r: (decoder.pos < decoder.arr.length && readVarString(decoder)) ||
|
|
2531
|
+
r: (decoder.pos < decoder.arr.length && readVarString(decoder)) ||
|
|
2532
|
+
undefined,
|
|
2524
2533
|
};
|
|
2525
2534
|
default:
|
|
2526
2535
|
throw new TypeError(`Unknown message type: ${type}`);
|
|
@@ -2537,7 +2546,8 @@
|
|
|
2537
2546
|
}
|
|
2538
2547
|
// Start running the machine. If the last stage is a sink, it will consume the data and never emit anything
|
|
2539
2548
|
// to us here...
|
|
2540
|
-
for await (const chunk of result) {
|
|
2549
|
+
for await (const chunk of result) {
|
|
2550
|
+
}
|
|
2541
2551
|
}
|
|
2542
2552
|
|
|
2543
2553
|
async function* consumeChunkedBinaryStream(source) {
|
|
@@ -2591,7 +2601,7 @@
|
|
|
2591
2601
|
}
|
|
2592
2602
|
if (pos + len > chunk.byteLength) {
|
|
2593
2603
|
bufs.push(chunk.slice(pos));
|
|
2594
|
-
len -=
|
|
2604
|
+
len -= chunk.byteLength - pos;
|
|
2595
2605
|
state = 2;
|
|
2596
2606
|
pos = chunk.byteLength; // will break while loop.
|
|
2597
2607
|
}
|
|
@@ -2622,7 +2632,7 @@
|
|
|
2622
2632
|
function getFetchResponseBodyGenerator(res) {
|
|
2623
2633
|
return async function* () {
|
|
2624
2634
|
if (!res.body)
|
|
2625
|
-
throw new Error(
|
|
2635
|
+
throw new Error('Response body is not readable');
|
|
2626
2636
|
const reader = res.body.getReader();
|
|
2627
2637
|
try {
|
|
2628
2638
|
while (true) {
|
|
@@ -2691,11 +2701,11 @@
|
|
|
2691
2701
|
return false;
|
|
2692
2702
|
}
|
|
2693
2703
|
if (Array.isArray(obj)) {
|
|
2694
|
-
return obj.some(item => hasBlobRefs(item, visited));
|
|
2704
|
+
return obj.some((item) => hasBlobRefs(item, visited));
|
|
2695
2705
|
}
|
|
2696
2706
|
// Only traverse POJOs
|
|
2697
2707
|
if (obj.constructor === Object) {
|
|
2698
|
-
return Object.values(obj).some(value => hasBlobRefs(value, visited));
|
|
2708
|
+
return Object.values(obj).some((value) => hasBlobRefs(value, visited));
|
|
2699
2709
|
}
|
|
2700
2710
|
return false;
|
|
2701
2711
|
}
|
|
@@ -2759,7 +2769,8 @@
|
|
|
2759
2769
|
*/
|
|
2760
2770
|
function resolveAllBlobRefs(obj_1, dbUrl_1) {
|
|
2761
2771
|
return __awaiter(this, arguments, void 0, function* (obj, dbUrl, resolvedBlobs = [], currentPath = '', visited = new WeakMap(), tracker) {
|
|
2762
|
-
if (obj == null) {
|
|
2772
|
+
if (obj == null) {
|
|
2773
|
+
// null or undefined
|
|
2763
2774
|
return obj;
|
|
2764
2775
|
}
|
|
2765
2776
|
// Check if this is a BlobRef - resolve it and track it
|
|
@@ -2808,9 +2819,7 @@
|
|
|
2808
2819
|
* Check if an object has unresolved BlobRefs
|
|
2809
2820
|
*/
|
|
2810
2821
|
function hasUnresolvedBlobRefs(obj) {
|
|
2811
|
-
return (typeof obj === 'object' &&
|
|
2812
|
-
obj !== null &&
|
|
2813
|
-
obj._hasBlobRefs === 1);
|
|
2822
|
+
return (typeof obj === 'object' && obj !== null && obj._hasBlobRefs === 1);
|
|
2814
2823
|
}
|
|
2815
2824
|
|
|
2816
2825
|
function getSyncableTables(db) {
|
|
@@ -2875,7 +2884,7 @@
|
|
|
2875
2884
|
isDownloading: isDownloading && stats.blobsRemaining > 0,
|
|
2876
2885
|
blobsRemaining: stats.blobsRemaining,
|
|
2877
2886
|
bytesRemaining: stats.bytesRemaining,
|
|
2878
|
-
})), operators.share({ resetOnRefCountZero: () => rxjs.timer(2000) }) // Keep alive for 2s after last unsubscription to avoid rapid re-subscriptions during UI updates
|
|
2887
|
+
})), operators.share({ resetOnRefCountZero: () => rxjs.timer(2000) }) // Keep alive for 2s after last unsubscription to avoid rapid re-subscriptions during UI updates
|
|
2879
2888
|
);
|
|
2880
2889
|
}
|
|
2881
2890
|
/**
|
|
@@ -2959,13 +2968,13 @@
|
|
|
2959
2968
|
}
|
|
2960
2969
|
setDownloadingState(downloading$, true);
|
|
2961
2970
|
try {
|
|
2962
|
-
debugLog(`Eager download: Found ${syncedTables.length} syncable tables: ${syncedTables.map(t => t.name).join(', ')}`);
|
|
2971
|
+
debugLog(`Eager download: Found ${syncedTables.length} syncable tables: ${syncedTables.map((t) => t.name).join(', ')}`);
|
|
2963
2972
|
for (const table of syncedTables) {
|
|
2964
2973
|
if (signal === null || signal === void 0 ? void 0 : signal.aborted)
|
|
2965
2974
|
;
|
|
2966
2975
|
try {
|
|
2967
2976
|
// Check if table has _hasBlobRefs index
|
|
2968
|
-
const hasIndex = table.schema.indexes.some(idx => idx.name === '_hasBlobRefs');
|
|
2977
|
+
const hasIndex = table.schema.indexes.some((idx) => idx.name === '_hasBlobRefs');
|
|
2969
2978
|
if (!hasIndex)
|
|
2970
2979
|
continue;
|
|
2971
2980
|
// Query objects with _hasBlobRefs marker
|
|
@@ -2981,7 +2990,7 @@
|
|
|
2981
2990
|
const MAX_CONCURRENT = 6;
|
|
2982
2991
|
const primaryKey = table.schema.primKey;
|
|
2983
2992
|
// Filter to actionable objects first
|
|
2984
|
-
const pending = unresolvedObjects.filter(obj => {
|
|
2993
|
+
const pending = unresolvedObjects.filter((obj) => {
|
|
2985
2994
|
if (!hasUnresolvedBlobRefs(obj))
|
|
2986
2995
|
return false;
|
|
2987
2996
|
const key = primaryKey.keyPath
|
|
@@ -3042,7 +3051,7 @@
|
|
|
3042
3051
|
try {
|
|
3043
3052
|
// Send sync event to SW:
|
|
3044
3053
|
const sw = yield navigator.serviceWorker.ready;
|
|
3045
|
-
if (purpose ===
|
|
3054
|
+
if (purpose === 'push' && sw.sync) {
|
|
3046
3055
|
yield sw.sync.register(`dexie-cloud:${db.name}`);
|
|
3047
3056
|
}
|
|
3048
3057
|
if (sw.active) {
|
|
@@ -3051,7 +3060,7 @@
|
|
|
3051
3060
|
sw.active.postMessage({
|
|
3052
3061
|
type: 'dexie-cloud-sync',
|
|
3053
3062
|
dbName: db.name,
|
|
3054
|
-
purpose
|
|
3063
|
+
purpose,
|
|
3055
3064
|
});
|
|
3056
3065
|
}
|
|
3057
3066
|
else {
|
|
@@ -3176,14 +3185,15 @@
|
|
|
3176
3185
|
// the domain extension like .com, .net, etc.
|
|
3177
3186
|
// (\sas\s[\w-+.]+@([\w-]+\.)+[\w-]{2,10})?$ : This part is optional (due to the ? at the end).
|
|
3178
3187
|
// If present, it matches " as " followed by another valid email address. This allows for the
|
|
3179
|
-
// input to be either a single email address or two email addresses separated by " as ".
|
|
3188
|
+
// input to be either a single email address or two email addresses separated by " as ".
|
|
3180
3189
|
//
|
|
3181
3190
|
// The use case for "<email1> as <email2>"" is for when a database owner with full access to the
|
|
3182
3191
|
// database needs to impersonate another user in the database in order to troubleshoot. This
|
|
3183
3192
|
// format will only be possible to use when email1 is the owner of an API client with GLOBAL_READ
|
|
3184
3193
|
// and GLOBAL_WRITE permissions on the database. The email will be checked on the server before
|
|
3185
3194
|
// allowing it and giving out a token for email2, using the OTP sent to email1.
|
|
3186
|
-
while (!email ||
|
|
3195
|
+
while (!email ||
|
|
3196
|
+
!/^[\w-+.]+@([\w-]+\.)+[\w-]{2,10}(\sas\s[\w-+.]+@([\w-]+\.)+[\w-]{2,10})?$/.test(email)) {
|
|
3187
3197
|
const alerts = [];
|
|
3188
3198
|
if (firstPrompt && initialAlert)
|
|
3189
3199
|
alerts.push(initialAlert);
|
|
@@ -3249,7 +3259,7 @@
|
|
|
3249
3259
|
messageParams: {
|
|
3250
3260
|
currentUserId,
|
|
3251
3261
|
numUnsyncedChanges: numUnsyncedChanges.toString(),
|
|
3252
|
-
}
|
|
3262
|
+
},
|
|
3253
3263
|
},
|
|
3254
3264
|
];
|
|
3255
3265
|
return yield interactWithUser(userInteraction, {
|
|
@@ -3258,7 +3268,7 @@
|
|
|
3258
3268
|
alerts,
|
|
3259
3269
|
fields: {},
|
|
3260
3270
|
submitLabel: 'Confirm logout',
|
|
3261
|
-
cancelLabel: 'Cancel'
|
|
3271
|
+
cancelLabel: 'Cancel',
|
|
3262
3272
|
})
|
|
3263
3273
|
.then(() => true)
|
|
3264
3274
|
.catch(() => false);
|
|
@@ -3375,7 +3385,8 @@
|
|
|
3375
3385
|
if (!accessToken)
|
|
3376
3386
|
return null;
|
|
3377
3387
|
const expTime = (_a = accessTokenExpiration === null || accessTokenExpiration === void 0 ? void 0 : accessTokenExpiration.getTime()) !== null && _a !== void 0 ? _a : Infinity;
|
|
3378
|
-
if (expTime >
|
|
3388
|
+
if (expTime > Date.now() + 5 * MINUTES &&
|
|
3389
|
+
(((_b = currentUser.license) === null || _b === void 0 ? void 0 : _b.status) || 'ok') === 'ok') {
|
|
3379
3390
|
return currentUser;
|
|
3380
3391
|
}
|
|
3381
3392
|
if (!refreshToken) {
|
|
@@ -3535,11 +3546,13 @@
|
|
|
3535
3546
|
}
|
|
3536
3547
|
catch (error) {
|
|
3537
3548
|
// OAuth redirect is not an error - page is navigating away
|
|
3538
|
-
if (error instanceof OAuthRedirectError ||
|
|
3549
|
+
if (error instanceof OAuthRedirectError ||
|
|
3550
|
+
(error === null || error === void 0 ? void 0 : error.name) === 'OAuthRedirectError') {
|
|
3539
3551
|
throw error; // Re-throw without logging
|
|
3540
3552
|
}
|
|
3541
3553
|
// Policy rejections have already been shown to the user as a challenge
|
|
3542
|
-
if (error instanceof PolicyRejectionError ||
|
|
3554
|
+
if (error instanceof PolicyRejectionError ||
|
|
3555
|
+
(error === null || error === void 0 ? void 0 : error.name) === 'PolicyRejectionError') {
|
|
3543
3556
|
throw error;
|
|
3544
3557
|
}
|
|
3545
3558
|
if (error instanceof TokenErrorResponseError) {
|
|
@@ -3558,7 +3571,10 @@
|
|
|
3558
3571
|
if (isOffline) {
|
|
3559
3572
|
message = `You seem to be offline. Please connect to the internet and try again.`;
|
|
3560
3573
|
}
|
|
3561
|
-
else if (typeof location !== 'undefined' &&
|
|
3574
|
+
else if (typeof location !== 'undefined' &&
|
|
3575
|
+
(Dexie.debug ||
|
|
3576
|
+
location.hostname === 'localhost' ||
|
|
3577
|
+
location.hostname === '127.0.0.1')) {
|
|
3562
3578
|
// The audience is most likely the developer. Suggest to whitelist the localhost origin:
|
|
3563
3579
|
const whitelistCommand = `npx dexie-cloud whitelist ${location.origin}`;
|
|
3564
3580
|
message = `Could not connect to server. Please verify that your origin '${location.origin}' is whitelisted using \`npx dexie-cloud whitelist\``;
|
|
@@ -3608,31 +3624,31 @@
|
|
|
3608
3624
|
}
|
|
3609
3625
|
static load(db, userId) {
|
|
3610
3626
|
return db
|
|
3611
|
-
.table(
|
|
3627
|
+
.table('$logins')
|
|
3612
3628
|
.get(userId)
|
|
3613
3629
|
.then((userLogin) => new AuthPersistedContext(db, userLogin || {
|
|
3614
3630
|
userId,
|
|
3615
3631
|
claims: {
|
|
3616
|
-
sub: userId
|
|
3632
|
+
sub: userId,
|
|
3617
3633
|
},
|
|
3618
|
-
lastLogin: new Date(0)
|
|
3634
|
+
lastLogin: new Date(0),
|
|
3619
3635
|
}));
|
|
3620
3636
|
}
|
|
3621
3637
|
save() {
|
|
3622
3638
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3623
3639
|
const db = wm$4.get(this);
|
|
3624
|
-
db.table(
|
|
3640
|
+
db.table('$logins').put(this);
|
|
3625
3641
|
});
|
|
3626
3642
|
}
|
|
3627
3643
|
}
|
|
3628
3644
|
|
|
3629
3645
|
const UNAUTHORIZED_USER = {
|
|
3630
|
-
userId:
|
|
3631
|
-
name:
|
|
3646
|
+
userId: 'unauthorized',
|
|
3647
|
+
name: 'Unauthorized',
|
|
3632
3648
|
claims: {
|
|
3633
|
-
sub:
|
|
3649
|
+
sub: 'unauthorized',
|
|
3634
3650
|
},
|
|
3635
|
-
lastLogin: new Date(0)
|
|
3651
|
+
lastLogin: new Date(0),
|
|
3636
3652
|
};
|
|
3637
3653
|
try {
|
|
3638
3654
|
Object.freeze(UNAUTHORIZED_USER);
|
|
@@ -3701,7 +3717,7 @@
|
|
|
3701
3717
|
this.httpStatus = res.status;
|
|
3702
3718
|
}
|
|
3703
3719
|
get name() {
|
|
3704
|
-
return
|
|
3720
|
+
return 'HttpError';
|
|
3705
3721
|
}
|
|
3706
3722
|
}
|
|
3707
3723
|
|
|
@@ -3740,7 +3756,7 @@
|
|
|
3740
3756
|
*/
|
|
3741
3757
|
function exchangeOAuthCode(options) {
|
|
3742
3758
|
return __awaiter(this, void 0, void 0, function* () {
|
|
3743
|
-
const { databaseUrl, code, publicKey, scopes = ['ACCESS_DB'], intent } = options;
|
|
3759
|
+
const { databaseUrl, code, publicKey, scopes = ['ACCESS_DB'], intent, } = options;
|
|
3744
3760
|
const tokenRequest = Object.assign({ grant_type: 'authorization_code', code, public_key: publicKey, scopes }, (intent !== undefined ? { intent } : {}));
|
|
3745
3761
|
try {
|
|
3746
3762
|
const res = yield fetch(`${databaseUrl}/token`, {
|
|
@@ -3798,7 +3814,8 @@
|
|
|
3798
3814
|
return response;
|
|
3799
3815
|
}
|
|
3800
3816
|
catch (error) {
|
|
3801
|
-
if (error instanceof OAuthError ||
|
|
3817
|
+
if (error instanceof OAuthError ||
|
|
3818
|
+
error instanceof TokenErrorResponseError) {
|
|
3802
3819
|
throw error;
|
|
3803
3820
|
}
|
|
3804
3821
|
if (error instanceof TypeError) {
|
|
@@ -3836,7 +3853,7 @@
|
|
|
3836
3853
|
try {
|
|
3837
3854
|
const res = yield fetch(`${databaseUrl}/auth-providers`, {
|
|
3838
3855
|
method: 'GET',
|
|
3839
|
-
headers: {
|
|
3856
|
+
headers: { Accept: 'application/json' },
|
|
3840
3857
|
mode: 'cors',
|
|
3841
3858
|
});
|
|
3842
3859
|
if (res.status === 404) {
|
|
@@ -4166,7 +4183,7 @@
|
|
|
4166
4183
|
* @param args
|
|
4167
4184
|
*/
|
|
4168
4185
|
function prodLog(level, ...args) {
|
|
4169
|
-
globalThis[
|
|
4186
|
+
globalThis['con' + 'sole'][level](...args);
|
|
4170
4187
|
}
|
|
4171
4188
|
|
|
4172
4189
|
/** This function changes or sets the current user as requested.
|
|
@@ -4278,8 +4295,10 @@
|
|
|
4278
4295
|
}
|
|
4279
4296
|
|
|
4280
4297
|
const swHolder = {};
|
|
4281
|
-
const swContainer = typeof self !== 'undefined' &&
|
|
4282
|
-
|
|
4298
|
+
const swContainer = typeof self !== 'undefined' &&
|
|
4299
|
+
self.document && // self.document is to verify we're not the SW ourself
|
|
4300
|
+
typeof navigator !== 'undefined' &&
|
|
4301
|
+
navigator.serviceWorker;
|
|
4283
4302
|
if (swContainer)
|
|
4284
4303
|
swContainer.ready.then((registration) => (swHolder.registration = registration));
|
|
4285
4304
|
if (typeof self !== 'undefined' && 'clients' in self && !self.document) {
|
|
@@ -4333,7 +4352,8 @@
|
|
|
4333
4352
|
}
|
|
4334
4353
|
}
|
|
4335
4354
|
|
|
4336
|
-
const events = globalThis['lbc-events'] ||
|
|
4355
|
+
const events = globalThis['lbc-events'] ||
|
|
4356
|
+
(globalThis['lbc-events'] = new Map());
|
|
4337
4357
|
function addListener(name, listener) {
|
|
4338
4358
|
if (events.has(name)) {
|
|
4339
4359
|
events.get(name).push(listener);
|
|
@@ -4354,25 +4374,25 @@
|
|
|
4354
4374
|
function dispatch(ev) {
|
|
4355
4375
|
const listeners = events.get(ev.type);
|
|
4356
4376
|
if (listeners) {
|
|
4357
|
-
listeners.forEach(listener => {
|
|
4377
|
+
listeners.forEach((listener) => {
|
|
4358
4378
|
try {
|
|
4359
4379
|
listener(ev);
|
|
4360
4380
|
}
|
|
4361
|
-
catch (_a) {
|
|
4362
|
-
}
|
|
4381
|
+
catch (_a) { }
|
|
4363
4382
|
});
|
|
4364
4383
|
}
|
|
4365
4384
|
}
|
|
4366
4385
|
class BroadcastedAndLocalEvent extends rxjs.Observable {
|
|
4367
4386
|
constructor(name) {
|
|
4368
|
-
const bc = typeof BroadcastChannel ===
|
|
4369
|
-
? new SWBroadcastChannel(name)
|
|
4370
|
-
|
|
4387
|
+
const bc = typeof BroadcastChannel === 'undefined'
|
|
4388
|
+
? new SWBroadcastChannel(name)
|
|
4389
|
+
: new BroadcastChannel(name);
|
|
4390
|
+
super((subscriber) => {
|
|
4371
4391
|
function onCustomEvent(ev) {
|
|
4372
4392
|
subscriber.next(ev.detail);
|
|
4373
4393
|
}
|
|
4374
4394
|
function onMessageEvent(ev) {
|
|
4375
|
-
console.debug(
|
|
4395
|
+
console.debug('BroadcastedAndLocalEvent: onMessageEvent', ev);
|
|
4376
4396
|
subscriber.next(ev.data);
|
|
4377
4397
|
}
|
|
4378
4398
|
let unsubscribe;
|
|
@@ -4380,11 +4400,11 @@
|
|
|
4380
4400
|
addListener(`lbc-${name}`, onCustomEvent); // Works better in service worker
|
|
4381
4401
|
try {
|
|
4382
4402
|
if (bc instanceof SWBroadcastChannel) {
|
|
4383
|
-
unsubscribe = bc.subscribe(message => subscriber.next(message));
|
|
4403
|
+
unsubscribe = bc.subscribe((message) => subscriber.next(message));
|
|
4384
4404
|
}
|
|
4385
4405
|
else {
|
|
4386
|
-
console.debug(
|
|
4387
|
-
bc.addEventListener(
|
|
4406
|
+
console.debug('BroadcastedAndLocalEvent: bc.addEventListener()', name, 'bc is a', bc);
|
|
4407
|
+
bc.addEventListener('message', onMessageEvent);
|
|
4388
4408
|
}
|
|
4389
4409
|
}
|
|
4390
4410
|
catch (err) {
|
|
@@ -4398,7 +4418,7 @@
|
|
|
4398
4418
|
unsubscribe();
|
|
4399
4419
|
}
|
|
4400
4420
|
else {
|
|
4401
|
-
bc.removeEventListener(
|
|
4421
|
+
bc.removeEventListener('message', onMessageEvent);
|
|
4402
4422
|
}
|
|
4403
4423
|
};
|
|
4404
4424
|
});
|
|
@@ -4406,7 +4426,7 @@
|
|
|
4406
4426
|
this.bc = bc;
|
|
4407
4427
|
}
|
|
4408
4428
|
next(message) {
|
|
4409
|
-
console.debug(
|
|
4429
|
+
console.debug('BroadcastedAndLocalEvent: bc.postMessage()', Object.assign({}, message), 'bc is a', this.bc);
|
|
4410
4430
|
this.bc.postMessage(message);
|
|
4411
4431
|
const ev = new CustomEvent(`lbc-${this.name}`, { detail: message });
|
|
4412
4432
|
//self.dispatchEvent(ev);
|
|
@@ -4499,7 +4519,7 @@
|
|
|
4499
4519
|
}
|
|
4500
4520
|
const strKey = '' + mut.keys[0];
|
|
4501
4521
|
const changeSpecs = mut.changeSpecs[0];
|
|
4502
|
-
if (Object.values(changeSpecs).some(v => typeof v ===
|
|
4522
|
+
if (Object.values(changeSpecs).some((v) => typeof v === 'object' && v && '@@propmod' in v)) {
|
|
4503
4523
|
continue; // Cannot optimize if any PropModification is present
|
|
4504
4524
|
}
|
|
4505
4525
|
let keyCoverage = updateCoverage.get(strKey);
|
|
@@ -4507,11 +4527,13 @@
|
|
|
4507
4527
|
keyCoverage.push({ txid: mut.txid, updateSpec: changeSpecs });
|
|
4508
4528
|
}
|
|
4509
4529
|
else {
|
|
4510
|
-
updateCoverage.set(strKey, [
|
|
4530
|
+
updateCoverage.set(strKey, [
|
|
4531
|
+
{ txid: mut.txid, updateSpec: changeSpecs },
|
|
4532
|
+
]);
|
|
4511
4533
|
}
|
|
4512
4534
|
}
|
|
4513
4535
|
}
|
|
4514
|
-
muts = muts.filter(mut => {
|
|
4536
|
+
muts = muts.filter((mut) => {
|
|
4515
4537
|
// Only apply optimization to update mutations that are single-key
|
|
4516
4538
|
if (mut.type !== 'update')
|
|
4517
4539
|
return true;
|
|
@@ -4519,7 +4541,7 @@
|
|
|
4519
4541
|
return true;
|
|
4520
4542
|
// Check if this has PropModifications - if so, skip optimization
|
|
4521
4543
|
const changeSpecs = mut.changeSpecs[0];
|
|
4522
|
-
if (Object.values(changeSpecs).some(v => typeof v ===
|
|
4544
|
+
if (Object.values(changeSpecs).some((v) => typeof v === 'object' && v && '@@propmod' in v)) {
|
|
4523
4545
|
return true; // Cannot optimize if any PropModification is present
|
|
4524
4546
|
}
|
|
4525
4547
|
// Keep track of properties that aren't overlapped by later transactions
|
|
@@ -4547,7 +4569,7 @@
|
|
|
4547
4569
|
return muts;
|
|
4548
4570
|
}
|
|
4549
4571
|
function canonicalizeToUpdateOps(muts) {
|
|
4550
|
-
muts = muts.map(mut => {
|
|
4572
|
+
muts = muts.map((mut) => {
|
|
4551
4573
|
if (mut.type === 'modify' && mut.criteria.index === null) {
|
|
4552
4574
|
// The criteria is on primary key. Convert to an update operation instead.
|
|
4553
4575
|
// It is simpler for the server to handle and also more efficient.
|
|
@@ -4769,7 +4791,7 @@
|
|
|
4769
4791
|
const delatMilliseconds = ((_b = (_a = syncRatelimitDelays.get(db)) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0) - Date.now();
|
|
4770
4792
|
if (delatMilliseconds > 0) {
|
|
4771
4793
|
console.debug(`Stalling sync request ${delatMilliseconds} ms to spare ratelimits`);
|
|
4772
|
-
yield new Promise(resolve => setTimeout(resolve, delatMilliseconds));
|
|
4794
|
+
yield new Promise((resolve) => setTimeout(resolve, delatMilliseconds));
|
|
4773
4795
|
}
|
|
4774
4796
|
});
|
|
4775
4797
|
}
|
|
@@ -4834,7 +4856,7 @@
|
|
|
4834
4856
|
baseRevs,
|
|
4835
4857
|
changes: encodeIdsForServer(db.dx.core.schema, currentUser, changes),
|
|
4836
4858
|
y,
|
|
4837
|
-
dxcv: db.cloud.version
|
|
4859
|
+
dxcv: db.cloud.version,
|
|
4838
4860
|
};
|
|
4839
4861
|
console.debug('Sync request', syncRequest);
|
|
4840
4862
|
db.syncStateChangedEvent.next({
|
|
@@ -4874,19 +4896,22 @@
|
|
|
4874
4896
|
return __awaiter(this, void 0, void 0, function* () {
|
|
4875
4897
|
const ignoredRealms = new Set(alreadySyncedRealms || []);
|
|
4876
4898
|
for (const table of syncifiedTables) {
|
|
4877
|
-
if (table.name ===
|
|
4899
|
+
if (table.name === 'members') {
|
|
4878
4900
|
// members
|
|
4879
4901
|
yield table.toCollection().modify((member) => {
|
|
4880
|
-
if (!ignoredRealms.has(member.realmId) &&
|
|
4902
|
+
if (!ignoredRealms.has(member.realmId) &&
|
|
4903
|
+
(!member.userId || member.userId === UNAUTHORIZED_USER.userId)) {
|
|
4881
4904
|
member.userId = currentUser.userId;
|
|
4882
4905
|
}
|
|
4883
4906
|
});
|
|
4884
4907
|
}
|
|
4885
|
-
else if (table.name ===
|
|
4886
|
-
else if (table.name ===
|
|
4908
|
+
else if (table.name === 'roles') ;
|
|
4909
|
+
else if (table.name === 'realms') {
|
|
4887
4910
|
// realms
|
|
4888
4911
|
yield table.toCollection().modify((realm) => {
|
|
4889
|
-
if (!ignoredRealms.has(realm.realmId) &&
|
|
4912
|
+
if (!ignoredRealms.has(realm.realmId) &&
|
|
4913
|
+
(realm.owner === undefined ||
|
|
4914
|
+
realm.owner === UNAUTHORIZED_USER.userId)) {
|
|
4890
4915
|
realm.owner = currentUser.userId;
|
|
4891
4916
|
}
|
|
4892
4917
|
});
|
|
@@ -4919,8 +4944,8 @@
|
|
|
4919
4944
|
let isOnline = false;
|
|
4920
4945
|
if (typeof self !== 'undefined' && typeof navigator !== 'undefined') {
|
|
4921
4946
|
isOnline = navigator.onLine;
|
|
4922
|
-
self.addEventListener('online', () => isOnline = true);
|
|
4923
|
-
self.addEventListener('offline', () => isOnline = false);
|
|
4947
|
+
self.addEventListener('online', () => (isOnline = true));
|
|
4948
|
+
self.addEventListener('offline', () => (isOnline = false));
|
|
4924
4949
|
}
|
|
4925
4950
|
|
|
4926
4951
|
function updateBaseRevs(db, schema, latestRevisions, serverRev) {
|
|
@@ -4937,7 +4962,10 @@
|
|
|
4937
4962
|
}));
|
|
4938
4963
|
// Clean up baseRevs for tables that do not exist anymore or are no longer marked for sync
|
|
4939
4964
|
// Resolve #2168 by also cleaning up baseRevs for tables that are not marked for sync
|
|
4940
|
-
yield db.$baseRevs
|
|
4965
|
+
yield db.$baseRevs
|
|
4966
|
+
.where('tableName')
|
|
4967
|
+
.noneOf(Object.keys(schema).filter((table) => schema[table].markedForSync))
|
|
4968
|
+
.delete();
|
|
4941
4969
|
});
|
|
4942
4970
|
}
|
|
4943
4971
|
|
|
@@ -5059,6 +5087,16 @@
|
|
|
5059
5087
|
}
|
|
5060
5088
|
break;
|
|
5061
5089
|
case 'update':
|
|
5090
|
+
if (!primaryKey.outbound && primaryKey.keyPath) {
|
|
5091
|
+
// The primary key should never be part of an updateSpec — it cannot change
|
|
5092
|
+
// and is already communicated via the operation's keys array.
|
|
5093
|
+
// For private singleton IDs (e.g. "#key:userId" on server, "#key" on client),
|
|
5094
|
+
// the encoded server-side key may leak into the changeSpec via getObjectDiff().
|
|
5095
|
+
// Strip it here unconditionally as a defensive measure.
|
|
5096
|
+
for (const changeSpec of mut.changeSpecs) {
|
|
5097
|
+
Dexie.delByKeyPath(changeSpec, primaryKey.keyPath);
|
|
5098
|
+
}
|
|
5099
|
+
}
|
|
5062
5100
|
yield bulkUpdate(table, keys, mut.changeSpecs);
|
|
5063
5101
|
break;
|
|
5064
5102
|
case 'delete':
|
|
@@ -5073,10 +5111,7 @@
|
|
|
5073
5111
|
const DEXIE_CLOUD_SYNCER_ID = 'dexie-cloud-syncer';
|
|
5074
5112
|
|
|
5075
5113
|
function listUpdatesSince(yTable, sinceIncluding) {
|
|
5076
|
-
return yTable
|
|
5077
|
-
.where('i')
|
|
5078
|
-
.between(sinceIncluding, Infinity, true)
|
|
5079
|
-
.toArray();
|
|
5114
|
+
return yTable.where('i').between(sinceIncluding, Infinity, true).toArray();
|
|
5080
5115
|
}
|
|
5081
5116
|
|
|
5082
5117
|
/**
|
|
@@ -14428,7 +14463,7 @@
|
|
|
14428
14463
|
}
|
|
14429
14464
|
return {
|
|
14430
14465
|
yMessages: result,
|
|
14431
|
-
lastUpdateIds
|
|
14466
|
+
lastUpdateIds,
|
|
14432
14467
|
};
|
|
14433
14468
|
});
|
|
14434
14469
|
}
|
|
@@ -14437,7 +14472,8 @@
|
|
|
14437
14472
|
var _a, _b, _c;
|
|
14438
14473
|
if (!db.dx._allTables[table])
|
|
14439
14474
|
return undefined;
|
|
14440
|
-
const utbl = (_c = (_b = (_a = db
|
|
14475
|
+
const utbl = (_c = (_b = (_a = db
|
|
14476
|
+
.table(table)) === null || _a === void 0 ? void 0 : _a.schema.yProps) === null || _b === void 0 ? void 0 : _b.find((p) => p.prop === ydocProp)) === null || _c === void 0 ? void 0 : _c.updatesTable;
|
|
14441
14477
|
if (!utbl) {
|
|
14442
14478
|
console.debug(`No updatesTable found for ${table}.${ydocProp}`);
|
|
14443
14479
|
return undefined;
|
|
@@ -14457,7 +14493,7 @@
|
|
|
14457
14493
|
*
|
|
14458
14494
|
* ==========================================================================
|
|
14459
14495
|
*
|
|
14460
|
-
* Version 4.4.0,
|
|
14496
|
+
* Version 4.4.0, Fri Mar 27 2026
|
|
14461
14497
|
*
|
|
14462
14498
|
* https://dexie.org
|
|
14463
14499
|
*
|
|
@@ -14474,7 +14510,7 @@
|
|
|
14474
14510
|
function getDocCache(db) {
|
|
14475
14511
|
var _a;
|
|
14476
14512
|
var _b;
|
|
14477
|
-
return (_a = (_b = db._novip)['_docCache']) !== null && _a !== void 0 ? _a : (_b['_docCache'] = {
|
|
14513
|
+
return ((_a = (_b = db._novip)['_docCache']) !== null && _a !== void 0 ? _a : (_b['_docCache'] = {
|
|
14478
14514
|
cache: {},
|
|
14479
14515
|
get size() {
|
|
14480
14516
|
return Object.keys(this.cache).length;
|
|
@@ -14505,7 +14541,7 @@
|
|
|
14505
14541
|
delete this.cache[cacheKey]; // Remove the entry from the cache only if it is the same doc.
|
|
14506
14542
|
}
|
|
14507
14543
|
},
|
|
14508
|
-
});
|
|
14544
|
+
}));
|
|
14509
14545
|
}
|
|
14510
14546
|
// Emulate a private boolean property "destroyed" on Y.Doc instances that we manage
|
|
14511
14547
|
// in createYDocProperty.ts:
|
|
@@ -14821,7 +14857,7 @@
|
|
|
14821
14857
|
}
|
|
14822
14858
|
throwIfDestroyed(doc);
|
|
14823
14859
|
this.stopObserving = observeYDocUpdates(this, doc, db, parentTable, updatesTable, parentId);
|
|
14824
|
-
DexieYProvider.on(
|
|
14860
|
+
DexieYProvider.on('new').fire(this); // Allow for addons to invoke their sync- and awareness providers here.
|
|
14825
14861
|
}
|
|
14826
14862
|
destroy() {
|
|
14827
14863
|
var _a, _b, _c;
|
|
@@ -14846,16 +14882,16 @@
|
|
|
14846
14882
|
});
|
|
14847
14883
|
DexieYProvider.getDocCache = getDocCache;
|
|
14848
14884
|
//
|
|
14849
|
-
// Eliminate dual package hazard
|
|
14885
|
+
// Eliminate dual package hazard
|
|
14850
14886
|
//
|
|
14851
14887
|
// Since we're holding static state, make sure to singletonize DexieYProvider
|
|
14852
14888
|
//
|
|
14853
|
-
if (Dexie.Dexie[
|
|
14889
|
+
if (Dexie.Dexie['DexieYProvider']) {
|
|
14854
14890
|
// @ts-ignore
|
|
14855
|
-
DexieYProvider = Dexie.Dexie[
|
|
14891
|
+
DexieYProvider = Dexie.Dexie['DexieYProvider'] || DexieYProvider;
|
|
14856
14892
|
}
|
|
14857
14893
|
else {
|
|
14858
|
-
Dexie.Dexie[
|
|
14894
|
+
Dexie.Dexie['DexieYProvider'] = DexieYProvider;
|
|
14859
14895
|
}
|
|
14860
14896
|
|
|
14861
14897
|
function applyYServerMessages(yMessages, db) {
|
|
@@ -14981,10 +15017,18 @@
|
|
|
14981
15017
|
*/
|
|
14982
15018
|
// TypedArray/DataView tags for size check
|
|
14983
15019
|
const ARRAYBUFFER_VIEW_TAGS = new Set([
|
|
14984
|
-
'Int8Array',
|
|
14985
|
-
'
|
|
14986
|
-
'
|
|
14987
|
-
'
|
|
15020
|
+
'Int8Array',
|
|
15021
|
+
'Uint8Array',
|
|
15022
|
+
'Uint8ClampedArray',
|
|
15023
|
+
'Int16Array',
|
|
15024
|
+
'Uint16Array',
|
|
15025
|
+
'Int32Array',
|
|
15026
|
+
'Uint32Array',
|
|
15027
|
+
'Float32Array',
|
|
15028
|
+
'Float64Array',
|
|
15029
|
+
'BigInt64Array',
|
|
15030
|
+
'BigUint64Array',
|
|
15031
|
+
'DataView',
|
|
14988
15032
|
]);
|
|
14989
15033
|
// Static Set for O(1) lookup of binary type tags
|
|
14990
15034
|
const BINARY_TYPE_TAGS = new Set([
|
|
@@ -15084,7 +15128,7 @@
|
|
|
15084
15128
|
const response = yield fetch(uploadUrl, {
|
|
15085
15129
|
method: 'PUT',
|
|
15086
15130
|
headers: {
|
|
15087
|
-
|
|
15131
|
+
Authorization: `Bearer ${accessToken}`,
|
|
15088
15132
|
'Content-Type': contentType,
|
|
15089
15133
|
},
|
|
15090
15134
|
body,
|
|
@@ -15100,8 +15144,7 @@
|
|
|
15100
15144
|
// The server returns the ref with version prefix (e.g., "1:blobId")
|
|
15101
15145
|
const result = yield response.json();
|
|
15102
15146
|
// Return BlobRef with server's ref (includes version) and original type preserved in _bt
|
|
15103
|
-
return Object.assign({ _bt: origType, ref: result.ref, size: size }, (origType === 'Blob' ? { ct: contentType } : {})
|
|
15104
|
-
);
|
|
15147
|
+
return Object.assign({ _bt: origType, ref: result.ref, size: size }, (origType === 'Blob' ? { ct: contentType } : {}));
|
|
15105
15148
|
});
|
|
15106
15149
|
}
|
|
15107
15150
|
function offloadBlobsAndMarkDirty(obj_1, databaseUrl_1, getCachedAccessToken_1) {
|
|
@@ -15109,7 +15152,10 @@
|
|
|
15109
15152
|
const dirtyFlag = { dirty: false };
|
|
15110
15153
|
const result = yield offloadBlobs(obj, databaseUrl, getCachedAccessToken, maxStringLength, dirtyFlag);
|
|
15111
15154
|
// Mark the object as dirty for sync if any blobs were offloaded
|
|
15112
|
-
if (dirtyFlag.dirty &&
|
|
15155
|
+
if (dirtyFlag.dirty &&
|
|
15156
|
+
typeof result === 'object' &&
|
|
15157
|
+
result !== null &&
|
|
15158
|
+
result.constructor === Object) {
|
|
15113
15159
|
result._hasBlobRefs = 1;
|
|
15114
15160
|
}
|
|
15115
15161
|
return result;
|
|
@@ -15125,7 +15171,9 @@
|
|
|
15125
15171
|
return obj;
|
|
15126
15172
|
}
|
|
15127
15173
|
// Check if this is a long string that should be offloaded
|
|
15128
|
-
if (typeof obj === 'string' &&
|
|
15174
|
+
if (typeof obj === 'string' &&
|
|
15175
|
+
obj.length > maxStringLength &&
|
|
15176
|
+
maxStringLength !== Infinity) {
|
|
15129
15177
|
if (blobEndpointSupported.get(databaseUrl) === false) {
|
|
15130
15178
|
return obj;
|
|
15131
15179
|
}
|
|
@@ -15211,11 +15259,11 @@
|
|
|
15211
15259
|
switch (op.type) {
|
|
15212
15260
|
case 'insert':
|
|
15213
15261
|
case 'upsert': {
|
|
15214
|
-
const processedValues = yield Promise.all(op.values.map(value => offloadBlobsAndMarkDirty(value, databaseUrl, getCachedAccessToken, maxStringLength)));
|
|
15262
|
+
const processedValues = yield Promise.all(op.values.map((value) => offloadBlobsAndMarkDirty(value, databaseUrl, getCachedAccessToken, maxStringLength)));
|
|
15215
15263
|
return Object.assign(Object.assign({}, op), { values: processedValues });
|
|
15216
15264
|
}
|
|
15217
15265
|
case 'update': {
|
|
15218
|
-
const processedChangeSpecs = yield Promise.all(op.changeSpecs.map(spec => offloadBlobsAndMarkDirty(spec, databaseUrl, getCachedAccessToken, maxStringLength)));
|
|
15266
|
+
const processedChangeSpecs = yield Promise.all(op.changeSpecs.map((spec) => offloadBlobsAndMarkDirty(spec, databaseUrl, getCachedAccessToken, maxStringLength)));
|
|
15219
15267
|
return Object.assign(Object.assign({}, op), { changeSpecs: processedChangeSpecs });
|
|
15220
15268
|
}
|
|
15221
15269
|
case 'modify': {
|
|
@@ -15248,9 +15296,9 @@
|
|
|
15248
15296
|
switch (op.type) {
|
|
15249
15297
|
case 'insert':
|
|
15250
15298
|
case 'upsert':
|
|
15251
|
-
return op.values.some(value => hasLargeBlobs(value, maxStringLength));
|
|
15299
|
+
return op.values.some((value) => hasLargeBlobs(value, maxStringLength));
|
|
15252
15300
|
case 'update':
|
|
15253
|
-
return op.changeSpecs.some(spec => hasLargeBlobs(spec, maxStringLength));
|
|
15301
|
+
return op.changeSpecs.some((spec) => hasLargeBlobs(spec, maxStringLength));
|
|
15254
15302
|
case 'modify':
|
|
15255
15303
|
return hasLargeBlobs(op.changeSpec, maxStringLength);
|
|
15256
15304
|
default:
|
|
@@ -15262,7 +15310,9 @@
|
|
|
15262
15310
|
return false;
|
|
15263
15311
|
}
|
|
15264
15312
|
// Check long strings
|
|
15265
|
-
if (typeof obj === 'string' &&
|
|
15313
|
+
if (typeof obj === 'string' &&
|
|
15314
|
+
obj.length > maxStringLength &&
|
|
15315
|
+
maxStringLength !== Infinity) {
|
|
15266
15316
|
return true;
|
|
15267
15317
|
}
|
|
15268
15318
|
if (shouldOffloadBlob(obj)) {
|
|
@@ -15277,13 +15327,13 @@
|
|
|
15277
15327
|
}
|
|
15278
15328
|
visited.add(obj);
|
|
15279
15329
|
if (Array.isArray(obj)) {
|
|
15280
|
-
return obj.some(item => hasLargeBlobs(item, maxStringLength, visited));
|
|
15330
|
+
return obj.some((item) => hasLargeBlobs(item, maxStringLength, visited));
|
|
15281
15331
|
}
|
|
15282
15332
|
// Traverse plain objects (POJO-like) - use duck typing since IndexedDB
|
|
15283
15333
|
// may return objects where constructor !== Object
|
|
15284
15334
|
const proto = Object.getPrototypeOf(obj);
|
|
15285
15335
|
if (proto === Object.prototype || proto === null) {
|
|
15286
|
-
return Object.values(obj).some(value => hasLargeBlobs(value, maxStringLength, visited));
|
|
15336
|
+
return Object.values(obj).some((value) => hasLargeBlobs(value, maxStringLength, visited));
|
|
15287
15337
|
}
|
|
15288
15338
|
return false;
|
|
15289
15339
|
}
|
|
@@ -15337,7 +15387,7 @@
|
|
|
15337
15387
|
yield db.table(yTable).add({
|
|
15338
15388
|
i: DEXIE_CLOUD_SYNCER_ID,
|
|
15339
15389
|
unsentFrom,
|
|
15340
|
-
receivedUntil
|
|
15390
|
+
receivedUntil,
|
|
15341
15391
|
});
|
|
15342
15392
|
}
|
|
15343
15393
|
else {
|
|
@@ -15477,19 +15527,22 @@
|
|
|
15477
15527
|
return Promise.resolve(cached.accessToken);
|
|
15478
15528
|
}
|
|
15479
15529
|
const currentUser = db.cloud.currentUser.value;
|
|
15480
|
-
if (currentUser &&
|
|
15530
|
+
if (currentUser &&
|
|
15531
|
+
currentUser.accessToken &&
|
|
15532
|
+
((_b = (_a = currentUser.accessTokenExpiration) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : Infinity) >
|
|
15533
|
+
Date.now() + 5 * MINUTES) {
|
|
15481
15534
|
wm$2.set(db, {
|
|
15482
15535
|
accessToken: currentUser.accessToken,
|
|
15483
|
-
expiration: (_d = (_c = currentUser.accessTokenExpiration) === null || _c === void 0 ? void 0 : _c.getTime()) !== null && _d !== void 0 ? _d : Infinity
|
|
15536
|
+
expiration: (_d = (_c = currentUser.accessTokenExpiration) === null || _c === void 0 ? void 0 : _c.getTime()) !== null && _d !== void 0 ? _d : Infinity,
|
|
15484
15537
|
});
|
|
15485
15538
|
return Promise.resolve(currentUser.accessToken);
|
|
15486
15539
|
}
|
|
15487
|
-
return Dexie.ignoreTransaction(() => loadAccessToken(db).then(user => {
|
|
15540
|
+
return Dexie.ignoreTransaction(() => loadAccessToken(db).then((user) => {
|
|
15488
15541
|
var _a, _b;
|
|
15489
15542
|
if (user === null || user === void 0 ? void 0 : user.accessToken) {
|
|
15490
15543
|
wm$2.set(db, {
|
|
15491
15544
|
accessToken: user.accessToken,
|
|
15492
|
-
expiration: (_b = (_a = user.accessTokenExpiration) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : Infinity
|
|
15545
|
+
expiration: (_b = (_a = user.accessTokenExpiration) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : Infinity,
|
|
15493
15546
|
});
|
|
15494
15547
|
}
|
|
15495
15548
|
return (user === null || user === void 0 ? void 0 : user.accessToken) || null;
|
|
@@ -15500,7 +15553,8 @@
|
|
|
15500
15553
|
function sync(db, options, schema, syncOptions) {
|
|
15501
15554
|
return _sync(db, options, schema, syncOptions)
|
|
15502
15555
|
.then((result) => {
|
|
15503
|
-
if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) {
|
|
15556
|
+
if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) {
|
|
15557
|
+
// && syncOptions?.purpose !== 'push') {
|
|
15504
15558
|
db.syncStateChangedEvent.next({
|
|
15505
15559
|
phase: 'in-sync',
|
|
15506
15560
|
});
|
|
@@ -15587,7 +15641,7 @@
|
|
|
15587
15641
|
const syncState = yield db.getPersistedSyncState();
|
|
15588
15642
|
let baseRevs = yield db.$baseRevs.toArray();
|
|
15589
15643
|
// Resolve #2168
|
|
15590
|
-
baseRevs = baseRevs.filter(br => tablesToSync.some(tbl => tbl.name === br.tableName));
|
|
15644
|
+
baseRevs = baseRevs.filter((br) => tablesToSync.some((tbl) => tbl.name === br.tableName));
|
|
15591
15645
|
let clientChanges = yield listClientChanges(mutationTables, db);
|
|
15592
15646
|
const yResults = yield listYClientMessagesAndStateVector(db, tablesToSync);
|
|
15593
15647
|
throwIfCancelled(cancelToken);
|
|
@@ -15603,7 +15657,7 @@
|
|
|
15603
15657
|
}
|
|
15604
15658
|
return [clientChanges, syncState, baseRevs, yResults];
|
|
15605
15659
|
}));
|
|
15606
|
-
const pushSyncIsNeeded = clientChangeSet.some((set) => set.muts.some((mut) => mut.keys.length > 0)) || yMessages.some(m => m.type === 'u-c');
|
|
15660
|
+
const pushSyncIsNeeded = clientChangeSet.some((set) => set.muts.some((mut) => mut.keys.length > 0)) || yMessages.some((m) => m.type === 'u-c');
|
|
15607
15661
|
if (justCheckIfNeeded) {
|
|
15608
15662
|
console.debug('Sync is needed:', pushSyncIsNeeded);
|
|
15609
15663
|
return pushSyncIsNeeded;
|
|
@@ -15747,7 +15801,7 @@
|
|
|
15747
15801
|
db.$syncState.put(newSyncState, 'syncState');
|
|
15748
15802
|
return {
|
|
15749
15803
|
done: addedClientChanges.length === 0,
|
|
15750
|
-
newSyncState
|
|
15804
|
+
newSyncState,
|
|
15751
15805
|
};
|
|
15752
15806
|
}));
|
|
15753
15807
|
if (!done) {
|
|
@@ -15755,7 +15809,7 @@
|
|
|
15755
15809
|
yield checkSyncRateLimitDelay(db);
|
|
15756
15810
|
return yield _sync(db, options, schema, { isInitialSync, cancelToken });
|
|
15757
15811
|
}
|
|
15758
|
-
const usingYProps = Object.values(schema).some(tbl => { var _a; return (_a = tbl.yProps) === null || _a === void 0 ? void 0 : _a.length; });
|
|
15812
|
+
const usingYProps = Object.values(schema).some((tbl) => { var _a; return (_a = tbl.yProps) === null || _a === void 0 ? void 0 : _a.length; });
|
|
15759
15813
|
const serverSupportsYprops = !!res.yMessages;
|
|
15760
15814
|
if (usingYProps && serverSupportsYprops) {
|
|
15761
15815
|
try {
|
|
@@ -16062,11 +16116,13 @@
|
|
|
16062
16116
|
download(blobRef, dbUrl) {
|
|
16063
16117
|
let promise = this.inFlight.get(blobRef.ref);
|
|
16064
16118
|
if (!promise) {
|
|
16065
|
-
promise = loadCachedAccessToken(this.db)
|
|
16119
|
+
promise = loadCachedAccessToken(this.db)
|
|
16120
|
+
.then((accessToken) => {
|
|
16066
16121
|
if (!accessToken)
|
|
16067
|
-
throw new Error(
|
|
16122
|
+
throw new Error('No access token available for blob download');
|
|
16068
16123
|
return downloadBlob(blobRef, dbUrl, accessToken);
|
|
16069
|
-
})
|
|
16124
|
+
})
|
|
16125
|
+
.finally(() => this.inFlight.delete(blobRef.ref));
|
|
16070
16126
|
// When the promise settles (either fulfilled or rejected), remove it from the in-flight map
|
|
16071
16127
|
this.inFlight.set(blobRef.ref, promise);
|
|
16072
16128
|
}
|
|
@@ -16086,8 +16142,8 @@
|
|
|
16086
16142
|
const downloadUrl = `${dbUrl}/blob/${blobRef.ref}`;
|
|
16087
16143
|
const response = yield fetch(downloadUrl, {
|
|
16088
16144
|
headers: {
|
|
16089
|
-
|
|
16090
|
-
}
|
|
16145
|
+
Authorization: `Bearer ${accessToken}`,
|
|
16146
|
+
},
|
|
16091
16147
|
});
|
|
16092
16148
|
if (!response.ok) {
|
|
16093
16149
|
throw new Error(`Failed to download blob ${blobRef.ref}: ${response.status} ${response.statusText}`);
|
|
@@ -16179,7 +16235,9 @@
|
|
|
16179
16235
|
return db.$syncState.get('schema').then((schema) => {
|
|
16180
16236
|
if (schema) {
|
|
16181
16237
|
for (const table of db.tables) {
|
|
16182
|
-
if (table.schema.primKey &&
|
|
16238
|
+
if (table.schema.primKey &&
|
|
16239
|
+
table.schema.primKey.keyPath &&
|
|
16240
|
+
schema[table.name]) {
|
|
16183
16241
|
schema[table.name].primaryKey = nameFromKeyPath(table.schema.primKey.keyPath);
|
|
16184
16242
|
}
|
|
16185
16243
|
}
|
|
@@ -16207,9 +16265,11 @@
|
|
|
16207
16265
|
return db;
|
|
16208
16266
|
}
|
|
16209
16267
|
function nameFromKeyPath(keyPath) {
|
|
16210
|
-
return typeof keyPath === 'string'
|
|
16211
|
-
keyPath
|
|
16212
|
-
|
|
16268
|
+
return typeof keyPath === 'string'
|
|
16269
|
+
? keyPath
|
|
16270
|
+
: keyPath
|
|
16271
|
+
? '[' + [].join.call(keyPath, '+') + ']'
|
|
16272
|
+
: '';
|
|
16213
16273
|
}
|
|
16214
16274
|
|
|
16215
16275
|
// @ts-ignore
|
|
@@ -16231,7 +16291,7 @@
|
|
|
16231
16291
|
const DISABLE_SERVICEWORKER_STRATEGY = (isSafari && safariVersion <= 605) || // Disable for Safari for now.
|
|
16232
16292
|
isFirefox; // Disable for Firefox for now. Seems to have a bug in reading CryptoKeys from IDB from service workers
|
|
16233
16293
|
|
|
16234
|
-
const IS_SERVICE_WORKER = typeof self !==
|
|
16294
|
+
const IS_SERVICE_WORKER = typeof self !== 'undefined' && 'clients' in self && !self.document;
|
|
16235
16295
|
|
|
16236
16296
|
function throwVersionIncrementNeeded() {
|
|
16237
16297
|
throw new Dexie.SchemaError(`Version increment needed to allow dexie-cloud change tracking`);
|
|
@@ -16477,7 +16537,7 @@
|
|
|
16477
16537
|
// We must also degrade from consistent modify operations for the
|
|
16478
16538
|
// same reason - object might be there on server. Must but put up instead.
|
|
16479
16539
|
// FUTURE: This clumpsy behavior of private IDs could be refined later.
|
|
16480
|
-
// Suggestion is to in future, treat private IDs as we treat all objects
|
|
16540
|
+
// Suggestion is to in future, treat private IDs as we treat all objects
|
|
16481
16541
|
// and sync operations normally. Only that deletions should become soft deletes
|
|
16482
16542
|
// for them - so that server knows when a private ID has been deleted on server
|
|
16483
16543
|
// not accept insert/upserts on them.
|
|
@@ -16500,19 +16560,20 @@
|
|
|
16500
16560
|
}
|
|
16501
16561
|
|
|
16502
16562
|
function allSettled(possiblePromises) {
|
|
16503
|
-
return new Promise(resolve => {
|
|
16563
|
+
return new Promise((resolve) => {
|
|
16504
16564
|
if (possiblePromises.length === 0)
|
|
16505
16565
|
resolve([]);
|
|
16506
16566
|
let remaining = possiblePromises.length;
|
|
16507
16567
|
const results = new Array(remaining);
|
|
16508
|
-
possiblePromises.forEach((p, i) => Promise.resolve(p)
|
|
16568
|
+
possiblePromises.forEach((p, i) => Promise.resolve(p)
|
|
16569
|
+
.then((value) => (results[i] = { status: 'fulfilled', value }), (reason) => (results[i] = { status: 'rejected', reason }))
|
|
16509
16570
|
.then(() => --remaining || resolve(results)));
|
|
16510
16571
|
});
|
|
16511
16572
|
}
|
|
16512
16573
|
|
|
16513
16574
|
let counter$1 = 0;
|
|
16514
16575
|
function guardedTable(table) {
|
|
16515
|
-
const prop =
|
|
16576
|
+
const prop = '$lock' + ++counter$1;
|
|
16516
16577
|
return Object.assign(Object.assign({}, table), { count: readLock(table.count, prop), get: readLock(table.get, prop), getMany: readLock(table.getMany, prop), openCursor: readLock(table.openCursor, prop), query: readLock(table.query, prop), mutate: writeLock(table.mutate, prop) });
|
|
16517
16578
|
}
|
|
16518
16579
|
function readLock(fn, prop) {
|
|
@@ -16521,7 +16582,9 @@
|
|
|
16521
16582
|
const numWriters = writers.length;
|
|
16522
16583
|
const promise = (numWriters > 0
|
|
16523
16584
|
? writers[numWriters - 1].then(() => fn(req), () => fn(req))
|
|
16524
|
-
: fn(req)).finally(() => {
|
|
16585
|
+
: fn(req)).finally(() => {
|
|
16586
|
+
readers.splice(readers.indexOf(promise));
|
|
16587
|
+
});
|
|
16525
16588
|
readers.push(promise);
|
|
16526
16589
|
return promise;
|
|
16527
16590
|
};
|
|
@@ -16533,7 +16596,9 @@
|
|
|
16533
16596
|
? writers[writers.length - 1].then(() => fn(req), () => fn(req))
|
|
16534
16597
|
: readers.length > 0
|
|
16535
16598
|
? allSettled(readers).then(() => fn(req))
|
|
16536
|
-
: fn(req)).finally(() => {
|
|
16599
|
+
: fn(req)).finally(() => {
|
|
16600
|
+
writers.shift();
|
|
16601
|
+
});
|
|
16537
16602
|
writers.push(promise);
|
|
16538
16603
|
return promise;
|
|
16539
16604
|
};
|
|
@@ -16811,16 +16876,17 @@
|
|
|
16811
16876
|
userId,
|
|
16812
16877
|
values,
|
|
16813
16878
|
}
|
|
16814
|
-
: upsert && updates
|
|
16815
|
-
|
|
16816
|
-
|
|
16817
|
-
|
|
16818
|
-
|
|
16819
|
-
|
|
16820
|
-
|
|
16821
|
-
|
|
16822
|
-
|
|
16823
|
-
|
|
16879
|
+
: upsert && updates
|
|
16880
|
+
? {
|
|
16881
|
+
type: 'upsert',
|
|
16882
|
+
ts,
|
|
16883
|
+
opNo,
|
|
16884
|
+
keys,
|
|
16885
|
+
values,
|
|
16886
|
+
changeSpecs: updates.changeSpecs.filter((_, idx) => !failures[idx]),
|
|
16887
|
+
txid,
|
|
16888
|
+
userId,
|
|
16889
|
+
}
|
|
16824
16890
|
: criteria && changeSpec
|
|
16825
16891
|
? {
|
|
16826
16892
|
// Common changeSpec for all keys
|
|
@@ -16933,7 +16999,8 @@
|
|
|
16933
16999
|
return;
|
|
16934
17000
|
}
|
|
16935
17001
|
// Atomic update of just the blob property
|
|
16936
|
-
this.db
|
|
17002
|
+
this.db
|
|
17003
|
+
.transaction('rw', item.tableName, (tx) => {
|
|
16937
17004
|
const trans = tx.idbtrans;
|
|
16938
17005
|
trans.disableChangeTracking = true; // Don't regard this as a change for sync purposes
|
|
16939
17006
|
trans.disableAccessControl = true; // Bypass any access control checks since this is an internal operation
|
|
@@ -16942,7 +17009,7 @@
|
|
|
16942
17009
|
for (const blob of item.resolvedBlobs) {
|
|
16943
17010
|
updateSpec[blob.keyPath] = blob.data;
|
|
16944
17011
|
}
|
|
16945
|
-
tx.table(item.tableName).update(item.primaryKey, obj => {
|
|
17012
|
+
tx.table(item.tableName).update(item.primaryKey, (obj) => {
|
|
16946
17013
|
// Check that object still has the same unresolved blob refs before applying update (i.e. it hasn't been modified since we read it)
|
|
16947
17014
|
for (const blob of item.resolvedBlobs) {
|
|
16948
17015
|
// Verify atomicity - none of the blob properties has been modified since we read it. If any of them was modified, skip updating this item to avoid overwriting user changes.
|
|
@@ -16963,9 +17030,11 @@
|
|
|
16963
17030
|
}
|
|
16964
17031
|
delete obj._hasBlobRefs; // Clear the _hasBlobRefs marker if all refs was resolved.
|
|
16965
17032
|
});
|
|
16966
|
-
})
|
|
17033
|
+
})
|
|
17034
|
+
.catch((error) => {
|
|
16967
17035
|
console.error(`Error saving resolved blobs on ${item.tableName}:${item.primaryKey}:`, error);
|
|
16968
|
-
})
|
|
17036
|
+
})
|
|
17037
|
+
.finally(() => {
|
|
16969
17038
|
// Process next item in the queue
|
|
16970
17039
|
return this.processQueue();
|
|
16971
17040
|
});
|
|
@@ -17016,7 +17085,7 @@
|
|
|
17016
17085
|
if ((_a = req.trans) === null || _a === void 0 ? void 0 : _a.disableBlobResolve) {
|
|
17017
17086
|
return downlevelTable.get(req);
|
|
17018
17087
|
}
|
|
17019
|
-
return downlevelTable.get(req).then(result => {
|
|
17088
|
+
return downlevelTable.get(req).then((result) => {
|
|
17020
17089
|
if (result && hasUnresolvedBlobRefs(result)) {
|
|
17021
17090
|
return resolveAndSave(downlevelTable, req.trans, req.key, result, blobSavingQueue, db);
|
|
17022
17091
|
}
|
|
@@ -17028,9 +17097,9 @@
|
|
|
17028
17097
|
if ((_a = req.trans) === null || _a === void 0 ? void 0 : _a.disableBlobResolve) {
|
|
17029
17098
|
return downlevelTable.getMany(req);
|
|
17030
17099
|
}
|
|
17031
|
-
return downlevelTable.getMany(req).then(results => {
|
|
17100
|
+
return downlevelTable.getMany(req).then((results) => {
|
|
17032
17101
|
// Check if any results need resolution
|
|
17033
|
-
const needsResolution = results.some(r => r && hasUnresolvedBlobRefs(r));
|
|
17102
|
+
const needsResolution = results.some((r) => r && hasUnresolvedBlobRefs(r));
|
|
17034
17103
|
if (!needsResolution)
|
|
17035
17104
|
return results;
|
|
17036
17105
|
return Dexie.Promise.all(results.map((result, index) => {
|
|
@@ -17046,19 +17115,19 @@
|
|
|
17046
17115
|
if ((_a = req.trans) === null || _a === void 0 ? void 0 : _a.disableBlobResolve) {
|
|
17047
17116
|
return downlevelTable.query(req);
|
|
17048
17117
|
}
|
|
17049
|
-
return downlevelTable.query(req).then(result => {
|
|
17118
|
+
return downlevelTable.query(req).then((result) => {
|
|
17050
17119
|
if (!result.result || !Array.isArray(result.result))
|
|
17051
17120
|
return result;
|
|
17052
17121
|
// Check if any results need resolution
|
|
17053
|
-
const needsResolution = result.result.some(r => r && hasUnresolvedBlobRefs(r));
|
|
17122
|
+
const needsResolution = result.result.some((r) => r && hasUnresolvedBlobRefs(r));
|
|
17054
17123
|
if (!needsResolution)
|
|
17055
17124
|
return result;
|
|
17056
|
-
return Dexie.Promise.all(result.result.map(item => {
|
|
17125
|
+
return Dexie.Promise.all(result.result.map((item) => {
|
|
17057
17126
|
if (item && hasUnresolvedBlobRefs(item)) {
|
|
17058
17127
|
return resolveAndSave(downlevelTable, req.trans, undefined, item, blobSavingQueue, db);
|
|
17059
17128
|
}
|
|
17060
17129
|
return item;
|
|
17061
|
-
})).then(resolved => (Object.assign(Object.assign({}, result), { result: resolved })));
|
|
17130
|
+
})).then((resolved) => (Object.assign(Object.assign({}, result), { result: resolved })));
|
|
17062
17131
|
});
|
|
17063
17132
|
},
|
|
17064
17133
|
openCursor(req) {
|
|
@@ -17066,7 +17135,7 @@
|
|
|
17066
17135
|
if ((_a = req.trans) === null || _a === void 0 ? void 0 : _a.disableBlobResolve) {
|
|
17067
17136
|
return downlevelTable.openCursor(req);
|
|
17068
17137
|
}
|
|
17069
|
-
return downlevelTable.openCursor(req).then(cursor => {
|
|
17138
|
+
return downlevelTable.openCursor(req).then((cursor) => {
|
|
17070
17139
|
if (!cursor)
|
|
17071
17140
|
return cursor; // No results, so no resolution needed
|
|
17072
17141
|
if (!req.values)
|
|
@@ -17096,7 +17165,7 @@
|
|
|
17096
17165
|
value: {
|
|
17097
17166
|
value: cursor.value,
|
|
17098
17167
|
enumerable: true,
|
|
17099
|
-
writable: true
|
|
17168
|
+
writable: true,
|
|
17100
17169
|
},
|
|
17101
17170
|
start: {
|
|
17102
17171
|
value(onNext) {
|
|
@@ -17108,17 +17177,17 @@
|
|
|
17108
17177
|
onNext();
|
|
17109
17178
|
return;
|
|
17110
17179
|
}
|
|
17111
|
-
resolveAndSave(table, cursor.trans, cursor.primaryKey, rawValue, blobSavingQueue, db, true).then(resolved => {
|
|
17180
|
+
resolveAndSave(table, cursor.trans, cursor.primaryKey, rawValue, blobSavingQueue, db, true).then((resolved) => {
|
|
17112
17181
|
wrappedCursor.value = resolved;
|
|
17113
17182
|
onNext();
|
|
17114
|
-
}, err => {
|
|
17183
|
+
}, (err) => {
|
|
17115
17184
|
console.error('Failed to resolve BlobRefs for cursor value:', err);
|
|
17116
17185
|
wrappedCursor.value = rawValue;
|
|
17117
17186
|
onNext();
|
|
17118
17187
|
});
|
|
17119
17188
|
});
|
|
17120
|
-
}
|
|
17121
|
-
}
|
|
17189
|
+
},
|
|
17190
|
+
},
|
|
17122
17191
|
});
|
|
17123
17192
|
return wrappedCursor;
|
|
17124
17193
|
}
|
|
@@ -17163,12 +17232,15 @@
|
|
|
17163
17232
|
const resolvePromise = needsWaitFor
|
|
17164
17233
|
? Dexie.waitFor(resolutionPromise)
|
|
17165
17234
|
: Dexie.Promise.resolve(resolutionPromise);
|
|
17166
|
-
return resolvePromise
|
|
17235
|
+
return resolvePromise
|
|
17236
|
+
.then((resolved) => {
|
|
17167
17237
|
// Get primary key from the object
|
|
17168
17238
|
const primaryKey = table.schema.primaryKey;
|
|
17169
|
-
const key = pKey !== undefined
|
|
17170
|
-
?
|
|
17171
|
-
:
|
|
17239
|
+
const key = pKey !== undefined
|
|
17240
|
+
? pKey
|
|
17241
|
+
: primaryKey.keyPath
|
|
17242
|
+
? Dexie.getByKeyPath(obj, primaryKey.keyPath)
|
|
17243
|
+
: undefined;
|
|
17172
17244
|
if (key !== undefined) {
|
|
17173
17245
|
// Queue each resolved blob individually for atomic update
|
|
17174
17246
|
// This uses setTimeout(fn, 0) to completely isolate from
|
|
@@ -17179,13 +17251,16 @@
|
|
|
17179
17251
|
else {
|
|
17180
17252
|
// For rw transactions, we can save directly without queueing
|
|
17181
17253
|
// since we're still in the same transaction context
|
|
17182
|
-
table
|
|
17254
|
+
table
|
|
17255
|
+
.mutate({ type: 'put', keys: [key], values: [resolved], trans })
|
|
17256
|
+
.catch((err) => {
|
|
17183
17257
|
console.error(`Failed to save resolved blob on ${table.name}:${key}:`, err);
|
|
17184
17258
|
});
|
|
17185
17259
|
}
|
|
17186
17260
|
}
|
|
17187
17261
|
return resolved;
|
|
17188
|
-
})
|
|
17262
|
+
})
|
|
17263
|
+
.catch((err) => {
|
|
17189
17264
|
console.error(`[dexie-cloud:blobResolve] Failed to resolve BlobRefs on ${table.name}:`, err);
|
|
17190
17265
|
return obj; // Return original object on error - never block the read pipeline
|
|
17191
17266
|
});
|
|
@@ -17214,9 +17289,13 @@
|
|
|
17214
17289
|
return; // Continue
|
|
17215
17290
|
}
|
|
17216
17291
|
// They have declared this table. Merge indexes in case they didn't declare all indexes we need.
|
|
17217
|
-
const requestedIndexes = schemaSrc
|
|
17218
|
-
|
|
17219
|
-
|
|
17292
|
+
const requestedIndexes = schemaSrc
|
|
17293
|
+
.split(',')
|
|
17294
|
+
.map((spec) => spec.trim());
|
|
17295
|
+
const builtInIndexes = DEXIE_CLOUD_SCHEMA[tableName]
|
|
17296
|
+
.split(',')
|
|
17297
|
+
.map((spec) => spec.trim());
|
|
17298
|
+
const requestedIndexSet = new Set(requestedIndexes.map((index) => index.replace(/([&*]|\+\+)/g, '')));
|
|
17220
17299
|
// Verify that primary key is unchanged
|
|
17221
17300
|
if (requestedIndexes[0] !== builtInIndexes[0]) {
|
|
17222
17301
|
// Primary key must match exactly
|
|
@@ -17225,7 +17304,7 @@
|
|
|
17225
17304
|
// Merge indexes
|
|
17226
17305
|
for (let i = 1; i < builtInIndexes.length; ++i) {
|
|
17227
17306
|
const builtInIndex = builtInIndexes[i];
|
|
17228
|
-
if (!requestedIndexSet.has(builtInIndex.replace(/([&*]|\+\+)/g,
|
|
17307
|
+
if (!requestedIndexSet.has(builtInIndex.replace(/([&*]|\+\+)/g, ''))) {
|
|
17229
17308
|
// Add built-in index if not already requested
|
|
17230
17309
|
storesClone[tableName] += `,${builtInIndex}`;
|
|
17231
17310
|
}
|
|
@@ -17234,7 +17313,7 @@
|
|
|
17234
17313
|
// Populate dexie.cloud.schema
|
|
17235
17314
|
const cloudSchema = dexie.cloud.schema || (dexie.cloud.schema = {});
|
|
17236
17315
|
const allPrefixes = new Set();
|
|
17237
|
-
Object.keys(storesClone).forEach(tableName => {
|
|
17316
|
+
Object.keys(storesClone).forEach((tableName) => {
|
|
17238
17317
|
var _a;
|
|
17239
17318
|
const schemaSrc = (_a = storesClone[tableName]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
17240
17319
|
const cloudTableSchema = cloudSchema[tableName] || (cloudSchema[tableName] = {});
|
|
@@ -17363,7 +17442,7 @@
|
|
|
17363
17442
|
class TokenExpiredError extends Error {
|
|
17364
17443
|
constructor() {
|
|
17365
17444
|
super(...arguments);
|
|
17366
|
-
this.name =
|
|
17445
|
+
this.name = 'TokenExpiredError';
|
|
17367
17446
|
}
|
|
17368
17447
|
}
|
|
17369
17448
|
|
|
@@ -17849,7 +17928,7 @@
|
|
|
17849
17928
|
// Connect the WebSocket to given url:
|
|
17850
17929
|
console.debug('dexie-cloud WebSocket create');
|
|
17851
17930
|
const ws = (this.ws = new WebSocket(`${wsUrl}/changes?${searchParams}`));
|
|
17852
|
-
ws.binaryType =
|
|
17931
|
+
ws.binaryType = 'arraybuffer';
|
|
17853
17932
|
ws.onclose = (event) => {
|
|
17854
17933
|
if (!this.pinger)
|
|
17855
17934
|
return;
|
|
@@ -17888,10 +17967,17 @@
|
|
|
17888
17967
|
getOpenDocSignal(doc).next(); // Make yHandler reopen the document on server.
|
|
17889
17968
|
}
|
|
17890
17969
|
}
|
|
17891
|
-
else if (msg.type === 'u-ack' ||
|
|
17970
|
+
else if (msg.type === 'u-ack' ||
|
|
17971
|
+
msg.type === 'u-reject' ||
|
|
17972
|
+
msg.type === 'u-s' ||
|
|
17973
|
+
msg.type === 'in-sync' ||
|
|
17974
|
+
msg.type === 'outdated-server-rev' ||
|
|
17975
|
+
msg.type === 'y-complete-sync-done') {
|
|
17892
17976
|
applyYServerMessages([msg], this.db).then((_a) => __awaiter(this, [_a], void 0, function* ({ resyncNeeded, yServerRevision, receivedUntils }) {
|
|
17893
17977
|
if (yServerRevision) {
|
|
17894
|
-
yield this.db.$syncState.update('syncState', {
|
|
17978
|
+
yield this.db.$syncState.update('syncState', {
|
|
17979
|
+
yServerRevision: yServerRevision,
|
|
17980
|
+
});
|
|
17895
17981
|
}
|
|
17896
17982
|
if (msg.type === 'u-s' && receivedUntils) {
|
|
17897
17983
|
const utbl = getUpdatesTable(this.db, msg.table, msg.prop);
|
|
@@ -18094,7 +18180,9 @@
|
|
|
18094
18180
|
return __awaiter(this, void 0, void 0, function* () {
|
|
18095
18181
|
var _a;
|
|
18096
18182
|
return ((_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.databaseUrl) && db.cloud.schema
|
|
18097
|
-
? yield sync(db, db.cloud.options, db.cloud.schema, {
|
|
18183
|
+
? yield sync(db, db.cloud.options, db.cloud.schema, {
|
|
18184
|
+
justCheckIfNeeded: true,
|
|
18185
|
+
})
|
|
18098
18186
|
: false;
|
|
18099
18187
|
});
|
|
18100
18188
|
}
|
|
@@ -18306,243 +18394,243 @@
|
|
|
18306
18394
|
const Styles = {
|
|
18307
18395
|
Alert: {
|
|
18308
18396
|
error: {
|
|
18309
|
-
color:
|
|
18310
|
-
fontWeight:
|
|
18397
|
+
color: 'red',
|
|
18398
|
+
fontWeight: 'bold',
|
|
18311
18399
|
},
|
|
18312
18400
|
warning: {
|
|
18313
|
-
color:
|
|
18314
|
-
fontWeight:
|
|
18401
|
+
color: '#f80',
|
|
18402
|
+
fontWeight: 'bold',
|
|
18315
18403
|
},
|
|
18316
18404
|
info: {
|
|
18317
|
-
color:
|
|
18318
|
-
}
|
|
18405
|
+
color: 'black',
|
|
18406
|
+
},
|
|
18319
18407
|
},
|
|
18320
18408
|
Darken: {
|
|
18321
|
-
position:
|
|
18409
|
+
position: 'fixed',
|
|
18322
18410
|
top: 0,
|
|
18323
18411
|
left: 0,
|
|
18324
18412
|
opacity: 0.5,
|
|
18325
|
-
backgroundColor:
|
|
18326
|
-
width:
|
|
18327
|
-
height:
|
|
18413
|
+
backgroundColor: '#000',
|
|
18414
|
+
width: '100vw',
|
|
18415
|
+
height: '100vh',
|
|
18328
18416
|
zIndex: 150,
|
|
18329
|
-
webkitBackdropFilter:
|
|
18330
|
-
backdropFilter:
|
|
18417
|
+
webkitBackdropFilter: 'blur(2px)',
|
|
18418
|
+
backdropFilter: 'blur(2px)',
|
|
18331
18419
|
},
|
|
18332
18420
|
DialogOuter: {
|
|
18333
|
-
position:
|
|
18421
|
+
position: 'fixed',
|
|
18334
18422
|
top: 0,
|
|
18335
18423
|
left: 0,
|
|
18336
|
-
width:
|
|
18337
|
-
height:
|
|
18424
|
+
width: '100vw',
|
|
18425
|
+
height: '100vh',
|
|
18338
18426
|
zIndex: 150,
|
|
18339
|
-
alignItems:
|
|
18340
|
-
display:
|
|
18341
|
-
justifyContent:
|
|
18342
|
-
padding:
|
|
18343
|
-
boxSizing:
|
|
18427
|
+
alignItems: 'center',
|
|
18428
|
+
display: 'flex',
|
|
18429
|
+
justifyContent: 'center',
|
|
18430
|
+
padding: '16px',
|
|
18431
|
+
boxSizing: 'border-box',
|
|
18344
18432
|
},
|
|
18345
18433
|
DialogInner: {
|
|
18346
|
-
position:
|
|
18347
|
-
color:
|
|
18348
|
-
backgroundColor:
|
|
18349
|
-
padding:
|
|
18350
|
-
marginBottom:
|
|
18351
|
-
maxWidth:
|
|
18352
|
-
width:
|
|
18353
|
-
maxHeight:
|
|
18354
|
-
overflowY:
|
|
18355
|
-
border:
|
|
18356
|
-
borderRadius:
|
|
18357
|
-
boxShadow:
|
|
18358
|
-
fontFamily:
|
|
18359
|
-
boxSizing:
|
|
18434
|
+
position: 'relative',
|
|
18435
|
+
color: '#222',
|
|
18436
|
+
backgroundColor: '#fff',
|
|
18437
|
+
padding: '24px',
|
|
18438
|
+
marginBottom: '2em',
|
|
18439
|
+
maxWidth: '400px',
|
|
18440
|
+
width: '100%',
|
|
18441
|
+
maxHeight: '90%',
|
|
18442
|
+
overflowY: 'auto',
|
|
18443
|
+
border: '3px solid #3d3d5d',
|
|
18444
|
+
borderRadius: '8px',
|
|
18445
|
+
boxShadow: '0 0 80px 10px #666',
|
|
18446
|
+
fontFamily: 'sans-serif',
|
|
18447
|
+
boxSizing: 'border-box',
|
|
18360
18448
|
},
|
|
18361
18449
|
Input: {
|
|
18362
|
-
height:
|
|
18363
|
-
width:
|
|
18364
|
-
maxWidth:
|
|
18365
|
-
borderColor:
|
|
18366
|
-
outline:
|
|
18367
|
-
fontSize:
|
|
18368
|
-
padding:
|
|
18369
|
-
boxSizing:
|
|
18370
|
-
backgroundColor:
|
|
18371
|
-
borderRadius:
|
|
18372
|
-
border:
|
|
18373
|
-
marginTop:
|
|
18374
|
-
fontFamily:
|
|
18450
|
+
height: '35px',
|
|
18451
|
+
width: '100%',
|
|
18452
|
+
maxWidth: '100%',
|
|
18453
|
+
borderColor: '#ccf4',
|
|
18454
|
+
outline: 'none',
|
|
18455
|
+
fontSize: '16px',
|
|
18456
|
+
padding: '8px',
|
|
18457
|
+
boxSizing: 'border-box',
|
|
18458
|
+
backgroundColor: '#f9f9f9',
|
|
18459
|
+
borderRadius: '4px',
|
|
18460
|
+
border: '1px solid #ccc',
|
|
18461
|
+
marginTop: '6px',
|
|
18462
|
+
fontFamily: 'inherit',
|
|
18375
18463
|
},
|
|
18376
18464
|
Button: {
|
|
18377
|
-
padding:
|
|
18378
|
-
margin:
|
|
18379
|
-
border:
|
|
18380
|
-
borderRadius:
|
|
18381
|
-
backgroundColor:
|
|
18382
|
-
cursor:
|
|
18383
|
-
fontSize:
|
|
18384
|
-
fontWeight:
|
|
18385
|
-
color:
|
|
18386
|
-
transition:
|
|
18465
|
+
padding: '10px 20px',
|
|
18466
|
+
margin: '0 4px',
|
|
18467
|
+
border: '1px solid #d1d5db',
|
|
18468
|
+
borderRadius: '6px',
|
|
18469
|
+
backgroundColor: '#ffffff',
|
|
18470
|
+
cursor: 'pointer',
|
|
18471
|
+
fontSize: '14px',
|
|
18472
|
+
fontWeight: '500',
|
|
18473
|
+
color: '#374151',
|
|
18474
|
+
transition: 'all 0.2s ease',
|
|
18387
18475
|
},
|
|
18388
18476
|
PrimaryButton: {
|
|
18389
|
-
padding:
|
|
18390
|
-
margin:
|
|
18391
|
-
border:
|
|
18392
|
-
borderRadius:
|
|
18393
|
-
backgroundColor:
|
|
18394
|
-
color:
|
|
18395
|
-
cursor:
|
|
18396
|
-
fontSize:
|
|
18397
|
-
fontWeight:
|
|
18398
|
-
transition:
|
|
18477
|
+
padding: '10px 20px',
|
|
18478
|
+
margin: '0 4px',
|
|
18479
|
+
border: '1px solid #3b82f6',
|
|
18480
|
+
borderRadius: '6px',
|
|
18481
|
+
backgroundColor: '#3b82f6',
|
|
18482
|
+
color: 'white',
|
|
18483
|
+
cursor: 'pointer',
|
|
18484
|
+
fontSize: '14px',
|
|
18485
|
+
fontWeight: '500',
|
|
18486
|
+
transition: 'all 0.2s ease',
|
|
18399
18487
|
},
|
|
18400
18488
|
ButtonsDiv: {
|
|
18401
|
-
display:
|
|
18402
|
-
justifyContent:
|
|
18403
|
-
gap:
|
|
18404
|
-
marginTop:
|
|
18405
|
-
paddingTop:
|
|
18489
|
+
display: 'flex',
|
|
18490
|
+
justifyContent: 'flex-end',
|
|
18491
|
+
gap: '12px',
|
|
18492
|
+
marginTop: '24px',
|
|
18493
|
+
paddingTop: '20px',
|
|
18406
18494
|
},
|
|
18407
18495
|
Label: {
|
|
18408
|
-
display:
|
|
18409
|
-
marginBottom:
|
|
18410
|
-
fontSize:
|
|
18411
|
-
fontWeight:
|
|
18412
|
-
color:
|
|
18496
|
+
display: 'block',
|
|
18497
|
+
marginBottom: '12px',
|
|
18498
|
+
fontSize: '14px',
|
|
18499
|
+
fontWeight: '500',
|
|
18500
|
+
color: '#333',
|
|
18413
18501
|
},
|
|
18414
18502
|
WindowHeader: {
|
|
18415
|
-
margin:
|
|
18416
|
-
fontSize:
|
|
18417
|
-
fontWeight:
|
|
18418
|
-
color:
|
|
18419
|
-
borderBottom:
|
|
18420
|
-
paddingBottom:
|
|
18503
|
+
margin: '0 0 20px 0',
|
|
18504
|
+
fontSize: '18px',
|
|
18505
|
+
fontWeight: '600',
|
|
18506
|
+
color: '#333',
|
|
18507
|
+
borderBottom: '1px solid #eee',
|
|
18508
|
+
paddingBottom: '10px',
|
|
18421
18509
|
},
|
|
18422
18510
|
// OAuth Provider Button Styles
|
|
18423
18511
|
ProviderButton: {
|
|
18424
|
-
display:
|
|
18425
|
-
alignItems:
|
|
18426
|
-
justifyContent:
|
|
18427
|
-
width:
|
|
18428
|
-
padding:
|
|
18429
|
-
marginBottom:
|
|
18430
|
-
border:
|
|
18431
|
-
borderRadius:
|
|
18432
|
-
backgroundColor:
|
|
18433
|
-
cursor:
|
|
18434
|
-
fontSize:
|
|
18435
|
-
fontWeight:
|
|
18436
|
-
color:
|
|
18437
|
-
transition:
|
|
18438
|
-
gap:
|
|
18512
|
+
display: 'flex',
|
|
18513
|
+
alignItems: 'center',
|
|
18514
|
+
justifyContent: 'center',
|
|
18515
|
+
width: '100%',
|
|
18516
|
+
padding: '12px 16px',
|
|
18517
|
+
marginBottom: '10px',
|
|
18518
|
+
border: '1px solid #d1d5db',
|
|
18519
|
+
borderRadius: '6px',
|
|
18520
|
+
backgroundColor: '#ffffff',
|
|
18521
|
+
cursor: 'pointer',
|
|
18522
|
+
fontSize: '14px',
|
|
18523
|
+
fontWeight: '500',
|
|
18524
|
+
color: '#374151',
|
|
18525
|
+
transition: 'all 0.2s ease',
|
|
18526
|
+
gap: '12px',
|
|
18439
18527
|
},
|
|
18440
18528
|
ProviderButtonIcon: {
|
|
18441
|
-
width:
|
|
18442
|
-
height:
|
|
18529
|
+
width: '20px',
|
|
18530
|
+
height: '20px',
|
|
18443
18531
|
flexShrink: 0,
|
|
18444
|
-
display:
|
|
18445
|
-
alignItems:
|
|
18446
|
-
justifyContent:
|
|
18532
|
+
display: 'flex',
|
|
18533
|
+
alignItems: 'center',
|
|
18534
|
+
justifyContent: 'center',
|
|
18447
18535
|
},
|
|
18448
18536
|
ProviderButtonText: {
|
|
18449
18537
|
flex: 1,
|
|
18450
|
-
textAlign:
|
|
18538
|
+
textAlign: 'left',
|
|
18451
18539
|
},
|
|
18452
18540
|
// Provider-specific colors
|
|
18453
18541
|
ProviderGoogle: {
|
|
18454
|
-
backgroundColor:
|
|
18455
|
-
border:
|
|
18456
|
-
color:
|
|
18542
|
+
backgroundColor: '#ffffff',
|
|
18543
|
+
border: '1px solid #dadce0',
|
|
18544
|
+
color: '#3c4043',
|
|
18457
18545
|
},
|
|
18458
18546
|
ProviderGitHub: {
|
|
18459
|
-
backgroundColor:
|
|
18460
|
-
border:
|
|
18461
|
-
color:
|
|
18547
|
+
backgroundColor: '#ffffff',
|
|
18548
|
+
border: '1px solid #dadce0',
|
|
18549
|
+
color: '#181717',
|
|
18462
18550
|
},
|
|
18463
18551
|
ProviderMicrosoft: {
|
|
18464
|
-
backgroundColor:
|
|
18465
|
-
border:
|
|
18466
|
-
color:
|
|
18552
|
+
backgroundColor: '#ffffff',
|
|
18553
|
+
border: '1px solid #dadce0',
|
|
18554
|
+
color: '#5e5e5e',
|
|
18467
18555
|
},
|
|
18468
18556
|
ProviderApple: {
|
|
18469
|
-
backgroundColor:
|
|
18470
|
-
border:
|
|
18471
|
-
color:
|
|
18557
|
+
backgroundColor: '#000000',
|
|
18558
|
+
border: '1px solid #000000',
|
|
18559
|
+
color: '#ffffff',
|
|
18472
18560
|
},
|
|
18473
18561
|
ProviderCustom: {
|
|
18474
|
-
backgroundColor:
|
|
18475
|
-
border:
|
|
18476
|
-
color:
|
|
18562
|
+
backgroundColor: '#ffffff',
|
|
18563
|
+
border: '1px solid #dadce0',
|
|
18564
|
+
color: '#181717',
|
|
18477
18565
|
},
|
|
18478
18566
|
// Divider styles
|
|
18479
18567
|
Divider: {
|
|
18480
|
-
display:
|
|
18481
|
-
alignItems:
|
|
18482
|
-
margin:
|
|
18483
|
-
color:
|
|
18484
|
-
fontSize:
|
|
18568
|
+
display: 'flex',
|
|
18569
|
+
alignItems: 'center',
|
|
18570
|
+
margin: '20px 0',
|
|
18571
|
+
color: '#6b7280',
|
|
18572
|
+
fontSize: '13px',
|
|
18485
18573
|
},
|
|
18486
18574
|
DividerLine: {
|
|
18487
18575
|
flex: 1,
|
|
18488
|
-
height:
|
|
18489
|
-
backgroundColor:
|
|
18576
|
+
height: '1px',
|
|
18577
|
+
backgroundColor: '#e5e7eb',
|
|
18490
18578
|
},
|
|
18491
18579
|
DividerText: {
|
|
18492
|
-
padding:
|
|
18493
|
-
color:
|
|
18580
|
+
padding: '0 12px',
|
|
18581
|
+
color: '#9ca3af',
|
|
18494
18582
|
},
|
|
18495
18583
|
// OTP Button (Continue with email)
|
|
18496
18584
|
OtpButton: {
|
|
18497
|
-
display:
|
|
18498
|
-
alignItems:
|
|
18499
|
-
justifyContent:
|
|
18500
|
-
width:
|
|
18501
|
-
padding:
|
|
18502
|
-
border:
|
|
18503
|
-
borderRadius:
|
|
18504
|
-
backgroundColor:
|
|
18505
|
-
cursor:
|
|
18506
|
-
fontSize:
|
|
18507
|
-
fontWeight:
|
|
18508
|
-
color:
|
|
18509
|
-
transition:
|
|
18510
|
-
gap:
|
|
18585
|
+
display: 'flex',
|
|
18586
|
+
alignItems: 'center',
|
|
18587
|
+
justifyContent: 'center',
|
|
18588
|
+
width: '100%',
|
|
18589
|
+
padding: '12px 16px',
|
|
18590
|
+
border: '1px solid #d1d5db',
|
|
18591
|
+
borderRadius: '6px',
|
|
18592
|
+
backgroundColor: '#f9fafb',
|
|
18593
|
+
cursor: 'pointer',
|
|
18594
|
+
fontSize: '14px',
|
|
18595
|
+
fontWeight: '500',
|
|
18596
|
+
color: '#374151',
|
|
18597
|
+
transition: 'all 0.2s ease',
|
|
18598
|
+
gap: '12px',
|
|
18511
18599
|
},
|
|
18512
18600
|
// Copy button for alerts with copyText
|
|
18513
18601
|
CopyButton: {
|
|
18514
|
-
display:
|
|
18515
|
-
alignItems:
|
|
18516
|
-
gap:
|
|
18517
|
-
padding:
|
|
18518
|
-
marginTop:
|
|
18519
|
-
border:
|
|
18520
|
-
borderRadius:
|
|
18521
|
-
backgroundColor:
|
|
18522
|
-
cursor:
|
|
18523
|
-
fontSize:
|
|
18524
|
-
fontWeight:
|
|
18525
|
-
color:
|
|
18526
|
-
transition:
|
|
18527
|
-
fontFamily:
|
|
18602
|
+
display: 'inline-flex',
|
|
18603
|
+
alignItems: 'center',
|
|
18604
|
+
gap: '4px',
|
|
18605
|
+
padding: '4px 10px',
|
|
18606
|
+
marginTop: '8px',
|
|
18607
|
+
border: '1px solid #d1d5db',
|
|
18608
|
+
borderRadius: '4px',
|
|
18609
|
+
backgroundColor: '#f9fafb',
|
|
18610
|
+
cursor: 'pointer',
|
|
18611
|
+
fontSize: '12px',
|
|
18612
|
+
fontWeight: '500',
|
|
18613
|
+
color: '#374151',
|
|
18614
|
+
transition: 'all 0.15s ease',
|
|
18615
|
+
fontFamily: 'monospace',
|
|
18528
18616
|
},
|
|
18529
18617
|
CopyButtonCopied: {
|
|
18530
|
-
display:
|
|
18531
|
-
alignItems:
|
|
18532
|
-
gap:
|
|
18533
|
-
padding:
|
|
18534
|
-
marginTop:
|
|
18535
|
-
border:
|
|
18536
|
-
borderRadius:
|
|
18537
|
-
backgroundColor:
|
|
18538
|
-
cursor:
|
|
18539
|
-
fontSize:
|
|
18540
|
-
fontWeight:
|
|
18541
|
-
color:
|
|
18542
|
-
fontFamily:
|
|
18618
|
+
display: 'inline-flex',
|
|
18619
|
+
alignItems: 'center',
|
|
18620
|
+
gap: '4px',
|
|
18621
|
+
padding: '4px 10px',
|
|
18622
|
+
marginTop: '8px',
|
|
18623
|
+
border: '1px solid #22c55e',
|
|
18624
|
+
borderRadius: '4px',
|
|
18625
|
+
backgroundColor: '#f0fdf4',
|
|
18626
|
+
cursor: 'default',
|
|
18627
|
+
fontSize: '12px',
|
|
18628
|
+
fontWeight: '500',
|
|
18629
|
+
color: '#16a34a',
|
|
18630
|
+
fontFamily: 'monospace',
|
|
18543
18631
|
}};
|
|
18544
18632
|
|
|
18545
|
-
function Dialog({ children, className }) {
|
|
18633
|
+
function Dialog({ children, className, }) {
|
|
18546
18634
|
return (_$1("div", { className: `dexie-dialog ${className || ''}` },
|
|
18547
18635
|
_$1("div", { style: Styles.Darken }),
|
|
18548
18636
|
_$1("div", { style: Styles.DialogOuter },
|
|
@@ -18566,7 +18654,7 @@
|
|
|
18566
18654
|
* @returns A final message where parameters have been replaced with values.
|
|
18567
18655
|
*/
|
|
18568
18656
|
function resolveText({ message, messageCode, messageParams }) {
|
|
18569
|
-
return message.replace(/\{\w+\}/
|
|
18657
|
+
return message.replace(/\{\w+\}/gi, (n) => messageParams[n.substring(1, n.length - 1)]);
|
|
18570
18658
|
}
|
|
18571
18659
|
|
|
18572
18660
|
/** Get style based on styleHint (for provider branding, etc.) */
|
|
@@ -18653,13 +18741,13 @@
|
|
|
18653
18741
|
alerts.map((alert, idx) => (_$1("div", { key: idx },
|
|
18654
18742
|
_$1("p", { style: Styles.Alert[alert.type] }, resolveText(alert)),
|
|
18655
18743
|
alert.copyText && _$1(CopyButton, { text: alert.copyText })))),
|
|
18656
|
-
hasOptions && (_$1("div", { class: "dxc-options" }, hasMultipleGroups
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
|
|
18662
|
-
|
|
18744
|
+
hasOptions && (_$1("div", { class: "dxc-options" }, hasMultipleGroups
|
|
18745
|
+
? // Render with dividers between groups
|
|
18746
|
+
Array.from(optionGroups.entries()).map(([groupName, groupOptions], groupIdx) => (_$1(k$1, { key: groupName },
|
|
18747
|
+
groupIdx > 0 && _$1(Divider, null),
|
|
18748
|
+
groupOptions.map((option) => (_$1(OptionButton, { key: `${option.name}-${option.value}`, option: option, onClick: () => handleOptionClick(option) }))))))
|
|
18749
|
+
: // Simple case: all options in one group
|
|
18750
|
+
options.map((option) => (_$1(OptionButton, { key: `${option.name}-${option.value}`, option: option, onClick: () => handleOptionClick(option) }))))),
|
|
18663
18751
|
hasOptions && hasFields && _$1(Divider, null),
|
|
18664
18752
|
hasFields && (_$1("form", { onSubmit: (ev) => {
|
|
18665
18753
|
ev.preventDefault();
|
|
@@ -18671,7 +18759,8 @@
|
|
|
18671
18759
|
const value = valueTransformer(type, (_a = ev.target) === null || _a === void 0 ? void 0 : _a['value']);
|
|
18672
18760
|
let updatedParams = Object.assign(Object.assign({}, params), { [fieldName]: value });
|
|
18673
18761
|
setParams(updatedParams);
|
|
18674
|
-
if (type === 'otp' &&
|
|
18762
|
+
if (type === 'otp' &&
|
|
18763
|
+
(value === null || value === void 0 ? void 0 : value.trim().length) === OTP_LENGTH) {
|
|
18675
18764
|
// Auto-submit when OTP is filled in.
|
|
18676
18765
|
onSubmit(updatedParams);
|
|
18677
18766
|
}
|
|
@@ -18713,7 +18802,10 @@
|
|
|
18713
18802
|
const handleClick = () => {
|
|
18714
18803
|
var _a;
|
|
18715
18804
|
if (typeof navigator !== 'undefined' && ((_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.writeText)) {
|
|
18716
|
-
navigator.clipboard
|
|
18805
|
+
navigator.clipboard
|
|
18806
|
+
.writeText(text)
|
|
18807
|
+
.then(scheduleCopiedReset)
|
|
18808
|
+
.catch(() => {
|
|
18717
18809
|
fallbackCopy(text, scheduleCopiedReset);
|
|
18718
18810
|
});
|
|
18719
18811
|
}
|
|
@@ -18784,7 +18876,7 @@
|
|
|
18784
18876
|
},
|
|
18785
18877
|
get closed() {
|
|
18786
18878
|
return closed;
|
|
18787
|
-
}
|
|
18879
|
+
},
|
|
18788
18880
|
};
|
|
18789
18881
|
}
|
|
18790
18882
|
|
|
@@ -18829,14 +18921,14 @@
|
|
|
18829
18921
|
lazyWebSocketStatus,
|
|
18830
18922
|
db.syncStateChangedEvent.pipe(operators.startWith({ phase: 'initial' })),
|
|
18831
18923
|
getCurrentUserEmitter(db.dx._novip),
|
|
18832
|
-
userIsReallyActive
|
|
18924
|
+
userIsReallyActive,
|
|
18833
18925
|
]).pipe(operators.map(([status, syncState, user, userIsActive]) => {
|
|
18834
18926
|
var _a;
|
|
18835
18927
|
if (((_a = user.license) === null || _a === void 0 ? void 0 : _a.status) && user.license.status !== 'ok') {
|
|
18836
18928
|
return {
|
|
18837
18929
|
phase: 'offline',
|
|
18838
18930
|
status: 'offline',
|
|
18839
|
-
license: user.license.status
|
|
18931
|
+
license: user.license.status,
|
|
18840
18932
|
};
|
|
18841
18933
|
}
|
|
18842
18934
|
let { phase, error, progress } = syncState;
|
|
@@ -18856,7 +18948,8 @@
|
|
|
18856
18948
|
}
|
|
18857
18949
|
const previousPhase = db.cloud.syncState.value.phase;
|
|
18858
18950
|
//const previousStatus = db.cloud.syncState.value.status;
|
|
18859
|
-
if (previousPhase === 'error' &&
|
|
18951
|
+
if (previousPhase === 'error' &&
|
|
18952
|
+
(syncState.phase === 'pushing' || syncState.phase === 'pulling')) {
|
|
18860
18953
|
// We were in an errored state but is now doing sync. Show "connecting" icon.
|
|
18861
18954
|
adjustedStatus = 'connecting';
|
|
18862
18955
|
}
|
|
@@ -18871,7 +18964,7 @@
|
|
|
18871
18964
|
error,
|
|
18872
18965
|
progress,
|
|
18873
18966
|
status: isOnline ? adjustedStatus : 'offline',
|
|
18874
|
-
license: 'ok'
|
|
18967
|
+
license: 'ok',
|
|
18875
18968
|
};
|
|
18876
18969
|
return retState;
|
|
18877
18970
|
}));
|
|
@@ -18892,7 +18985,7 @@
|
|
|
18892
18985
|
},
|
|
18893
18986
|
complete() {
|
|
18894
18987
|
observer.complete();
|
|
18895
|
-
}
|
|
18988
|
+
},
|
|
18896
18989
|
});
|
|
18897
18990
|
if (!didEmit && !subscription.closed) {
|
|
18898
18991
|
observer.next(currentValue);
|
|
@@ -19133,7 +19226,9 @@
|
|
|
19133
19226
|
const realm = permissionsLookup[realmId || dexie.cloud.currentUserId];
|
|
19134
19227
|
if (!realm)
|
|
19135
19228
|
return new PermissionChecker({}, tableName, !owner || owner === dexie.cloud.currentUserId);
|
|
19136
|
-
return new PermissionChecker(realm.permissions, tableName, realmId === undefined ||
|
|
19229
|
+
return new PermissionChecker(realm.permissions, tableName, realmId === undefined ||
|
|
19230
|
+
realmId === dexie.cloud.currentUserId ||
|
|
19231
|
+
owner === dexie.cloud.currentUserId);
|
|
19137
19232
|
};
|
|
19138
19233
|
const o = source.pipe(operators.map(mapper));
|
|
19139
19234
|
o.getValue = () => mapper(source.getValue());
|
|
@@ -19175,7 +19270,19 @@
|
|
|
19175
19270
|
return; // The table that holds the doc is not marked for sync - leave it to dexie. No syncing, no awareness.
|
|
19176
19271
|
}
|
|
19177
19272
|
let awareness;
|
|
19273
|
+
const existingDescriptor = Object.getOwnPropertyDescriptor(provider, 'awareness');
|
|
19274
|
+
if (existingDescriptor) {
|
|
19275
|
+
// Provider already initialized — likely a leaked handler from a previous db instance
|
|
19276
|
+
// (e.g. HMR where db.close() didn't fire). Destroy the stale awareness so the new
|
|
19277
|
+
// handler can take over cleanly.
|
|
19278
|
+
const staleAwareness = provider.awareness;
|
|
19279
|
+
if (staleAwareness) {
|
|
19280
|
+
staleAwareness.destroy();
|
|
19281
|
+
awarenessWeakMap.delete(doc);
|
|
19282
|
+
}
|
|
19283
|
+
}
|
|
19178
19284
|
Object.defineProperty(provider, 'awareness', {
|
|
19285
|
+
configurable: true,
|
|
19179
19286
|
get() {
|
|
19180
19287
|
if (awareness)
|
|
19181
19288
|
return awareness;
|
|
@@ -19358,10 +19465,12 @@
|
|
|
19358
19465
|
const { code, provider, state, error } = payload;
|
|
19359
19466
|
// Check for error first
|
|
19360
19467
|
if (error) {
|
|
19361
|
-
if (error.toLowerCase().includes('access_denied') ||
|
|
19468
|
+
if (error.toLowerCase().includes('access_denied') ||
|
|
19469
|
+
error.toLowerCase().includes('access denied')) {
|
|
19362
19470
|
throw new OAuthError('access_denied', provider, error);
|
|
19363
19471
|
}
|
|
19364
|
-
if (error.toLowerCase().includes('email') &&
|
|
19472
|
+
if (error.toLowerCase().includes('email') &&
|
|
19473
|
+
error.toLowerCase().includes('verif')) {
|
|
19365
19474
|
throw new OAuthError('email_not_verified', provider, error);
|
|
19366
19475
|
}
|
|
19367
19476
|
throw new OAuthError('provider_error', provider, error);
|
|
@@ -19387,7 +19496,9 @@
|
|
|
19387
19496
|
return;
|
|
19388
19497
|
}
|
|
19389
19498
|
url.searchParams.delete('dxc-auth');
|
|
19390
|
-
const cleanUrl = url.pathname +
|
|
19499
|
+
const cleanUrl = url.pathname +
|
|
19500
|
+
(url.searchParams.toString() ? `?${url.searchParams.toString()}` : '') +
|
|
19501
|
+
url.hash;
|
|
19391
19502
|
window.history.replaceState(null, '', cleanUrl);
|
|
19392
19503
|
}
|
|
19393
19504
|
|
|
@@ -19400,8 +19511,8 @@
|
|
|
19400
19511
|
|
|
19401
19512
|
const ydocTriggers = {};
|
|
19402
19513
|
const middlewares = new WeakMap();
|
|
19403
|
-
const txRunner = TriggerRunner(
|
|
19404
|
-
const unloadRunner = TriggerRunner(
|
|
19514
|
+
const txRunner = TriggerRunner('tx'); // Trigger registry for transaction completion. Avoids open docs.
|
|
19515
|
+
const unloadRunner = TriggerRunner('unload'); // Trigger registry for unload. Runs when a document is closed.
|
|
19405
19516
|
function TriggerRunner(name) {
|
|
19406
19517
|
let triggerExecPromise = null;
|
|
19407
19518
|
let triggerScheduled = false;
|
|
@@ -19440,7 +19551,7 @@
|
|
|
19440
19551
|
yield triggerExecPromise.catch(() => { });
|
|
19441
19552
|
setTimeout(() => {
|
|
19442
19553
|
// setTimeout() is to escape from Promise.PSD zones and never run within liveQueries or transaction scopes
|
|
19443
|
-
console.log(
|
|
19554
|
+
console.log('Running trigger really!', name);
|
|
19444
19555
|
triggerScheduled = false;
|
|
19445
19556
|
const registryCopy = registry;
|
|
19446
19557
|
registry = new Map();
|
|
@@ -19607,7 +19718,7 @@
|
|
|
19607
19718
|
const downloading$ = createDownloadingState();
|
|
19608
19719
|
dexie.cloud = {
|
|
19609
19720
|
// @ts-ignore
|
|
19610
|
-
version: "4.4.
|
|
19721
|
+
version: "4.4.7",
|
|
19611
19722
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
19612
19723
|
schema: null,
|
|
19613
19724
|
get currentUserId() {
|
|
@@ -19663,7 +19774,10 @@
|
|
|
19663
19774
|
const callback = parseOAuthCallback();
|
|
19664
19775
|
if (callback) {
|
|
19665
19776
|
// Store the pending auth code for processing when db is ready
|
|
19666
|
-
pendingOAuthCode = {
|
|
19777
|
+
pendingOAuthCode = {
|
|
19778
|
+
code: callback.code,
|
|
19779
|
+
provider: callback.provider,
|
|
19780
|
+
};
|
|
19667
19781
|
console.debug('[dexie-cloud] OAuth callback detected, auth code stored for processing');
|
|
19668
19782
|
}
|
|
19669
19783
|
}
|
|
@@ -19780,7 +19894,7 @@
|
|
|
19780
19894
|
if (eagerBlobDownloadInFlight)
|
|
19781
19895
|
return;
|
|
19782
19896
|
eagerBlobDownloadInFlight = Dexie.ignoreTransaction(() => downloadUnresolvedBlobs(db, downloading$))
|
|
19783
|
-
.catch(err => {
|
|
19897
|
+
.catch((err) => {
|
|
19784
19898
|
console.error('[dexie-cloud] Eager blob download failed:', err);
|
|
19785
19899
|
})
|
|
19786
19900
|
.finally(() => {
|
|
@@ -19873,7 +19987,10 @@
|
|
|
19873
19987
|
// Let's assign all props as the newPersistedSchems should be what we should be working with.
|
|
19874
19988
|
Object.assign(schema, newPersistedSchema);
|
|
19875
19989
|
}
|
|
19876
|
-
return [
|
|
19990
|
+
return [
|
|
19991
|
+
persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.initiallySynced,
|
|
19992
|
+
persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.realms,
|
|
19993
|
+
];
|
|
19877
19994
|
}));
|
|
19878
19995
|
if (initiallySynced) {
|
|
19879
19996
|
db.setInitiallySynced(true);
|
|
@@ -19882,8 +19999,10 @@
|
|
|
19882
19999
|
// Manage CurrentUser observable:
|
|
19883
20000
|
throwIfClosed();
|
|
19884
20001
|
if (!db.cloud.isServiceWorkerDB) {
|
|
19885
|
-
subscriptions.push(Dexie.liveQuery(() => db.getCurrentUser().then(user => {
|
|
19886
|
-
if (!user.isLoggedIn &&
|
|
20002
|
+
subscriptions.push(Dexie.liveQuery(() => db.getCurrentUser().then((user) => {
|
|
20003
|
+
if (!user.isLoggedIn &&
|
|
20004
|
+
typeof location !== 'undefined' &&
|
|
20005
|
+
/dxc-auth\=/.test(location.search)) {
|
|
19887
20006
|
// Still loading user because OAuth redirect just happened.
|
|
19888
20007
|
// Keep isLoading true.
|
|
19889
20008
|
return Object.assign(Object.assign({}, user), { isLoading: true });
|
|
@@ -19921,7 +20040,7 @@
|
|
|
19921
20040
|
type: 'error',
|
|
19922
20041
|
messageCode: 'GENERIC_ERROR',
|
|
19923
20042
|
message: error.message,
|
|
19924
|
-
messageParams: { provider: error.provider || 'unknown' }
|
|
20043
|
+
messageParams: { provider: error.provider || 'unknown' },
|
|
19925
20044
|
});
|
|
19926
20045
|
// Clean up URL (remove dxc-auth param)
|
|
19927
20046
|
cleanupOAuthUrl();
|
|
@@ -19971,7 +20090,8 @@
|
|
|
19971
20090
|
}
|
|
19972
20091
|
}
|
|
19973
20092
|
}
|
|
19974
|
-
if (user.isLoggedIn &&
|
|
20093
|
+
if (user.isLoggedIn &&
|
|
20094
|
+
(!lastSyncedRealms || !lastSyncedRealms.includes(user.userId))) {
|
|
19975
20095
|
// User has been logged in but this is not reflected in the sync state.
|
|
19976
20096
|
// This can happen if page is reloaded after login but before the sync call following
|
|
19977
20097
|
// the login was complete.
|
|
@@ -20034,7 +20154,7 @@
|
|
|
20034
20154
|
}
|
|
20035
20155
|
}
|
|
20036
20156
|
// @ts-ignore
|
|
20037
|
-
dexieCloud.version = "4.4.
|
|
20157
|
+
dexieCloud.version = "4.4.7";
|
|
20038
20158
|
Dexie.Cloud = dexieCloud;
|
|
20039
20159
|
|
|
20040
20160
|
exports.default = dexieCloud;
|