dexie-cloud-addon 4.2.3 → 4.2.5
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/dexie-cloud-import.json +2 -1
- package/dist/modern/dexie-cloud-addon.js +146 -168
- package/dist/modern/dexie-cloud-addon.js.map +1 -1
- package/dist/modern/dexie-cloud-addon.min.js +1 -1
- package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
- package/dist/modern/service-worker.js +146 -168
- 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/umd/dexie-cloud-addon.js +1623 -2458
- 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 +2003 -2838
- 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 +14 -11
- 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-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.2.
|
|
11
|
+
* Version 4.2.5, Sat Dec 20 2025
|
|
12
12
|
*
|
|
13
13
|
* https://dexie.org
|
|
14
14
|
*
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
37
37
|
PERFORMANCE OF THIS SOFTWARE.
|
|
38
38
|
***************************************************************************** */
|
|
39
|
-
/* global Reflect, Promise */
|
|
39
|
+
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
function __rest(s, e) {
|
|
@@ -80,8 +80,9 @@
|
|
|
80
80
|
function __asyncGenerator(thisArg, _arguments, generator) {
|
|
81
81
|
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
82
82
|
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
83
|
-
return i =
|
|
84
|
-
function
|
|
83
|
+
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
84
|
+
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
85
|
+
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
85
86
|
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
86
87
|
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
87
88
|
function fulfill(value) { resume("next", value); }
|
|
@@ -95,7 +96,12 @@
|
|
|
95
96
|
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
96
97
|
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
97
98
|
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
98
|
-
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
102
|
+
var e = new Error(message);
|
|
103
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
104
|
+
};
|
|
99
105
|
|
|
100
106
|
function assert(b) {
|
|
101
107
|
if (!b)
|
|
@@ -276,13 +282,12 @@
|
|
|
276
282
|
function subtractChanges(target, // Server change set
|
|
277
283
|
changesToSubtract // additional mutations on client during syncWithServer()
|
|
278
284
|
) {
|
|
279
|
-
var _a, _b, _c;
|
|
280
285
|
for (const [table, mutationSet] of Object.entries(changesToSubtract)) {
|
|
281
286
|
for (const [key, mut] of Object.entries(mutationSet)) {
|
|
282
287
|
switch (mut.type) {
|
|
283
288
|
case 'ups':
|
|
284
289
|
{
|
|
285
|
-
const targetMut =
|
|
290
|
+
const targetMut = target[table]?.[key];
|
|
286
291
|
if (targetMut) {
|
|
287
292
|
switch (targetMut.type) {
|
|
288
293
|
case 'ups':
|
|
@@ -300,10 +305,10 @@
|
|
|
300
305
|
}
|
|
301
306
|
break;
|
|
302
307
|
case 'del':
|
|
303
|
-
|
|
308
|
+
delete target[table]?.[key];
|
|
304
309
|
break;
|
|
305
310
|
case 'upd': {
|
|
306
|
-
const targetMut =
|
|
311
|
+
const targetMut = target[table]?.[key];
|
|
307
312
|
if (targetMut) {
|
|
308
313
|
switch (targetMut.type) {
|
|
309
314
|
case 'ups':
|
|
@@ -336,17 +341,14 @@
|
|
|
336
341
|
* @param inSet
|
|
337
342
|
* @returns DBOperationsSet representing inSet
|
|
338
343
|
*/
|
|
339
|
-
function toDBOperationSet(inSet, txid
|
|
340
|
-
// Fictive transaction:
|
|
341
|
-
if (!txid)
|
|
342
|
-
txid = randomString$1(16);
|
|
344
|
+
function toDBOperationSet(inSet, txid) {
|
|
343
345
|
// Convert data into a temporary map to collect mutations of same table and type
|
|
344
346
|
const map = {};
|
|
345
347
|
for (const [table, ops] of Object.entries(inSet)) {
|
|
346
348
|
for (const [key, op] of Object.entries(ops)) {
|
|
347
349
|
const mapEntry = map[table] || (map[table] = {});
|
|
348
350
|
const ops = mapEntry[op.type] || (mapEntry[op.type] = []);
|
|
349
|
-
ops.push(
|
|
351
|
+
ops.push({ key, ...op }); // DBKeyMutation doesn't contain key, so we need to bring it in.
|
|
350
352
|
}
|
|
351
353
|
}
|
|
352
354
|
// Start computing the resulting format:
|
|
@@ -407,8 +409,8 @@
|
|
|
407
409
|
* @module math
|
|
408
410
|
*/
|
|
409
411
|
|
|
410
|
-
const floor
|
|
411
|
-
const abs
|
|
412
|
+
const floor = Math.floor;
|
|
413
|
+
const abs = Math.abs;
|
|
412
414
|
|
|
413
415
|
/**
|
|
414
416
|
* @function
|
|
@@ -416,7 +418,7 @@
|
|
|
416
418
|
* @param {number} b
|
|
417
419
|
* @return {number} The smaller element of a and b
|
|
418
420
|
*/
|
|
419
|
-
const min
|
|
421
|
+
const min = (a, b) => a < b ? a : b;
|
|
420
422
|
|
|
421
423
|
/**
|
|
422
424
|
* @function
|
|
@@ -424,24 +426,41 @@
|
|
|
424
426
|
* @param {number} b
|
|
425
427
|
* @return {number} The bigger element of a and b
|
|
426
428
|
*/
|
|
427
|
-
const max
|
|
429
|
+
const max = (a, b) => a > b ? a : b;
|
|
428
430
|
|
|
429
431
|
/**
|
|
430
432
|
* @param {number} n
|
|
431
433
|
* @return {boolean} Wether n is negative. This function also differentiates between -0 and +0
|
|
432
434
|
*/
|
|
433
|
-
const isNegativeZero
|
|
435
|
+
const isNegativeZero = n => n !== 0 ? n < 0 : 1 / n < 0;
|
|
434
436
|
|
|
435
437
|
/* eslint-env browser */
|
|
436
438
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
439
|
+
/**
|
|
440
|
+
* Binary data constants.
|
|
441
|
+
*
|
|
442
|
+
* @module binary
|
|
443
|
+
*/
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* n-th bit activated.
|
|
447
|
+
*
|
|
448
|
+
* @type {number}
|
|
449
|
+
*/
|
|
450
|
+
const BIT1 = 1;
|
|
451
|
+
const BIT2 = 2;
|
|
452
|
+
const BIT3 = 4;
|
|
453
|
+
const BIT4 = 8;
|
|
454
|
+
const BIT6 = 32;
|
|
455
|
+
const BIT7 = 64;
|
|
456
|
+
const BIT8 = 128;
|
|
457
|
+
const BITS5 = 31;
|
|
458
|
+
const BITS6 = 63;
|
|
459
|
+
const BITS7 = 127;
|
|
441
460
|
/**
|
|
442
461
|
* @type {number}
|
|
443
462
|
*/
|
|
444
|
-
const BITS31
|
|
463
|
+
const BITS31 = 0x7FFFFFFF;
|
|
445
464
|
|
|
446
465
|
/**
|
|
447
466
|
* Utility helpers for working with numbers.
|
|
@@ -450,10 +469,18 @@
|
|
|
450
469
|
*/
|
|
451
470
|
|
|
452
471
|
|
|
453
|
-
const MAX_SAFE_INTEGER
|
|
472
|
+
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
|
|
454
473
|
|
|
455
474
|
/* c8 ignore next */
|
|
456
|
-
const isInteger
|
|
475
|
+
const isInteger = Number.isInteger || (num => typeof num === 'number' && isFinite(num) && floor(num) === num);
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Utility module to work with sets.
|
|
479
|
+
*
|
|
480
|
+
* @module set
|
|
481
|
+
*/
|
|
482
|
+
|
|
483
|
+
const create$5 = () => new Set();
|
|
457
484
|
|
|
458
485
|
/**
|
|
459
486
|
* Utility module to work with Arrays.
|
|
@@ -462,13 +489,68 @@
|
|
|
462
489
|
*/
|
|
463
490
|
|
|
464
491
|
|
|
465
|
-
|
|
492
|
+
/**
|
|
493
|
+
* Return the last element of an array. The element must exist
|
|
494
|
+
*
|
|
495
|
+
* @template L
|
|
496
|
+
* @param {ArrayLike<L>} arr
|
|
497
|
+
* @return {L}
|
|
498
|
+
*/
|
|
499
|
+
const last = arr => arr[arr.length - 1];
|
|
500
|
+
|
|
501
|
+
/**
|
|
502
|
+
* Append elements from src to dest
|
|
503
|
+
*
|
|
504
|
+
* @template M
|
|
505
|
+
* @param {Array<M>} dest
|
|
506
|
+
* @param {Array<M>} src
|
|
507
|
+
*/
|
|
508
|
+
const appendTo = (dest, src) => {
|
|
509
|
+
for (let i = 0; i < src.length; i++) {
|
|
510
|
+
dest.push(src[i]);
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Transforms something array-like to an actual Array.
|
|
516
|
+
*
|
|
517
|
+
* @function
|
|
518
|
+
* @template T
|
|
519
|
+
* @param {ArrayLike<T>|Iterable<T>} arraylike
|
|
520
|
+
* @return {T}
|
|
521
|
+
*/
|
|
522
|
+
const from = Array.from;
|
|
523
|
+
|
|
524
|
+
const isArray = Array.isArray;
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* @param {string} s
|
|
528
|
+
* @return {string}
|
|
529
|
+
*/
|
|
530
|
+
const toLowerCase = s => s.toLowerCase();
|
|
531
|
+
|
|
532
|
+
const trimLeftRegex = /^\s*/g;
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* @param {string} s
|
|
536
|
+
* @return {string}
|
|
537
|
+
*/
|
|
538
|
+
const trimLeft = s => s.replace(trimLeftRegex, '');
|
|
539
|
+
|
|
540
|
+
const fromCamelCaseRegex = /([A-Z])/g;
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* @param {string} s
|
|
544
|
+
* @param {string} separator
|
|
545
|
+
* @return {string}
|
|
546
|
+
*/
|
|
547
|
+
const fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, match => `${separator}${toLowerCase(match)}`));
|
|
466
548
|
|
|
467
549
|
/**
|
|
468
550
|
* @param {string} str
|
|
469
551
|
* @return {Uint8Array}
|
|
470
552
|
*/
|
|
471
|
-
const _encodeUtf8Polyfill
|
|
553
|
+
const _encodeUtf8Polyfill = str => {
|
|
472
554
|
const encodedString = unescape(encodeURIComponent(str));
|
|
473
555
|
const len = encodedString.length;
|
|
474
556
|
const buf = new Uint8Array(len);
|
|
@@ -479,33 +561,33 @@
|
|
|
479
561
|
};
|
|
480
562
|
|
|
481
563
|
/* c8 ignore next */
|
|
482
|
-
const utf8TextEncoder
|
|
564
|
+
const utf8TextEncoder = /** @type {TextEncoder} */ (typeof TextEncoder !== 'undefined' ? new TextEncoder() : null);
|
|
483
565
|
|
|
484
566
|
/**
|
|
485
567
|
* @param {string} str
|
|
486
568
|
* @return {Uint8Array}
|
|
487
569
|
*/
|
|
488
|
-
const _encodeUtf8Native
|
|
570
|
+
const _encodeUtf8Native = str => utf8TextEncoder.encode(str);
|
|
489
571
|
|
|
490
572
|
/**
|
|
491
573
|
* @param {string} str
|
|
492
574
|
* @return {Uint8Array}
|
|
493
575
|
*/
|
|
494
576
|
/* c8 ignore next */
|
|
495
|
-
const encodeUtf8
|
|
577
|
+
const encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill;
|
|
496
578
|
|
|
497
579
|
/* c8 ignore next */
|
|
498
|
-
let utf8TextDecoder
|
|
580
|
+
let utf8TextDecoder = typeof TextDecoder === 'undefined' ? null : new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
|
|
499
581
|
|
|
500
582
|
/* c8 ignore start */
|
|
501
|
-
if (utf8TextDecoder
|
|
583
|
+
if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) {
|
|
502
584
|
// Safari doesn't handle BOM correctly.
|
|
503
585
|
// This fixes a bug in Safari 13.0.5 where it produces a BOM the first time it is called.
|
|
504
586
|
// utf8TextDecoder.decode(new Uint8Array()).length === 1 on the first call and
|
|
505
587
|
// utf8TextDecoder.decode(new Uint8Array()).length === 1 on the second call
|
|
506
588
|
// Another issue is that from then on no BOM chars are recognized anymore
|
|
507
589
|
/* c8 ignore next */
|
|
508
|
-
utf8TextDecoder
|
|
590
|
+
utf8TextDecoder = null;
|
|
509
591
|
}
|
|
510
592
|
|
|
511
593
|
/**
|
|
@@ -540,7 +622,7 @@
|
|
|
540
622
|
/**
|
|
541
623
|
* A BinaryEncoder handles the encoding to an Uint8Array.
|
|
542
624
|
*/
|
|
543
|
-
|
|
625
|
+
class Encoder {
|
|
544
626
|
constructor () {
|
|
545
627
|
this.cpos = 0;
|
|
546
628
|
this.cbuf = new Uint8Array(100);
|
|
@@ -549,7 +631,13 @@
|
|
|
549
631
|
*/
|
|
550
632
|
this.bufs = [];
|
|
551
633
|
}
|
|
552
|
-
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
/**
|
|
637
|
+
* @function
|
|
638
|
+
* @return {Encoder}
|
|
639
|
+
*/
|
|
640
|
+
const createEncoder = () => new Encoder();
|
|
553
641
|
|
|
554
642
|
/**
|
|
555
643
|
* The current length of the encoded data.
|
|
@@ -558,7 +646,7 @@
|
|
|
558
646
|
* @param {Encoder} encoder
|
|
559
647
|
* @return {number}
|
|
560
648
|
*/
|
|
561
|
-
const length$
|
|
649
|
+
const length$1 = encoder => {
|
|
562
650
|
let len = encoder.cpos;
|
|
563
651
|
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
564
652
|
len += encoder.bufs[i].length;
|
|
@@ -573,8 +661,8 @@
|
|
|
573
661
|
* @param {Encoder} encoder
|
|
574
662
|
* @return {Uint8Array} The created ArrayBuffer.
|
|
575
663
|
*/
|
|
576
|
-
const toUint8Array
|
|
577
|
-
const uint8arr = new Uint8Array(length$
|
|
664
|
+
const toUint8Array = encoder => {
|
|
665
|
+
const uint8arr = new Uint8Array(length$1(encoder));
|
|
578
666
|
let curPos = 0;
|
|
579
667
|
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
580
668
|
const d = encoder.bufs[i];
|
|
@@ -592,11 +680,11 @@
|
|
|
592
680
|
* @param {Encoder} encoder
|
|
593
681
|
* @param {number} len
|
|
594
682
|
*/
|
|
595
|
-
const verifyLen
|
|
683
|
+
const verifyLen = (encoder, len) => {
|
|
596
684
|
const bufferLen = encoder.cbuf.length;
|
|
597
685
|
if (bufferLen - encoder.cpos < len) {
|
|
598
686
|
encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos));
|
|
599
|
-
encoder.cbuf = new Uint8Array(max
|
|
687
|
+
encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2);
|
|
600
688
|
encoder.cpos = 0;
|
|
601
689
|
}
|
|
602
690
|
};
|
|
@@ -608,7 +696,7 @@
|
|
|
608
696
|
* @param {Encoder} encoder
|
|
609
697
|
* @param {number} num The byte that is to be encoded.
|
|
610
698
|
*/
|
|
611
|
-
const write
|
|
699
|
+
const write = (encoder, num) => {
|
|
612
700
|
const bufferLen = encoder.cbuf.length;
|
|
613
701
|
if (encoder.cpos === bufferLen) {
|
|
614
702
|
encoder.bufs.push(encoder.cbuf);
|
|
@@ -618,6 +706,15 @@
|
|
|
618
706
|
encoder.cbuf[encoder.cpos++] = num;
|
|
619
707
|
};
|
|
620
708
|
|
|
709
|
+
/**
|
|
710
|
+
* Write one byte as an unsigned integer.
|
|
711
|
+
*
|
|
712
|
+
* @function
|
|
713
|
+
* @param {Encoder} encoder
|
|
714
|
+
* @param {number} num The number that is to be encoded.
|
|
715
|
+
*/
|
|
716
|
+
const writeUint8 = write;
|
|
717
|
+
|
|
621
718
|
/**
|
|
622
719
|
* Write a variable length unsigned integer. Max encodable integer is 2^53.
|
|
623
720
|
*
|
|
@@ -625,12 +722,12 @@
|
|
|
625
722
|
* @param {Encoder} encoder
|
|
626
723
|
* @param {number} num The number that is to be encoded.
|
|
627
724
|
*/
|
|
628
|
-
const writeVarUint
|
|
629
|
-
while (num > BITS7
|
|
630
|
-
write
|
|
631
|
-
num = floor
|
|
725
|
+
const writeVarUint = (encoder, num) => {
|
|
726
|
+
while (num > BITS7) {
|
|
727
|
+
write(encoder, BIT8 | (BITS7 & num));
|
|
728
|
+
num = floor(num / 128); // shift >>> 7
|
|
632
729
|
}
|
|
633
|
-
write
|
|
730
|
+
write(encoder, BITS7 & num);
|
|
634
731
|
};
|
|
635
732
|
|
|
636
733
|
/**
|
|
@@ -642,27 +739,27 @@
|
|
|
642
739
|
* @param {Encoder} encoder
|
|
643
740
|
* @param {number} num The number that is to be encoded.
|
|
644
741
|
*/
|
|
645
|
-
const writeVarInt
|
|
646
|
-
const isNegative = isNegativeZero
|
|
742
|
+
const writeVarInt = (encoder, num) => {
|
|
743
|
+
const isNegative = isNegativeZero(num);
|
|
647
744
|
if (isNegative) {
|
|
648
745
|
num = -num;
|
|
649
746
|
}
|
|
650
747
|
// |- whether to continue reading |- whether is negative |- number
|
|
651
|
-
write
|
|
652
|
-
num = floor
|
|
748
|
+
write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | (BITS6 & num));
|
|
749
|
+
num = floor(num / 64); // shift >>> 6
|
|
653
750
|
// We don't need to consider the case of num === 0 so we can use a different
|
|
654
751
|
// pattern here than above.
|
|
655
752
|
while (num > 0) {
|
|
656
|
-
write
|
|
657
|
-
num = floor
|
|
753
|
+
write(encoder, (num > BITS7 ? BIT8 : 0) | (BITS7 & num));
|
|
754
|
+
num = floor(num / 128); // shift >>> 7
|
|
658
755
|
}
|
|
659
756
|
};
|
|
660
757
|
|
|
661
758
|
/**
|
|
662
759
|
* A cache to store strings temporarily
|
|
663
760
|
*/
|
|
664
|
-
const _strBuffer
|
|
665
|
-
const _maxStrBSize
|
|
761
|
+
const _strBuffer = new Uint8Array(30000);
|
|
762
|
+
const _maxStrBSize = _strBuffer.length / 3;
|
|
666
763
|
|
|
667
764
|
/**
|
|
668
765
|
* Write a variable length string.
|
|
@@ -671,17 +768,17 @@
|
|
|
671
768
|
* @param {Encoder} encoder
|
|
672
769
|
* @param {String} str The string that is to be encoded.
|
|
673
770
|
*/
|
|
674
|
-
const _writeVarStringNative
|
|
675
|
-
if (str.length < _maxStrBSize
|
|
771
|
+
const _writeVarStringNative = (encoder, str) => {
|
|
772
|
+
if (str.length < _maxStrBSize) {
|
|
676
773
|
// We can encode the string into the existing buffer
|
|
677
774
|
/* c8 ignore next */
|
|
678
|
-
const written = utf8TextEncoder
|
|
679
|
-
writeVarUint
|
|
775
|
+
const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0;
|
|
776
|
+
writeVarUint(encoder, written);
|
|
680
777
|
for (let i = 0; i < written; i++) {
|
|
681
|
-
write
|
|
778
|
+
write(encoder, _strBuffer[i]);
|
|
682
779
|
}
|
|
683
780
|
} else {
|
|
684
|
-
writeVarUint8Array
|
|
781
|
+
writeVarUint8Array(encoder, encodeUtf8(str));
|
|
685
782
|
}
|
|
686
783
|
};
|
|
687
784
|
|
|
@@ -692,12 +789,12 @@
|
|
|
692
789
|
* @param {Encoder} encoder
|
|
693
790
|
* @param {String} str The string that is to be encoded.
|
|
694
791
|
*/
|
|
695
|
-
const _writeVarStringPolyfill
|
|
792
|
+
const _writeVarStringPolyfill = (encoder, str) => {
|
|
696
793
|
const encodedString = unescape(encodeURIComponent(str));
|
|
697
794
|
const len = encodedString.length;
|
|
698
|
-
writeVarUint
|
|
795
|
+
writeVarUint(encoder, len);
|
|
699
796
|
for (let i = 0; i < len; i++) {
|
|
700
|
-
write
|
|
797
|
+
write(encoder, /** @type {number} */ (encodedString.codePointAt(i)));
|
|
701
798
|
}
|
|
702
799
|
};
|
|
703
800
|
|
|
@@ -709,7 +806,20 @@
|
|
|
709
806
|
* @param {String} str The string that is to be encoded.
|
|
710
807
|
*/
|
|
711
808
|
/* c8 ignore next */
|
|
712
|
-
const writeVarString
|
|
809
|
+
const writeVarString = (utf8TextEncoder && /** @type {any} */ (utf8TextEncoder).encodeInto) ? _writeVarStringNative : _writeVarStringPolyfill;
|
|
810
|
+
|
|
811
|
+
/**
|
|
812
|
+
* Write the content of another Encoder.
|
|
813
|
+
*
|
|
814
|
+
* @TODO: can be improved!
|
|
815
|
+
* - Note: Should consider that when appending a lot of small Encoders, we should rather clone than referencing the old structure.
|
|
816
|
+
* Encoders start with a rather big initial buffer.
|
|
817
|
+
*
|
|
818
|
+
* @function
|
|
819
|
+
* @param {Encoder} encoder The enUint8Arr
|
|
820
|
+
* @param {Encoder} append The BinaryEncoder to be written.
|
|
821
|
+
*/
|
|
822
|
+
const writeBinaryEncoder = (encoder, append) => writeUint8Array(encoder, toUint8Array(append));
|
|
713
823
|
|
|
714
824
|
/**
|
|
715
825
|
* Append fixed-length Uint8Array to the encoder.
|
|
@@ -718,10 +828,10 @@
|
|
|
718
828
|
* @param {Encoder} encoder
|
|
719
829
|
* @param {Uint8Array} uint8Array
|
|
720
830
|
*/
|
|
721
|
-
const writeUint8Array
|
|
831
|
+
const writeUint8Array = (encoder, uint8Array) => {
|
|
722
832
|
const bufferLen = encoder.cbuf.length;
|
|
723
833
|
const cpos = encoder.cpos;
|
|
724
|
-
const leftCopyLen = min
|
|
834
|
+
const leftCopyLen = min(bufferLen - cpos, uint8Array.length);
|
|
725
835
|
const rightCopyLen = uint8Array.length - leftCopyLen;
|
|
726
836
|
encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos);
|
|
727
837
|
encoder.cpos += leftCopyLen;
|
|
@@ -730,7 +840,7 @@
|
|
|
730
840
|
// Append new buffer
|
|
731
841
|
encoder.bufs.push(encoder.cbuf);
|
|
732
842
|
// must have at least size of remaining buffer
|
|
733
|
-
encoder.cbuf = new Uint8Array(max
|
|
843
|
+
encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen));
|
|
734
844
|
// copy array
|
|
735
845
|
encoder.cbuf.set(uint8Array.subarray(leftCopyLen));
|
|
736
846
|
encoder.cpos = rightCopyLen;
|
|
@@ -744,9 +854,9 @@
|
|
|
744
854
|
* @param {Encoder} encoder
|
|
745
855
|
* @param {Uint8Array} uint8Array
|
|
746
856
|
*/
|
|
747
|
-
const writeVarUint8Array
|
|
748
|
-
writeVarUint
|
|
749
|
-
writeUint8Array
|
|
857
|
+
const writeVarUint8Array = (encoder, uint8Array) => {
|
|
858
|
+
writeVarUint(encoder, uint8Array.byteLength);
|
|
859
|
+
writeUint8Array(encoder, uint8Array);
|
|
750
860
|
};
|
|
751
861
|
|
|
752
862
|
/**
|
|
@@ -766,8 +876,8 @@
|
|
|
766
876
|
* @param {number} len
|
|
767
877
|
* @return {DataView}
|
|
768
878
|
*/
|
|
769
|
-
const writeOnDataView
|
|
770
|
-
verifyLen
|
|
879
|
+
const writeOnDataView = (encoder, len) => {
|
|
880
|
+
verifyLen(encoder, len);
|
|
771
881
|
const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len);
|
|
772
882
|
encoder.cpos += len;
|
|
773
883
|
return dview
|
|
@@ -777,36 +887,36 @@
|
|
|
777
887
|
* @param {Encoder} encoder
|
|
778
888
|
* @param {number} num
|
|
779
889
|
*/
|
|
780
|
-
const writeFloat32
|
|
890
|
+
const writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false);
|
|
781
891
|
|
|
782
892
|
/**
|
|
783
893
|
* @param {Encoder} encoder
|
|
784
894
|
* @param {number} num
|
|
785
895
|
*/
|
|
786
|
-
const writeFloat64
|
|
896
|
+
const writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false);
|
|
787
897
|
|
|
788
898
|
/**
|
|
789
899
|
* @param {Encoder} encoder
|
|
790
900
|
* @param {bigint} num
|
|
791
901
|
*/
|
|
792
|
-
const writeBigInt64
|
|
902
|
+
const writeBigInt64 = (encoder, num) => /** @type {any} */ (writeOnDataView(encoder, 8)).setBigInt64(0, num, false);
|
|
793
903
|
|
|
794
904
|
/**
|
|
795
905
|
* @param {Encoder} encoder
|
|
796
906
|
* @param {bigint} num
|
|
797
907
|
*/
|
|
798
|
-
const writeBigUint64 = (encoder, num) => /** @type {any} */ (writeOnDataView
|
|
908
|
+
const writeBigUint64 = (encoder, num) => /** @type {any} */ (writeOnDataView(encoder, 8)).setBigUint64(0, num, false);
|
|
799
909
|
|
|
800
|
-
const floatTestBed
|
|
910
|
+
const floatTestBed = new DataView(new ArrayBuffer(4));
|
|
801
911
|
/**
|
|
802
912
|
* Check if a number can be encoded as a 32 bit float.
|
|
803
913
|
*
|
|
804
914
|
* @param {number} num
|
|
805
915
|
* @return {boolean}
|
|
806
916
|
*/
|
|
807
|
-
const isFloat32
|
|
808
|
-
floatTestBed
|
|
809
|
-
return floatTestBed
|
|
917
|
+
const isFloat32 = num => {
|
|
918
|
+
floatTestBed.setFloat32(0, num);
|
|
919
|
+
return floatTestBed.getFloat32(0) === num
|
|
810
920
|
};
|
|
811
921
|
|
|
812
922
|
/**
|
|
@@ -846,795 +956,1137 @@
|
|
|
846
956
|
* @param {Encoder} encoder
|
|
847
957
|
* @param {undefined|null|number|bigint|boolean|string|Object<string,any>|Array<any>|Uint8Array} data
|
|
848
958
|
*/
|
|
849
|
-
const writeAny
|
|
959
|
+
const writeAny = (encoder, data) => {
|
|
850
960
|
switch (typeof data) {
|
|
851
961
|
case 'string':
|
|
852
962
|
// TYPE 119: STRING
|
|
853
|
-
write
|
|
854
|
-
writeVarString
|
|
963
|
+
write(encoder, 119);
|
|
964
|
+
writeVarString(encoder, data);
|
|
855
965
|
break
|
|
856
966
|
case 'number':
|
|
857
|
-
if (isInteger
|
|
967
|
+
if (isInteger(data) && abs(data) <= BITS31) {
|
|
858
968
|
// TYPE 125: INTEGER
|
|
859
|
-
write
|
|
860
|
-
writeVarInt
|
|
861
|
-
} else if (isFloat32
|
|
969
|
+
write(encoder, 125);
|
|
970
|
+
writeVarInt(encoder, data);
|
|
971
|
+
} else if (isFloat32(data)) {
|
|
862
972
|
// TYPE 124: FLOAT32
|
|
863
|
-
write
|
|
864
|
-
writeFloat32
|
|
973
|
+
write(encoder, 124);
|
|
974
|
+
writeFloat32(encoder, data);
|
|
865
975
|
} else {
|
|
866
976
|
// TYPE 123: FLOAT64
|
|
867
|
-
write
|
|
868
|
-
writeFloat64
|
|
977
|
+
write(encoder, 123);
|
|
978
|
+
writeFloat64(encoder, data);
|
|
869
979
|
}
|
|
870
980
|
break
|
|
871
981
|
case 'bigint':
|
|
872
982
|
// TYPE 122: BigInt
|
|
873
|
-
write
|
|
874
|
-
writeBigInt64
|
|
983
|
+
write(encoder, 122);
|
|
984
|
+
writeBigInt64(encoder, data);
|
|
875
985
|
break
|
|
876
986
|
case 'object':
|
|
877
987
|
if (data === null) {
|
|
878
988
|
// TYPE 126: null
|
|
879
|
-
write
|
|
880
|
-
} else if (isArray
|
|
989
|
+
write(encoder, 126);
|
|
990
|
+
} else if (isArray(data)) {
|
|
881
991
|
// TYPE 117: Array
|
|
882
|
-
write
|
|
883
|
-
writeVarUint
|
|
992
|
+
write(encoder, 117);
|
|
993
|
+
writeVarUint(encoder, data.length);
|
|
884
994
|
for (let i = 0; i < data.length; i++) {
|
|
885
|
-
writeAny
|
|
995
|
+
writeAny(encoder, data[i]);
|
|
886
996
|
}
|
|
887
997
|
} else if (data instanceof Uint8Array) {
|
|
888
998
|
// TYPE 116: ArrayBuffer
|
|
889
|
-
write
|
|
890
|
-
writeVarUint8Array
|
|
999
|
+
write(encoder, 116);
|
|
1000
|
+
writeVarUint8Array(encoder, data);
|
|
891
1001
|
} else {
|
|
892
1002
|
// TYPE 118: Object
|
|
893
|
-
write
|
|
1003
|
+
write(encoder, 118);
|
|
894
1004
|
const keys = Object.keys(data);
|
|
895
|
-
writeVarUint
|
|
1005
|
+
writeVarUint(encoder, keys.length);
|
|
896
1006
|
for (let i = 0; i < keys.length; i++) {
|
|
897
1007
|
const key = keys[i];
|
|
898
|
-
writeVarString
|
|
899
|
-
writeAny
|
|
1008
|
+
writeVarString(encoder, key);
|
|
1009
|
+
writeAny(encoder, data[key]);
|
|
900
1010
|
}
|
|
901
1011
|
}
|
|
902
1012
|
break
|
|
903
1013
|
case 'boolean':
|
|
904
1014
|
// TYPE 120/121: boolean (true/false)
|
|
905
|
-
write
|
|
1015
|
+
write(encoder, data ? 120 : 121);
|
|
906
1016
|
break
|
|
907
1017
|
default:
|
|
908
1018
|
// TYPE 127: undefined
|
|
909
|
-
write
|
|
1019
|
+
write(encoder, 127);
|
|
910
1020
|
}
|
|
911
1021
|
};
|
|
912
1022
|
|
|
913
|
-
function encodeYMessage(msg) {
|
|
914
|
-
const encoder = new Encoder$1();
|
|
915
|
-
writeVarString$1(encoder, msg.type);
|
|
916
|
-
if ('table' in msg)
|
|
917
|
-
writeVarString$1(encoder, msg.table);
|
|
918
|
-
if ('prop' in msg)
|
|
919
|
-
writeVarString$1(encoder, msg.prop);
|
|
920
|
-
switch (msg.type) {
|
|
921
|
-
case 'u-ack':
|
|
922
|
-
case 'u-reject':
|
|
923
|
-
writeBigUint64(encoder, BigInt(msg.i));
|
|
924
|
-
break;
|
|
925
|
-
case 'outdated-server-rev':
|
|
926
|
-
break;
|
|
927
|
-
case 'y-complete-sync-done':
|
|
928
|
-
writeVarString$1(encoder, msg.yServerRev);
|
|
929
|
-
break;
|
|
930
|
-
default:
|
|
931
|
-
writeAny$1(encoder, msg.k);
|
|
932
|
-
switch (msg.type) {
|
|
933
|
-
case 'aware':
|
|
934
|
-
writeVarUint8Array$1(encoder, msg.u);
|
|
935
|
-
break;
|
|
936
|
-
case 'doc-open':
|
|
937
|
-
writeAny$1(encoder, msg.serverRev);
|
|
938
|
-
writeAny$1(encoder, msg.sv);
|
|
939
|
-
break;
|
|
940
|
-
case 'doc-close':
|
|
941
|
-
break;
|
|
942
|
-
case 'sv':
|
|
943
|
-
writeVarUint8Array$1(encoder, msg.sv);
|
|
944
|
-
break;
|
|
945
|
-
case 'u-c':
|
|
946
|
-
writeVarUint8Array$1(encoder, msg.u);
|
|
947
|
-
writeBigUint64(encoder, BigInt(msg.i));
|
|
948
|
-
break;
|
|
949
|
-
case 'u-s':
|
|
950
|
-
writeVarUint8Array$1(encoder, msg.u);
|
|
951
|
-
writeVarString$1(encoder, msg.r || '');
|
|
952
|
-
break;
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
return toUint8Array$1(encoder);
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
/**
|
|
959
|
-
* Error helpers.
|
|
960
|
-
*
|
|
961
|
-
* @module error
|
|
962
|
-
*/
|
|
963
|
-
|
|
964
1023
|
/**
|
|
965
|
-
*
|
|
966
|
-
* @return {Error}
|
|
1024
|
+
* Now come a few stateful encoder that have their own classes.
|
|
967
1025
|
*/
|
|
968
|
-
/* c8 ignore next */
|
|
969
|
-
const create$6 = s => new Error(s);
|
|
970
1026
|
|
|
971
1027
|
/**
|
|
972
|
-
*
|
|
1028
|
+
* Basic Run Length Encoder - a basic compression implementation.
|
|
973
1029
|
*
|
|
974
|
-
*
|
|
1030
|
+
* Encodes [1,1,1,7] to [1,3,7,1] (3 times 1, 1 time 7). This encoder might do more harm than good if there are a lot of values that are not repeated.
|
|
975
1031
|
*
|
|
976
|
-
*
|
|
977
|
-
* and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
|
|
978
|
-
* which is also used in Protocol Buffers.
|
|
1032
|
+
* It was originally used for image compression. Cool .. article http://csbruce.com/cbm/transactor/pdfs/trans_v7_i06.pdf
|
|
979
1033
|
*
|
|
980
|
-
*
|
|
981
|
-
* // encoding step
|
|
982
|
-
* const encoder = encoding.createEncoder()
|
|
983
|
-
* encoding.writeVarUint(encoder, 256)
|
|
984
|
-
* encoding.writeVarString(encoder, 'Hello world!')
|
|
985
|
-
* const buf = encoding.toUint8Array(encoder)
|
|
986
|
-
* ```
|
|
987
|
-
*
|
|
988
|
-
* ```js
|
|
989
|
-
* // decoding step
|
|
990
|
-
* const decoder = decoding.createDecoder(buf)
|
|
991
|
-
* decoding.readVarUint(decoder) // => 256
|
|
992
|
-
* decoding.readVarString(decoder) // => 'Hello world!'
|
|
993
|
-
* decoding.hasContent(decoder) // => false - all data is read
|
|
994
|
-
* ```
|
|
1034
|
+
* @note T must not be null!
|
|
995
1035
|
*
|
|
996
|
-
* @
|
|
997
|
-
*/
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
const errorUnexpectedEndOfArray$1 = create$6('Unexpected end of array');
|
|
1001
|
-
const errorIntegerOutOfRange$1 = create$6('Integer out of Range');
|
|
1002
|
-
|
|
1003
|
-
/**
|
|
1004
|
-
* A Decoder handles the decoding of an Uint8Array.
|
|
1036
|
+
* @template T
|
|
1005
1037
|
*/
|
|
1006
|
-
|
|
1038
|
+
class RleEncoder extends Encoder {
|
|
1007
1039
|
/**
|
|
1008
|
-
* @param {
|
|
1040
|
+
* @param {function(Encoder, T):void} writer
|
|
1009
1041
|
*/
|
|
1010
|
-
constructor (
|
|
1042
|
+
constructor (writer) {
|
|
1043
|
+
super();
|
|
1011
1044
|
/**
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
1014
|
-
* @type {Uint8Array}
|
|
1045
|
+
* The writer
|
|
1015
1046
|
*/
|
|
1016
|
-
this.
|
|
1047
|
+
this.w = writer;
|
|
1017
1048
|
/**
|
|
1018
|
-
* Current
|
|
1019
|
-
*
|
|
1020
|
-
* @type {number}
|
|
1049
|
+
* Current state
|
|
1050
|
+
* @type {T|null}
|
|
1021
1051
|
*/
|
|
1022
|
-
this.
|
|
1052
|
+
this.s = null;
|
|
1053
|
+
this.count = 0;
|
|
1023
1054
|
}
|
|
1024
|
-
};
|
|
1025
1055
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1056
|
+
/**
|
|
1057
|
+
* @param {T} v
|
|
1058
|
+
*/
|
|
1059
|
+
write (v) {
|
|
1060
|
+
if (this.s === v) {
|
|
1061
|
+
this.count++;
|
|
1062
|
+
} else {
|
|
1063
|
+
if (this.count > 0) {
|
|
1064
|
+
// flush counter, unless this is the first value (count = 0)
|
|
1065
|
+
writeVarUint(this, this.count - 1); // since count is always > 0, we can decrement by one. non-standard encoding ftw
|
|
1066
|
+
}
|
|
1067
|
+
this.count = 1;
|
|
1068
|
+
// write first value
|
|
1069
|
+
this.w(this, v);
|
|
1070
|
+
this.s = v;
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1032
1074
|
|
|
1033
1075
|
/**
|
|
1034
|
-
*
|
|
1035
|
-
*
|
|
1036
|
-
* Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.
|
|
1037
|
-
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
1038
|
-
*
|
|
1039
|
-
* @function
|
|
1040
|
-
* @param {Decoder} decoder The decoder instance
|
|
1041
|
-
* @param {number} len The length of bytes to read
|
|
1042
|
-
* @return {Uint8Array}
|
|
1076
|
+
* @param {UintOptRleEncoder} encoder
|
|
1043
1077
|
*/
|
|
1044
|
-
const
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1078
|
+
const flushUintOptRleEncoder = encoder => {
|
|
1079
|
+
if (encoder.count > 0) {
|
|
1080
|
+
// flush counter, unless this is the first value (count = 0)
|
|
1081
|
+
// case 1: just a single value. set sign to positive
|
|
1082
|
+
// case 2: write several values. set sign to negative to indicate that there is a length coming
|
|
1083
|
+
writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s);
|
|
1084
|
+
if (encoder.count > 1) {
|
|
1085
|
+
writeVarUint(encoder.encoder, encoder.count - 2); // since count is always > 1, we can decrement by one. non-standard encoding ftw
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1048
1088
|
};
|
|
1049
1089
|
|
|
1050
1090
|
/**
|
|
1051
|
-
*
|
|
1091
|
+
* Optimized Rle encoder that does not suffer from the mentioned problem of the basic Rle encoder.
|
|
1052
1092
|
*
|
|
1053
|
-
*
|
|
1054
|
-
*
|
|
1093
|
+
* Internally uses VarInt encoder to write unsigned integers. If the input occurs multiple times, we write
|
|
1094
|
+
* write it as a negative number. The UintOptRleDecoder then understands that it needs to read a count.
|
|
1055
1095
|
*
|
|
1056
|
-
*
|
|
1057
|
-
* @param {Decoder} decoder
|
|
1058
|
-
* @return {Uint8Array}
|
|
1096
|
+
* Encodes [1,2,3,3,3] as [1,2,-3,3] (once 1, once 2, three times 3)
|
|
1059
1097
|
*/
|
|
1060
|
-
|
|
1098
|
+
class UintOptRleEncoder {
|
|
1099
|
+
constructor () {
|
|
1100
|
+
this.encoder = new Encoder();
|
|
1101
|
+
/**
|
|
1102
|
+
* @type {number}
|
|
1103
|
+
*/
|
|
1104
|
+
this.s = 0;
|
|
1105
|
+
this.count = 0;
|
|
1106
|
+
}
|
|
1061
1107
|
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1108
|
+
/**
|
|
1109
|
+
* @param {number} v
|
|
1110
|
+
*/
|
|
1111
|
+
write (v) {
|
|
1112
|
+
if (this.s === v) {
|
|
1113
|
+
this.count++;
|
|
1114
|
+
} else {
|
|
1115
|
+
flushUintOptRleEncoder(this);
|
|
1116
|
+
this.count = 1;
|
|
1117
|
+
this.s = v;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
/**
|
|
1122
|
+
* Flush the encoded state and transform this to a Uint8Array.
|
|
1123
|
+
*
|
|
1124
|
+
* Note that this should only be called once.
|
|
1125
|
+
*/
|
|
1126
|
+
toUint8Array () {
|
|
1127
|
+
flushUintOptRleEncoder(this);
|
|
1128
|
+
return toUint8Array(this.encoder)
|
|
1129
|
+
}
|
|
1130
|
+
}
|
|
1069
1131
|
|
|
1070
1132
|
/**
|
|
1071
|
-
*
|
|
1072
|
-
* 1/8th of the storage is used as encoding overhead.
|
|
1073
|
-
* * numbers < 2^7 is stored in one bytlength
|
|
1074
|
-
* * numbers < 2^14 is stored in two bylength
|
|
1075
|
-
*
|
|
1076
|
-
* @function
|
|
1077
|
-
* @param {Decoder} decoder
|
|
1078
|
-
* @return {number} An unsigned integer.length
|
|
1133
|
+
* @param {IntDiffOptRleEncoder} encoder
|
|
1079
1134
|
*/
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
//
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
if (
|
|
1090
|
-
|
|
1091
|
-
}
|
|
1092
|
-
/* c8 ignore start */
|
|
1093
|
-
if (num > MAX_SAFE_INTEGER$1) {
|
|
1094
|
-
throw errorIntegerOutOfRange$1
|
|
1135
|
+
const flushIntDiffOptRleEncoder = encoder => {
|
|
1136
|
+
if (encoder.count > 0) {
|
|
1137
|
+
// 31 bit making up the diff | wether to write the counter
|
|
1138
|
+
// const encodedDiff = encoder.diff << 1 | (encoder.count === 1 ? 0 : 1)
|
|
1139
|
+
const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1);
|
|
1140
|
+
// flush counter, unless this is the first value (count = 0)
|
|
1141
|
+
// case 1: just a single value. set first bit to positive
|
|
1142
|
+
// case 2: write several values. set first bit to negative to indicate that there is a length coming
|
|
1143
|
+
writeVarInt(encoder.encoder, encodedDiff);
|
|
1144
|
+
if (encoder.count > 1) {
|
|
1145
|
+
writeVarUint(encoder.encoder, encoder.count - 2); // since count is always > 1, we can decrement by one. non-standard encoding ftw
|
|
1095
1146
|
}
|
|
1096
|
-
/* c8 ignore stop */
|
|
1097
1147
|
}
|
|
1098
|
-
throw errorUnexpectedEndOfArray$1
|
|
1099
1148
|
};
|
|
1100
1149
|
|
|
1101
1150
|
/**
|
|
1102
|
-
*
|
|
1103
|
-
* 1/8th of the storage is used as encoding overhead.
|
|
1104
|
-
* * numbers < 2^7 is stored in one bytlength
|
|
1105
|
-
* * numbers < 2^14 is stored in two bylength
|
|
1106
|
-
* @todo This should probably create the inverse ~num if number is negative - but this would be a breaking change.
|
|
1151
|
+
* A combination of the IntDiffEncoder and the UintOptRleEncoder.
|
|
1107
1152
|
*
|
|
1108
|
-
*
|
|
1109
|
-
*
|
|
1110
|
-
*
|
|
1153
|
+
* The count approach is similar to the UintDiffOptRleEncoder, but instead of using the negative bitflag, it encodes
|
|
1154
|
+
* in the LSB whether a count is to be read. Therefore this Encoder only supports 31 bit integers!
|
|
1155
|
+
*
|
|
1156
|
+
* Encodes [1, 2, 3, 2] as [3, 1, 6, -1] (more specifically [(1 << 1) | 1, (3 << 0) | 0, -1])
|
|
1157
|
+
*
|
|
1158
|
+
* Internally uses variable length encoding. Contrary to normal UintVar encoding, the first byte contains:
|
|
1159
|
+
* * 1 bit that denotes whether the next value is a count (LSB)
|
|
1160
|
+
* * 1 bit that denotes whether this value is negative (MSB - 1)
|
|
1161
|
+
* * 1 bit that denotes whether to continue reading the variable length integer (MSB)
|
|
1162
|
+
*
|
|
1163
|
+
* Therefore, only five bits remain to encode diff ranges.
|
|
1164
|
+
*
|
|
1165
|
+
* Use this Encoder only when appropriate. In most cases, this is probably a bad idea.
|
|
1111
1166
|
*/
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1167
|
+
class IntDiffOptRleEncoder {
|
|
1168
|
+
constructor () {
|
|
1169
|
+
this.encoder = new Encoder();
|
|
1170
|
+
/**
|
|
1171
|
+
* @type {number}
|
|
1172
|
+
*/
|
|
1173
|
+
this.s = 0;
|
|
1174
|
+
this.count = 0;
|
|
1175
|
+
this.diff = 0;
|
|
1120
1176
|
}
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1177
|
+
|
|
1178
|
+
/**
|
|
1179
|
+
* @param {number} v
|
|
1180
|
+
*/
|
|
1181
|
+
write (v) {
|
|
1182
|
+
if (this.diff === v - this.s) {
|
|
1183
|
+
this.s = v;
|
|
1184
|
+
this.count++;
|
|
1185
|
+
} else {
|
|
1186
|
+
flushIntDiffOptRleEncoder(this);
|
|
1187
|
+
this.count = 1;
|
|
1188
|
+
this.diff = v - this.s;
|
|
1189
|
+
this.s = v;
|
|
1133
1190
|
}
|
|
1134
|
-
/* c8 ignore stop */
|
|
1135
1191
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1192
|
+
|
|
1193
|
+
/**
|
|
1194
|
+
* Flush the encoded state and transform this to a Uint8Array.
|
|
1195
|
+
*
|
|
1196
|
+
* Note that this should only be called once.
|
|
1197
|
+
*/
|
|
1198
|
+
toUint8Array () {
|
|
1199
|
+
flushIntDiffOptRleEncoder(this);
|
|
1200
|
+
return toUint8Array(this.encoder)
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1138
1203
|
|
|
1139
1204
|
/**
|
|
1140
|
-
*
|
|
1141
|
-
* Better not modify this anymore..
|
|
1205
|
+
* Optimized String Encoder.
|
|
1142
1206
|
*
|
|
1143
|
-
*
|
|
1144
|
-
* when
|
|
1145
|
-
* But most environments have a maximum number of arguments per functions.
|
|
1146
|
-
* For effiency reasons we apply a maximum of 10000 characters at once.
|
|
1207
|
+
* Encoding many small strings in a simple Encoder is not very efficient. The function call to decode a string takes some time and creates references that must be eventually deleted.
|
|
1208
|
+
* In practice, when decoding several million small strings, the GC will kick in more and more often to collect orphaned string objects (or maybe there is another reason?).
|
|
1147
1209
|
*
|
|
1148
|
-
*
|
|
1149
|
-
*
|
|
1150
|
-
*
|
|
1210
|
+
* This string encoder solves the above problem. All strings are concatenated and written as a single string using a single encoding call.
|
|
1211
|
+
*
|
|
1212
|
+
* The lengths are encoded using a UintOptRleEncoder.
|
|
1151
1213
|
*/
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
encodedString += String.fromCodePoint.apply(null, /** @type {any} */ (bytes));
|
|
1171
|
-
remainingLen -= nextLen;
|
|
1172
|
-
}
|
|
1214
|
+
class StringEncoder {
|
|
1215
|
+
constructor () {
|
|
1216
|
+
/**
|
|
1217
|
+
* @type {Array<string>}
|
|
1218
|
+
*/
|
|
1219
|
+
this.sarr = [];
|
|
1220
|
+
this.s = '';
|
|
1221
|
+
this.lensE = new UintOptRleEncoder();
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
/**
|
|
1225
|
+
* @param {string} string
|
|
1226
|
+
*/
|
|
1227
|
+
write (string) {
|
|
1228
|
+
this.s += string;
|
|
1229
|
+
if (this.s.length > 19) {
|
|
1230
|
+
this.sarr.push(this.s);
|
|
1231
|
+
this.s = '';
|
|
1173
1232
|
}
|
|
1174
|
-
|
|
1233
|
+
this.lensE.write(string.length);
|
|
1234
|
+
}
|
|
1235
|
+
|
|
1236
|
+
toUint8Array () {
|
|
1237
|
+
const encoder = new Encoder();
|
|
1238
|
+
this.sarr.push(this.s);
|
|
1239
|
+
this.s = '';
|
|
1240
|
+
writeVarString(encoder, this.sarr.join(''));
|
|
1241
|
+
writeUint8Array(encoder, this.lensE.toUint8Array());
|
|
1242
|
+
return toUint8Array(encoder)
|
|
1175
1243
|
}
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
function encodeYMessage(msg) {
|
|
1247
|
+
const encoder = new Encoder();
|
|
1248
|
+
writeVarString(encoder, msg.type);
|
|
1249
|
+
if ('table' in msg)
|
|
1250
|
+
writeVarString(encoder, msg.table);
|
|
1251
|
+
if ('prop' in msg)
|
|
1252
|
+
writeVarString(encoder, msg.prop);
|
|
1253
|
+
switch (msg.type) {
|
|
1254
|
+
case 'u-ack':
|
|
1255
|
+
case 'u-reject':
|
|
1256
|
+
writeBigUint64(encoder, BigInt(msg.i));
|
|
1257
|
+
break;
|
|
1258
|
+
case 'outdated-server-rev':
|
|
1259
|
+
break;
|
|
1260
|
+
case 'y-complete-sync-done':
|
|
1261
|
+
writeVarString(encoder, msg.yServerRev);
|
|
1262
|
+
break;
|
|
1263
|
+
default:
|
|
1264
|
+
writeAny(encoder, msg.k);
|
|
1265
|
+
switch (msg.type) {
|
|
1266
|
+
case 'aware':
|
|
1267
|
+
writeVarUint8Array(encoder, msg.u);
|
|
1268
|
+
break;
|
|
1269
|
+
case 'doc-open':
|
|
1270
|
+
writeAny(encoder, msg.serverRev);
|
|
1271
|
+
writeAny(encoder, msg.sv);
|
|
1272
|
+
break;
|
|
1273
|
+
case 'doc-close':
|
|
1274
|
+
break;
|
|
1275
|
+
case 'sv':
|
|
1276
|
+
writeVarUint8Array(encoder, msg.sv);
|
|
1277
|
+
break;
|
|
1278
|
+
case 'u-c':
|
|
1279
|
+
writeVarUint8Array(encoder, msg.u);
|
|
1280
|
+
writeBigUint64(encoder, BigInt(msg.i));
|
|
1281
|
+
break;
|
|
1282
|
+
case 'u-s':
|
|
1283
|
+
writeVarUint8Array(encoder, msg.u);
|
|
1284
|
+
writeVarString(encoder, msg.r || '');
|
|
1285
|
+
break;
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
return toUint8Array(encoder);
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
/**
|
|
1292
|
+
* Error helpers.
|
|
1293
|
+
*
|
|
1294
|
+
* @module error
|
|
1295
|
+
*/
|
|
1296
|
+
|
|
1297
|
+
/**
|
|
1298
|
+
* @param {string} s
|
|
1299
|
+
* @return {Error}
|
|
1300
|
+
*/
|
|
1301
|
+
/* c8 ignore next */
|
|
1302
|
+
const create$4 = s => new Error(s);
|
|
1303
|
+
|
|
1304
|
+
/**
|
|
1305
|
+
* @throws {Error}
|
|
1306
|
+
* @return {never}
|
|
1307
|
+
*/
|
|
1308
|
+
/* c8 ignore next 3 */
|
|
1309
|
+
const methodUnimplemented = () => {
|
|
1310
|
+
throw create$4('Method unimplemented')
|
|
1176
1311
|
};
|
|
1177
|
-
/* c8 ignore stop */
|
|
1178
1312
|
|
|
1179
1313
|
/**
|
|
1180
|
-
* @
|
|
1181
|
-
* @
|
|
1182
|
-
* @return {String} The read String
|
|
1314
|
+
* @throws {Error}
|
|
1315
|
+
* @return {never}
|
|
1183
1316
|
*/
|
|
1184
|
-
|
|
1185
|
-
|
|
1317
|
+
/* c8 ignore next 3 */
|
|
1318
|
+
const unexpectedCase = () => {
|
|
1319
|
+
throw create$4('Unexpected case')
|
|
1320
|
+
};
|
|
1186
1321
|
|
|
1187
1322
|
/**
|
|
1188
|
-
*
|
|
1189
|
-
* * varUint is used to store the length of the string
|
|
1323
|
+
* Efficient schema-less binary decoding with support for variable length encoding.
|
|
1190
1324
|
*
|
|
1191
|
-
*
|
|
1192
|
-
*
|
|
1193
|
-
*
|
|
1325
|
+
* Use [lib0/decoding] with [lib0/encoding]. Every encoding function has a corresponding decoding function.
|
|
1326
|
+
*
|
|
1327
|
+
* Encodes numbers in little-endian order (least to most significant byte order)
|
|
1328
|
+
* and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
|
|
1329
|
+
* which is also used in Protocol Buffers.
|
|
1330
|
+
*
|
|
1331
|
+
* ```js
|
|
1332
|
+
* // encoding step
|
|
1333
|
+
* const encoder = encoding.createEncoder()
|
|
1334
|
+
* encoding.writeVarUint(encoder, 256)
|
|
1335
|
+
* encoding.writeVarString(encoder, 'Hello world!')
|
|
1336
|
+
* const buf = encoding.toUint8Array(encoder)
|
|
1337
|
+
* ```
|
|
1338
|
+
*
|
|
1339
|
+
* ```js
|
|
1340
|
+
* // decoding step
|
|
1341
|
+
* const decoder = decoding.createDecoder(buf)
|
|
1342
|
+
* decoding.readVarUint(decoder) // => 256
|
|
1343
|
+
* decoding.readVarString(decoder) // => 'Hello world!'
|
|
1344
|
+
* decoding.hasContent(decoder) // => false - all data is read
|
|
1345
|
+
* ```
|
|
1194
1346
|
*
|
|
1347
|
+
* @module decoding
|
|
1195
1348
|
*/
|
|
1196
|
-
|
|
1197
|
-
|
|
1349
|
+
|
|
1350
|
+
|
|
1351
|
+
const errorUnexpectedEndOfArray = create$4('Unexpected end of array');
|
|
1352
|
+
const errorIntegerOutOfRange = create$4('Integer out of Range');
|
|
1198
1353
|
|
|
1199
1354
|
/**
|
|
1200
|
-
*
|
|
1201
|
-
* @param {number} len
|
|
1202
|
-
* @return {DataView}
|
|
1355
|
+
* A Decoder handles the decoding of an Uint8Array.
|
|
1203
1356
|
*/
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1357
|
+
class Decoder {
|
|
1358
|
+
/**
|
|
1359
|
+
* @param {Uint8Array} uint8Array Binary data to decode
|
|
1360
|
+
*/
|
|
1361
|
+
constructor (uint8Array) {
|
|
1362
|
+
/**
|
|
1363
|
+
* Decoding target.
|
|
1364
|
+
*
|
|
1365
|
+
* @type {Uint8Array}
|
|
1366
|
+
*/
|
|
1367
|
+
this.arr = uint8Array;
|
|
1368
|
+
/**
|
|
1369
|
+
* Current decoding position.
|
|
1370
|
+
*
|
|
1371
|
+
* @type {number}
|
|
1372
|
+
*/
|
|
1373
|
+
this.pos = 0;
|
|
1374
|
+
}
|
|
1375
|
+
}
|
|
1209
1376
|
|
|
1210
1377
|
/**
|
|
1211
|
-
* @
|
|
1378
|
+
* @function
|
|
1379
|
+
* @param {Uint8Array} uint8Array
|
|
1380
|
+
* @return {Decoder}
|
|
1212
1381
|
*/
|
|
1213
|
-
const
|
|
1382
|
+
const createDecoder = uint8Array => new Decoder(uint8Array);
|
|
1214
1383
|
|
|
1215
1384
|
/**
|
|
1385
|
+
* @function
|
|
1216
1386
|
* @param {Decoder} decoder
|
|
1387
|
+
* @return {boolean}
|
|
1217
1388
|
*/
|
|
1218
|
-
const
|
|
1389
|
+
const hasContent = decoder => decoder.pos !== decoder.arr.length;
|
|
1219
1390
|
|
|
1220
1391
|
/**
|
|
1221
|
-
*
|
|
1392
|
+
* Create an Uint8Array view of the next `len` bytes and advance the position by `len`.
|
|
1393
|
+
*
|
|
1394
|
+
* Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.
|
|
1395
|
+
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
1396
|
+
*
|
|
1397
|
+
* @function
|
|
1398
|
+
* @param {Decoder} decoder The decoder instance
|
|
1399
|
+
* @param {number} len The length of bytes to read
|
|
1400
|
+
* @return {Uint8Array}
|
|
1222
1401
|
*/
|
|
1223
|
-
const
|
|
1402
|
+
const readUint8Array = (decoder, len) => {
|
|
1403
|
+
const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len);
|
|
1404
|
+
decoder.pos += len;
|
|
1405
|
+
return view
|
|
1406
|
+
};
|
|
1224
1407
|
|
|
1225
1408
|
/**
|
|
1409
|
+
* Read variable length Uint8Array.
|
|
1410
|
+
*
|
|
1411
|
+
* Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.
|
|
1412
|
+
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
1413
|
+
*
|
|
1414
|
+
* @function
|
|
1226
1415
|
* @param {Decoder} decoder
|
|
1416
|
+
* @return {Uint8Array}
|
|
1227
1417
|
*/
|
|
1228
|
-
const
|
|
1418
|
+
const readVarUint8Array = decoder => readUint8Array(decoder, readVarUint(decoder));
|
|
1229
1419
|
|
|
1230
1420
|
/**
|
|
1231
|
-
*
|
|
1421
|
+
* Read one byte as unsigned integer.
|
|
1422
|
+
* @function
|
|
1423
|
+
* @param {Decoder} decoder The decoder instance
|
|
1424
|
+
* @return {number} Unsigned 8-bit integer
|
|
1232
1425
|
*/
|
|
1233
|
-
const
|
|
1234
|
-
decoder => undefined, // CASE 127: undefined
|
|
1235
|
-
decoder => null, // CASE 126: null
|
|
1236
|
-
readVarInt$1, // CASE 125: integer
|
|
1237
|
-
readFloat32$1, // CASE 124: float32
|
|
1238
|
-
readFloat64$1, // CASE 123: float64
|
|
1239
|
-
readBigInt64$1, // CASE 122: bigint
|
|
1240
|
-
decoder => false, // CASE 121: boolean (false)
|
|
1241
|
-
decoder => true, // CASE 120: boolean (true)
|
|
1242
|
-
readVarString$1, // CASE 119: string
|
|
1243
|
-
decoder => { // CASE 118: object<string,any>
|
|
1244
|
-
const len = readVarUint$1(decoder);
|
|
1245
|
-
/**
|
|
1246
|
-
* @type {Object<string,any>}
|
|
1247
|
-
*/
|
|
1248
|
-
const obj = {};
|
|
1249
|
-
for (let i = 0; i < len; i++) {
|
|
1250
|
-
const key = readVarString$1(decoder);
|
|
1251
|
-
obj[key] = readAny$1(decoder);
|
|
1252
|
-
}
|
|
1253
|
-
return obj
|
|
1254
|
-
},
|
|
1255
|
-
decoder => { // CASE 117: array<any>
|
|
1256
|
-
const len = readVarUint$1(decoder);
|
|
1257
|
-
const arr = [];
|
|
1258
|
-
for (let i = 0; i < len; i++) {
|
|
1259
|
-
arr.push(readAny$1(decoder));
|
|
1260
|
-
}
|
|
1261
|
-
return arr
|
|
1262
|
-
},
|
|
1263
|
-
readVarUint8Array$1 // CASE 116: Uint8Array
|
|
1264
|
-
];
|
|
1426
|
+
const readUint8 = decoder => decoder.arr[decoder.pos++];
|
|
1265
1427
|
|
|
1266
1428
|
/**
|
|
1429
|
+
* Read unsigned integer (32bit) with variable length.
|
|
1430
|
+
* 1/8th of the storage is used as encoding overhead.
|
|
1431
|
+
* * numbers < 2^7 is stored in one bytlength
|
|
1432
|
+
* * numbers < 2^14 is stored in two bylength
|
|
1433
|
+
*
|
|
1434
|
+
* @function
|
|
1267
1435
|
* @param {Decoder} decoder
|
|
1436
|
+
* @return {number} An unsigned integer.length
|
|
1268
1437
|
*/
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1438
|
+
const readVarUint = decoder => {
|
|
1439
|
+
let num = 0;
|
|
1440
|
+
let mult = 1;
|
|
1441
|
+
const len = decoder.arr.length;
|
|
1442
|
+
while (decoder.pos < len) {
|
|
1443
|
+
const r = decoder.arr[decoder.pos++];
|
|
1444
|
+
// num = num | ((r & binary.BITS7) << len)
|
|
1445
|
+
num = num + (r & BITS7) * mult; // shift $r << (7*#iterations) and add it to num
|
|
1446
|
+
mult *= 128; // next iteration, shift 7 "more" to the left
|
|
1447
|
+
if (r < BIT8) {
|
|
1448
|
+
return num
|
|
1276
1449
|
}
|
|
1277
|
-
|
|
1278
|
-
|
|
1450
|
+
/* c8 ignore start */
|
|
1451
|
+
if (num > MAX_SAFE_INTEGER) {
|
|
1452
|
+
throw errorIntegerOutOfRange
|
|
1279
1453
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
case 'u-reject':
|
|
1285
|
-
return {
|
|
1286
|
-
type,
|
|
1287
|
-
table,
|
|
1288
|
-
prop,
|
|
1289
|
-
i: Number(readBigUint64(decoder)),
|
|
1290
|
-
};
|
|
1291
|
-
default: {
|
|
1292
|
-
const k = readAny$1(decoder);
|
|
1293
|
-
switch (type) {
|
|
1294
|
-
case 'in-sync':
|
|
1295
|
-
return { type, table, prop, k };
|
|
1296
|
-
case 'aware':
|
|
1297
|
-
return {
|
|
1298
|
-
type,
|
|
1299
|
-
table,
|
|
1300
|
-
prop,
|
|
1301
|
-
k,
|
|
1302
|
-
u: readVarUint8Array$1(decoder),
|
|
1303
|
-
};
|
|
1304
|
-
case 'doc-open':
|
|
1305
|
-
return {
|
|
1306
|
-
type,
|
|
1307
|
-
table,
|
|
1308
|
-
prop,
|
|
1309
|
-
k,
|
|
1310
|
-
serverRev: readAny$1(decoder),
|
|
1311
|
-
sv: readAny$1(decoder),
|
|
1312
|
-
};
|
|
1313
|
-
case 'doc-close':
|
|
1314
|
-
return { type, table, prop, k };
|
|
1315
|
-
case 'sv':
|
|
1316
|
-
return {
|
|
1317
|
-
type,
|
|
1318
|
-
table,
|
|
1319
|
-
prop,
|
|
1320
|
-
k,
|
|
1321
|
-
sv: readVarUint8Array$1(decoder),
|
|
1322
|
-
};
|
|
1323
|
-
case 'u-c':
|
|
1324
|
-
return {
|
|
1325
|
-
type,
|
|
1326
|
-
table,
|
|
1327
|
-
prop,
|
|
1328
|
-
k,
|
|
1329
|
-
u: readVarUint8Array$1(decoder),
|
|
1330
|
-
i: Number(readBigUint64(decoder)),
|
|
1331
|
-
};
|
|
1332
|
-
case 'u-s':
|
|
1333
|
-
return {
|
|
1334
|
-
type,
|
|
1335
|
-
table,
|
|
1336
|
-
prop,
|
|
1337
|
-
k,
|
|
1338
|
-
u: readVarUint8Array$1(decoder),
|
|
1339
|
-
r: (decoder.pos < decoder.arr.length && readVarString$1(decoder)) || undefined,
|
|
1340
|
-
};
|
|
1341
|
-
default:
|
|
1342
|
-
throw new TypeError(`Unknown message type: ${type}`);
|
|
1343
|
-
}
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1346
|
-
}
|
|
1454
|
+
/* c8 ignore stop */
|
|
1455
|
+
}
|
|
1456
|
+
throw errorUnexpectedEndOfArray
|
|
1457
|
+
};
|
|
1347
1458
|
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1459
|
+
/**
|
|
1460
|
+
* Read signed integer (32bit) with variable length.
|
|
1461
|
+
* 1/8th of the storage is used as encoding overhead.
|
|
1462
|
+
* * numbers < 2^7 is stored in one bytlength
|
|
1463
|
+
* * numbers < 2^14 is stored in two bylength
|
|
1464
|
+
* @todo This should probably create the inverse ~num if number is negative - but this would be a breaking change.
|
|
1465
|
+
*
|
|
1466
|
+
* @function
|
|
1467
|
+
* @param {Decoder} decoder
|
|
1468
|
+
* @return {number} An unsigned integer.length
|
|
1469
|
+
*/
|
|
1470
|
+
const readVarInt = decoder => {
|
|
1471
|
+
let r = decoder.arr[decoder.pos++];
|
|
1472
|
+
let num = r & BITS6;
|
|
1473
|
+
let mult = 64;
|
|
1474
|
+
const sign = (r & BIT7) > 0 ? -1 : 1;
|
|
1475
|
+
if ((r & BIT8) === 0) {
|
|
1476
|
+
// don't continue reading
|
|
1477
|
+
return sign * num
|
|
1478
|
+
}
|
|
1479
|
+
const len = decoder.arr.length;
|
|
1480
|
+
while (decoder.pos < len) {
|
|
1481
|
+
r = decoder.arr[decoder.pos++];
|
|
1482
|
+
// num = num | ((r & binary.BITS7) << len)
|
|
1483
|
+
num = num + (r & BITS7) * mult;
|
|
1484
|
+
mult *= 128;
|
|
1485
|
+
if (r < BIT8) {
|
|
1486
|
+
return sign * num
|
|
1354
1487
|
}
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
for (var _d = true, result_1 = __asyncValues(result), result_1_1; result_1_1 = await result_1.next(), _a = result_1_1.done, !_a; _d = true) {
|
|
1359
|
-
_c = result_1_1.value;
|
|
1360
|
-
_d = false;
|
|
1361
|
-
const chunk = _c;
|
|
1362
|
-
}
|
|
1488
|
+
/* c8 ignore start */
|
|
1489
|
+
if (num > MAX_SAFE_INTEGER) {
|
|
1490
|
+
throw errorIntegerOutOfRange
|
|
1363
1491
|
}
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1492
|
+
/* c8 ignore stop */
|
|
1493
|
+
}
|
|
1494
|
+
throw errorUnexpectedEndOfArray
|
|
1495
|
+
};
|
|
1496
|
+
|
|
1497
|
+
/**
|
|
1498
|
+
* We don't test this function anymore as we use native decoding/encoding by default now.
|
|
1499
|
+
* Better not modify this anymore..
|
|
1500
|
+
*
|
|
1501
|
+
* Transforming utf8 to a string is pretty expensive. The code performs 10x better
|
|
1502
|
+
* when String.fromCodePoint is fed with all characters as arguments.
|
|
1503
|
+
* But most environments have a maximum number of arguments per functions.
|
|
1504
|
+
* For effiency reasons we apply a maximum of 10000 characters at once.
|
|
1505
|
+
*
|
|
1506
|
+
* @function
|
|
1507
|
+
* @param {Decoder} decoder
|
|
1508
|
+
* @return {String} The read String.
|
|
1509
|
+
*/
|
|
1510
|
+
/* c8 ignore start */
|
|
1511
|
+
const _readVarStringPolyfill = decoder => {
|
|
1512
|
+
let remainingLen = readVarUint(decoder);
|
|
1513
|
+
if (remainingLen === 0) {
|
|
1514
|
+
return ''
|
|
1515
|
+
} else {
|
|
1516
|
+
let encodedString = String.fromCodePoint(readUint8(decoder)); // remember to decrease remainingLen
|
|
1517
|
+
if (--remainingLen < 100) { // do not create a Uint8Array for small strings
|
|
1518
|
+
while (remainingLen--) {
|
|
1519
|
+
encodedString += String.fromCodePoint(readUint8(decoder));
|
|
1520
|
+
}
|
|
1521
|
+
} else {
|
|
1522
|
+
while (remainingLen > 0) {
|
|
1523
|
+
const nextLen = remainingLen < 10000 ? remainingLen : 10000;
|
|
1524
|
+
// this is dangerous, we create a fresh array view from the existing buffer
|
|
1525
|
+
const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen);
|
|
1526
|
+
decoder.pos += nextLen;
|
|
1527
|
+
// Starting with ES5.1 we can supply a generic array-like object as arguments
|
|
1528
|
+
encodedString += String.fromCodePoint.apply(null, /** @type {any} */ (bytes));
|
|
1529
|
+
remainingLen -= nextLen;
|
|
1530
|
+
}
|
|
1370
1531
|
}
|
|
1371
|
-
|
|
1532
|
+
return decodeURIComponent(escape(encodedString))
|
|
1533
|
+
}
|
|
1534
|
+
};
|
|
1535
|
+
/* c8 ignore stop */
|
|
1372
1536
|
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
let len = 0;
|
|
1381
|
-
try {
|
|
1382
|
-
for (var _d = true, source_1 = __asyncValues(source), source_1_1; source_1_1 = yield __await(source_1.next()), _a = source_1_1.done, !_a; _d = true) {
|
|
1383
|
-
_c = source_1_1.value;
|
|
1384
|
-
_d = false;
|
|
1385
|
-
const chunk = _c;
|
|
1386
|
-
const dw = new DataView(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
1387
|
-
let pos = 0;
|
|
1388
|
-
while (pos < chunk.byteLength) {
|
|
1389
|
-
switch (state) {
|
|
1390
|
-
case 0:
|
|
1391
|
-
// Beginning of a size header
|
|
1392
|
-
if (pos + 4 > chunk.byteLength) {
|
|
1393
|
-
for (const b of chunk.slice(pos)) {
|
|
1394
|
-
if (sizeBufPos === 4)
|
|
1395
|
-
break;
|
|
1396
|
-
sizeBuf[sizeBufPos++] = b;
|
|
1397
|
-
++pos;
|
|
1398
|
-
}
|
|
1399
|
-
if (sizeBufPos < 4) {
|
|
1400
|
-
// Need more bytes in order to read length.
|
|
1401
|
-
// Will go out from while loop as well because pos is defenitely = chunk.byteLength here.
|
|
1402
|
-
break;
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
else if (sizeBufPos > 0 && sizeBufPos < 4) {
|
|
1406
|
-
for (const b of chunk.slice(pos, pos + 4 - sizeBufPos)) {
|
|
1407
|
-
sizeBuf[sizeBufPos++] = b;
|
|
1408
|
-
++pos;
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
// Intentional fall-through...
|
|
1412
|
-
case 1:
|
|
1413
|
-
len =
|
|
1414
|
-
sizeBufPos === 4
|
|
1415
|
-
? new DataView(sizeBuf.buffer, 0, 4).getUint32(0, false)
|
|
1416
|
-
: dw.getUint32(pos, false);
|
|
1417
|
-
if (sizeBufPos)
|
|
1418
|
-
sizeBufPos = 0; // in this case pos is already forwarded
|
|
1419
|
-
else
|
|
1420
|
-
pos += 4; // else pos is not yet forwarded - that's why we do it now
|
|
1421
|
-
// Intentional fall-through...
|
|
1422
|
-
case 2:
|
|
1423
|
-
// Eat the chunk
|
|
1424
|
-
if (pos >= chunk.byteLength) {
|
|
1425
|
-
state = 2;
|
|
1426
|
-
break;
|
|
1427
|
-
}
|
|
1428
|
-
if (pos + len > chunk.byteLength) {
|
|
1429
|
-
bufs.push(chunk.slice(pos));
|
|
1430
|
-
len -= (chunk.byteLength - pos);
|
|
1431
|
-
state = 2;
|
|
1432
|
-
pos = chunk.byteLength; // will break while loop.
|
|
1433
|
-
}
|
|
1434
|
-
else {
|
|
1435
|
-
if (bufs.length > 0) {
|
|
1436
|
-
const concats = new Uint8Array(bufs.reduce((p, c) => p + c.byteLength, len));
|
|
1437
|
-
let p = 0;
|
|
1438
|
-
for (const buf of bufs) {
|
|
1439
|
-
concats.set(buf, p);
|
|
1440
|
-
p += buf.byteLength;
|
|
1441
|
-
}
|
|
1442
|
-
concats.set(chunk.slice(pos, pos + len), p);
|
|
1443
|
-
bufs = [];
|
|
1444
|
-
yield yield __await(concats);
|
|
1445
|
-
}
|
|
1446
|
-
else {
|
|
1447
|
-
yield yield __await(chunk.slice(pos, pos + len));
|
|
1448
|
-
}
|
|
1449
|
-
pos += len;
|
|
1450
|
-
state = 0;
|
|
1451
|
-
}
|
|
1452
|
-
break;
|
|
1453
|
-
}
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
1458
|
-
finally {
|
|
1459
|
-
try {
|
|
1460
|
-
if (!_d && !_a && (_b = source_1.return)) yield __await(_b.call(source_1));
|
|
1461
|
-
}
|
|
1462
|
-
finally { if (e_1) throw e_1.error; }
|
|
1463
|
-
}
|
|
1464
|
-
});
|
|
1465
|
-
}
|
|
1537
|
+
/**
|
|
1538
|
+
* @function
|
|
1539
|
+
* @param {Decoder} decoder
|
|
1540
|
+
* @return {String} The read String
|
|
1541
|
+
*/
|
|
1542
|
+
const _readVarStringNative = decoder =>
|
|
1543
|
+
/** @type any */ (utf8TextDecoder).decode(readVarUint8Array(decoder));
|
|
1466
1544
|
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
yield yield __await(value);
|
|
1479
|
-
}
|
|
1480
|
-
}
|
|
1481
|
-
finally {
|
|
1482
|
-
reader.releaseLock();
|
|
1483
|
-
}
|
|
1484
|
-
});
|
|
1485
|
-
};
|
|
1486
|
-
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Read string of variable length
|
|
1547
|
+
* * varUint is used to store the length of the string
|
|
1548
|
+
*
|
|
1549
|
+
* @function
|
|
1550
|
+
* @param {Decoder} decoder
|
|
1551
|
+
* @return {String} The read String
|
|
1552
|
+
*
|
|
1553
|
+
*/
|
|
1554
|
+
/* c8 ignore next */
|
|
1555
|
+
const readVarString = utf8TextDecoder ? _readVarStringNative : _readVarStringPolyfill;
|
|
1487
1556
|
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
if (sw.active) {
|
|
1499
|
-
// Use postMessage for pull syncs and for browsers not supporting sync event (Firefox, Safari).
|
|
1500
|
-
// Also chromium based browsers with sw.sync as a fallback for sleepy sync events not taking action for a while.
|
|
1501
|
-
sw.active.postMessage({
|
|
1502
|
-
type: 'dexie-cloud-sync',
|
|
1503
|
-
dbName: db.name,
|
|
1504
|
-
purpose
|
|
1505
|
-
});
|
|
1506
|
-
}
|
|
1507
|
-
else {
|
|
1508
|
-
throw new Error(`Failed to trigger sync - there's no active service worker`);
|
|
1509
|
-
}
|
|
1510
|
-
return;
|
|
1511
|
-
}
|
|
1512
|
-
catch (e) {
|
|
1513
|
-
if (!hasComplainedAboutSyncEvent) {
|
|
1514
|
-
console.debug(`Dexie Cloud: Could not register sync event`, e);
|
|
1515
|
-
hasComplainedAboutSyncEvent = true;
|
|
1516
|
-
}
|
|
1517
|
-
}
|
|
1518
|
-
});
|
|
1519
|
-
}
|
|
1520
|
-
function registerPeriodicSyncEvent(db) {
|
|
1521
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1522
|
-
var _a;
|
|
1523
|
-
try {
|
|
1524
|
-
// Register periodicSync event to SW:
|
|
1525
|
-
// @ts-ignore
|
|
1526
|
-
const { periodicSync } = yield navigator.serviceWorker.ready;
|
|
1527
|
-
if (periodicSync) {
|
|
1528
|
-
try {
|
|
1529
|
-
yield periodicSync.register(`dexie-cloud:${db.name}`, (_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.periodicSync);
|
|
1530
|
-
console.debug(`Dexie Cloud: Successfully registered periodicsync event for ${db.name}`);
|
|
1531
|
-
}
|
|
1532
|
-
catch (e) {
|
|
1533
|
-
console.debug(`Dexie Cloud: Failed to register periodic sync. Your PWA must be installed to allow background sync.`, e);
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
else {
|
|
1537
|
-
console.debug(`Dexie Cloud: periodicSync not supported.`);
|
|
1538
|
-
}
|
|
1539
|
-
}
|
|
1540
|
-
catch (e) {
|
|
1541
|
-
console.debug(`Dexie Cloud: Could not register periodicSync for ${db.name}`, e);
|
|
1542
|
-
}
|
|
1543
|
-
});
|
|
1544
|
-
}
|
|
1557
|
+
/**
|
|
1558
|
+
* @param {Decoder} decoder
|
|
1559
|
+
* @param {number} len
|
|
1560
|
+
* @return {DataView}
|
|
1561
|
+
*/
|
|
1562
|
+
const readFromDataView = (decoder, len) => {
|
|
1563
|
+
const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len);
|
|
1564
|
+
decoder.pos += len;
|
|
1565
|
+
return dv
|
|
1566
|
+
};
|
|
1545
1567
|
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1568
|
+
/**
|
|
1569
|
+
* @param {Decoder} decoder
|
|
1570
|
+
*/
|
|
1571
|
+
const readFloat32 = decoder => readFromDataView(decoder, 4).getFloat32(0, false);
|
|
1572
|
+
|
|
1573
|
+
/**
|
|
1574
|
+
* @param {Decoder} decoder
|
|
1575
|
+
*/
|
|
1576
|
+
const readFloat64 = decoder => readFromDataView(decoder, 8).getFloat64(0, false);
|
|
1577
|
+
|
|
1578
|
+
/**
|
|
1579
|
+
* @param {Decoder} decoder
|
|
1580
|
+
*/
|
|
1581
|
+
const readBigInt64 = decoder => /** @type {any} */ (readFromDataView(decoder, 8)).getBigInt64(0, false);
|
|
1582
|
+
|
|
1583
|
+
/**
|
|
1584
|
+
* @param {Decoder} decoder
|
|
1585
|
+
*/
|
|
1586
|
+
const readBigUint64 = decoder => /** @type {any} */ (readFromDataView(decoder, 8)).getBigUint64(0, false);
|
|
1587
|
+
|
|
1588
|
+
/**
|
|
1589
|
+
* @type {Array<function(Decoder):any>}
|
|
1590
|
+
*/
|
|
1591
|
+
const readAnyLookupTable = [
|
|
1592
|
+
decoder => undefined, // CASE 127: undefined
|
|
1593
|
+
decoder => null, // CASE 126: null
|
|
1594
|
+
readVarInt, // CASE 125: integer
|
|
1595
|
+
readFloat32, // CASE 124: float32
|
|
1596
|
+
readFloat64, // CASE 123: float64
|
|
1597
|
+
readBigInt64, // CASE 122: bigint
|
|
1598
|
+
decoder => false, // CASE 121: boolean (false)
|
|
1599
|
+
decoder => true, // CASE 120: boolean (true)
|
|
1600
|
+
readVarString, // CASE 119: string
|
|
1601
|
+
decoder => { // CASE 118: object<string,any>
|
|
1602
|
+
const len = readVarUint(decoder);
|
|
1603
|
+
/**
|
|
1604
|
+
* @type {Object<string,any>}
|
|
1605
|
+
*/
|
|
1606
|
+
const obj = {};
|
|
1607
|
+
for (let i = 0; i < len; i++) {
|
|
1608
|
+
const key = readVarString(decoder);
|
|
1609
|
+
obj[key] = readAny(decoder);
|
|
1550
1610
|
}
|
|
1551
|
-
|
|
1552
|
-
|
|
1611
|
+
return obj
|
|
1612
|
+
},
|
|
1613
|
+
decoder => { // CASE 117: array<any>
|
|
1614
|
+
const len = readVarUint(decoder);
|
|
1615
|
+
const arr = [];
|
|
1616
|
+
for (let i = 0; i < len; i++) {
|
|
1617
|
+
arr.push(readAny(decoder));
|
|
1618
|
+
}
|
|
1619
|
+
return arr
|
|
1620
|
+
},
|
|
1621
|
+
readVarUint8Array // CASE 116: Uint8Array
|
|
1622
|
+
];
|
|
1623
|
+
|
|
1624
|
+
/**
|
|
1625
|
+
* @param {Decoder} decoder
|
|
1626
|
+
*/
|
|
1627
|
+
const readAny = decoder => readAnyLookupTable[127 - readUint8(decoder)](decoder);
|
|
1628
|
+
|
|
1629
|
+
/**
|
|
1630
|
+
* T must not be null.
|
|
1631
|
+
*
|
|
1632
|
+
* @template T
|
|
1633
|
+
*/
|
|
1634
|
+
class RleDecoder extends Decoder {
|
|
1635
|
+
/**
|
|
1636
|
+
* @param {Uint8Array} uint8Array
|
|
1637
|
+
* @param {function(Decoder):T} reader
|
|
1638
|
+
*/
|
|
1639
|
+
constructor (uint8Array, reader) {
|
|
1640
|
+
super(uint8Array);
|
|
1641
|
+
/**
|
|
1642
|
+
* The reader
|
|
1643
|
+
*/
|
|
1644
|
+
this.reader = reader;
|
|
1645
|
+
/**
|
|
1646
|
+
* Current state
|
|
1647
|
+
* @type {T|null}
|
|
1648
|
+
*/
|
|
1649
|
+
this.s = null;
|
|
1650
|
+
this.count = 0;
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
read () {
|
|
1654
|
+
if (this.count === 0) {
|
|
1655
|
+
this.s = this.reader(this);
|
|
1656
|
+
if (hasContent(this)) {
|
|
1657
|
+
this.count = readVarUint(this) + 1; // see encoder implementation for the reason why this is incremented
|
|
1658
|
+
} else {
|
|
1659
|
+
this.count = -1; // read the current value forever
|
|
1660
|
+
}
|
|
1553
1661
|
}
|
|
1662
|
+
this.count--;
|
|
1663
|
+
return /** @type {T} */ (this.s)
|
|
1664
|
+
}
|
|
1554
1665
|
}
|
|
1555
1666
|
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
else {
|
|
1580
|
-
return Buffer.from(b).toString("base64");
|
|
1581
|
-
}
|
|
1667
|
+
class UintOptRleDecoder extends Decoder {
|
|
1668
|
+
/**
|
|
1669
|
+
* @param {Uint8Array} uint8Array
|
|
1670
|
+
*/
|
|
1671
|
+
constructor (uint8Array) {
|
|
1672
|
+
super(uint8Array);
|
|
1673
|
+
/**
|
|
1674
|
+
* @type {number}
|
|
1675
|
+
*/
|
|
1676
|
+
this.s = 0;
|
|
1677
|
+
this.count = 0;
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
read () {
|
|
1681
|
+
if (this.count === 0) {
|
|
1682
|
+
this.s = readVarInt(this);
|
|
1683
|
+
// if the sign is negative, we read the count too, otherwise count is 1
|
|
1684
|
+
const isNegative = isNegativeZero(this.s);
|
|
1685
|
+
this.count = 1;
|
|
1686
|
+
if (isNegative) {
|
|
1687
|
+
this.s = -this.s;
|
|
1688
|
+
this.count = readVarUint(this) + 2;
|
|
1689
|
+
}
|
|
1582
1690
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
// @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64
|
|
1588
|
-
return u8a.toBase64();
|
|
1589
|
-
}
|
|
1590
|
-
: (b) => {
|
|
1591
|
-
// Legacy DOM workaround
|
|
1592
|
-
const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);
|
|
1593
|
-
const CHUNK_SIZE = 0x1000;
|
|
1594
|
-
const strs = [];
|
|
1595
|
-
for (let i = 0, l = u8a.length; i < l; i += CHUNK_SIZE) {
|
|
1596
|
-
const chunk = u8a.subarray(i, i + CHUNK_SIZE);
|
|
1597
|
-
strs.push(String.fromCharCode.apply(null, chunk));
|
|
1598
|
-
}
|
|
1599
|
-
return btoa(strs.join(""));
|
|
1600
|
-
};
|
|
1691
|
+
this.count--;
|
|
1692
|
+
return /** @type {number} */ (this.s)
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1601
1695
|
|
|
1602
|
-
class
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1696
|
+
class IntDiffOptRleDecoder extends Decoder {
|
|
1697
|
+
/**
|
|
1698
|
+
* @param {Uint8Array} uint8Array
|
|
1699
|
+
*/
|
|
1700
|
+
constructor (uint8Array) {
|
|
1701
|
+
super(uint8Array);
|
|
1702
|
+
/**
|
|
1703
|
+
* @type {number}
|
|
1704
|
+
*/
|
|
1705
|
+
this.s = 0;
|
|
1706
|
+
this.count = 0;
|
|
1707
|
+
this.diff = 0;
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
/**
|
|
1711
|
+
* @return {number}
|
|
1712
|
+
*/
|
|
1713
|
+
read () {
|
|
1714
|
+
if (this.count === 0) {
|
|
1715
|
+
const diff = readVarInt(this);
|
|
1716
|
+
// if the first bit is set, we read more data
|
|
1717
|
+
const hasCount = diff & 1;
|
|
1718
|
+
this.diff = floor(diff / 2); // shift >> 1
|
|
1719
|
+
this.count = 1;
|
|
1720
|
+
if (hasCount) {
|
|
1721
|
+
this.count = readVarUint(this) + 2;
|
|
1722
|
+
}
|
|
1609
1723
|
}
|
|
1724
|
+
this.s += this.diff;
|
|
1725
|
+
this.count--;
|
|
1726
|
+
return this.s
|
|
1727
|
+
}
|
|
1610
1728
|
}
|
|
1611
1729
|
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1730
|
+
class StringDecoder {
|
|
1731
|
+
/**
|
|
1732
|
+
* @param {Uint8Array} uint8Array
|
|
1733
|
+
*/
|
|
1734
|
+
constructor (uint8Array) {
|
|
1735
|
+
this.decoder = new UintOptRleDecoder(uint8Array);
|
|
1736
|
+
this.str = readVarString(this.decoder);
|
|
1737
|
+
/**
|
|
1738
|
+
* @type {number}
|
|
1739
|
+
*/
|
|
1740
|
+
this.spos = 0;
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1743
|
+
/**
|
|
1744
|
+
* @return {string}
|
|
1745
|
+
*/
|
|
1746
|
+
read () {
|
|
1747
|
+
const end = this.spos + this.decoder.read();
|
|
1748
|
+
const res = this.str.slice(this.spos, end);
|
|
1749
|
+
this.spos = end;
|
|
1750
|
+
return res
|
|
1751
|
+
}
|
|
1632
1752
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1753
|
+
|
|
1754
|
+
function decodeYMessage(a) {
|
|
1755
|
+
const decoder = new Decoder(a);
|
|
1756
|
+
const type = readVarString(decoder);
|
|
1757
|
+
if (type === 'outdated-server-rev') {
|
|
1758
|
+
return { type };
|
|
1759
|
+
}
|
|
1760
|
+
if (type === 'y-complete-sync-done') {
|
|
1761
|
+
return { type, yServerRev: readVarString(decoder) };
|
|
1762
|
+
}
|
|
1763
|
+
const table = readVarString(decoder);
|
|
1764
|
+
const prop = readVarString(decoder);
|
|
1765
|
+
switch (type) {
|
|
1766
|
+
case 'u-ack':
|
|
1767
|
+
case 'u-reject':
|
|
1768
|
+
return {
|
|
1769
|
+
type,
|
|
1770
|
+
table,
|
|
1771
|
+
prop,
|
|
1772
|
+
i: Number(readBigUint64(decoder)),
|
|
1773
|
+
};
|
|
1774
|
+
default: {
|
|
1775
|
+
const k = readAny(decoder);
|
|
1776
|
+
switch (type) {
|
|
1777
|
+
case 'in-sync':
|
|
1778
|
+
return { type, table, prop, k };
|
|
1779
|
+
case 'aware':
|
|
1780
|
+
return {
|
|
1781
|
+
type,
|
|
1782
|
+
table,
|
|
1783
|
+
prop,
|
|
1784
|
+
k,
|
|
1785
|
+
u: readVarUint8Array(decoder),
|
|
1786
|
+
};
|
|
1787
|
+
case 'doc-open':
|
|
1788
|
+
return {
|
|
1789
|
+
type,
|
|
1790
|
+
table,
|
|
1791
|
+
prop,
|
|
1792
|
+
k,
|
|
1793
|
+
serverRev: readAny(decoder),
|
|
1794
|
+
sv: readAny(decoder),
|
|
1795
|
+
};
|
|
1796
|
+
case 'doc-close':
|
|
1797
|
+
return { type, table, prop, k };
|
|
1798
|
+
case 'sv':
|
|
1799
|
+
return {
|
|
1800
|
+
type,
|
|
1801
|
+
table,
|
|
1802
|
+
prop,
|
|
1803
|
+
k,
|
|
1804
|
+
sv: readVarUint8Array(decoder),
|
|
1805
|
+
};
|
|
1806
|
+
case 'u-c':
|
|
1807
|
+
return {
|
|
1808
|
+
type,
|
|
1809
|
+
table,
|
|
1810
|
+
prop,
|
|
1811
|
+
k,
|
|
1812
|
+
u: readVarUint8Array(decoder),
|
|
1813
|
+
i: Number(readBigUint64(decoder)),
|
|
1814
|
+
};
|
|
1815
|
+
case 'u-s':
|
|
1816
|
+
return {
|
|
1817
|
+
type,
|
|
1818
|
+
table,
|
|
1819
|
+
prop,
|
|
1820
|
+
k,
|
|
1821
|
+
u: readVarUint8Array(decoder),
|
|
1822
|
+
r: (decoder.pos < decoder.arr.length && readVarString(decoder)) || undefined,
|
|
1823
|
+
};
|
|
1824
|
+
default:
|
|
1825
|
+
throw new TypeError(`Unknown message type: ${type}`);
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
async function asyncIterablePipeline(source, ...stages) {
|
|
1832
|
+
// Chain generators by sending outdata from one to another
|
|
1833
|
+
let result = source(); // Start with the source generator
|
|
1834
|
+
for (let i = 0; i < stages.length; i++) {
|
|
1835
|
+
result = stages[i](result); // Pass on the result to next generator
|
|
1836
|
+
}
|
|
1837
|
+
// Start running the machine. If the last stage is a sink, it will consume the data and never emit anything
|
|
1838
|
+
// to us here...
|
|
1839
|
+
for await (const chunk of result) { }
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
async function* consumeChunkedBinaryStream(source) {
|
|
1843
|
+
let state = 0;
|
|
1844
|
+
let sizeBuf = new Uint8Array(4);
|
|
1845
|
+
let sizeBufPos = 0;
|
|
1846
|
+
let bufs = [];
|
|
1847
|
+
let len = 0;
|
|
1848
|
+
for await (const chunk of source) {
|
|
1849
|
+
const dw = new DataView(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
1850
|
+
let pos = 0;
|
|
1851
|
+
while (pos < chunk.byteLength) {
|
|
1852
|
+
switch (state) {
|
|
1853
|
+
case 0:
|
|
1854
|
+
// Beginning of a size header
|
|
1855
|
+
if (pos + 4 > chunk.byteLength) {
|
|
1856
|
+
for (const b of chunk.slice(pos)) {
|
|
1857
|
+
if (sizeBufPos === 4)
|
|
1858
|
+
break;
|
|
1859
|
+
sizeBuf[sizeBufPos++] = b;
|
|
1860
|
+
++pos;
|
|
1861
|
+
}
|
|
1862
|
+
if (sizeBufPos < 4) {
|
|
1863
|
+
// Need more bytes in order to read length.
|
|
1864
|
+
// Will go out from while loop as well because pos is defenitely = chunk.byteLength here.
|
|
1865
|
+
break;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
else if (sizeBufPos > 0 && sizeBufPos < 4) {
|
|
1869
|
+
for (const b of chunk.slice(pos, pos + 4 - sizeBufPos)) {
|
|
1870
|
+
sizeBuf[sizeBufPos++] = b;
|
|
1871
|
+
++pos;
|
|
1872
|
+
}
|
|
1873
|
+
}
|
|
1874
|
+
// Intentional fall-through...
|
|
1875
|
+
case 1:
|
|
1876
|
+
len =
|
|
1877
|
+
sizeBufPos === 4
|
|
1878
|
+
? new DataView(sizeBuf.buffer, 0, 4).getUint32(0, false)
|
|
1879
|
+
: dw.getUint32(pos, false);
|
|
1880
|
+
if (sizeBufPos)
|
|
1881
|
+
sizeBufPos = 0; // in this case pos is already forwarded
|
|
1882
|
+
else
|
|
1883
|
+
pos += 4; // else pos is not yet forwarded - that's why we do it now
|
|
1884
|
+
// Intentional fall-through...
|
|
1885
|
+
case 2:
|
|
1886
|
+
// Eat the chunk
|
|
1887
|
+
if (pos >= chunk.byteLength) {
|
|
1888
|
+
state = 2;
|
|
1889
|
+
break;
|
|
1890
|
+
}
|
|
1891
|
+
if (pos + len > chunk.byteLength) {
|
|
1892
|
+
bufs.push(chunk.slice(pos));
|
|
1893
|
+
len -= (chunk.byteLength - pos);
|
|
1894
|
+
state = 2;
|
|
1895
|
+
pos = chunk.byteLength; // will break while loop.
|
|
1896
|
+
}
|
|
1897
|
+
else {
|
|
1898
|
+
if (bufs.length > 0) {
|
|
1899
|
+
const concats = new Uint8Array(bufs.reduce((p, c) => p + c.byteLength, len));
|
|
1900
|
+
let p = 0;
|
|
1901
|
+
for (const buf of bufs) {
|
|
1902
|
+
concats.set(buf, p);
|
|
1903
|
+
p += buf.byteLength;
|
|
1904
|
+
}
|
|
1905
|
+
concats.set(chunk.slice(pos, pos + len), p);
|
|
1906
|
+
bufs = [];
|
|
1907
|
+
yield concats;
|
|
1908
|
+
}
|
|
1909
|
+
else {
|
|
1910
|
+
yield chunk.slice(pos, pos + len);
|
|
1911
|
+
}
|
|
1912
|
+
pos += len;
|
|
1913
|
+
state = 0;
|
|
1914
|
+
}
|
|
1915
|
+
break;
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
function getFetchResponseBodyGenerator(res) {
|
|
1922
|
+
return async function* () {
|
|
1923
|
+
if (!res.body)
|
|
1924
|
+
throw new Error("Response body is not readable");
|
|
1925
|
+
const reader = res.body.getReader();
|
|
1926
|
+
try {
|
|
1927
|
+
while (true) {
|
|
1928
|
+
const { done, value } = await reader.read();
|
|
1929
|
+
if (done)
|
|
1930
|
+
return;
|
|
1931
|
+
yield value;
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
finally {
|
|
1935
|
+
reader.releaseLock();
|
|
1936
|
+
}
|
|
1937
|
+
};
|
|
1938
|
+
}
|
|
1939
|
+
|
|
1940
|
+
//const hasSW = 'serviceWorker' in navigator;
|
|
1941
|
+
let hasComplainedAboutSyncEvent = false;
|
|
1942
|
+
function registerSyncEvent(db, purpose) {
|
|
1943
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1944
|
+
try {
|
|
1945
|
+
// Send sync event to SW:
|
|
1946
|
+
const sw = yield navigator.serviceWorker.ready;
|
|
1947
|
+
if (purpose === "push" && sw.sync) {
|
|
1948
|
+
yield sw.sync.register(`dexie-cloud:${db.name}`);
|
|
1949
|
+
}
|
|
1950
|
+
if (sw.active) {
|
|
1951
|
+
// Use postMessage for pull syncs and for browsers not supporting sync event (Firefox, Safari).
|
|
1952
|
+
// Also chromium based browsers with sw.sync as a fallback for sleepy sync events not taking action for a while.
|
|
1953
|
+
sw.active.postMessage({
|
|
1954
|
+
type: 'dexie-cloud-sync',
|
|
1955
|
+
dbName: db.name,
|
|
1956
|
+
purpose
|
|
1957
|
+
});
|
|
1958
|
+
}
|
|
1959
|
+
else {
|
|
1960
|
+
throw new Error(`Failed to trigger sync - there's no active service worker`);
|
|
1961
|
+
}
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1964
|
+
catch (e) {
|
|
1965
|
+
if (!hasComplainedAboutSyncEvent) {
|
|
1966
|
+
console.debug(`Dexie Cloud: Could not register sync event`, e);
|
|
1967
|
+
hasComplainedAboutSyncEvent = true;
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
});
|
|
1971
|
+
}
|
|
1972
|
+
function registerPeriodicSyncEvent(db) {
|
|
1973
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1974
|
+
var _a;
|
|
1975
|
+
try {
|
|
1976
|
+
// Register periodicSync event to SW:
|
|
1977
|
+
// @ts-ignore
|
|
1978
|
+
const { periodicSync } = yield navigator.serviceWorker.ready;
|
|
1979
|
+
if (periodicSync) {
|
|
1980
|
+
try {
|
|
1981
|
+
yield periodicSync.register(`dexie-cloud:${db.name}`, (_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.periodicSync);
|
|
1982
|
+
console.debug(`Dexie Cloud: Successfully registered periodicsync event for ${db.name}`);
|
|
1983
|
+
}
|
|
1984
|
+
catch (e) {
|
|
1985
|
+
console.debug(`Dexie Cloud: Failed to register periodic sync. Your PWA must be installed to allow background sync.`, e);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
else {
|
|
1989
|
+
console.debug(`Dexie Cloud: periodicSync not supported.`);
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1992
|
+
catch (e) {
|
|
1993
|
+
console.debug(`Dexie Cloud: Could not register periodicSync for ${db.name}`, e);
|
|
1994
|
+
}
|
|
1995
|
+
});
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
function triggerSync(db, purpose) {
|
|
1999
|
+
if (db.cloud.usingServiceWorker) {
|
|
2000
|
+
console.debug('registering sync event');
|
|
2001
|
+
registerSyncEvent(db, purpose);
|
|
2002
|
+
}
|
|
2003
|
+
else {
|
|
2004
|
+
db.localSyncEvent.next({ purpose });
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
|
|
2008
|
+
const hasArrayBufferFromBase64 = "fromBase64" in Uint8Array; // https://github.com/tc39/proposal-arraybuffer-base64;
|
|
2009
|
+
const hasArrayBufferToBase64 = "toBase64" in Uint8Array.prototype; // https://github.com/tc39/proposal-arraybuffer-base64;
|
|
2010
|
+
const b64decode = typeof Buffer !== "undefined"
|
|
2011
|
+
? (base64) => Buffer.from(base64, "base64") // Node
|
|
2012
|
+
: hasArrayBufferFromBase64
|
|
2013
|
+
? // @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64
|
|
2014
|
+
(base64) => Uint8Array.fromBase64(base64) // Modern javascript standard
|
|
2015
|
+
: (base64) => {
|
|
2016
|
+
// Legacy DOM workaround
|
|
2017
|
+
const binary_string = atob(base64);
|
|
2018
|
+
const len = binary_string.length;
|
|
2019
|
+
const bytes = new Uint8Array(len);
|
|
2020
|
+
for (var i = 0; i < len; i++) {
|
|
2021
|
+
bytes[i] = binary_string.charCodeAt(i);
|
|
2022
|
+
}
|
|
2023
|
+
return bytes;
|
|
2024
|
+
};
|
|
2025
|
+
const b64encode = typeof Buffer !== "undefined"
|
|
2026
|
+
? (b) => {
|
|
2027
|
+
// Node
|
|
2028
|
+
if (ArrayBuffer.isView(b)) {
|
|
2029
|
+
return Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString("base64");
|
|
2030
|
+
}
|
|
2031
|
+
else {
|
|
2032
|
+
return Buffer.from(b).toString("base64");
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
: hasArrayBufferToBase64
|
|
2036
|
+
? (b) => {
|
|
2037
|
+
// Uint8Array.prototype.toBase64 is available in modern browsers
|
|
2038
|
+
const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);
|
|
2039
|
+
// @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/toBase64
|
|
2040
|
+
return u8a.toBase64();
|
|
2041
|
+
}
|
|
2042
|
+
: (b) => {
|
|
2043
|
+
// Legacy DOM workaround
|
|
2044
|
+
const u8a = ArrayBuffer.isView(b) ? b : new Uint8Array(b);
|
|
2045
|
+
const CHUNK_SIZE = 0x1000;
|
|
2046
|
+
const strs = [];
|
|
2047
|
+
for (let i = 0, l = u8a.length; i < l; i += CHUNK_SIZE) {
|
|
2048
|
+
const chunk = u8a.subarray(i, i + CHUNK_SIZE);
|
|
2049
|
+
strs.push(String.fromCharCode.apply(null, chunk));
|
|
2050
|
+
}
|
|
2051
|
+
return btoa(strs.join(""));
|
|
2052
|
+
};
|
|
2053
|
+
|
|
2054
|
+
class TokenErrorResponseError extends Error {
|
|
2055
|
+
constructor({ title, message, messageCode, messageParams, }) {
|
|
2056
|
+
super(message);
|
|
2057
|
+
this.name = 'TokenErrorResponseError';
|
|
2058
|
+
this.title = title;
|
|
2059
|
+
this.messageCode = messageCode;
|
|
2060
|
+
this.messageParams = messageParams;
|
|
2061
|
+
}
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
function interactWithUser(userInteraction, req) {
|
|
2065
|
+
return new Promise((resolve, reject) => {
|
|
2066
|
+
const interactionProps = Object.assign(Object.assign({ submitLabel: 'Submit', cancelLabel: 'Cancel' }, req), { onSubmit: (res) => {
|
|
2067
|
+
userInteraction.next(undefined);
|
|
2068
|
+
resolve(res);
|
|
2069
|
+
}, onCancel: () => {
|
|
2070
|
+
userInteraction.next(undefined);
|
|
2071
|
+
reject(new Dexie.AbortError('User cancelled'));
|
|
2072
|
+
} });
|
|
2073
|
+
userInteraction.next(interactionProps);
|
|
2074
|
+
// Start subscribing for external updates to db.cloud.userInteraction, and if so, cancel this request.
|
|
2075
|
+
/*const subscription = userInteraction.subscribe((currentInteractionProps) => {
|
|
2076
|
+
if (currentInteractionProps !== interactionProps) {
|
|
2077
|
+
if (subscription) subscription.unsubscribe();
|
|
2078
|
+
if (!done) {
|
|
2079
|
+
reject(new Dexie.AbortError("User cancelled"));
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
});*/
|
|
2083
|
+
});
|
|
2084
|
+
}
|
|
2085
|
+
function alertUser(userInteraction, title, ...alerts) {
|
|
2086
|
+
return interactWithUser(userInteraction, {
|
|
2087
|
+
type: 'message-alert',
|
|
2088
|
+
title,
|
|
2089
|
+
alerts,
|
|
1638
2090
|
fields: {},
|
|
1639
2091
|
submitLabel: 'OK',
|
|
1640
2092
|
cancelLabel: null,
|
|
@@ -2535,10 +2987,17 @@
|
|
|
2535
2987
|
return true;
|
|
2536
2988
|
if (mut.keys.length !== 1 || mut.changeSpecs.length !== 1)
|
|
2537
2989
|
return true;
|
|
2990
|
+
// Check if this has PropModifications - if so, skip optimization
|
|
2991
|
+
const changeSpecs = mut.changeSpecs[0];
|
|
2992
|
+
if (Object.values(changeSpecs).some(v => typeof v === "object" && v && "@@propmod" in v)) {
|
|
2993
|
+
return true; // Cannot optimize if any PropModification is present
|
|
2994
|
+
}
|
|
2538
2995
|
// Keep track of properties that aren't overlapped by later transactions
|
|
2539
2996
|
const unoverlappedProps = new Set(Object.keys(mut.changeSpecs[0]));
|
|
2540
2997
|
const strKey = '' + mut.keys[0];
|
|
2541
2998
|
const keyCoverage = updateCoverage.get(strKey);
|
|
2999
|
+
if (!keyCoverage)
|
|
3000
|
+
return true; // No coverage info - cannot optimize
|
|
2542
3001
|
for (let i = keyCoverage.length - 1; i >= 0; --i) {
|
|
2543
3002
|
const { txid, updateSpec } = keyCoverage[i];
|
|
2544
3003
|
if (txid === mut.txid)
|
|
@@ -3204,7 +3663,8 @@
|
|
|
3204
3663
|
return Object.assign({ $t: 'PropModification' }, propModification['@@propmod']);
|
|
3205
3664
|
},
|
|
3206
3665
|
revive: (_a) => {
|
|
3207
|
-
var
|
|
3666
|
+
var { $t } = _a, // strip '$t'
|
|
3667
|
+
propModSpec = __rest(_a, ["$t"]) // keep the rest
|
|
3208
3668
|
;
|
|
3209
3669
|
return new Dexie.PropModification(propModSpec);
|
|
3210
3670
|
},
|
|
@@ -3381,1748 +3841,456 @@
|
|
|
3381
3841
|
const syncRes = TSON.parse(text);
|
|
3382
3842
|
return syncRes;
|
|
3383
3843
|
}
|
|
3384
|
-
}
|
|
3385
|
-
});
|
|
3386
|
-
}
|
|
3387
|
-
|
|
3388
|
-
function modifyLocalObjectsWithNewUserId(syncifiedTables, currentUser, alreadySyncedRealms) {
|
|
3389
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3390
|
-
const ignoredRealms = new Set(alreadySyncedRealms || []);
|
|
3391
|
-
for (const table of syncifiedTables) {
|
|
3392
|
-
if (table.name === "members") {
|
|
3393
|
-
// members
|
|
3394
|
-
yield table.toCollection().modify((member) => {
|
|
3395
|
-
if (!ignoredRealms.has(member.realmId) && (!member.userId || member.userId === UNAUTHORIZED_USER.userId)) {
|
|
3396
|
-
member.userId = currentUser.userId;
|
|
3397
|
-
}
|
|
3398
|
-
});
|
|
3399
|
-
}
|
|
3400
|
-
else if (table.name === "roles") ;
|
|
3401
|
-
else if (table.name === "realms") {
|
|
3402
|
-
// realms
|
|
3403
|
-
yield table.toCollection().modify((realm) => {
|
|
3404
|
-
if (!ignoredRealms.has(realm.realmId) && (realm.owner === undefined || realm.owner === UNAUTHORIZED_USER.userId)) {
|
|
3405
|
-
realm.owner = currentUser.userId;
|
|
3406
|
-
}
|
|
3407
|
-
});
|
|
3408
|
-
}
|
|
3409
|
-
else {
|
|
3410
|
-
// application entities
|
|
3411
|
-
yield table.toCollection().modify((obj) => {
|
|
3412
|
-
if (!obj.realmId || !ignoredRealms.has(obj.realmId)) {
|
|
3413
|
-
if (!obj.owner || obj.owner === UNAUTHORIZED_USER.userId)
|
|
3414
|
-
obj.owner = currentUser.userId;
|
|
3415
|
-
if (!obj.realmId || obj.realmId === UNAUTHORIZED_USER.userId) {
|
|
3416
|
-
obj.realmId = currentUser.userId;
|
|
3417
|
-
}
|
|
3418
|
-
}
|
|
3419
|
-
});
|
|
3420
|
-
}
|
|
3421
|
-
}
|
|
3422
|
-
});
|
|
3423
|
-
}
|
|
3424
|
-
|
|
3425
|
-
function throwIfCancelled(cancelToken) {
|
|
3426
|
-
if (cancelToken === null || cancelToken === void 0 ? void 0 : cancelToken.cancelled)
|
|
3427
|
-
throw new Dexie.AbortError(`Operation was cancelled`);
|
|
3428
|
-
}
|
|
3429
|
-
|
|
3430
|
-
/* Need this because navigator.onLine seems to say "false" when it is actually online.
|
|
3431
|
-
This function relies initially on navigator.onLine but then uses online and offline events
|
|
3432
|
-
which seem to be more reliable.
|
|
3433
|
-
*/
|
|
3434
|
-
let isOnline = false;
|
|
3435
|
-
if (typeof self !== 'undefined' && typeof navigator !== 'undefined') {
|
|
3436
|
-
isOnline = navigator.onLine;
|
|
3437
|
-
self.addEventListener('online', () => isOnline = true);
|
|
3438
|
-
self.addEventListener('offline', () => isOnline = false);
|
|
3439
|
-
}
|
|
3440
|
-
|
|
3441
|
-
function updateBaseRevs(db, schema, latestRevisions, serverRev) {
|
|
3442
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3443
|
-
yield db.$baseRevs.bulkPut(Object.keys(schema)
|
|
3444
|
-
.filter((table) => schema[table].markedForSync)
|
|
3445
|
-
.map((tableName) => {
|
|
3446
|
-
const lastClientRevOnPreviousServerRev = latestRevisions[tableName] || 0;
|
|
3447
|
-
return {
|
|
3448
|
-
tableName,
|
|
3449
|
-
clientRev: lastClientRevOnPreviousServerRev + 1,
|
|
3450
|
-
serverRev,
|
|
3451
|
-
};
|
|
3452
|
-
}));
|
|
3453
|
-
// Clean up baseRevs for tables that do not exist anymore or are no longer marked for sync
|
|
3454
|
-
// Resolve #2168 by also cleaning up baseRevs for tables that are not marked for sync
|
|
3455
|
-
yield db.$baseRevs.where('tableName').noneOf(Object.keys(schema).filter((table) => schema[table].markedForSync)).delete();
|
|
3456
|
-
});
|
|
3457
|
-
}
|
|
3458
|
-
|
|
3459
|
-
function getLatestRevisionsPerTable(clientChangeSet, lastRevisions = {}) {
|
|
3460
|
-
for (const { table, muts } of clientChangeSet) {
|
|
3461
|
-
const lastRev = muts.length > 0 ? muts[muts.length - 1].rev : null;
|
|
3462
|
-
lastRevisions[table] = lastRev || lastRevisions[table] || 0;
|
|
3463
|
-
}
|
|
3464
|
-
return lastRevisions;
|
|
3465
|
-
}
|
|
3466
|
-
|
|
3467
|
-
function bulkUpdate(table, keys, changeSpecs) {
|
|
3468
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3469
|
-
const objs = yield table.bulkGet(keys);
|
|
3470
|
-
const resultKeys = [];
|
|
3471
|
-
const resultObjs = [];
|
|
3472
|
-
keys.forEach((key, idx) => {
|
|
3473
|
-
const obj = objs[idx];
|
|
3474
|
-
if (obj) {
|
|
3475
|
-
for (const [keyPath, value] of Object.entries(changeSpecs[idx])) {
|
|
3476
|
-
if (keyPath === table.schema.primKey.keyPath) {
|
|
3477
|
-
if (Dexie.cmp(value, key) !== 0) {
|
|
3478
|
-
throw new Error(`Cannot change primary key`);
|
|
3479
|
-
}
|
|
3480
|
-
}
|
|
3481
|
-
else {
|
|
3482
|
-
Dexie.setByKeyPath(obj, keyPath, value);
|
|
3483
|
-
}
|
|
3484
|
-
}
|
|
3485
|
-
resultKeys.push(key);
|
|
3486
|
-
resultObjs.push(obj);
|
|
3487
|
-
}
|
|
3488
|
-
});
|
|
3489
|
-
yield (table.schema.primKey.keyPath == null
|
|
3490
|
-
? table.bulkPut(resultObjs, resultKeys)
|
|
3491
|
-
: table.bulkPut(resultObjs));
|
|
3492
|
-
});
|
|
3493
|
-
}
|
|
3494
|
-
|
|
3495
|
-
function applyServerChanges(changes, db) {
|
|
3496
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
3497
|
-
console.debug('Applying server changes', changes, Dexie.currentTransaction);
|
|
3498
|
-
for (const { table: tableName, muts } of changes) {
|
|
3499
|
-
if (!db.dx._allTables[tableName]) {
|
|
3500
|
-
console.debug(`Server sent changes for table ${tableName} that we don't have. Ignoring.`);
|
|
3501
|
-
continue;
|
|
3502
|
-
}
|
|
3503
|
-
const table = db.table(tableName);
|
|
3504
|
-
const { primaryKey } = table.core.schema;
|
|
3505
|
-
const keyDecoder = (key) => {
|
|
3506
|
-
switch (key[0]) {
|
|
3507
|
-
case '[':
|
|
3508
|
-
// Decode JSON array
|
|
3509
|
-
if (key.endsWith(']'))
|
|
3510
|
-
try {
|
|
3511
|
-
// On server, array keys are transformed to JSON string representation
|
|
3512
|
-
return JSON.parse(key);
|
|
3513
|
-
}
|
|
3514
|
-
catch (_a) { }
|
|
3515
|
-
return key;
|
|
3516
|
-
case '#':
|
|
3517
|
-
// Decode private ID (do the opposite from what's done in encodeIdsForServer())
|
|
3518
|
-
if (key.endsWith(':' + db.cloud.currentUserId)) {
|
|
3519
|
-
return key.substr(0, key.length - db.cloud.currentUserId.length - 1);
|
|
3520
|
-
}
|
|
3521
|
-
return key;
|
|
3522
|
-
default:
|
|
3523
|
-
return key;
|
|
3524
|
-
}
|
|
3525
|
-
};
|
|
3526
|
-
for (const mut of muts) {
|
|
3527
|
-
const keys = mut.keys.map(keyDecoder);
|
|
3528
|
-
switch (mut.type) {
|
|
3529
|
-
case 'insert':
|
|
3530
|
-
if (primaryKey.outbound) {
|
|
3531
|
-
yield table.bulkAdd(mut.values, keys);
|
|
3532
|
-
}
|
|
3533
|
-
else {
|
|
3534
|
-
keys.forEach((key, i) => {
|
|
3535
|
-
// Make sure inbound keys are consistent
|
|
3536
|
-
Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath, key);
|
|
3537
|
-
});
|
|
3538
|
-
yield table.bulkAdd(mut.values);
|
|
3539
|
-
}
|
|
3540
|
-
break;
|
|
3541
|
-
case 'upsert':
|
|
3542
|
-
if (primaryKey.outbound) {
|
|
3543
|
-
yield table.bulkPut(mut.values, keys);
|
|
3544
|
-
}
|
|
3545
|
-
else {
|
|
3546
|
-
keys.forEach((key, i) => {
|
|
3547
|
-
// Make sure inbound keys are consistent
|
|
3548
|
-
Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath, key);
|
|
3549
|
-
});
|
|
3550
|
-
yield table.bulkPut(mut.values);
|
|
3551
|
-
}
|
|
3552
|
-
break;
|
|
3553
|
-
case 'modify':
|
|
3554
|
-
if (keys.length === 1) {
|
|
3555
|
-
yield table.update(keys[0], mut.changeSpec);
|
|
3556
|
-
}
|
|
3557
|
-
else {
|
|
3558
|
-
yield table.where(':id').anyOf(keys).modify(mut.changeSpec);
|
|
3559
|
-
}
|
|
3560
|
-
break;
|
|
3561
|
-
case 'update':
|
|
3562
|
-
yield bulkUpdate(table, keys, mut.changeSpecs);
|
|
3563
|
-
break;
|
|
3564
|
-
case 'delete':
|
|
3565
|
-
yield table.bulkDelete(keys);
|
|
3566
|
-
break;
|
|
3567
|
-
}
|
|
3568
|
-
}
|
|
3569
|
-
}
|
|
3570
|
-
});
|
|
3571
|
-
}
|
|
3572
|
-
|
|
3573
|
-
const DEXIE_CLOUD_SYNCER_ID = 'dexie-cloud-syncer';
|
|
3574
|
-
|
|
3575
|
-
function listUpdatesSince(yTable, sinceIncluding) {
|
|
3576
|
-
return yTable
|
|
3577
|
-
.where('i')
|
|
3578
|
-
.between(sinceIncluding, Infinity, true)
|
|
3579
|
-
.toArray();
|
|
3580
|
-
}
|
|
3581
|
-
|
|
3582
|
-
/**
|
|
3583
|
-
* Utility module to work with key-value stores.
|
|
3584
|
-
*
|
|
3585
|
-
* @module map
|
|
3586
|
-
*/
|
|
3587
|
-
|
|
3588
|
-
/**
|
|
3589
|
-
* Creates a new Map instance.
|
|
3590
|
-
*
|
|
3591
|
-
* @function
|
|
3592
|
-
* @return {Map<any, any>}
|
|
3593
|
-
*
|
|
3594
|
-
* @function
|
|
3595
|
-
*/
|
|
3596
|
-
const create$5 = () => new Map();
|
|
3597
|
-
|
|
3598
|
-
/**
|
|
3599
|
-
* Copy a Map object into a fresh Map object.
|
|
3600
|
-
*
|
|
3601
|
-
* @function
|
|
3602
|
-
* @template K,V
|
|
3603
|
-
* @param {Map<K,V>} m
|
|
3604
|
-
* @return {Map<K,V>}
|
|
3605
|
-
*/
|
|
3606
|
-
const copy = m => {
|
|
3607
|
-
const r = create$5();
|
|
3608
|
-
m.forEach((v, k) => { r.set(k, v); });
|
|
3609
|
-
return r
|
|
3610
|
-
};
|
|
3611
|
-
|
|
3612
|
-
/**
|
|
3613
|
-
* Get map property. Create T if property is undefined and set T on map.
|
|
3614
|
-
*
|
|
3615
|
-
* ```js
|
|
3616
|
-
* const listeners = map.setIfUndefined(events, 'eventName', set.create)
|
|
3617
|
-
* listeners.add(listener)
|
|
3618
|
-
* ```
|
|
3619
|
-
*
|
|
3620
|
-
* @function
|
|
3621
|
-
* @template {Map<any, any>} MAP
|
|
3622
|
-
* @template {MAP extends Map<any,infer V> ? function():V : unknown} CF
|
|
3623
|
-
* @param {MAP} map
|
|
3624
|
-
* @param {MAP extends Map<infer K,any> ? K : unknown} key
|
|
3625
|
-
* @param {CF} createT
|
|
3626
|
-
* @return {ReturnType<CF>}
|
|
3627
|
-
*/
|
|
3628
|
-
const setIfUndefined = (map, key, createT) => {
|
|
3629
|
-
let set = map.get(key);
|
|
3630
|
-
if (set === undefined) {
|
|
3631
|
-
map.set(key, set = createT());
|
|
3632
|
-
}
|
|
3633
|
-
return set
|
|
3634
|
-
};
|
|
3635
|
-
|
|
3636
|
-
/**
|
|
3637
|
-
* Creates an Array and populates it with the content of all key-value pairs using the `f(value, key)` function.
|
|
3638
|
-
*
|
|
3639
|
-
* @function
|
|
3640
|
-
* @template K
|
|
3641
|
-
* @template V
|
|
3642
|
-
* @template R
|
|
3643
|
-
* @param {Map<K,V>} m
|
|
3644
|
-
* @param {function(V,K):R} f
|
|
3645
|
-
* @return {Array<R>}
|
|
3646
|
-
*/
|
|
3647
|
-
const map = (m, f) => {
|
|
3648
|
-
const res = [];
|
|
3649
|
-
for (const [key, value] of m) {
|
|
3650
|
-
res.push(f(value, key));
|
|
3651
|
-
}
|
|
3652
|
-
return res
|
|
3653
|
-
};
|
|
3654
|
-
|
|
3655
|
-
/**
|
|
3656
|
-
* Tests whether any key-value pairs pass the test implemented by `f(value, key)`.
|
|
3657
|
-
*
|
|
3658
|
-
* @todo should rename to some - similarly to Array.some
|
|
3659
|
-
*
|
|
3660
|
-
* @function
|
|
3661
|
-
* @template K
|
|
3662
|
-
* @template V
|
|
3663
|
-
* @param {Map<K,V>} m
|
|
3664
|
-
* @param {function(V,K):boolean} f
|
|
3665
|
-
* @return {boolean}
|
|
3666
|
-
*/
|
|
3667
|
-
const any = (m, f) => {
|
|
3668
|
-
for (const [key, value] of m) {
|
|
3669
|
-
if (f(value, key)) {
|
|
3670
|
-
return true
|
|
3671
|
-
}
|
|
3672
|
-
}
|
|
3673
|
-
return false
|
|
3674
|
-
};
|
|
3675
|
-
|
|
3676
|
-
/**
|
|
3677
|
-
* Utility module to work with sets.
|
|
3678
|
-
*
|
|
3679
|
-
* @module set
|
|
3680
|
-
*/
|
|
3681
|
-
|
|
3682
|
-
const create$4 = () => new Set();
|
|
3683
|
-
|
|
3684
|
-
/**
|
|
3685
|
-
* Utility module to work with Arrays.
|
|
3686
|
-
*
|
|
3687
|
-
* @module array
|
|
3688
|
-
*/
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
/**
|
|
3692
|
-
* Return the last element of an array. The element must exist
|
|
3693
|
-
*
|
|
3694
|
-
* @template L
|
|
3695
|
-
* @param {ArrayLike<L>} arr
|
|
3696
|
-
* @return {L}
|
|
3697
|
-
*/
|
|
3698
|
-
const last = arr => arr[arr.length - 1];
|
|
3699
|
-
|
|
3700
|
-
/**
|
|
3701
|
-
* Append elements from src to dest
|
|
3702
|
-
*
|
|
3703
|
-
* @template M
|
|
3704
|
-
* @param {Array<M>} dest
|
|
3705
|
-
* @param {Array<M>} src
|
|
3706
|
-
*/
|
|
3707
|
-
const appendTo = (dest, src) => {
|
|
3708
|
-
for (let i = 0; i < src.length; i++) {
|
|
3709
|
-
dest.push(src[i]);
|
|
3710
|
-
}
|
|
3711
|
-
};
|
|
3712
|
-
|
|
3713
|
-
/**
|
|
3714
|
-
* Transforms something array-like to an actual Array.
|
|
3715
|
-
*
|
|
3716
|
-
* @function
|
|
3717
|
-
* @template T
|
|
3718
|
-
* @param {ArrayLike<T>|Iterable<T>} arraylike
|
|
3719
|
-
* @return {T}
|
|
3720
|
-
*/
|
|
3721
|
-
const from = Array.from;
|
|
3722
|
-
|
|
3723
|
-
const isArray = Array.isArray;
|
|
3724
|
-
|
|
3725
|
-
/**
|
|
3726
|
-
* Observable class prototype.
|
|
3727
|
-
*
|
|
3728
|
-
* @module observable
|
|
3729
|
-
*/
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
/**
|
|
3733
|
-
* Handles named events.
|
|
3734
|
-
* @experimental
|
|
3735
|
-
*
|
|
3736
|
-
* This is basically a (better typed) duplicate of Observable, which will replace Observable in the
|
|
3737
|
-
* next release.
|
|
3738
|
-
*
|
|
3739
|
-
* @template {{[key in keyof EVENTS]: function(...any):void}} EVENTS
|
|
3740
|
-
*/
|
|
3741
|
-
class ObservableV2 {
|
|
3742
|
-
constructor () {
|
|
3743
|
-
/**
|
|
3744
|
-
* Some desc.
|
|
3745
|
-
* @type {Map<string, Set<any>>}
|
|
3746
|
-
*/
|
|
3747
|
-
this._observers = create$5();
|
|
3748
|
-
}
|
|
3749
|
-
|
|
3750
|
-
/**
|
|
3751
|
-
* @template {keyof EVENTS & string} NAME
|
|
3752
|
-
* @param {NAME} name
|
|
3753
|
-
* @param {EVENTS[NAME]} f
|
|
3754
|
-
*/
|
|
3755
|
-
on (name, f) {
|
|
3756
|
-
setIfUndefined(this._observers, /** @type {string} */ (name), create$4).add(f);
|
|
3757
|
-
return f
|
|
3758
|
-
}
|
|
3759
|
-
|
|
3760
|
-
/**
|
|
3761
|
-
* @template {keyof EVENTS & string} NAME
|
|
3762
|
-
* @param {NAME} name
|
|
3763
|
-
* @param {EVENTS[NAME]} f
|
|
3764
|
-
*/
|
|
3765
|
-
once (name, f) {
|
|
3766
|
-
/**
|
|
3767
|
-
* @param {...any} args
|
|
3768
|
-
*/
|
|
3769
|
-
const _f = (...args) => {
|
|
3770
|
-
this.off(name, /** @type {any} */ (_f));
|
|
3771
|
-
f(...args);
|
|
3772
|
-
};
|
|
3773
|
-
this.on(name, /** @type {any} */ (_f));
|
|
3774
|
-
}
|
|
3775
|
-
|
|
3776
|
-
/**
|
|
3777
|
-
* @template {keyof EVENTS & string} NAME
|
|
3778
|
-
* @param {NAME} name
|
|
3779
|
-
* @param {EVENTS[NAME]} f
|
|
3780
|
-
*/
|
|
3781
|
-
off (name, f) {
|
|
3782
|
-
const observers = this._observers.get(name);
|
|
3783
|
-
if (observers !== undefined) {
|
|
3784
|
-
observers.delete(f);
|
|
3785
|
-
if (observers.size === 0) {
|
|
3786
|
-
this._observers.delete(name);
|
|
3787
|
-
}
|
|
3788
|
-
}
|
|
3789
|
-
}
|
|
3790
|
-
|
|
3791
|
-
/**
|
|
3792
|
-
* Emit a named event. All registered event listeners that listen to the
|
|
3793
|
-
* specified name will receive the event.
|
|
3794
|
-
*
|
|
3795
|
-
* @todo This should catch exceptions
|
|
3796
|
-
*
|
|
3797
|
-
* @template {keyof EVENTS & string} NAME
|
|
3798
|
-
* @param {NAME} name The event name.
|
|
3799
|
-
* @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener.
|
|
3800
|
-
*/
|
|
3801
|
-
emit (name, args) {
|
|
3802
|
-
// copy all listeners to an array first to make sure that no event is emitted to listeners that are subscribed while the event handler is called.
|
|
3803
|
-
return from((this._observers.get(name) || create$5()).values()).forEach(f => f(...args))
|
|
3804
|
-
}
|
|
3805
|
-
|
|
3806
|
-
destroy () {
|
|
3807
|
-
this._observers = create$5();
|
|
3808
|
-
}
|
|
3809
|
-
}
|
|
3810
|
-
|
|
3811
|
-
/* c8 ignore start */
|
|
3812
|
-
/**
|
|
3813
|
-
* Handles named events.
|
|
3814
|
-
*
|
|
3815
|
-
* @deprecated
|
|
3816
|
-
* @template N
|
|
3817
|
-
*/
|
|
3818
|
-
class Observable {
|
|
3819
|
-
constructor () {
|
|
3820
|
-
/**
|
|
3821
|
-
* Some desc.
|
|
3822
|
-
* @type {Map<N, any>}
|
|
3823
|
-
*/
|
|
3824
|
-
this._observers = create$5();
|
|
3825
|
-
}
|
|
3826
|
-
|
|
3827
|
-
/**
|
|
3828
|
-
* @param {N} name
|
|
3829
|
-
* @param {function} f
|
|
3830
|
-
*/
|
|
3831
|
-
on (name, f) {
|
|
3832
|
-
setIfUndefined(this._observers, name, create$4).add(f);
|
|
3833
|
-
}
|
|
3834
|
-
|
|
3835
|
-
/**
|
|
3836
|
-
* @param {N} name
|
|
3837
|
-
* @param {function} f
|
|
3838
|
-
*/
|
|
3839
|
-
once (name, f) {
|
|
3840
|
-
/**
|
|
3841
|
-
* @param {...any} args
|
|
3842
|
-
*/
|
|
3843
|
-
const _f = (...args) => {
|
|
3844
|
-
this.off(name, _f);
|
|
3845
|
-
f(...args);
|
|
3846
|
-
};
|
|
3847
|
-
this.on(name, _f);
|
|
3848
|
-
}
|
|
3849
|
-
|
|
3850
|
-
/**
|
|
3851
|
-
* @param {N} name
|
|
3852
|
-
* @param {function} f
|
|
3853
|
-
*/
|
|
3854
|
-
off (name, f) {
|
|
3855
|
-
const observers = this._observers.get(name);
|
|
3856
|
-
if (observers !== undefined) {
|
|
3857
|
-
observers.delete(f);
|
|
3858
|
-
if (observers.size === 0) {
|
|
3859
|
-
this._observers.delete(name);
|
|
3860
|
-
}
|
|
3861
|
-
}
|
|
3862
|
-
}
|
|
3863
|
-
|
|
3864
|
-
/**
|
|
3865
|
-
* Emit a named event. All registered event listeners that listen to the
|
|
3866
|
-
* specified name will receive the event.
|
|
3867
|
-
*
|
|
3868
|
-
* @todo This should catch exceptions
|
|
3869
|
-
*
|
|
3870
|
-
* @param {N} name The event name.
|
|
3871
|
-
* @param {Array<any>} args The arguments that are applied to the event listener.
|
|
3872
|
-
*/
|
|
3873
|
-
emit (name, args) {
|
|
3874
|
-
// copy all listeners to an array first to make sure that no event is emitted to listeners that are subscribed while the event handler is called.
|
|
3875
|
-
return from((this._observers.get(name) || create$5()).values()).forEach(f => f(...args))
|
|
3876
|
-
}
|
|
3877
|
-
|
|
3878
|
-
destroy () {
|
|
3879
|
-
this._observers = create$5();
|
|
3880
|
-
}
|
|
3881
|
-
}
|
|
3882
|
-
/* c8 ignore end */
|
|
3883
|
-
|
|
3884
|
-
/**
|
|
3885
|
-
* Common Math expressions.
|
|
3886
|
-
*
|
|
3887
|
-
* @module math
|
|
3888
|
-
*/
|
|
3889
|
-
|
|
3890
|
-
const floor = Math.floor;
|
|
3891
|
-
const abs = Math.abs;
|
|
3892
|
-
|
|
3893
|
-
/**
|
|
3894
|
-
* @function
|
|
3895
|
-
* @param {number} a
|
|
3896
|
-
* @param {number} b
|
|
3897
|
-
* @return {number} The smaller element of a and b
|
|
3898
|
-
*/
|
|
3899
|
-
const min = (a, b) => a < b ? a : b;
|
|
3900
|
-
|
|
3901
|
-
/**
|
|
3902
|
-
* @function
|
|
3903
|
-
* @param {number} a
|
|
3904
|
-
* @param {number} b
|
|
3905
|
-
* @return {number} The bigger element of a and b
|
|
3906
|
-
*/
|
|
3907
|
-
const max = (a, b) => a > b ? a : b;
|
|
3908
|
-
|
|
3909
|
-
/**
|
|
3910
|
-
* @param {number} n
|
|
3911
|
-
* @return {boolean} Wether n is negative. This function also differentiates between -0 and +0
|
|
3912
|
-
*/
|
|
3913
|
-
const isNegativeZero = n => n !== 0 ? n < 0 : 1 / n < 0;
|
|
3914
|
-
|
|
3915
|
-
/* eslint-env browser */
|
|
3916
|
-
|
|
3917
|
-
/**
|
|
3918
|
-
* Binary data constants.
|
|
3919
|
-
*
|
|
3920
|
-
* @module binary
|
|
3921
|
-
*/
|
|
3922
|
-
|
|
3923
|
-
/**
|
|
3924
|
-
* n-th bit activated.
|
|
3925
|
-
*
|
|
3926
|
-
* @type {number}
|
|
3927
|
-
*/
|
|
3928
|
-
const BIT1 = 1;
|
|
3929
|
-
const BIT2 = 2;
|
|
3930
|
-
const BIT3 = 4;
|
|
3931
|
-
const BIT4 = 8;
|
|
3932
|
-
const BIT6 = 32;
|
|
3933
|
-
const BIT7 = 64;
|
|
3934
|
-
const BIT8 = 128;
|
|
3935
|
-
const BITS5 = 31;
|
|
3936
|
-
const BITS6 = 63;
|
|
3937
|
-
const BITS7 = 127;
|
|
3938
|
-
/**
|
|
3939
|
-
* @type {number}
|
|
3940
|
-
*/
|
|
3941
|
-
const BITS31 = 0x7FFFFFFF;
|
|
3942
|
-
|
|
3943
|
-
/**
|
|
3944
|
-
* Utility helpers for working with numbers.
|
|
3945
|
-
*
|
|
3946
|
-
* @module number
|
|
3947
|
-
*/
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
|
|
3951
|
-
|
|
3952
|
-
/* c8 ignore next */
|
|
3953
|
-
const isInteger = Number.isInteger || (num => typeof num === 'number' && isFinite(num) && floor(num) === num);
|
|
3954
|
-
|
|
3955
|
-
/**
|
|
3956
|
-
* @param {string} s
|
|
3957
|
-
* @return {string}
|
|
3958
|
-
*/
|
|
3959
|
-
const toLowerCase = s => s.toLowerCase();
|
|
3960
|
-
|
|
3961
|
-
const trimLeftRegex = /^\s*/g;
|
|
3962
|
-
|
|
3963
|
-
/**
|
|
3964
|
-
* @param {string} s
|
|
3965
|
-
* @return {string}
|
|
3966
|
-
*/
|
|
3967
|
-
const trimLeft = s => s.replace(trimLeftRegex, '');
|
|
3968
|
-
|
|
3969
|
-
const fromCamelCaseRegex = /([A-Z])/g;
|
|
3970
|
-
|
|
3971
|
-
/**
|
|
3972
|
-
* @param {string} s
|
|
3973
|
-
* @param {string} separator
|
|
3974
|
-
* @return {string}
|
|
3975
|
-
*/
|
|
3976
|
-
const fromCamelCase = (s, separator) => trimLeft(s.replace(fromCamelCaseRegex, match => `${separator}${toLowerCase(match)}`));
|
|
3977
|
-
|
|
3978
|
-
/**
|
|
3979
|
-
* @param {string} str
|
|
3980
|
-
* @return {Uint8Array}
|
|
3981
|
-
*/
|
|
3982
|
-
const _encodeUtf8Polyfill = str => {
|
|
3983
|
-
const encodedString = unescape(encodeURIComponent(str));
|
|
3984
|
-
const len = encodedString.length;
|
|
3985
|
-
const buf = new Uint8Array(len);
|
|
3986
|
-
for (let i = 0; i < len; i++) {
|
|
3987
|
-
buf[i] = /** @type {number} */ (encodedString.codePointAt(i));
|
|
3988
|
-
}
|
|
3989
|
-
return buf
|
|
3990
|
-
};
|
|
3991
|
-
|
|
3992
|
-
/* c8 ignore next */
|
|
3993
|
-
const utf8TextEncoder = /** @type {TextEncoder} */ (typeof TextEncoder !== 'undefined' ? new TextEncoder() : null);
|
|
3994
|
-
|
|
3995
|
-
/**
|
|
3996
|
-
* @param {string} str
|
|
3997
|
-
* @return {Uint8Array}
|
|
3998
|
-
*/
|
|
3999
|
-
const _encodeUtf8Native = str => utf8TextEncoder.encode(str);
|
|
4000
|
-
|
|
4001
|
-
/**
|
|
4002
|
-
* @param {string} str
|
|
4003
|
-
* @return {Uint8Array}
|
|
4004
|
-
*/
|
|
4005
|
-
/* c8 ignore next */
|
|
4006
|
-
const encodeUtf8 = utf8TextEncoder ? _encodeUtf8Native : _encodeUtf8Polyfill;
|
|
4007
|
-
|
|
4008
|
-
/* c8 ignore next */
|
|
4009
|
-
let utf8TextDecoder = typeof TextDecoder === 'undefined' ? null : new TextDecoder('utf-8', { fatal: true, ignoreBOM: true });
|
|
4010
|
-
|
|
4011
|
-
/* c8 ignore start */
|
|
4012
|
-
if (utf8TextDecoder && utf8TextDecoder.decode(new Uint8Array()).length === 1) {
|
|
4013
|
-
// Safari doesn't handle BOM correctly.
|
|
4014
|
-
// This fixes a bug in Safari 13.0.5 where it produces a BOM the first time it is called.
|
|
4015
|
-
// utf8TextDecoder.decode(new Uint8Array()).length === 1 on the first call and
|
|
4016
|
-
// utf8TextDecoder.decode(new Uint8Array()).length === 1 on the second call
|
|
4017
|
-
// Another issue is that from then on no BOM chars are recognized anymore
|
|
4018
|
-
/* c8 ignore next */
|
|
4019
|
-
utf8TextDecoder = null;
|
|
4020
|
-
}
|
|
4021
|
-
|
|
4022
|
-
/**
|
|
4023
|
-
* Efficient schema-less binary encoding with support for variable length encoding.
|
|
4024
|
-
*
|
|
4025
|
-
* Use [lib0/encoding] with [lib0/decoding]. Every encoding function has a corresponding decoding function.
|
|
4026
|
-
*
|
|
4027
|
-
* Encodes numbers in little-endian order (least to most significant byte order)
|
|
4028
|
-
* and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)
|
|
4029
|
-
* which is also used in Protocol Buffers.
|
|
4030
|
-
*
|
|
4031
|
-
* ```js
|
|
4032
|
-
* // encoding step
|
|
4033
|
-
* const encoder = encoding.createEncoder()
|
|
4034
|
-
* encoding.writeVarUint(encoder, 256)
|
|
4035
|
-
* encoding.writeVarString(encoder, 'Hello world!')
|
|
4036
|
-
* const buf = encoding.toUint8Array(encoder)
|
|
4037
|
-
* ```
|
|
4038
|
-
*
|
|
4039
|
-
* ```js
|
|
4040
|
-
* // decoding step
|
|
4041
|
-
* const decoder = decoding.createDecoder(buf)
|
|
4042
|
-
* decoding.readVarUint(decoder) // => 256
|
|
4043
|
-
* decoding.readVarString(decoder) // => 'Hello world!'
|
|
4044
|
-
* decoding.hasContent(decoder) // => false - all data is read
|
|
4045
|
-
* ```
|
|
4046
|
-
*
|
|
4047
|
-
* @module encoding
|
|
4048
|
-
*/
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
/**
|
|
4052
|
-
* A BinaryEncoder handles the encoding to an Uint8Array.
|
|
4053
|
-
*/
|
|
4054
|
-
class Encoder {
|
|
4055
|
-
constructor () {
|
|
4056
|
-
this.cpos = 0;
|
|
4057
|
-
this.cbuf = new Uint8Array(100);
|
|
4058
|
-
/**
|
|
4059
|
-
* @type {Array<Uint8Array>}
|
|
4060
|
-
*/
|
|
4061
|
-
this.bufs = [];
|
|
4062
|
-
}
|
|
4063
|
-
}
|
|
4064
|
-
|
|
4065
|
-
/**
|
|
4066
|
-
* @function
|
|
4067
|
-
* @return {Encoder}
|
|
4068
|
-
*/
|
|
4069
|
-
const createEncoder = () => new Encoder();
|
|
4070
|
-
|
|
4071
|
-
/**
|
|
4072
|
-
* The current length of the encoded data.
|
|
4073
|
-
*
|
|
4074
|
-
* @function
|
|
4075
|
-
* @param {Encoder} encoder
|
|
4076
|
-
* @return {number}
|
|
4077
|
-
*/
|
|
4078
|
-
const length$1 = encoder => {
|
|
4079
|
-
let len = encoder.cpos;
|
|
4080
|
-
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
4081
|
-
len += encoder.bufs[i].length;
|
|
4082
|
-
}
|
|
4083
|
-
return len
|
|
4084
|
-
};
|
|
4085
|
-
|
|
4086
|
-
/**
|
|
4087
|
-
* Transform to Uint8Array.
|
|
4088
|
-
*
|
|
4089
|
-
* @function
|
|
4090
|
-
* @param {Encoder} encoder
|
|
4091
|
-
* @return {Uint8Array} The created ArrayBuffer.
|
|
4092
|
-
*/
|
|
4093
|
-
const toUint8Array = encoder => {
|
|
4094
|
-
const uint8arr = new Uint8Array(length$1(encoder));
|
|
4095
|
-
let curPos = 0;
|
|
4096
|
-
for (let i = 0; i < encoder.bufs.length; i++) {
|
|
4097
|
-
const d = encoder.bufs[i];
|
|
4098
|
-
uint8arr.set(d, curPos);
|
|
4099
|
-
curPos += d.length;
|
|
4100
|
-
}
|
|
4101
|
-
uint8arr.set(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos), curPos);
|
|
4102
|
-
return uint8arr
|
|
4103
|
-
};
|
|
4104
|
-
|
|
4105
|
-
/**
|
|
4106
|
-
* Verify that it is possible to write `len` bytes wtihout checking. If
|
|
4107
|
-
* necessary, a new Buffer with the required length is attached.
|
|
4108
|
-
*
|
|
4109
|
-
* @param {Encoder} encoder
|
|
4110
|
-
* @param {number} len
|
|
4111
|
-
*/
|
|
4112
|
-
const verifyLen = (encoder, len) => {
|
|
4113
|
-
const bufferLen = encoder.cbuf.length;
|
|
4114
|
-
if (bufferLen - encoder.cpos < len) {
|
|
4115
|
-
encoder.bufs.push(new Uint8Array(encoder.cbuf.buffer, 0, encoder.cpos));
|
|
4116
|
-
encoder.cbuf = new Uint8Array(max(bufferLen, len) * 2);
|
|
4117
|
-
encoder.cpos = 0;
|
|
4118
|
-
}
|
|
4119
|
-
};
|
|
4120
|
-
|
|
4121
|
-
/**
|
|
4122
|
-
* Write one byte to the encoder.
|
|
4123
|
-
*
|
|
4124
|
-
* @function
|
|
4125
|
-
* @param {Encoder} encoder
|
|
4126
|
-
* @param {number} num The byte that is to be encoded.
|
|
4127
|
-
*/
|
|
4128
|
-
const write = (encoder, num) => {
|
|
4129
|
-
const bufferLen = encoder.cbuf.length;
|
|
4130
|
-
if (encoder.cpos === bufferLen) {
|
|
4131
|
-
encoder.bufs.push(encoder.cbuf);
|
|
4132
|
-
encoder.cbuf = new Uint8Array(bufferLen * 2);
|
|
4133
|
-
encoder.cpos = 0;
|
|
4134
|
-
}
|
|
4135
|
-
encoder.cbuf[encoder.cpos++] = num;
|
|
4136
|
-
};
|
|
4137
|
-
|
|
4138
|
-
/**
|
|
4139
|
-
* Write one byte as an unsigned integer.
|
|
4140
|
-
*
|
|
4141
|
-
* @function
|
|
4142
|
-
* @param {Encoder} encoder
|
|
4143
|
-
* @param {number} num The number that is to be encoded.
|
|
4144
|
-
*/
|
|
4145
|
-
const writeUint8 = write;
|
|
4146
|
-
|
|
4147
|
-
/**
|
|
4148
|
-
* Write a variable length unsigned integer. Max encodable integer is 2^53.
|
|
4149
|
-
*
|
|
4150
|
-
* @function
|
|
4151
|
-
* @param {Encoder} encoder
|
|
4152
|
-
* @param {number} num The number that is to be encoded.
|
|
4153
|
-
*/
|
|
4154
|
-
const writeVarUint = (encoder, num) => {
|
|
4155
|
-
while (num > BITS7) {
|
|
4156
|
-
write(encoder, BIT8 | (BITS7 & num));
|
|
4157
|
-
num = floor(num / 128); // shift >>> 7
|
|
4158
|
-
}
|
|
4159
|
-
write(encoder, BITS7 & num);
|
|
4160
|
-
};
|
|
4161
|
-
|
|
4162
|
-
/**
|
|
4163
|
-
* Write a variable length integer.
|
|
4164
|
-
*
|
|
4165
|
-
* We use the 7th bit instead for signaling that this is a negative number.
|
|
4166
|
-
*
|
|
4167
|
-
* @function
|
|
4168
|
-
* @param {Encoder} encoder
|
|
4169
|
-
* @param {number} num The number that is to be encoded.
|
|
4170
|
-
*/
|
|
4171
|
-
const writeVarInt = (encoder, num) => {
|
|
4172
|
-
const isNegative = isNegativeZero(num);
|
|
4173
|
-
if (isNegative) {
|
|
4174
|
-
num = -num;
|
|
4175
|
-
}
|
|
4176
|
-
// |- whether to continue reading |- whether is negative |- number
|
|
4177
|
-
write(encoder, (num > BITS6 ? BIT8 : 0) | (isNegative ? BIT7 : 0) | (BITS6 & num));
|
|
4178
|
-
num = floor(num / 64); // shift >>> 6
|
|
4179
|
-
// We don't need to consider the case of num === 0 so we can use a different
|
|
4180
|
-
// pattern here than above.
|
|
4181
|
-
while (num > 0) {
|
|
4182
|
-
write(encoder, (num > BITS7 ? BIT8 : 0) | (BITS7 & num));
|
|
4183
|
-
num = floor(num / 128); // shift >>> 7
|
|
4184
|
-
}
|
|
4185
|
-
};
|
|
4186
|
-
|
|
4187
|
-
/**
|
|
4188
|
-
* A cache to store strings temporarily
|
|
4189
|
-
*/
|
|
4190
|
-
const _strBuffer = new Uint8Array(30000);
|
|
4191
|
-
const _maxStrBSize = _strBuffer.length / 3;
|
|
4192
|
-
|
|
4193
|
-
/**
|
|
4194
|
-
* Write a variable length string.
|
|
4195
|
-
*
|
|
4196
|
-
* @function
|
|
4197
|
-
* @param {Encoder} encoder
|
|
4198
|
-
* @param {String} str The string that is to be encoded.
|
|
4199
|
-
*/
|
|
4200
|
-
const _writeVarStringNative = (encoder, str) => {
|
|
4201
|
-
if (str.length < _maxStrBSize) {
|
|
4202
|
-
// We can encode the string into the existing buffer
|
|
4203
|
-
/* c8 ignore next */
|
|
4204
|
-
const written = utf8TextEncoder.encodeInto(str, _strBuffer).written || 0;
|
|
4205
|
-
writeVarUint(encoder, written);
|
|
4206
|
-
for (let i = 0; i < written; i++) {
|
|
4207
|
-
write(encoder, _strBuffer[i]);
|
|
4208
|
-
}
|
|
4209
|
-
} else {
|
|
4210
|
-
writeVarUint8Array(encoder, encodeUtf8(str));
|
|
4211
|
-
}
|
|
4212
|
-
};
|
|
4213
|
-
|
|
4214
|
-
/**
|
|
4215
|
-
* Write a variable length string.
|
|
4216
|
-
*
|
|
4217
|
-
* @function
|
|
4218
|
-
* @param {Encoder} encoder
|
|
4219
|
-
* @param {String} str The string that is to be encoded.
|
|
4220
|
-
*/
|
|
4221
|
-
const _writeVarStringPolyfill = (encoder, str) => {
|
|
4222
|
-
const encodedString = unescape(encodeURIComponent(str));
|
|
4223
|
-
const len = encodedString.length;
|
|
4224
|
-
writeVarUint(encoder, len);
|
|
4225
|
-
for (let i = 0; i < len; i++) {
|
|
4226
|
-
write(encoder, /** @type {number} */ (encodedString.codePointAt(i)));
|
|
4227
|
-
}
|
|
4228
|
-
};
|
|
4229
|
-
|
|
4230
|
-
/**
|
|
4231
|
-
* Write a variable length string.
|
|
4232
|
-
*
|
|
4233
|
-
* @function
|
|
4234
|
-
* @param {Encoder} encoder
|
|
4235
|
-
* @param {String} str The string that is to be encoded.
|
|
4236
|
-
*/
|
|
4237
|
-
/* c8 ignore next */
|
|
4238
|
-
const writeVarString = (utf8TextEncoder && /** @type {any} */ (utf8TextEncoder).encodeInto) ? _writeVarStringNative : _writeVarStringPolyfill;
|
|
4239
|
-
|
|
4240
|
-
/**
|
|
4241
|
-
* Write the content of another Encoder.
|
|
4242
|
-
*
|
|
4243
|
-
* @TODO: can be improved!
|
|
4244
|
-
* - Note: Should consider that when appending a lot of small Encoders, we should rather clone than referencing the old structure.
|
|
4245
|
-
* Encoders start with a rather big initial buffer.
|
|
4246
|
-
*
|
|
4247
|
-
* @function
|
|
4248
|
-
* @param {Encoder} encoder The enUint8Arr
|
|
4249
|
-
* @param {Encoder} append The BinaryEncoder to be written.
|
|
4250
|
-
*/
|
|
4251
|
-
const writeBinaryEncoder = (encoder, append) => writeUint8Array(encoder, toUint8Array(append));
|
|
4252
|
-
|
|
4253
|
-
/**
|
|
4254
|
-
* Append fixed-length Uint8Array to the encoder.
|
|
4255
|
-
*
|
|
4256
|
-
* @function
|
|
4257
|
-
* @param {Encoder} encoder
|
|
4258
|
-
* @param {Uint8Array} uint8Array
|
|
4259
|
-
*/
|
|
4260
|
-
const writeUint8Array = (encoder, uint8Array) => {
|
|
4261
|
-
const bufferLen = encoder.cbuf.length;
|
|
4262
|
-
const cpos = encoder.cpos;
|
|
4263
|
-
const leftCopyLen = min(bufferLen - cpos, uint8Array.length);
|
|
4264
|
-
const rightCopyLen = uint8Array.length - leftCopyLen;
|
|
4265
|
-
encoder.cbuf.set(uint8Array.subarray(0, leftCopyLen), cpos);
|
|
4266
|
-
encoder.cpos += leftCopyLen;
|
|
4267
|
-
if (rightCopyLen > 0) {
|
|
4268
|
-
// Still something to write, write right half..
|
|
4269
|
-
// Append new buffer
|
|
4270
|
-
encoder.bufs.push(encoder.cbuf);
|
|
4271
|
-
// must have at least size of remaining buffer
|
|
4272
|
-
encoder.cbuf = new Uint8Array(max(bufferLen * 2, rightCopyLen));
|
|
4273
|
-
// copy array
|
|
4274
|
-
encoder.cbuf.set(uint8Array.subarray(leftCopyLen));
|
|
4275
|
-
encoder.cpos = rightCopyLen;
|
|
4276
|
-
}
|
|
4277
|
-
};
|
|
4278
|
-
|
|
4279
|
-
/**
|
|
4280
|
-
* Append an Uint8Array to Encoder.
|
|
4281
|
-
*
|
|
4282
|
-
* @function
|
|
4283
|
-
* @param {Encoder} encoder
|
|
4284
|
-
* @param {Uint8Array} uint8Array
|
|
4285
|
-
*/
|
|
4286
|
-
const writeVarUint8Array = (encoder, uint8Array) => {
|
|
4287
|
-
writeVarUint(encoder, uint8Array.byteLength);
|
|
4288
|
-
writeUint8Array(encoder, uint8Array);
|
|
4289
|
-
};
|
|
4290
|
-
|
|
4291
|
-
/**
|
|
4292
|
-
* Create an DataView of the next `len` bytes. Use it to write data after
|
|
4293
|
-
* calling this function.
|
|
4294
|
-
*
|
|
4295
|
-
* ```js
|
|
4296
|
-
* // write float32 using DataView
|
|
4297
|
-
* const dv = writeOnDataView(encoder, 4)
|
|
4298
|
-
* dv.setFloat32(0, 1.1)
|
|
4299
|
-
* // read float32 using DataView
|
|
4300
|
-
* const dv = readFromDataView(encoder, 4)
|
|
4301
|
-
* dv.getFloat32(0) // => 1.100000023841858 (leaving it to the reader to find out why this is the correct result)
|
|
4302
|
-
* ```
|
|
4303
|
-
*
|
|
4304
|
-
* @param {Encoder} encoder
|
|
4305
|
-
* @param {number} len
|
|
4306
|
-
* @return {DataView}
|
|
4307
|
-
*/
|
|
4308
|
-
const writeOnDataView = (encoder, len) => {
|
|
4309
|
-
verifyLen(encoder, len);
|
|
4310
|
-
const dview = new DataView(encoder.cbuf.buffer, encoder.cpos, len);
|
|
4311
|
-
encoder.cpos += len;
|
|
4312
|
-
return dview
|
|
4313
|
-
};
|
|
4314
|
-
|
|
4315
|
-
/**
|
|
4316
|
-
* @param {Encoder} encoder
|
|
4317
|
-
* @param {number} num
|
|
4318
|
-
*/
|
|
4319
|
-
const writeFloat32 = (encoder, num) => writeOnDataView(encoder, 4).setFloat32(0, num, false);
|
|
4320
|
-
|
|
4321
|
-
/**
|
|
4322
|
-
* @param {Encoder} encoder
|
|
4323
|
-
* @param {number} num
|
|
4324
|
-
*/
|
|
4325
|
-
const writeFloat64 = (encoder, num) => writeOnDataView(encoder, 8).setFloat64(0, num, false);
|
|
4326
|
-
|
|
4327
|
-
/**
|
|
4328
|
-
* @param {Encoder} encoder
|
|
4329
|
-
* @param {bigint} num
|
|
4330
|
-
*/
|
|
4331
|
-
const writeBigInt64 = (encoder, num) => /** @type {any} */ (writeOnDataView(encoder, 8)).setBigInt64(0, num, false);
|
|
4332
|
-
|
|
4333
|
-
const floatTestBed = new DataView(new ArrayBuffer(4));
|
|
4334
|
-
/**
|
|
4335
|
-
* Check if a number can be encoded as a 32 bit float.
|
|
4336
|
-
*
|
|
4337
|
-
* @param {number} num
|
|
4338
|
-
* @return {boolean}
|
|
4339
|
-
*/
|
|
4340
|
-
const isFloat32 = num => {
|
|
4341
|
-
floatTestBed.setFloat32(0, num);
|
|
4342
|
-
return floatTestBed.getFloat32(0) === num
|
|
4343
|
-
};
|
|
4344
|
-
|
|
4345
|
-
/**
|
|
4346
|
-
* Encode data with efficient binary format.
|
|
4347
|
-
*
|
|
4348
|
-
* Differences to JSON:
|
|
4349
|
-
* • Transforms data to a binary format (not to a string)
|
|
4350
|
-
* • Encodes undefined, NaN, and ArrayBuffer (these can't be represented in JSON)
|
|
4351
|
-
* • Numbers are efficiently encoded either as a variable length integer, as a
|
|
4352
|
-
* 32 bit float, as a 64 bit float, or as a 64 bit bigint.
|
|
4353
|
-
*
|
|
4354
|
-
* Encoding table:
|
|
4355
|
-
*
|
|
4356
|
-
* | Data Type | Prefix | Encoding Method | Comment |
|
|
4357
|
-
* | ------------------- | -------- | ------------------ | ------- |
|
|
4358
|
-
* | undefined | 127 | | Functions, symbol, and everything that cannot be identified is encoded as undefined |
|
|
4359
|
-
* | null | 126 | | |
|
|
4360
|
-
* | integer | 125 | writeVarInt | Only encodes 32 bit signed integers |
|
|
4361
|
-
* | float32 | 124 | writeFloat32 | |
|
|
4362
|
-
* | float64 | 123 | writeFloat64 | |
|
|
4363
|
-
* | bigint | 122 | writeBigInt64 | |
|
|
4364
|
-
* | boolean (false) | 121 | | True and false are different data types so we save the following byte |
|
|
4365
|
-
* | boolean (true) | 120 | | - 0b01111000 so the last bit determines whether true or false |
|
|
4366
|
-
* | string | 119 | writeVarString | |
|
|
4367
|
-
* | object<string,any> | 118 | custom | Writes {length} then {length} key-value pairs |
|
|
4368
|
-
* | array<any> | 117 | custom | Writes {length} then {length} json values |
|
|
4369
|
-
* | Uint8Array | 116 | writeVarUint8Array | We use Uint8Array for any kind of binary data |
|
|
4370
|
-
*
|
|
4371
|
-
* Reasons for the decreasing prefix:
|
|
4372
|
-
* We need the first bit for extendability (later we may want to encode the
|
|
4373
|
-
* prefix with writeVarUint). The remaining 7 bits are divided as follows:
|
|
4374
|
-
* [0-30] the beginning of the data range is used for custom purposes
|
|
4375
|
-
* (defined by the function that uses this library)
|
|
4376
|
-
* [31-127] the end of the data range is used for data encoding by
|
|
4377
|
-
* lib0/encoding.js
|
|
4378
|
-
*
|
|
4379
|
-
* @param {Encoder} encoder
|
|
4380
|
-
* @param {undefined|null|number|bigint|boolean|string|Object<string,any>|Array<any>|Uint8Array} data
|
|
4381
|
-
*/
|
|
4382
|
-
const writeAny = (encoder, data) => {
|
|
4383
|
-
switch (typeof data) {
|
|
4384
|
-
case 'string':
|
|
4385
|
-
// TYPE 119: STRING
|
|
4386
|
-
write(encoder, 119);
|
|
4387
|
-
writeVarString(encoder, data);
|
|
4388
|
-
break
|
|
4389
|
-
case 'number':
|
|
4390
|
-
if (isInteger(data) && abs(data) <= BITS31) {
|
|
4391
|
-
// TYPE 125: INTEGER
|
|
4392
|
-
write(encoder, 125);
|
|
4393
|
-
writeVarInt(encoder, data);
|
|
4394
|
-
} else if (isFloat32(data)) {
|
|
4395
|
-
// TYPE 124: FLOAT32
|
|
4396
|
-
write(encoder, 124);
|
|
4397
|
-
writeFloat32(encoder, data);
|
|
4398
|
-
} else {
|
|
4399
|
-
// TYPE 123: FLOAT64
|
|
4400
|
-
write(encoder, 123);
|
|
4401
|
-
writeFloat64(encoder, data);
|
|
4402
|
-
}
|
|
4403
|
-
break
|
|
4404
|
-
case 'bigint':
|
|
4405
|
-
// TYPE 122: BigInt
|
|
4406
|
-
write(encoder, 122);
|
|
4407
|
-
writeBigInt64(encoder, data);
|
|
4408
|
-
break
|
|
4409
|
-
case 'object':
|
|
4410
|
-
if (data === null) {
|
|
4411
|
-
// TYPE 126: null
|
|
4412
|
-
write(encoder, 126);
|
|
4413
|
-
} else if (isArray(data)) {
|
|
4414
|
-
// TYPE 117: Array
|
|
4415
|
-
write(encoder, 117);
|
|
4416
|
-
writeVarUint(encoder, data.length);
|
|
4417
|
-
for (let i = 0; i < data.length; i++) {
|
|
4418
|
-
writeAny(encoder, data[i]);
|
|
4419
|
-
}
|
|
4420
|
-
} else if (data instanceof Uint8Array) {
|
|
4421
|
-
// TYPE 116: ArrayBuffer
|
|
4422
|
-
write(encoder, 116);
|
|
4423
|
-
writeVarUint8Array(encoder, data);
|
|
4424
|
-
} else {
|
|
4425
|
-
// TYPE 118: Object
|
|
4426
|
-
write(encoder, 118);
|
|
4427
|
-
const keys = Object.keys(data);
|
|
4428
|
-
writeVarUint(encoder, keys.length);
|
|
4429
|
-
for (let i = 0; i < keys.length; i++) {
|
|
4430
|
-
const key = keys[i];
|
|
4431
|
-
writeVarString(encoder, key);
|
|
4432
|
-
writeAny(encoder, data[key]);
|
|
4433
|
-
}
|
|
4434
|
-
}
|
|
4435
|
-
break
|
|
4436
|
-
case 'boolean':
|
|
4437
|
-
// TYPE 120/121: boolean (true/false)
|
|
4438
|
-
write(encoder, data ? 120 : 121);
|
|
4439
|
-
break
|
|
4440
|
-
default:
|
|
4441
|
-
// TYPE 127: undefined
|
|
4442
|
-
write(encoder, 127);
|
|
4443
|
-
}
|
|
4444
|
-
};
|
|
4445
|
-
|
|
4446
|
-
/**
|
|
4447
|
-
* Now come a few stateful encoder that have their own classes.
|
|
4448
|
-
*/
|
|
4449
|
-
|
|
4450
|
-
/**
|
|
4451
|
-
* Basic Run Length Encoder - a basic compression implementation.
|
|
4452
|
-
*
|
|
4453
|
-
* Encodes [1,1,1,7] to [1,3,7,1] (3 times 1, 1 time 7). This encoder might do more harm than good if there are a lot of values that are not repeated.
|
|
4454
|
-
*
|
|
4455
|
-
* It was originally used for image compression. Cool .. article http://csbruce.com/cbm/transactor/pdfs/trans_v7_i06.pdf
|
|
4456
|
-
*
|
|
4457
|
-
* @note T must not be null!
|
|
4458
|
-
*
|
|
4459
|
-
* @template T
|
|
4460
|
-
*/
|
|
4461
|
-
class RleEncoder extends Encoder {
|
|
4462
|
-
/**
|
|
4463
|
-
* @param {function(Encoder, T):void} writer
|
|
4464
|
-
*/
|
|
4465
|
-
constructor (writer) {
|
|
4466
|
-
super();
|
|
4467
|
-
/**
|
|
4468
|
-
* The writer
|
|
4469
|
-
*/
|
|
4470
|
-
this.w = writer;
|
|
4471
|
-
/**
|
|
4472
|
-
* Current state
|
|
4473
|
-
* @type {T|null}
|
|
4474
|
-
*/
|
|
4475
|
-
this.s = null;
|
|
4476
|
-
this.count = 0;
|
|
4477
|
-
}
|
|
4478
|
-
|
|
4479
|
-
/**
|
|
4480
|
-
* @param {T} v
|
|
4481
|
-
*/
|
|
4482
|
-
write (v) {
|
|
4483
|
-
if (this.s === v) {
|
|
4484
|
-
this.count++;
|
|
4485
|
-
} else {
|
|
4486
|
-
if (this.count > 0) {
|
|
4487
|
-
// flush counter, unless this is the first value (count = 0)
|
|
4488
|
-
writeVarUint(this, this.count - 1); // since count is always > 0, we can decrement by one. non-standard encoding ftw
|
|
4489
|
-
}
|
|
4490
|
-
this.count = 1;
|
|
4491
|
-
// write first value
|
|
4492
|
-
this.w(this, v);
|
|
4493
|
-
this.s = v;
|
|
4494
|
-
}
|
|
4495
|
-
}
|
|
4496
|
-
}
|
|
4497
|
-
|
|
4498
|
-
/**
|
|
4499
|
-
* @param {UintOptRleEncoder} encoder
|
|
4500
|
-
*/
|
|
4501
|
-
const flushUintOptRleEncoder = encoder => {
|
|
4502
|
-
if (encoder.count > 0) {
|
|
4503
|
-
// flush counter, unless this is the first value (count = 0)
|
|
4504
|
-
// case 1: just a single value. set sign to positive
|
|
4505
|
-
// case 2: write several values. set sign to negative to indicate that there is a length coming
|
|
4506
|
-
writeVarInt(encoder.encoder, encoder.count === 1 ? encoder.s : -encoder.s);
|
|
4507
|
-
if (encoder.count > 1) {
|
|
4508
|
-
writeVarUint(encoder.encoder, encoder.count - 2); // since count is always > 1, we can decrement by one. non-standard encoding ftw
|
|
4509
|
-
}
|
|
4510
|
-
}
|
|
4511
|
-
};
|
|
4512
|
-
|
|
4513
|
-
/**
|
|
4514
|
-
* Optimized Rle encoder that does not suffer from the mentioned problem of the basic Rle encoder.
|
|
4515
|
-
*
|
|
4516
|
-
* Internally uses VarInt encoder to write unsigned integers. If the input occurs multiple times, we write
|
|
4517
|
-
* write it as a negative number. The UintOptRleDecoder then understands that it needs to read a count.
|
|
4518
|
-
*
|
|
4519
|
-
* Encodes [1,2,3,3,3] as [1,2,-3,3] (once 1, once 2, three times 3)
|
|
4520
|
-
*/
|
|
4521
|
-
class UintOptRleEncoder {
|
|
4522
|
-
constructor () {
|
|
4523
|
-
this.encoder = new Encoder();
|
|
4524
|
-
/**
|
|
4525
|
-
* @type {number}
|
|
4526
|
-
*/
|
|
4527
|
-
this.s = 0;
|
|
4528
|
-
this.count = 0;
|
|
4529
|
-
}
|
|
4530
|
-
|
|
4531
|
-
/**
|
|
4532
|
-
* @param {number} v
|
|
4533
|
-
*/
|
|
4534
|
-
write (v) {
|
|
4535
|
-
if (this.s === v) {
|
|
4536
|
-
this.count++;
|
|
4537
|
-
} else {
|
|
4538
|
-
flushUintOptRleEncoder(this);
|
|
4539
|
-
this.count = 1;
|
|
4540
|
-
this.s = v;
|
|
4541
|
-
}
|
|
4542
|
-
}
|
|
4543
|
-
|
|
4544
|
-
/**
|
|
4545
|
-
* Flush the encoded state and transform this to a Uint8Array.
|
|
4546
|
-
*
|
|
4547
|
-
* Note that this should only be called once.
|
|
4548
|
-
*/
|
|
4549
|
-
toUint8Array () {
|
|
4550
|
-
flushUintOptRleEncoder(this);
|
|
4551
|
-
return toUint8Array(this.encoder)
|
|
4552
|
-
}
|
|
4553
|
-
}
|
|
4554
|
-
|
|
4555
|
-
/**
|
|
4556
|
-
* @param {IntDiffOptRleEncoder} encoder
|
|
4557
|
-
*/
|
|
4558
|
-
const flushIntDiffOptRleEncoder = encoder => {
|
|
4559
|
-
if (encoder.count > 0) {
|
|
4560
|
-
// 31 bit making up the diff | wether to write the counter
|
|
4561
|
-
// const encodedDiff = encoder.diff << 1 | (encoder.count === 1 ? 0 : 1)
|
|
4562
|
-
const encodedDiff = encoder.diff * 2 + (encoder.count === 1 ? 0 : 1);
|
|
4563
|
-
// flush counter, unless this is the first value (count = 0)
|
|
4564
|
-
// case 1: just a single value. set first bit to positive
|
|
4565
|
-
// case 2: write several values. set first bit to negative to indicate that there is a length coming
|
|
4566
|
-
writeVarInt(encoder.encoder, encodedDiff);
|
|
4567
|
-
if (encoder.count > 1) {
|
|
4568
|
-
writeVarUint(encoder.encoder, encoder.count - 2); // since count is always > 1, we can decrement by one. non-standard encoding ftw
|
|
4569
|
-
}
|
|
4570
|
-
}
|
|
4571
|
-
};
|
|
4572
|
-
|
|
4573
|
-
/**
|
|
4574
|
-
* A combination of the IntDiffEncoder and the UintOptRleEncoder.
|
|
4575
|
-
*
|
|
4576
|
-
* The count approach is similar to the UintDiffOptRleEncoder, but instead of using the negative bitflag, it encodes
|
|
4577
|
-
* in the LSB whether a count is to be read. Therefore this Encoder only supports 31 bit integers!
|
|
4578
|
-
*
|
|
4579
|
-
* Encodes [1, 2, 3, 2] as [3, 1, 6, -1] (more specifically [(1 << 1) | 1, (3 << 0) | 0, -1])
|
|
4580
|
-
*
|
|
4581
|
-
* Internally uses variable length encoding. Contrary to normal UintVar encoding, the first byte contains:
|
|
4582
|
-
* * 1 bit that denotes whether the next value is a count (LSB)
|
|
4583
|
-
* * 1 bit that denotes whether this value is negative (MSB - 1)
|
|
4584
|
-
* * 1 bit that denotes whether to continue reading the variable length integer (MSB)
|
|
4585
|
-
*
|
|
4586
|
-
* Therefore, only five bits remain to encode diff ranges.
|
|
4587
|
-
*
|
|
4588
|
-
* Use this Encoder only when appropriate. In most cases, this is probably a bad idea.
|
|
4589
|
-
*/
|
|
4590
|
-
class IntDiffOptRleEncoder {
|
|
4591
|
-
constructor () {
|
|
4592
|
-
this.encoder = new Encoder();
|
|
4593
|
-
/**
|
|
4594
|
-
* @type {number}
|
|
4595
|
-
*/
|
|
4596
|
-
this.s = 0;
|
|
4597
|
-
this.count = 0;
|
|
4598
|
-
this.diff = 0;
|
|
4599
|
-
}
|
|
4600
|
-
|
|
4601
|
-
/**
|
|
4602
|
-
* @param {number} v
|
|
4603
|
-
*/
|
|
4604
|
-
write (v) {
|
|
4605
|
-
if (this.diff === v - this.s) {
|
|
4606
|
-
this.s = v;
|
|
4607
|
-
this.count++;
|
|
4608
|
-
} else {
|
|
4609
|
-
flushIntDiffOptRleEncoder(this);
|
|
4610
|
-
this.count = 1;
|
|
4611
|
-
this.diff = v - this.s;
|
|
4612
|
-
this.s = v;
|
|
4613
|
-
}
|
|
4614
|
-
}
|
|
4615
|
-
|
|
4616
|
-
/**
|
|
4617
|
-
* Flush the encoded state and transform this to a Uint8Array.
|
|
4618
|
-
*
|
|
4619
|
-
* Note that this should only be called once.
|
|
4620
|
-
*/
|
|
4621
|
-
toUint8Array () {
|
|
4622
|
-
flushIntDiffOptRleEncoder(this);
|
|
4623
|
-
return toUint8Array(this.encoder)
|
|
4624
|
-
}
|
|
3844
|
+
}
|
|
3845
|
+
});
|
|
4625
3846
|
}
|
|
4626
3847
|
|
|
4627
|
-
|
|
4628
|
-
|
|
4629
|
-
|
|
4630
|
-
|
|
4631
|
-
|
|
4632
|
-
|
|
4633
|
-
|
|
4634
|
-
|
|
4635
|
-
|
|
4636
|
-
|
|
4637
|
-
|
|
4638
|
-
|
|
4639
|
-
|
|
4640
|
-
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
this.s = '';
|
|
4663
|
-
writeVarString(encoder, this.sarr.join(''));
|
|
4664
|
-
writeUint8Array(encoder, this.lensE.toUint8Array());
|
|
4665
|
-
return toUint8Array(encoder)
|
|
4666
|
-
}
|
|
3848
|
+
function modifyLocalObjectsWithNewUserId(syncifiedTables, currentUser, alreadySyncedRealms) {
|
|
3849
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
3850
|
+
const ignoredRealms = new Set(alreadySyncedRealms || []);
|
|
3851
|
+
for (const table of syncifiedTables) {
|
|
3852
|
+
if (table.name === "members") {
|
|
3853
|
+
// members
|
|
3854
|
+
yield table.toCollection().modify((member) => {
|
|
3855
|
+
if (!ignoredRealms.has(member.realmId) && (!member.userId || member.userId === UNAUTHORIZED_USER.userId)) {
|
|
3856
|
+
member.userId = currentUser.userId;
|
|
3857
|
+
}
|
|
3858
|
+
});
|
|
3859
|
+
}
|
|
3860
|
+
else if (table.name === "roles") ;
|
|
3861
|
+
else if (table.name === "realms") {
|
|
3862
|
+
// realms
|
|
3863
|
+
yield table.toCollection().modify((realm) => {
|
|
3864
|
+
if (!ignoredRealms.has(realm.realmId) && (realm.owner === undefined || realm.owner === UNAUTHORIZED_USER.userId)) {
|
|
3865
|
+
realm.owner = currentUser.userId;
|
|
3866
|
+
}
|
|
3867
|
+
});
|
|
3868
|
+
}
|
|
3869
|
+
else {
|
|
3870
|
+
// application entities
|
|
3871
|
+
yield table.toCollection().modify((obj) => {
|
|
3872
|
+
if (!obj.realmId || !ignoredRealms.has(obj.realmId)) {
|
|
3873
|
+
if (!obj.owner || obj.owner === UNAUTHORIZED_USER.userId)
|
|
3874
|
+
obj.owner = currentUser.userId;
|
|
3875
|
+
if (!obj.realmId || obj.realmId === UNAUTHORIZED_USER.userId) {
|
|
3876
|
+
obj.realmId = currentUser.userId;
|
|
3877
|
+
}
|
|
3878
|
+
}
|
|
3879
|
+
});
|
|
3880
|
+
}
|
|
3881
|
+
}
|
|
3882
|
+
});
|
|
4667
3883
|
}
|
|
4668
3884
|
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
*/
|
|
4674
|
-
|
|
4675
|
-
/**
|
|
4676
|
-
* @param {string} s
|
|
4677
|
-
* @return {Error}
|
|
4678
|
-
*/
|
|
4679
|
-
/* c8 ignore next */
|
|
4680
|
-
const create$3 = s => new Error(s);
|
|
4681
|
-
|
|
4682
|
-
/**
|
|
4683
|
-
* @throws {Error}
|
|
4684
|
-
* @return {never}
|
|
4685
|
-
*/
|
|
4686
|
-
/* c8 ignore next 3 */
|
|
4687
|
-
const methodUnimplemented = () => {
|
|
4688
|
-
throw create$3('Method unimplemented')
|
|
4689
|
-
};
|
|
3885
|
+
function throwIfCancelled(cancelToken) {
|
|
3886
|
+
if (cancelToken === null || cancelToken === void 0 ? void 0 : cancelToken.cancelled)
|
|
3887
|
+
throw new Dexie.AbortError(`Operation was cancelled`);
|
|
3888
|
+
}
|
|
4690
3889
|
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
3890
|
+
/* Need this because navigator.onLine seems to say "false" when it is actually online.
|
|
3891
|
+
This function relies initially on navigator.onLine but then uses online and offline events
|
|
3892
|
+
which seem to be more reliable.
|
|
3893
|
+
*/
|
|
3894
|
+
let isOnline = false;
|
|
3895
|
+
if (typeof self !== 'undefined' && typeof navigator !== 'undefined') {
|
|
3896
|
+
isOnline = navigator.onLine;
|
|
3897
|
+
self.addEventListener('online', () => isOnline = true);
|
|
3898
|
+
self.addEventListener('offline', () => isOnline = false);
|
|
3899
|
+
}
|
|
4699
3900
|
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
* ```js
|
|
4718
|
-
* // decoding step
|
|
4719
|
-
* const decoder = decoding.createDecoder(buf)
|
|
4720
|
-
* decoding.readVarUint(decoder) // => 256
|
|
4721
|
-
* decoding.readVarString(decoder) // => 'Hello world!'
|
|
4722
|
-
* decoding.hasContent(decoder) // => false - all data is read
|
|
4723
|
-
* ```
|
|
4724
|
-
*
|
|
4725
|
-
* @module decoding
|
|
4726
|
-
*/
|
|
3901
|
+
function updateBaseRevs(db, schema, latestRevisions, serverRev) {
|
|
3902
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
3903
|
+
yield db.$baseRevs.bulkPut(Object.keys(schema)
|
|
3904
|
+
.filter((table) => schema[table].markedForSync)
|
|
3905
|
+
.map((tableName) => {
|
|
3906
|
+
const lastClientRevOnPreviousServerRev = latestRevisions[tableName] || 0;
|
|
3907
|
+
return {
|
|
3908
|
+
tableName,
|
|
3909
|
+
clientRev: lastClientRevOnPreviousServerRev + 1,
|
|
3910
|
+
serverRev,
|
|
3911
|
+
};
|
|
3912
|
+
}));
|
|
3913
|
+
// Clean up baseRevs for tables that do not exist anymore or are no longer marked for sync
|
|
3914
|
+
// Resolve #2168 by also cleaning up baseRevs for tables that are not marked for sync
|
|
3915
|
+
yield db.$baseRevs.where('tableName').noneOf(Object.keys(schema).filter((table) => schema[table].markedForSync)).delete();
|
|
3916
|
+
});
|
|
3917
|
+
}
|
|
4727
3918
|
|
|
3919
|
+
function getLatestRevisionsPerTable(clientChangeSet, lastRevisions = {}) {
|
|
3920
|
+
for (const { table, muts } of clientChangeSet) {
|
|
3921
|
+
const lastRev = muts.length > 0 ? muts[muts.length - 1].rev : null;
|
|
3922
|
+
lastRevisions[table] = lastRev || lastRevisions[table] || 0;
|
|
3923
|
+
}
|
|
3924
|
+
return lastRevisions;
|
|
3925
|
+
}
|
|
4728
3926
|
|
|
4729
|
-
|
|
4730
|
-
|
|
3927
|
+
function bulkUpdate(table, keys, changeSpecs) {
|
|
3928
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
3929
|
+
const objs = yield table.bulkGet(keys);
|
|
3930
|
+
const resultKeys = [];
|
|
3931
|
+
const resultObjs = [];
|
|
3932
|
+
keys.forEach((key, idx) => {
|
|
3933
|
+
const obj = objs[idx];
|
|
3934
|
+
if (obj) {
|
|
3935
|
+
for (const [keyPath, value] of Object.entries(changeSpecs[idx])) {
|
|
3936
|
+
if (keyPath === table.schema.primKey.keyPath) {
|
|
3937
|
+
if (Dexie.cmp(value, key) !== 0) {
|
|
3938
|
+
throw new Error(`Cannot change primary key`);
|
|
3939
|
+
}
|
|
3940
|
+
}
|
|
3941
|
+
else {
|
|
3942
|
+
Dexie.setByKeyPath(obj, keyPath, value);
|
|
3943
|
+
}
|
|
3944
|
+
}
|
|
3945
|
+
resultKeys.push(key);
|
|
3946
|
+
resultObjs.push(obj);
|
|
3947
|
+
}
|
|
3948
|
+
});
|
|
3949
|
+
yield (table.schema.primKey.keyPath == null
|
|
3950
|
+
? table.bulkPut(resultObjs, resultKeys)
|
|
3951
|
+
: table.bulkPut(resultObjs));
|
|
3952
|
+
});
|
|
3953
|
+
}
|
|
4731
3954
|
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
|
|
4752
|
-
|
|
3955
|
+
function applyServerChanges(changes, db) {
|
|
3956
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
3957
|
+
console.debug('Applying server changes', changes, Dexie.currentTransaction);
|
|
3958
|
+
for (const { table: tableName, muts } of changes) {
|
|
3959
|
+
if (!db.dx._allTables[tableName]) {
|
|
3960
|
+
console.debug(`Server sent changes for table ${tableName} that we don't have. Ignoring.`);
|
|
3961
|
+
continue;
|
|
3962
|
+
}
|
|
3963
|
+
const table = db.table(tableName);
|
|
3964
|
+
const { primaryKey } = table.core.schema;
|
|
3965
|
+
const keyDecoder = (key) => {
|
|
3966
|
+
switch (key[0]) {
|
|
3967
|
+
case '[':
|
|
3968
|
+
// Decode JSON array
|
|
3969
|
+
if (key.endsWith(']'))
|
|
3970
|
+
try {
|
|
3971
|
+
// On server, array keys are transformed to JSON string representation
|
|
3972
|
+
return JSON.parse(key);
|
|
3973
|
+
}
|
|
3974
|
+
catch (_a) { }
|
|
3975
|
+
return key;
|
|
3976
|
+
case '#':
|
|
3977
|
+
// Decode private ID (do the opposite from what's done in encodeIdsForServer())
|
|
3978
|
+
if (key.endsWith(':' + db.cloud.currentUserId)) {
|
|
3979
|
+
return key.substr(0, key.length - db.cloud.currentUserId.length - 1);
|
|
3980
|
+
}
|
|
3981
|
+
return key;
|
|
3982
|
+
default:
|
|
3983
|
+
return key;
|
|
3984
|
+
}
|
|
3985
|
+
};
|
|
3986
|
+
for (const mut of muts) {
|
|
3987
|
+
const keys = mut.keys.map(keyDecoder);
|
|
3988
|
+
switch (mut.type) {
|
|
3989
|
+
case 'insert':
|
|
3990
|
+
if (primaryKey.outbound) {
|
|
3991
|
+
yield table.bulkAdd(mut.values, keys);
|
|
3992
|
+
}
|
|
3993
|
+
else {
|
|
3994
|
+
keys.forEach((key, i) => {
|
|
3995
|
+
// Make sure inbound keys are consistent
|
|
3996
|
+
Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath, key);
|
|
3997
|
+
});
|
|
3998
|
+
yield table.bulkAdd(mut.values);
|
|
3999
|
+
}
|
|
4000
|
+
break;
|
|
4001
|
+
case 'upsert':
|
|
4002
|
+
if (primaryKey.outbound) {
|
|
4003
|
+
yield table.bulkPut(mut.values, keys);
|
|
4004
|
+
}
|
|
4005
|
+
else {
|
|
4006
|
+
keys.forEach((key, i) => {
|
|
4007
|
+
// Make sure inbound keys are consistent
|
|
4008
|
+
Dexie.setByKeyPath(mut.values[i], primaryKey.keyPath, key);
|
|
4009
|
+
});
|
|
4010
|
+
yield table.bulkPut(mut.values);
|
|
4011
|
+
}
|
|
4012
|
+
break;
|
|
4013
|
+
case 'modify':
|
|
4014
|
+
if (keys.length === 1) {
|
|
4015
|
+
yield table.update(keys[0], mut.changeSpec);
|
|
4016
|
+
}
|
|
4017
|
+
else {
|
|
4018
|
+
yield table.where(':id').anyOf(keys).modify(mut.changeSpec);
|
|
4019
|
+
}
|
|
4020
|
+
break;
|
|
4021
|
+
case 'update':
|
|
4022
|
+
yield bulkUpdate(table, keys, mut.changeSpecs);
|
|
4023
|
+
break;
|
|
4024
|
+
case 'delete':
|
|
4025
|
+
yield table.bulkDelete(keys);
|
|
4026
|
+
break;
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
});
|
|
4753
4031
|
}
|
|
4754
4032
|
|
|
4755
|
-
|
|
4756
|
-
* @function
|
|
4757
|
-
* @param {Uint8Array} uint8Array
|
|
4758
|
-
* @return {Decoder}
|
|
4759
|
-
*/
|
|
4760
|
-
const createDecoder = uint8Array => new Decoder(uint8Array);
|
|
4033
|
+
const DEXIE_CLOUD_SYNCER_ID = 'dexie-cloud-syncer';
|
|
4761
4034
|
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4035
|
+
function listUpdatesSince(yTable, sinceIncluding) {
|
|
4036
|
+
return yTable
|
|
4037
|
+
.where('i')
|
|
4038
|
+
.between(sinceIncluding, Infinity, true)
|
|
4039
|
+
.toArray();
|
|
4040
|
+
}
|
|
4768
4041
|
|
|
4769
4042
|
/**
|
|
4770
|
-
*
|
|
4771
|
-
*
|
|
4772
|
-
* Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.
|
|
4773
|
-
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
4043
|
+
* Utility module to work with key-value stores.
|
|
4774
4044
|
*
|
|
4775
|
-
* @
|
|
4776
|
-
* @param {Decoder} decoder The decoder instance
|
|
4777
|
-
* @param {number} len The length of bytes to read
|
|
4778
|
-
* @return {Uint8Array}
|
|
4045
|
+
* @module map
|
|
4779
4046
|
*/
|
|
4780
|
-
const readUint8Array = (decoder, len) => {
|
|
4781
|
-
const view = new Uint8Array(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len);
|
|
4782
|
-
decoder.pos += len;
|
|
4783
|
-
return view
|
|
4784
|
-
};
|
|
4785
4047
|
|
|
4786
4048
|
/**
|
|
4787
|
-
*
|
|
4788
|
-
*
|
|
4789
|
-
* Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.
|
|
4790
|
-
* Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.
|
|
4049
|
+
* Creates a new Map instance.
|
|
4791
4050
|
*
|
|
4792
4051
|
* @function
|
|
4793
|
-
* @
|
|
4794
|
-
*
|
|
4795
|
-
*/
|
|
4796
|
-
const readVarUint8Array = decoder => readUint8Array(decoder, readVarUint(decoder));
|
|
4797
|
-
|
|
4798
|
-
/**
|
|
4799
|
-
* Read one byte as unsigned integer.
|
|
4052
|
+
* @return {Map<any, any>}
|
|
4053
|
+
*
|
|
4800
4054
|
* @function
|
|
4801
|
-
* @param {Decoder} decoder The decoder instance
|
|
4802
|
-
* @return {number} Unsigned 8-bit integer
|
|
4803
4055
|
*/
|
|
4804
|
-
const
|
|
4056
|
+
const create$3 = () => new Map();
|
|
4805
4057
|
|
|
4806
4058
|
/**
|
|
4807
|
-
*
|
|
4808
|
-
* 1/8th of the storage is used as encoding overhead.
|
|
4809
|
-
* * numbers < 2^7 is stored in one bytlength
|
|
4810
|
-
* * numbers < 2^14 is stored in two bylength
|
|
4059
|
+
* Copy a Map object into a fresh Map object.
|
|
4811
4060
|
*
|
|
4812
4061
|
* @function
|
|
4813
|
-
* @
|
|
4814
|
-
* @
|
|
4062
|
+
* @template K,V
|
|
4063
|
+
* @param {Map<K,V>} m
|
|
4064
|
+
* @return {Map<K,V>}
|
|
4815
4065
|
*/
|
|
4816
|
-
const
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
while (decoder.pos < len) {
|
|
4821
|
-
const r = decoder.arr[decoder.pos++];
|
|
4822
|
-
// num = num | ((r & binary.BITS7) << len)
|
|
4823
|
-
num = num + (r & BITS7) * mult; // shift $r << (7*#iterations) and add it to num
|
|
4824
|
-
mult *= 128; // next iteration, shift 7 "more" to the left
|
|
4825
|
-
if (r < BIT8) {
|
|
4826
|
-
return num
|
|
4827
|
-
}
|
|
4828
|
-
/* c8 ignore start */
|
|
4829
|
-
if (num > MAX_SAFE_INTEGER) {
|
|
4830
|
-
throw errorIntegerOutOfRange
|
|
4831
|
-
}
|
|
4832
|
-
/* c8 ignore stop */
|
|
4833
|
-
}
|
|
4834
|
-
throw errorUnexpectedEndOfArray
|
|
4066
|
+
const copy = m => {
|
|
4067
|
+
const r = create$3();
|
|
4068
|
+
m.forEach((v, k) => { r.set(k, v); });
|
|
4069
|
+
return r
|
|
4835
4070
|
};
|
|
4836
4071
|
|
|
4837
4072
|
/**
|
|
4838
|
-
*
|
|
4839
|
-
*
|
|
4840
|
-
*
|
|
4841
|
-
*
|
|
4842
|
-
*
|
|
4073
|
+
* Get map property. Create T if property is undefined and set T on map.
|
|
4074
|
+
*
|
|
4075
|
+
* ```js
|
|
4076
|
+
* const listeners = map.setIfUndefined(events, 'eventName', set.create)
|
|
4077
|
+
* listeners.add(listener)
|
|
4078
|
+
* ```
|
|
4843
4079
|
*
|
|
4844
4080
|
* @function
|
|
4845
|
-
* @
|
|
4846
|
-
* @
|
|
4081
|
+
* @template {Map<any, any>} MAP
|
|
4082
|
+
* @template {MAP extends Map<any,infer V> ? function():V : unknown} CF
|
|
4083
|
+
* @param {MAP} map
|
|
4084
|
+
* @param {MAP extends Map<infer K,any> ? K : unknown} key
|
|
4085
|
+
* @param {CF} createT
|
|
4086
|
+
* @return {ReturnType<CF>}
|
|
4847
4087
|
*/
|
|
4848
|
-
const
|
|
4849
|
-
let
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
const sign = (r & BIT7) > 0 ? -1 : 1;
|
|
4853
|
-
if ((r & BIT8) === 0) {
|
|
4854
|
-
// don't continue reading
|
|
4855
|
-
return sign * num
|
|
4856
|
-
}
|
|
4857
|
-
const len = decoder.arr.length;
|
|
4858
|
-
while (decoder.pos < len) {
|
|
4859
|
-
r = decoder.arr[decoder.pos++];
|
|
4860
|
-
// num = num | ((r & binary.BITS7) << len)
|
|
4861
|
-
num = num + (r & BITS7) * mult;
|
|
4862
|
-
mult *= 128;
|
|
4863
|
-
if (r < BIT8) {
|
|
4864
|
-
return sign * num
|
|
4865
|
-
}
|
|
4866
|
-
/* c8 ignore start */
|
|
4867
|
-
if (num > MAX_SAFE_INTEGER) {
|
|
4868
|
-
throw errorIntegerOutOfRange
|
|
4869
|
-
}
|
|
4870
|
-
/* c8 ignore stop */
|
|
4088
|
+
const setIfUndefined = (map, key, createT) => {
|
|
4089
|
+
let set = map.get(key);
|
|
4090
|
+
if (set === undefined) {
|
|
4091
|
+
map.set(key, set = createT());
|
|
4871
4092
|
}
|
|
4872
|
-
|
|
4093
|
+
return set
|
|
4873
4094
|
};
|
|
4874
4095
|
|
|
4875
4096
|
/**
|
|
4876
|
-
*
|
|
4877
|
-
* Better not modify this anymore..
|
|
4878
|
-
*
|
|
4879
|
-
* Transforming utf8 to a string is pretty expensive. The code performs 10x better
|
|
4880
|
-
* when String.fromCodePoint is fed with all characters as arguments.
|
|
4881
|
-
* But most environments have a maximum number of arguments per functions.
|
|
4882
|
-
* For effiency reasons we apply a maximum of 10000 characters at once.
|
|
4097
|
+
* Creates an Array and populates it with the content of all key-value pairs using the `f(value, key)` function.
|
|
4883
4098
|
*
|
|
4884
4099
|
* @function
|
|
4885
|
-
* @
|
|
4886
|
-
* @
|
|
4100
|
+
* @template K
|
|
4101
|
+
* @template V
|
|
4102
|
+
* @template R
|
|
4103
|
+
* @param {Map<K,V>} m
|
|
4104
|
+
* @param {function(V,K):R} f
|
|
4105
|
+
* @return {Array<R>}
|
|
4887
4106
|
*/
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
return ''
|
|
4893
|
-
} else {
|
|
4894
|
-
let encodedString = String.fromCodePoint(readUint8(decoder)); // remember to decrease remainingLen
|
|
4895
|
-
if (--remainingLen < 100) { // do not create a Uint8Array for small strings
|
|
4896
|
-
while (remainingLen--) {
|
|
4897
|
-
encodedString += String.fromCodePoint(readUint8(decoder));
|
|
4898
|
-
}
|
|
4899
|
-
} else {
|
|
4900
|
-
while (remainingLen > 0) {
|
|
4901
|
-
const nextLen = remainingLen < 10000 ? remainingLen : 10000;
|
|
4902
|
-
// this is dangerous, we create a fresh array view from the existing buffer
|
|
4903
|
-
const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen);
|
|
4904
|
-
decoder.pos += nextLen;
|
|
4905
|
-
// Starting with ES5.1 we can supply a generic array-like object as arguments
|
|
4906
|
-
encodedString += String.fromCodePoint.apply(null, /** @type {any} */ (bytes));
|
|
4907
|
-
remainingLen -= nextLen;
|
|
4908
|
-
}
|
|
4909
|
-
}
|
|
4910
|
-
return decodeURIComponent(escape(encodedString))
|
|
4107
|
+
const map = (m, f) => {
|
|
4108
|
+
const res = [];
|
|
4109
|
+
for (const [key, value] of m) {
|
|
4110
|
+
res.push(f(value, key));
|
|
4911
4111
|
}
|
|
4112
|
+
return res
|
|
4912
4113
|
};
|
|
4913
|
-
/* c8 ignore stop */
|
|
4914
|
-
|
|
4915
|
-
/**
|
|
4916
|
-
* @function
|
|
4917
|
-
* @param {Decoder} decoder
|
|
4918
|
-
* @return {String} The read String
|
|
4919
|
-
*/
|
|
4920
|
-
const _readVarStringNative = decoder =>
|
|
4921
|
-
/** @type any */ (utf8TextDecoder).decode(readVarUint8Array(decoder));
|
|
4922
4114
|
|
|
4923
4115
|
/**
|
|
4924
|
-
*
|
|
4925
|
-
* * varUint is used to store the length of the string
|
|
4116
|
+
* Tests whether any key-value pairs pass the test implemented by `f(value, key)`.
|
|
4926
4117
|
*
|
|
4927
|
-
* @
|
|
4928
|
-
* @param {Decoder} decoder
|
|
4929
|
-
* @return {String} The read String
|
|
4118
|
+
* @todo should rename to some - similarly to Array.some
|
|
4930
4119
|
*
|
|
4120
|
+
* @function
|
|
4121
|
+
* @template K
|
|
4122
|
+
* @template V
|
|
4123
|
+
* @param {Map<K,V>} m
|
|
4124
|
+
* @param {function(V,K):boolean} f
|
|
4125
|
+
* @return {boolean}
|
|
4931
4126
|
*/
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4937
|
-
|
|
4938
|
-
|
|
4939
|
-
|
|
4940
|
-
const readFromDataView = (decoder, len) => {
|
|
4941
|
-
const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len);
|
|
4942
|
-
decoder.pos += len;
|
|
4943
|
-
return dv
|
|
4944
|
-
};
|
|
4945
|
-
|
|
4946
|
-
/**
|
|
4947
|
-
* @param {Decoder} decoder
|
|
4948
|
-
*/
|
|
4949
|
-
const readFloat32 = decoder => readFromDataView(decoder, 4).getFloat32(0, false);
|
|
4127
|
+
const any = (m, f) => {
|
|
4128
|
+
for (const [key, value] of m) {
|
|
4129
|
+
if (f(value, key)) {
|
|
4130
|
+
return true
|
|
4131
|
+
}
|
|
4132
|
+
}
|
|
4133
|
+
return false
|
|
4134
|
+
};
|
|
4950
4135
|
|
|
4951
4136
|
/**
|
|
4952
|
-
*
|
|
4137
|
+
* Observable class prototype.
|
|
4138
|
+
*
|
|
4139
|
+
* @module observable
|
|
4953
4140
|
*/
|
|
4954
|
-
const readFloat64 = decoder => readFromDataView(decoder, 8).getFloat64(0, false);
|
|
4955
4141
|
|
|
4956
|
-
/**
|
|
4957
|
-
* @param {Decoder} decoder
|
|
4958
|
-
*/
|
|
4959
|
-
const readBigInt64 = decoder => /** @type {any} */ (readFromDataView(decoder, 8)).getBigInt64(0, false);
|
|
4960
4142
|
|
|
4961
4143
|
/**
|
|
4962
|
-
*
|
|
4144
|
+
* Handles named events.
|
|
4145
|
+
* @experimental
|
|
4146
|
+
*
|
|
4147
|
+
* This is basically a (better typed) duplicate of Observable, which will replace Observable in the
|
|
4148
|
+
* next release.
|
|
4149
|
+
*
|
|
4150
|
+
* @template {{[key in keyof EVENTS]: function(...any):void}} EVENTS
|
|
4963
4151
|
*/
|
|
4964
|
-
|
|
4965
|
-
|
|
4966
|
-
decoder => null, // CASE 126: null
|
|
4967
|
-
readVarInt, // CASE 125: integer
|
|
4968
|
-
readFloat32, // CASE 124: float32
|
|
4969
|
-
readFloat64, // CASE 123: float64
|
|
4970
|
-
readBigInt64, // CASE 122: bigint
|
|
4971
|
-
decoder => false, // CASE 121: boolean (false)
|
|
4972
|
-
decoder => true, // CASE 120: boolean (true)
|
|
4973
|
-
readVarString, // CASE 119: string
|
|
4974
|
-
decoder => { // CASE 118: object<string,any>
|
|
4975
|
-
const len = readVarUint(decoder);
|
|
4152
|
+
class ObservableV2 {
|
|
4153
|
+
constructor () {
|
|
4976
4154
|
/**
|
|
4977
|
-
*
|
|
4155
|
+
* Some desc.
|
|
4156
|
+
* @type {Map<string, Set<any>>}
|
|
4978
4157
|
*/
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
const key = readVarString(decoder);
|
|
4982
|
-
obj[key] = readAny(decoder);
|
|
4983
|
-
}
|
|
4984
|
-
return obj
|
|
4985
|
-
},
|
|
4986
|
-
decoder => { // CASE 117: array<any>
|
|
4987
|
-
const len = readVarUint(decoder);
|
|
4988
|
-
const arr = [];
|
|
4989
|
-
for (let i = 0; i < len; i++) {
|
|
4990
|
-
arr.push(readAny(decoder));
|
|
4991
|
-
}
|
|
4992
|
-
return arr
|
|
4993
|
-
},
|
|
4994
|
-
readVarUint8Array // CASE 116: Uint8Array
|
|
4995
|
-
];
|
|
4158
|
+
this._observers = create$3();
|
|
4159
|
+
}
|
|
4996
4160
|
|
|
4997
|
-
|
|
4998
|
-
|
|
4999
|
-
|
|
5000
|
-
|
|
4161
|
+
/**
|
|
4162
|
+
* @template {keyof EVENTS & string} NAME
|
|
4163
|
+
* @param {NAME} name
|
|
4164
|
+
* @param {EVENTS[NAME]} f
|
|
4165
|
+
*/
|
|
4166
|
+
on (name, f) {
|
|
4167
|
+
setIfUndefined(this._observers, /** @type {string} */ (name), create$5).add(f);
|
|
4168
|
+
return f
|
|
4169
|
+
}
|
|
5001
4170
|
|
|
5002
|
-
/**
|
|
5003
|
-
* T must not be null.
|
|
5004
|
-
*
|
|
5005
|
-
* @template T
|
|
5006
|
-
*/
|
|
5007
|
-
class RleDecoder extends Decoder {
|
|
5008
4171
|
/**
|
|
5009
|
-
* @
|
|
5010
|
-
* @param {
|
|
4172
|
+
* @template {keyof EVENTS & string} NAME
|
|
4173
|
+
* @param {NAME} name
|
|
4174
|
+
* @param {EVENTS[NAME]} f
|
|
5011
4175
|
*/
|
|
5012
|
-
|
|
5013
|
-
super(uint8Array);
|
|
5014
|
-
/**
|
|
5015
|
-
* The reader
|
|
5016
|
-
*/
|
|
5017
|
-
this.reader = reader;
|
|
4176
|
+
once (name, f) {
|
|
5018
4177
|
/**
|
|
5019
|
-
*
|
|
5020
|
-
* @type {T|null}
|
|
4178
|
+
* @param {...any} args
|
|
5021
4179
|
*/
|
|
5022
|
-
|
|
5023
|
-
|
|
4180
|
+
const _f = (...args) => {
|
|
4181
|
+
this.off(name, /** @type {any} */ (_f));
|
|
4182
|
+
f(...args);
|
|
4183
|
+
};
|
|
4184
|
+
this.on(name, /** @type {any} */ (_f));
|
|
5024
4185
|
}
|
|
5025
4186
|
|
|
5026
|
-
|
|
5027
|
-
|
|
5028
|
-
|
|
5029
|
-
|
|
5030
|
-
|
|
5031
|
-
|
|
5032
|
-
|
|
4187
|
+
/**
|
|
4188
|
+
* @template {keyof EVENTS & string} NAME
|
|
4189
|
+
* @param {NAME} name
|
|
4190
|
+
* @param {EVENTS[NAME]} f
|
|
4191
|
+
*/
|
|
4192
|
+
off (name, f) {
|
|
4193
|
+
const observers = this._observers.get(name);
|
|
4194
|
+
if (observers !== undefined) {
|
|
4195
|
+
observers.delete(f);
|
|
4196
|
+
if (observers.size === 0) {
|
|
4197
|
+
this._observers.delete(name);
|
|
5033
4198
|
}
|
|
5034
4199
|
}
|
|
5035
|
-
this.count--;
|
|
5036
|
-
return /** @type {T} */ (this.s)
|
|
5037
4200
|
}
|
|
5038
|
-
}
|
|
5039
4201
|
|
|
5040
|
-
class UintOptRleDecoder extends Decoder {
|
|
5041
4202
|
/**
|
|
5042
|
-
*
|
|
4203
|
+
* Emit a named event. All registered event listeners that listen to the
|
|
4204
|
+
* specified name will receive the event.
|
|
4205
|
+
*
|
|
4206
|
+
* @todo This should catch exceptions
|
|
4207
|
+
*
|
|
4208
|
+
* @template {keyof EVENTS & string} NAME
|
|
4209
|
+
* @param {NAME} name The event name.
|
|
4210
|
+
* @param {Parameters<EVENTS[NAME]>} args The arguments that are applied to the event listener.
|
|
5043
4211
|
*/
|
|
5044
|
-
|
|
5045
|
-
|
|
4212
|
+
emit (name, args) {
|
|
4213
|
+
// copy all listeners to an array first to make sure that no event is emitted to listeners that are subscribed while the event handler is called.
|
|
4214
|
+
return from((this._observers.get(name) || create$3()).values()).forEach(f => f(...args))
|
|
4215
|
+
}
|
|
4216
|
+
|
|
4217
|
+
destroy () {
|
|
4218
|
+
this._observers = create$3();
|
|
4219
|
+
}
|
|
4220
|
+
}
|
|
4221
|
+
|
|
4222
|
+
/* c8 ignore start */
|
|
4223
|
+
/**
|
|
4224
|
+
* Handles named events.
|
|
4225
|
+
*
|
|
4226
|
+
* @deprecated
|
|
4227
|
+
* @template N
|
|
4228
|
+
*/
|
|
4229
|
+
class Observable {
|
|
4230
|
+
constructor () {
|
|
5046
4231
|
/**
|
|
5047
|
-
*
|
|
4232
|
+
* Some desc.
|
|
4233
|
+
* @type {Map<N, any>}
|
|
5048
4234
|
*/
|
|
5049
|
-
this.
|
|
5050
|
-
this.count = 0;
|
|
4235
|
+
this._observers = create$3();
|
|
5051
4236
|
}
|
|
5052
4237
|
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
|
|
5057
|
-
|
|
5058
|
-
|
|
5059
|
-
if (isNegative) {
|
|
5060
|
-
this.s = -this.s;
|
|
5061
|
-
this.count = readVarUint(this) + 2;
|
|
5062
|
-
}
|
|
5063
|
-
}
|
|
5064
|
-
this.count--;
|
|
5065
|
-
return /** @type {number} */ (this.s)
|
|
4238
|
+
/**
|
|
4239
|
+
* @param {N} name
|
|
4240
|
+
* @param {function} f
|
|
4241
|
+
*/
|
|
4242
|
+
on (name, f) {
|
|
4243
|
+
setIfUndefined(this._observers, name, create$5).add(f);
|
|
5066
4244
|
}
|
|
5067
|
-
}
|
|
5068
4245
|
|
|
5069
|
-
class IntDiffOptRleDecoder extends Decoder {
|
|
5070
4246
|
/**
|
|
5071
|
-
* @param {
|
|
4247
|
+
* @param {N} name
|
|
4248
|
+
* @param {function} f
|
|
5072
4249
|
*/
|
|
5073
|
-
|
|
5074
|
-
super(uint8Array);
|
|
4250
|
+
once (name, f) {
|
|
5075
4251
|
/**
|
|
5076
|
-
* @
|
|
4252
|
+
* @param {...any} args
|
|
5077
4253
|
*/
|
|
5078
|
-
|
|
5079
|
-
|
|
5080
|
-
|
|
4254
|
+
const _f = (...args) => {
|
|
4255
|
+
this.off(name, _f);
|
|
4256
|
+
f(...args);
|
|
4257
|
+
};
|
|
4258
|
+
this.on(name, _f);
|
|
5081
4259
|
}
|
|
5082
4260
|
|
|
5083
4261
|
/**
|
|
5084
|
-
* @
|
|
4262
|
+
* @param {N} name
|
|
4263
|
+
* @param {function} f
|
|
5085
4264
|
*/
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
this.count = 1;
|
|
5093
|
-
if (hasCount) {
|
|
5094
|
-
this.count = readVarUint(this) + 2;
|
|
4265
|
+
off (name, f) {
|
|
4266
|
+
const observers = this._observers.get(name);
|
|
4267
|
+
if (observers !== undefined) {
|
|
4268
|
+
observers.delete(f);
|
|
4269
|
+
if (observers.size === 0) {
|
|
4270
|
+
this._observers.delete(name);
|
|
5095
4271
|
}
|
|
5096
4272
|
}
|
|
5097
|
-
this.s += this.diff;
|
|
5098
|
-
this.count--;
|
|
5099
|
-
return this.s
|
|
5100
4273
|
}
|
|
5101
|
-
}
|
|
5102
4274
|
|
|
5103
|
-
class StringDecoder {
|
|
5104
4275
|
/**
|
|
5105
|
-
*
|
|
4276
|
+
* Emit a named event. All registered event listeners that listen to the
|
|
4277
|
+
* specified name will receive the event.
|
|
4278
|
+
*
|
|
4279
|
+
* @todo This should catch exceptions
|
|
4280
|
+
*
|
|
4281
|
+
* @param {N} name The event name.
|
|
4282
|
+
* @param {Array<any>} args The arguments that are applied to the event listener.
|
|
5106
4283
|
*/
|
|
5107
|
-
|
|
5108
|
-
|
|
5109
|
-
this.
|
|
5110
|
-
/**
|
|
5111
|
-
* @type {number}
|
|
5112
|
-
*/
|
|
5113
|
-
this.spos = 0;
|
|
4284
|
+
emit (name, args) {
|
|
4285
|
+
// copy all listeners to an array first to make sure that no event is emitted to listeners that are subscribed while the event handler is called.
|
|
4286
|
+
return from((this._observers.get(name) || create$3()).values()).forEach(f => f(...args))
|
|
5114
4287
|
}
|
|
5115
4288
|
|
|
5116
|
-
|
|
5117
|
-
|
|
5118
|
-
*/
|
|
5119
|
-
read () {
|
|
5120
|
-
const end = this.spos + this.decoder.read();
|
|
5121
|
-
const res = this.str.slice(this.spos, end);
|
|
5122
|
-
this.spos = end;
|
|
5123
|
-
return res
|
|
4289
|
+
destroy () {
|
|
4290
|
+
this._observers = create$3();
|
|
5124
4291
|
}
|
|
5125
4292
|
}
|
|
4293
|
+
/* c8 ignore end */
|
|
5126
4294
|
|
|
5127
4295
|
/* eslint-env browser */
|
|
5128
4296
|
|
|
@@ -5303,10 +4471,10 @@
|
|
|
5303
4471
|
const size = obj => keys(obj).length;
|
|
5304
4472
|
|
|
5305
4473
|
/**
|
|
5306
|
-
* @param {Object|undefined} obj
|
|
4474
|
+
* @param {Object|null|undefined} obj
|
|
5307
4475
|
*/
|
|
5308
4476
|
const isEmpty = obj => {
|
|
5309
|
-
// eslint-disable-next-line
|
|
4477
|
+
// eslint-disable-next-line no-unreachable-loop
|
|
5310
4478
|
for (const _k in obj) {
|
|
5311
4479
|
return false
|
|
5312
4480
|
}
|
|
@@ -5314,8 +4482,9 @@
|
|
|
5314
4482
|
};
|
|
5315
4483
|
|
|
5316
4484
|
/**
|
|
5317
|
-
* @
|
|
5318
|
-
* @param {
|
|
4485
|
+
* @template {{ [key:string|number|symbol]: any }} T
|
|
4486
|
+
* @param {T} obj
|
|
4487
|
+
* @param {(v:T[keyof T],k:keyof T)=>boolean} f
|
|
5319
4488
|
* @return {boolean}
|
|
5320
4489
|
*/
|
|
5321
4490
|
const every = (obj, f) => {
|
|
@@ -5331,7 +4500,7 @@
|
|
|
5331
4500
|
* Calls `Object.prototype.hasOwnProperty`.
|
|
5332
4501
|
*
|
|
5333
4502
|
* @param {any} obj
|
|
5334
|
-
* @param {string|symbol} key
|
|
4503
|
+
* @param {string|number|symbol} key
|
|
5335
4504
|
* @return {boolean}
|
|
5336
4505
|
*/
|
|
5337
4506
|
const hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
|
|
@@ -5367,6 +4536,12 @@
|
|
|
5367
4536
|
return freeze(o)
|
|
5368
4537
|
};
|
|
5369
4538
|
|
|
4539
|
+
const EqualityTraitSymbol = Symbol('Equality');
|
|
4540
|
+
|
|
4541
|
+
/**
|
|
4542
|
+
* @typedef {{ [EqualityTraitSymbol]:(other:EqualityTrait)=>boolean }} EqualityTrait
|
|
4543
|
+
*/
|
|
4544
|
+
|
|
5370
4545
|
/**
|
|
5371
4546
|
* Common functions and function call helpers.
|
|
5372
4547
|
*
|
|
@@ -5392,15 +4567,6 @@
|
|
|
5392
4567
|
}
|
|
5393
4568
|
};
|
|
5394
4569
|
|
|
5395
|
-
/**
|
|
5396
|
-
* @template T
|
|
5397
|
-
*
|
|
5398
|
-
* @param {T} a
|
|
5399
|
-
* @param {T} b
|
|
5400
|
-
* @return {boolean}
|
|
5401
|
-
*/
|
|
5402
|
-
const equalityStrict = (a, b) => a === b;
|
|
5403
|
-
|
|
5404
4570
|
/* c8 ignore start */
|
|
5405
4571
|
|
|
5406
4572
|
/**
|
|
@@ -5409,14 +4575,14 @@
|
|
|
5409
4575
|
* @return {boolean}
|
|
5410
4576
|
*/
|
|
5411
4577
|
const equalityDeep = (a, b) => {
|
|
5412
|
-
if (a
|
|
5413
|
-
return
|
|
4578
|
+
if (a === b) {
|
|
4579
|
+
return true
|
|
5414
4580
|
}
|
|
5415
|
-
if (a.constructor !== b.constructor) {
|
|
4581
|
+
if (a == null || b == null || a.constructor !== b.constructor) {
|
|
5416
4582
|
return false
|
|
5417
4583
|
}
|
|
5418
|
-
if (a
|
|
5419
|
-
return
|
|
4584
|
+
if (a[EqualityTraitSymbol] != null) {
|
|
4585
|
+
return a[EqualityTraitSymbol](b)
|
|
5420
4586
|
}
|
|
5421
4587
|
switch (a.constructor) {
|
|
5422
4588
|
case ArrayBuffer:
|
|
@@ -5512,7 +4678,7 @@
|
|
|
5512
4678
|
const computeParams = () => {
|
|
5513
4679
|
if (params === undefined) {
|
|
5514
4680
|
if (isNode) {
|
|
5515
|
-
params = create$
|
|
4681
|
+
params = create$3();
|
|
5516
4682
|
const pargs = process.argv;
|
|
5517
4683
|
let currParamName = null;
|
|
5518
4684
|
for (let i = 0; i < pargs.length; i++) {
|
|
@@ -5534,7 +4700,7 @@
|
|
|
5534
4700
|
}
|
|
5535
4701
|
// in ReactNative for example this would not be true (unless connected to the Remote Debugger)
|
|
5536
4702
|
} else if (typeof location === 'object') {
|
|
5537
|
-
params = create$
|
|
4703
|
+
params = create$3(); // eslint-disable-next-line no-undef
|
|
5538
4704
|
(location.search || '?').slice(1).split('&').forEach((kv) => {
|
|
5539
4705
|
if (kv.length !== 0) {
|
|
5540
4706
|
const [key, value] = kv.split('=');
|
|
@@ -5543,7 +4709,7 @@
|
|
|
5543
4709
|
}
|
|
5544
4710
|
});
|
|
5545
4711
|
} else {
|
|
5546
|
-
params = create$
|
|
4712
|
+
params = create$3();
|
|
5547
4713
|
}
|
|
5548
4714
|
}
|
|
5549
4715
|
return params
|
|
@@ -5650,8 +4816,6 @@
|
|
|
5650
4816
|
|
|
5651
4817
|
/**
|
|
5652
4818
|
* Return fresh symbol.
|
|
5653
|
-
*
|
|
5654
|
-
* @return {Symbol}
|
|
5655
4819
|
*/
|
|
5656
4820
|
const create = Symbol;
|
|
5657
4821
|
|
|
@@ -5736,7 +4900,7 @@
|
|
|
5736
4900
|
}
|
|
5737
4901
|
const strBuilder = [];
|
|
5738
4902
|
const styles = [];
|
|
5739
|
-
const currentStyle = create$
|
|
4903
|
+
const currentStyle = create$3();
|
|
5740
4904
|
/**
|
|
5741
4905
|
* @type {Array<string|Object|number>}
|
|
5742
4906
|
*/
|
|
@@ -5807,7 +4971,7 @@
|
|
|
5807
4971
|
vconsoles.forEach((vc) => vc.print(args));
|
|
5808
4972
|
};
|
|
5809
4973
|
|
|
5810
|
-
const vconsoles = create$
|
|
4974
|
+
const vconsoles = create$5();
|
|
5811
4975
|
|
|
5812
4976
|
/**
|
|
5813
4977
|
* Utility module to create and manipulate Iterators.
|
|
@@ -7024,7 +6188,7 @@
|
|
|
7024
6188
|
/**
|
|
7025
6189
|
* @type {Map<number, { i: number, refs: Array<Item | GC> }>}
|
|
7026
6190
|
*/
|
|
7027
|
-
const clientRefs = create$
|
|
6191
|
+
const clientRefs = create$3();
|
|
7028
6192
|
const numOfStateUpdates = readVarUint(decoder.restDecoder);
|
|
7029
6193
|
for (let i = 0; i < numOfStateUpdates; i++) {
|
|
7030
6194
|
const numberOfStructs = readVarUint(decoder.restDecoder);
|
|
@@ -7524,7 +6688,7 @@
|
|
|
7524
6688
|
* @param {Snapshot} snapshot
|
|
7525
6689
|
*/
|
|
7526
6690
|
const splitSnapshotAffectedStructs = (transaction, snapshot) => {
|
|
7527
|
-
const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create$
|
|
6691
|
+
const meta = setIfUndefined(transaction.meta, splitSnapshotAffectedStructs, create$5);
|
|
7528
6692
|
const store = transaction.doc.store;
|
|
7529
6693
|
// check if we already split for this snapshot
|
|
7530
6694
|
if (!meta.has(snapshot)) {
|
|
@@ -7901,7 +7065,7 @@
|
|
|
7901
7065
|
const addChangedTypeToTransaction = (transaction, type, parentSub) => {
|
|
7902
7066
|
const item = type._item;
|
|
7903
7067
|
if (item === null || (item.id.clock < (transaction.beforeState.get(item.id.client) || 0) && !item.deleted)) {
|
|
7904
|
-
setIfUndefined(transaction.changed, type, create$
|
|
7068
|
+
setIfUndefined(transaction.changed, type, create$5).add(parentSub);
|
|
7905
7069
|
}
|
|
7906
7070
|
};
|
|
7907
7071
|
|
|
@@ -8636,7 +7800,7 @@
|
|
|
8636
7800
|
get keys () {
|
|
8637
7801
|
if (this._keys === null) {
|
|
8638
7802
|
if (this.transaction.doc._transactionCleanups.length === 0) {
|
|
8639
|
-
throw create$
|
|
7803
|
+
throw create$4(errorComputeChanges)
|
|
8640
7804
|
}
|
|
8641
7805
|
const keys = new Map();
|
|
8642
7806
|
const target = this.target;
|
|
@@ -8722,11 +7886,11 @@
|
|
|
8722
7886
|
let changes = this._changes;
|
|
8723
7887
|
if (changes === null) {
|
|
8724
7888
|
if (this.transaction.doc._transactionCleanups.length === 0) {
|
|
8725
|
-
throw create$
|
|
7889
|
+
throw create$4(errorComputeChanges)
|
|
8726
7890
|
}
|
|
8727
7891
|
const target = this.target;
|
|
8728
|
-
const added = create$
|
|
8729
|
-
const deleted = create$
|
|
7892
|
+
const added = create$5();
|
|
7893
|
+
const deleted = create$5();
|
|
8730
7894
|
/**
|
|
8731
7895
|
* @type {Array<{insert:Array<any>}|{delete:number}|{retain:number}>}
|
|
8732
7896
|
*/
|
|
@@ -9438,7 +8602,7 @@
|
|
|
9438
8602
|
packJsonContent();
|
|
9439
8603
|
};
|
|
9440
8604
|
|
|
9441
|
-
const lengthExceeded = () => create$
|
|
8605
|
+
const lengthExceeded = () => create$4('Length exceeded!');
|
|
9442
8606
|
|
|
9443
8607
|
/**
|
|
9444
8608
|
* @param {Transaction} transaction
|
|
@@ -10571,7 +9735,7 @@
|
|
|
10571
9735
|
/**
|
|
10572
9736
|
* @type {Map<string,ContentFormat>}
|
|
10573
9737
|
*/
|
|
10574
|
-
const endFormats = create$
|
|
9738
|
+
const endFormats = create$3();
|
|
10575
9739
|
while (end && (!end.countable || end.deleted)) {
|
|
10576
9740
|
if (!end.deleted && end.content.constructor === ContentFormat) {
|
|
10577
9741
|
const cf = /** @type {ContentFormat} */ (end.content);
|
|
@@ -10656,7 +9820,7 @@
|
|
|
10656
9820
|
transact(/** @type {Doc} */ (type.doc), transaction => {
|
|
10657
9821
|
let start = /** @type {Item} */ (type._start);
|
|
10658
9822
|
let end = type._start;
|
|
10659
|
-
let startAttributes = create$
|
|
9823
|
+
let startAttributes = create$3();
|
|
10660
9824
|
const currentAttributes = copy(startAttributes);
|
|
10661
9825
|
while (end) {
|
|
10662
9826
|
if (end.deleted === false) {
|
|
@@ -11823,7 +10987,7 @@
|
|
|
11823
10987
|
const pc = /** @type {Array<any>} */ (this._prelimContent);
|
|
11824
10988
|
const index = ref === null ? 0 : pc.findIndex(el => el === ref) + 1;
|
|
11825
10989
|
if (index === 0 && ref !== null) {
|
|
11826
|
-
throw create$
|
|
10990
|
+
throw create$4('Reference item not found')
|
|
11827
10991
|
}
|
|
11828
10992
|
pc.splice(index, 0, ...content);
|
|
11829
10993
|
}
|
|
@@ -14253,7 +13417,7 @@
|
|
|
14253
13417
|
*
|
|
14254
13418
|
* ==========================================================================
|
|
14255
13419
|
*
|
|
14256
|
-
* Version 4.2.
|
|
13420
|
+
* Version 4.2.2, Sat Dec 20 2025
|
|
14257
13421
|
*
|
|
14258
13422
|
* https://dexie.org
|
|
14259
13423
|
*
|
|
@@ -14335,6 +13499,8 @@
|
|
|
14335
13499
|
return doc;
|
|
14336
13500
|
}
|
|
14337
13501
|
|
|
13502
|
+
const { getByKeyPath } = Dexie.Dexie;
|
|
13503
|
+
|
|
14338
13504
|
let currentUpdateRow = null;
|
|
14339
13505
|
function setCurrentUpdateRow(row) {
|
|
14340
13506
|
currentUpdateRow = row;
|
|
@@ -14881,21 +14047,21 @@
|
|
|
14881
14047
|
_c = chunks_1_1.value;
|
|
14882
14048
|
_d = false;
|
|
14883
14049
|
const chunk = _c;
|
|
14884
|
-
const decoder = new Decoder
|
|
14885
|
-
while (hasContent
|
|
14886
|
-
switch (readUint8
|
|
14050
|
+
const decoder = new Decoder(chunk);
|
|
14051
|
+
while (hasContent(decoder)) {
|
|
14052
|
+
switch (readUint8(decoder)) {
|
|
14887
14053
|
case BINSTREAM_TYPE_REALMID:
|
|
14888
14054
|
yield __await(storeCollectedDocs(true));
|
|
14889
|
-
currentRealmId = readVarString
|
|
14055
|
+
currentRealmId = readVarString(decoder);
|
|
14890
14056
|
break;
|
|
14891
14057
|
case BINSTREAM_TYPE_TABLE_AND_PROP:
|
|
14892
14058
|
yield __await(storeCollectedDocs(false)); // still on same realm
|
|
14893
|
-
currentTable = readVarString
|
|
14894
|
-
currentProp = readVarString
|
|
14059
|
+
currentTable = readVarString(decoder);
|
|
14060
|
+
currentProp = readVarString(decoder);
|
|
14895
14061
|
break;
|
|
14896
14062
|
case BINSTREAM_TYPE_DOCUMENT: {
|
|
14897
|
-
const k = readAny
|
|
14898
|
-
const u = readVarUint8Array
|
|
14063
|
+
const k = readAny(decoder);
|
|
14064
|
+
const u = readVarUint8Array(decoder);
|
|
14899
14065
|
docsToInsert.push({
|
|
14900
14066
|
k,
|
|
14901
14067
|
u,
|
|
@@ -16275,7 +15441,8 @@
|
|
|
16275
15441
|
const cloudSchema = dexie.cloud.schema || (dexie.cloud.schema = {});
|
|
16276
15442
|
const allPrefixes = new Set();
|
|
16277
15443
|
Object.keys(storesClone).forEach(tableName => {
|
|
16278
|
-
|
|
15444
|
+
var _a;
|
|
15445
|
+
const schemaSrc = (_a = storesClone[tableName]) === null || _a === void 0 ? void 0 : _a.trim();
|
|
16279
15446
|
const cloudTableSchema = cloudSchema[tableName] || (cloudSchema[tableName] = {});
|
|
16280
15447
|
if (schemaSrc != null) {
|
|
16281
15448
|
if (/^\@/.test(schemaSrc)) {
|
|
@@ -16316,7 +15483,8 @@
|
|
|
16316
15483
|
// No support for guarding jobs. IE11, node.js, etc.
|
|
16317
15484
|
return job();
|
|
16318
15485
|
}
|
|
16319
|
-
|
|
15486
|
+
// @ts-expect-error - LockManager callback type inference issue with generics
|
|
15487
|
+
return navigator.locks.request(db.name + '|' + jobName, job);
|
|
16320
15488
|
}
|
|
16321
15489
|
|
|
16322
15490
|
function performInitialSync(db, cloudOptions, cloudSchema) {
|
|
@@ -17333,12 +16501,9 @@
|
|
|
17333
16501
|
}
|
|
17334
16502
|
}
|
|
17335
16503
|
|
|
17336
|
-
var n,l$1,u$1,t$1,o$1,f$1={},e$1=[],c$1=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function s$1(n,l){for(var u in l)n[u]=l[u];return n}function a$1(n){var l=n.parentNode;l&&l.removeChild(n);}function h(l,u,i){var t,o,r,f={};for(r in u)"key"==r?t=u[r]:"ref"==r?o=u[r]:f[r]=u[r];if(arguments.length>2&&(f.children=arguments.length>3?n.call(arguments,2):i),"function"==typeof l&&null!=l.defaultProps)for(r in l.defaultProps)void 0===f[r]&&(f[r]=l.defaultProps[r]);return v$1(l,f,t,o,null)}function v$1(n,i,t,o,r){var f={type:n,props:i,key:t,ref:o,__k:null,__:null,__b:0,__e:null,__d:void 0,__c:null,__h:null,constructor:void 0,__v:null==r?++u$1:r};return null==r&&null!=l$1.vnode&&l$1.vnode(f),f}function p$1(n){return n.children}function d$1(n,l){this.props=n,this.context=l;}function _$1(n,l){if(null==l)return n.__?_$1(n.__,n.__.__k.indexOf(n)+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?_$1(n):null}function k$1(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return k$1(n)}}function b$1(n){(!n.__d&&(n.__d=!0)&&t$1.push(n)&&!g$1.__r++||o$1!==l$1.debounceRendering)&&((o$1=l$1.debounceRendering)||setTimeout)(g$1);}function g$1(){for(var n;g$1.__r=t$1.length;)n=t$1.sort(function(n,l){return n.__v.__b-l.__v.__b}),t$1=[],n.some(function(n){var l,u,i,t,o,r;n.__d&&(o=(t=(l=n).__v).__e,(r=l.__P)&&(u=[],(i=s$1({},t)).__v=t.__v+1,j$1(r,t,i,l.__n,void 0!==r.ownerSVGElement,null!=t.__h?[o]:null,u,null==o?_$1(t):o,t.__h),z$1(u,t),t.__e!=o&&k$1(t)));});}function w$1(n,l,u,i,t,o,r,c,s,a){var h,y,d,k,b,g,w,x=i&&i.__k||e$1,C=x.length;for(u.__k=[],h=0;h<l.length;h++)if(null!=(k=u.__k[h]=null==(k=l[h])||"boolean"==typeof k?null:"string"==typeof k||"number"==typeof k||"bigint"==typeof k?v$1(null,k,null,null,k):Array.isArray(k)?v$1(p$1,{children:k},null,null,null):k.__b>0?v$1(k.type,k.props,k.key,null,k.__v):k)){if(k.__=u,k.__b=u.__b+1,null===(d=x[h])||d&&k.key==d.key&&k.type===d.type)x[h]=void 0;else for(y=0;y<C;y++){if((d=x[y])&&k.key==d.key&&k.type===d.type){x[y]=void 0;break}d=null;}j$1(n,k,d=d||f$1,t,o,r,c,s,a),b=k.__e,(y=k.ref)&&d.ref!=y&&(w||(w=[]),d.ref&&w.push(d.ref,null,k),w.push(y,k.__c||b,k)),null!=b?(null==g&&(g=b),"function"==typeof k.type&&k.__k===d.__k?k.__d=s=m$1(k,s,n):s=A(n,k,d,x,b,s),"function"==typeof u.type&&(u.__d=s)):s&&d.__e==s&&s.parentNode!=n&&(s=_$1(d));}for(u.__e=g,h=C;h--;)null!=x[h]&&("function"==typeof u.type&&null!=x[h].__e&&x[h].__e==u.__d&&(u.__d=_$1(i,h+1)),N(x[h],x[h]));if(w)for(h=0;h<w.length;h++)M(w[h],w[++h],w[++h]);}function m$1(n,l,u){for(var i,t=n.__k,o=0;t&&o<t.length;o++)(i=t[o])&&(i.__=n,l="function"==typeof i.type?m$1(i,l,u):A(u,i,i,t,i.__e,l));return l}function A(n,l,u,i,t,o){var r,f,e;if(void 0!==l.__d)r=l.__d,l.__d=void 0;else if(null==u||t!=o||null==t.parentNode)n:if(null==o||o.parentNode!==n)n.appendChild(t),r=null;else {for(f=o,e=0;(f=f.nextSibling)&&e<i.length;e+=2)if(f==t)break n;n.insertBefore(t,o),r=o;}return void 0!==r?r:t.nextSibling}function C(n,l,u,i,t){var o;for(o in u)"children"===o||"key"===o||o in l||H(n,o,null,u[o],i);for(o in l)t&&"function"!=typeof l[o]||"children"===o||"key"===o||"value"===o||"checked"===o||u[o]===l[o]||H(n,o,l[o],u[o],i);}function $(n,l,u){"-"===l[0]?n.setProperty(l,u):n[l]=null==u?"":"number"!=typeof u||c$1.test(l)?u:u+"px";}function H(n,l,u,i,t){var o;n:if("style"===l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof i&&(n.style.cssText=i=""),i)for(l in i)u&&l in u||$(n.style,l,"");if(u)for(l in u)i&&u[l]===i[l]||$(n.style,l,u[l]);}else if("o"===l[0]&&"n"===l[1])o=l!==(l=l.replace(/Capture$/,"")),l=l.toLowerCase()in n?l.toLowerCase().slice(2):l.slice(2),n.l||(n.l={}),n.l[l+o]=u,u?i||n.addEventListener(l,o?T:I,o):n.removeEventListener(l,o?T:I,o);else if("dangerouslySetInnerHTML"!==l){if(t)l=l.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("href"!==l&&"list"!==l&&"form"!==l&&"tabIndex"!==l&&"download"!==l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null!=u&&(!1!==u||"a"===l[0]&&"r"===l[1])?n.setAttribute(l,u):n.removeAttribute(l));}}function I(n){this.l[n.type+!1](l$1.event?l$1.event(n):n);}function T(n){this.l[n.type+!0](l$1.event?l$1.event(n):n);}function j$1(n,u,i,t,o,r,f,e,c){var a,h,v,y,_,k,b,g,m,x,A,C,$,H=u.type;if(void 0!==u.constructor)return null;null!=i.__h&&(c=i.__h,e=u.__e=i.__e,u.__h=null,r=[e]),(a=l$1.__b)&&a(u);try{n:if("function"==typeof H){if(g=u.props,m=(a=H.contextType)&&t[a.__c],x=a?m?m.props.value:a.__:t,i.__c?b=(h=u.__c=i.__c).__=h.__E:("prototype"in H&&H.prototype.render?u.__c=h=new H(g,x):(u.__c=h=new d$1(g,x),h.constructor=H,h.render=O),m&&m.sub(h),h.props=g,h.state||(h.state={}),h.context=x,h.__n=t,v=h.__d=!0,h.__h=[]),null==h.__s&&(h.__s=h.state),null!=H.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=s$1({},h.__s)),s$1(h.__s,H.getDerivedStateFromProps(g,h.__s))),y=h.props,_=h.state,v)null==H.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else {if(null==H.getDerivedStateFromProps&&g!==y&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(g,x),!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(g,h.__s,x)||u.__v===i.__v){h.props=g,h.state=h.__s,u.__v!==i.__v&&(h.__d=!1),h.__v=u,u.__e=i.__e,u.__k=i.__k,u.__k.forEach(function(n){n&&(n.__=u);}),h.__h.length&&f.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(g,h.__s,x),null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(y,_,k);});}if(h.context=x,h.props=g,h.__v=u,h.__P=n,A=l$1.__r,C=0,"prototype"in H&&H.prototype.render)h.state=h.__s,h.__d=!1,A&&A(u),a=h.render(h.props,h.state,h.context);else do{h.__d=!1,A&&A(u),a=h.render(h.props,h.state,h.context),h.state=h.__s;}while(h.__d&&++C<25);h.state=h.__s,null!=h.getChildContext&&(t=s$1(s$1({},t),h.getChildContext())),v||null==h.getSnapshotBeforeUpdate||(k=h.getSnapshotBeforeUpdate(y,_)),$=null!=a&&a.type===p$1&&null==a.key?a.props.children:a,w$1(n,Array.isArray($)?$:[$],u,i,t,o,r,f,e,c),h.base=u.__e,u.__h=null,h.__h.length&&f.push(h),b&&(h.__E=h.__=null),h.__e=!1;}else null==r&&u.__v===i.__v?(u.__k=i.__k,u.__e=i.__e):u.__e=L(i.__e,u,i,t,o,r,f,c);(a=l$1.diffed)&&a(u);}catch(n){u.__v=null,(c||null!=r)&&(u.__e=e,u.__h=!!c,r[r.indexOf(e)]=null),l$1.__e(n,u,i);}}function z$1(n,u){l$1.__c&&l$1.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u);});}catch(n){l$1.__e(n,u.__v);}});}function L(l,u,i,t,o,r,e,c){var s,h,v,y=i.props,p=u.props,d=u.type,k=0;if("svg"===d&&(o=!0),null!=r)for(;k<r.length;k++)if((s=r[k])&&"setAttribute"in s==!!d&&(d?s.localName===d:3===s.nodeType)){l=s,r[k]=null;break}if(null==l){if(null===d)return document.createTextNode(p);l=o?document.createElementNS("http://www.w3.org/2000/svg",d):document.createElement(d,p.is&&p),r=null,c=!1;}if(null===d)y===p||c&&l.data===p||(l.data=p);else {if(r=r&&n.call(l.childNodes),h=(y=i.props||f$1).dangerouslySetInnerHTML,v=p.dangerouslySetInnerHTML,!c){if(null!=r)for(y={},k=0;k<l.attributes.length;k++)y[l.attributes[k].name]=l.attributes[k].value;(v||h)&&(v&&(h&&v.__html==h.__html||v.__html===l.innerHTML)||(l.innerHTML=v&&v.__html||""));}if(C(l,p,y,o,c),v)u.__k=[];else if(k=u.props.children,w$1(l,Array.isArray(k)?k:[k],u,i,t,o&&"foreignObject"!==d,r,e,r?r[0]:i.__k&&_$1(i,0),c),null!=r)for(k=r.length;k--;)null!=r[k]&&a$1(r[k]);c||("value"in p&&void 0!==(k=p.value)&&(k!==l.value||"progress"===d&&!k||"option"===d&&k!==y.value)&&H(l,"value",k,y.value,!1),"checked"in p&&void 0!==(k=p.checked)&&k!==l.checked&&H(l,"checked",k,y.checked,!1));}return l}function M(n,u,i){try{"function"==typeof n?n(u):n.current=u;}catch(n){l$1.__e(n,i);}}function N(n,u,i){var t,o;if(l$1.unmount&&l$1.unmount(n),(t=n.ref)&&(t.current&&t.current!==n.__e||M(t,null,u)),null!=(t=n.__c)){if(t.componentWillUnmount)try{t.componentWillUnmount();}catch(n){l$1.__e(n,u);}t.base=t.__P=null;}if(t=n.__k)for(o=0;o<t.length;o++)t[o]&&N(t[o],u,"function"!=typeof n.type);i||null==n.__e||a$1(n.__e),n.__e=n.__d=void 0;}function O(n,l,u){return this.constructor(n,u)}function P(u,i,t){var o,r,e;l$1.__&&l$1.__(u,i),r=(o="function"==typeof t)?null:t&&t.__k||i.__k,e=[],j$1(i,u=(!o&&t||i).__k=h(p$1,null,[u]),r||f$1,f$1,void 0!==i.ownerSVGElement,!o&&t?[t]:r?null:i.firstChild?n.call(i.childNodes):null,e,!o&&t?t:r?r.__e:i.firstChild,o),z$1(e,u);}n=e$1.slice,l$1={__e:function(n,l,u,i){for(var t,o,r;l=l.__;)if((t=l.__c)&&!t.__)try{if((o=t.constructor)&&null!=o.getDerivedStateFromError&&(t.setState(o.getDerivedStateFromError(n)),r=t.__d),null!=t.componentDidCatch&&(t.componentDidCatch(n,i||{}),r=t.__d),r)return t.__E=t}catch(l){n=l;}throw n}},u$1=0,d$1.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!==this.state?this.__s:this.__s=s$1({},this.state),"function"==typeof n&&(n=n(s$1({},u),this.props)),n&&s$1(u,n),null!=n&&this.__v&&(l&&this.__h.push(l),b$1(this));},d$1.prototype.forceUpdate=function(n){this.__v&&(this.__e=!0,n&&this.__h.push(n),b$1(this));},d$1.prototype.render=p$1,t$1=[],g$1.__r=0;
|
|
16504
|
+
var n,l$1,u$1,i$1,r$1,o$1,e$1,f$1,c$1,s$1,a$1,p$1={},v$1=[],y=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,w$1=Array.isArray;function d$1(n,l){for(var u in l)n[u]=l[u];return n}function g(n){n&&n.parentNode&&n.parentNode.removeChild(n);}function _$1(l,u,t){var i,r,o,e={};for(o in u)"key"==o?i=u[o]:"ref"==o?r=u[o]:e[o]=u[o];if(arguments.length>2&&(e.children=arguments.length>3?n.call(arguments,2):t),"function"==typeof l&&null!=l.defaultProps)for(o in l.defaultProps) void 0===e[o]&&(e[o]=l.defaultProps[o]);return m$1(l,e,i,r,null)}function m$1(n,t,i,r,o){var e={type:n,props:t,key:i,ref:r,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:null==o?++u$1:o,__i:-1,__u:0};return null==o&&null!=l$1.vnode&&l$1.vnode(e),e}function k$1(n){return n.children}function x(n,l){this.props=n,this.context=l;}function S(n,l){if(null==l)return n.__?S(n.__,n.__i+1):null;for(var u;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e)return u.__e;return "function"==typeof n.type?S(n):null}function C$1(n){var l,u;if(null!=(n=n.__)&&null!=n.__c){for(n.__e=n.__c.base=null,l=0;l<n.__k.length;l++)if(null!=(u=n.__k[l])&&null!=u.__e){n.__e=n.__c.base=u.__e;break}return C$1(n)}}function M(n){(!n.__d&&(n.__d=true)&&i$1.push(n)&&!$.__r++||r$1!=l$1.debounceRendering)&&((r$1=l$1.debounceRendering)||o$1)($);}function $(){for(var n,u,t,r,o,f,c,s=1;i$1.length;)i$1.length>s&&i$1.sort(e$1),n=i$1.shift(),s=i$1.length,n.__d&&(t=void 0,r=void 0,o=(r=(u=n).__v).__e,f=[],c=[],u.__P&&((t=d$1({},r)).__v=r.__v+1,l$1.vnode&&l$1.vnode(t),O(u.__P,t,r,u.__n,u.__P.namespaceURI,32&r.__u?[o]:null,f,null==o?S(r):o,!!(32&r.__u),c),t.__v=r.__v,t.__.__k[t.__i]=t,N(f,t,c),r.__e=r.__=null,t.__e!=o&&C$1(t)));$.__r=0;}function I(n,l,u,t,i,r,o,e,f,c,s){var a,h,y,w,d,g,_,m=t&&t.__k||v$1,b=l.length;for(f=P(u,l,m,f,b),a=0;a<b;a++)null!=(y=u.__k[a])&&(h=-1==y.__i?p$1:m[y.__i]||p$1,y.__i=a,g=O(n,y,h,i,r,o,e,f,c,s),w=y.__e,y.ref&&h.ref!=y.ref&&(h.ref&&B$1(h.ref,null,y),s.push(y.ref,y.__c||w,y)),null==d&&null!=w&&(d=w),(_=!!(4&y.__u))||h.__k===y.__k?f=A$1(y,f,n,_):"function"==typeof y.type&&void 0!==g?f=g:w&&(f=w.nextSibling),y.__u&=-7);return u.__e=d,f}function P(n,l,u,t,i){var r,o,e,f,c,s=u.length,a=s,h=0;for(n.__k=new Array(i),r=0;r<i;r++)null!=(o=l[r])&&"boolean"!=typeof o&&"function"!=typeof o?("string"==typeof o||"number"==typeof o||"bigint"==typeof o||o.constructor==String?o=n.__k[r]=m$1(null,o,null,null,null):w$1(o)?o=n.__k[r]=m$1(k$1,{children:o},null,null,null):null==o.constructor&&o.__b>0?o=n.__k[r]=m$1(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):n.__k[r]=o,f=r+h,o.__=n,o.__b=n.__b+1,-1!=(c=o.__i=L(o,u,f,a))&&(a--,(e=u[c])&&(e.__u|=2)),null==e||null==e.__v?(-1==c&&(i>s?h--:i<s&&h++),"function"!=typeof o.type&&(o.__u|=4)):c!=f&&(c==f-1?h--:c==f+1?h++:(c>f?h--:h++,o.__u|=4))):n.__k[r]=null;if(a)for(r=0;r<s;r++)null!=(e=u[r])&&0==(2&e.__u)&&(e.__e==t&&(t=S(e)),D$1(e,e));return t}function A$1(n,l,u,t){var i,r;if("function"==typeof n.type){for(i=n.__k,r=0;i&&r<i.length;r++)i[r]&&(i[r].__=n,l=A$1(i[r],l,u,t));return l}n.__e!=l&&(t&&(l&&n.type&&!l.parentNode&&(l=S(n)),u.insertBefore(n.__e,l||null)),l=n.__e);do{l=l&&l.nextSibling;}while(null!=l&&8==l.nodeType);return l}function L(n,l,u,t){var i,r,o,e=n.key,f=n.type,c=l[u],s=null!=c&&0==(2&c.__u);if(null===c&&null==e||s&&e==c.key&&f==c.type)return u;if(t>(s?1:0))for(i=u-1,r=u+1;i>=0||r<l.length;)if(null!=(c=l[o=i>=0?i--:r++])&&0==(2&c.__u)&&e==c.key&&f==c.type)return o;return -1}function T$1(n,l,u){"-"==l[0]?n.setProperty(l,null==u?"":u):n[l]=null==u?"":"number"!=typeof u||y.test(l)?u:u+"px";}function j$1(n,l,u,t,i){var r,o;n:if("style"==l)if("string"==typeof u)n.style.cssText=u;else {if("string"==typeof t&&(n.style.cssText=t=""),t)for(l in t)u&&l in u||T$1(n.style,l,"");if(u)for(l in u)t&&u[l]==t[l]||T$1(n.style,l,u[l]);}else if("o"==l[0]&&"n"==l[1])r=l!=(l=l.replace(f$1,"$1")),o=l.toLowerCase(),l=o in n||"onFocusOut"==l||"onFocusIn"==l?o.slice(2):l.slice(2),n.l||(n.l={}),n.l[l+r]=u,u?t?u.u=t.u:(u.u=c$1,n.addEventListener(l,r?a$1:s$1,r)):n.removeEventListener(l,r?a$1:s$1,r);else {if("http://www.w3.org/2000/svg"==i)l=l.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if("width"!=l&&"height"!=l&&"href"!=l&&"list"!=l&&"form"!=l&&"tabIndex"!=l&&"download"!=l&&"rowSpan"!=l&&"colSpan"!=l&&"role"!=l&&"popover"!=l&&l in n)try{n[l]=null==u?"":u;break n}catch(n){}"function"==typeof u||(null==u||false===u&&"-"!=l[4]?n.removeAttribute(l):n.setAttribute(l,"popover"==l&&1==u?"":u));}}function F(n){return function(u){if(this.l){var t=this.l[u.type+n];if(null==u.t)u.t=c$1++;else if(u.t<t.u)return;return t(l$1.event?l$1.event(u):u)}}}function O(n,u,t,i,r,o,e,f,c,s){var a,h,p,v,y,_,m,b,S,C,M,$,P,A,H,L,T,j=u.type;if(null!=u.constructor)return null;128&t.__u&&(c=!!(32&t.__u),o=[f=u.__e=t.__e]),(a=l$1.__b)&&a(u);n:if("function"==typeof j)try{if(b=u.props,S="prototype"in j&&j.prototype.render,C=(a=j.contextType)&&i[a.__c],M=a?C?C.props.value:a.__:i,t.__c?m=(h=u.__c=t.__c).__=h.__E:(S?u.__c=h=new j(b,M):(u.__c=h=new x(b,M),h.constructor=j,h.render=E),C&&C.sub(h),h.state||(h.state={}),h.__n=i,p=h.__d=!0,h.__h=[],h._sb=[]),S&&null==h.__s&&(h.__s=h.state),S&&null!=j.getDerivedStateFromProps&&(h.__s==h.state&&(h.__s=d$1({},h.__s)),d$1(h.__s,j.getDerivedStateFromProps(b,h.__s))),v=h.props,y=h.state,h.__v=u,p)S&&null==j.getDerivedStateFromProps&&null!=h.componentWillMount&&h.componentWillMount(),S&&null!=h.componentDidMount&&h.__h.push(h.componentDidMount);else {if(S&&null==j.getDerivedStateFromProps&&b!==v&&null!=h.componentWillReceiveProps&&h.componentWillReceiveProps(b,M),u.__v==t.__v||!h.__e&&null!=h.shouldComponentUpdate&&!1===h.shouldComponentUpdate(b,h.__s,M)){for(u.__v!=t.__v&&(h.props=b,h.state=h.__s,h.__d=!1),u.__e=t.__e,u.__k=t.__k,u.__k.some(function(n){n&&(n.__=u);}),$=0;$<h._sb.length;$++)h.__h.push(h._sb[$]);h._sb=[],h.__h.length&&e.push(h);break n}null!=h.componentWillUpdate&&h.componentWillUpdate(b,h.__s,M),S&&null!=h.componentDidUpdate&&h.__h.push(function(){h.componentDidUpdate(v,y,_);});}if(h.context=M,h.props=b,h.__P=n,h.__e=!1,P=l$1.__r,A=0,S){for(h.state=h.__s,h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),H=0;H<h._sb.length;H++)h.__h.push(h._sb[H]);h._sb=[];}else do{h.__d=!1,P&&P(u),a=h.render(h.props,h.state,h.context),h.state=h.__s;}while(h.__d&&++A<25);h.state=h.__s,null!=h.getChildContext&&(i=d$1(d$1({},i),h.getChildContext())),S&&!p&&null!=h.getSnapshotBeforeUpdate&&(_=h.getSnapshotBeforeUpdate(v,y)),L=a,null!=a&&a.type===k$1&&null==a.key&&(L=V(a.props.children)),f=I(n,w$1(L)?L:[L],u,t,i,r,o,e,f,c,s),h.base=u.__e,u.__u&=-161,h.__h.length&&e.push(h),m&&(h.__E=h.__=null);}catch(n){if(u.__v=null,c||null!=o)if(n.then){for(u.__u|=c?160:128;f&&8==f.nodeType&&f.nextSibling;)f=f.nextSibling;o[o.indexOf(f)]=null,u.__e=f;}else {for(T=o.length;T--;)g(o[T]);z$1(u);}else u.__e=t.__e,u.__k=t.__k,n.then||z$1(u);l$1.__e(n,u,t);}else null==o&&u.__v==t.__v?(u.__k=t.__k,u.__e=t.__e):f=u.__e=q(t.__e,u,t,i,r,o,e,c,s);return (a=l$1.diffed)&&a(u),128&u.__u?void 0:f}function z$1(n){n&&n.__c&&(n.__c.__e=true),n&&n.__k&&n.__k.forEach(z$1);}function N(n,u,t){for(var i=0;i<t.length;i++)B$1(t[i],t[++i],t[++i]);l$1.__c&&l$1.__c(u,n),n.some(function(u){try{n=u.__h,u.__h=[],n.some(function(n){n.call(u);});}catch(n){l$1.__e(n,u.__v);}});}function V(n){return "object"!=typeof n||null==n||n.__b&&n.__b>0?n:w$1(n)?n.map(V):d$1({},n)}function q(u,t,i,r,o,e,f,c,s){var a,h,v,y,d,_,m,b=i.props||p$1,k=t.props,x=t.type;if("svg"==x?o="http://www.w3.org/2000/svg":"math"==x?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),null!=e)for(a=0;a<e.length;a++)if((d=e[a])&&"setAttribute"in d==!!x&&(x?d.localName==x:3==d.nodeType)){u=d,e[a]=null;break}if(null==u){if(null==x)return document.createTextNode(k);u=document.createElementNS(o,x,k.is&&k),c&&(l$1.__m&&l$1.__m(t,e),c=false),e=null;}if(null==x)b===k||c&&u.data==k||(u.data=k);else {if(e=e&&n.call(u.childNodes),!c&&null!=e)for(b={},a=0;a<u.attributes.length;a++)b[(d=u.attributes[a]).name]=d.value;for(a in b)if(d=b[a],"children"==a);else if("dangerouslySetInnerHTML"==a)v=d;else if(!(a in k)){if("value"==a&&"defaultValue"in k||"checked"==a&&"defaultChecked"in k)continue;j$1(u,a,null,d,o);}for(a in k)d=k[a],"children"==a?y=d:"dangerouslySetInnerHTML"==a?h=d:"value"==a?_=d:"checked"==a?m=d:c&&"function"!=typeof d||b[a]===d||j$1(u,a,d,b[a],o);if(h)c||v&&(h.__html==v.__html||h.__html==u.innerHTML)||(u.innerHTML=h.__html),t.__k=[];else if(v&&(u.innerHTML=""),I("template"==t.type?u.content:u,w$1(y)?y:[y],t,i,r,"foreignObject"==x?"http://www.w3.org/1999/xhtml":o,e,f,e?e[0]:i.__k&&S(i,0),c,s),null!=e)for(a=e.length;a--;)g(e[a]);c||(a="value","progress"==x&&null==_?u.removeAttribute("value"):null!=_&&(_!==u[a]||"progress"==x&&!_||"option"==x&&_!=b[a])&&j$1(u,a,_,b[a],o),a="checked",null!=m&&m!=u[a]&&j$1(u,a,m,b[a],o));}return u}function B$1(n,u,t){try{if("function"==typeof n){var i="function"==typeof n.__u;i&&n.__u(),i&&null==u||(n.__u=n(u));}else n.current=u;}catch(n){l$1.__e(n,t);}}function D$1(n,u,t){var i,r;if(l$1.unmount&&l$1.unmount(n),(i=n.ref)&&(i.current&&i.current!=n.__e||B$1(i,null,u)),null!=(i=n.__c)){if(i.componentWillUnmount)try{i.componentWillUnmount();}catch(n){l$1.__e(n,u);}i.base=i.__P=null;}if(i=n.__k)for(r=0;r<i.length;r++)i[r]&&D$1(i[r],u,t||"function"!=typeof n.type);t||g(n.__e),n.__c=n.__=n.__e=void 0;}function E(n,l,u){return this.constructor(n,u)}function G(u,t,i){var r,o,e,f;t==document&&(t=document.documentElement),l$1.__&&l$1.__(u,t),o=(r="function"=="undefined")?null:t.__k,e=[],f=[],O(t,u=(t).__k=_$1(k$1,null,[u]),o||p$1,p$1,t.namespaceURI,o?null:t.firstChild?n.call(t.childNodes):null,e,o?o.__e:t.firstChild,r,f),N(e,u,f);}n=v$1.slice,l$1={__e:function(n,l,u,t){for(var i,r,o;l=l.__;)if((i=l.__c)&&!i.__)try{if((r=i.constructor)&&null!=r.getDerivedStateFromError&&(i.setState(r.getDerivedStateFromError(n)),o=i.__d),null!=i.componentDidCatch&&(i.componentDidCatch(n,t||{}),o=i.__d),o)return i.__E=i}catch(l){n=l;}throw n}},u$1=0,x.prototype.setState=function(n,l){var u;u=null!=this.__s&&this.__s!=this.state?this.__s:this.__s=d$1({},this.state),"function"==typeof n&&(n=n(d$1({},u),this.props)),n&&d$1(u,n),null!=n&&this.__v&&(l&&this._sb.push(l),M(this));},x.prototype.forceUpdate=function(n){this.__v&&(this.__e=true,n&&this.__h.push(n),M(this));},x.prototype.render=k$1,i$1=[],o$1="function"==typeof Promise?Promise.prototype.then.bind(Promise.resolve()):setTimeout,e$1=function(n,l){return n.__v.__b-l.__v.__b},$.__r=0,f$1=/(PointerCapture)$|Capture$/i,c$1=0,s$1=F(false),a$1=F(true);
|
|
17337
16505
|
|
|
17338
16506
|
const Styles = {
|
|
17339
|
-
Error: {
|
|
17340
|
-
color: "red",
|
|
17341
|
-
},
|
|
17342
16507
|
Alert: {
|
|
17343
16508
|
error: {
|
|
17344
16509
|
color: "red",
|
|
@@ -17457,13 +16622,13 @@
|
|
|
17457
16622
|
};
|
|
17458
16623
|
|
|
17459
16624
|
function Dialog({ children, className }) {
|
|
17460
|
-
return (
|
|
17461
|
-
|
|
17462
|
-
|
|
17463
|
-
|
|
16625
|
+
return (_$1("div", { className: `dexie-dialog ${className || ''}` },
|
|
16626
|
+
_$1("div", { style: Styles.Darken }),
|
|
16627
|
+
_$1("div", { style: Styles.DialogOuter },
|
|
16628
|
+
_$1("div", { style: Styles.DialogInner }, children))));
|
|
17464
16629
|
}
|
|
17465
16630
|
|
|
17466
|
-
var t,r,u,i,o=0,
|
|
16631
|
+
var t,r,u,i,o=0,f=[],c=l$1,e=c.__b,a=c.__r,v=c.diffed,l=c.__c,m=c.unmount,s=c.__;function p(n,t){c.__h&&c.__h(r,n,o||t),o=0;var u=r.__H||(r.__H={__:[],__h:[]});return n>=u.__.length&&u.__.push({}),u.__[n]}function d(n){return o=1,h(D,n)}function h(n,u,i){var o=p(t++,2);if(o.t=n,!o.__c&&(o.__=[D(void 0,u),function(n){var t=o.__N?o.__N[0]:o.__[0],r=o.t(t,n);t!==r&&(o.__N=[r,o.__[1]],o.__c.setState({}));}],o.__c=r,!r.__f)){var f=function(n,t,r){if(!o.__c.__H)return true;var u=o.__c.__H.__.filter(function(n){return !!n.__c});if(u.every(function(n){return !n.__N}))return !c||c.call(this,n,t,r);var i=o.__c.props!==n;return u.forEach(function(n){if(n.__N){var t=n.__[0];n.__=n.__N,n.__N=void 0,t!==n.__[0]&&(i=true);}}),c&&c.call(this,n,t,r)||i};r.__f=true;var c=r.shouldComponentUpdate,e=r.componentWillUpdate;r.componentWillUpdate=function(n,t,r){if(this.__e){var u=c;c=void 0,f(n,t,r),c=u;}e&&e.call(this,n,t,r);},r.shouldComponentUpdate=f;}return o.__N||o.__}function _(n,u){var i=p(t++,4);!c.__s&&C(i.__H,u)&&(i.__=n,i.u=u,r.__h.push(i));}function A(n){return o=5,T(function(){return {current:n}},[])}function T(n,r){var u=p(t++,7);return C(u.__H,r)&&(u.__=n(),u.__H=r,u.__h=n),u.__}function j(){for(var n;n=f.shift();)if(n.__P&&n.__H)try{n.__H.__h.forEach(z),n.__H.__h.forEach(B),n.__H.__h=[];}catch(t){n.__H.__h=[],c.__e(t,n.__v);}}c.__b=function(n){r=null,e&&e(n);},c.__=function(n,t){n&&t.__k&&t.__k.__m&&(n.__m=t.__k.__m),s&&s(n,t);},c.__r=function(n){a&&a(n),t=0;var i=(r=n.__c).__H;i&&(u===r?(i.__h=[],r.__h=[],i.__.forEach(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0;})):(i.__h.forEach(z),i.__h.forEach(B),i.__h=[],t=0)),u=r;},c.diffed=function(n){v&&v(n);var t=n.__c;t&&t.__H&&(t.__H.__h.length&&(1!==f.push(t)&&i===c.requestAnimationFrame||((i=c.requestAnimationFrame)||w)(j)),t.__H.__.forEach(function(n){n.u&&(n.__H=n.u),n.u=void 0;})),u=r=null;},c.__c=function(n,t){t.some(function(n){try{n.__h.forEach(z),n.__h=n.__h.filter(function(n){return !n.__||B(n)});}catch(r){t.some(function(n){n.__h&&(n.__h=[]);}),t=[],c.__e(r,n.__v);}}),l&&l(n,t);},c.unmount=function(n){m&&m(n);var t,r=n.__c;r&&r.__H&&(r.__H.__.forEach(function(n){try{z(n);}catch(n){t=n;}}),r.__H=void 0,t&&c.__e(t,r.__v));};var k="function"==typeof requestAnimationFrame;function w(n){var t,r=function(){clearTimeout(u),k&&cancelAnimationFrame(t),setTimeout(n);},u=setTimeout(r,35);k&&(t=requestAnimationFrame(r));}function z(n){var t=r,u=n.__c;"function"==typeof u&&(n.__c=void 0,u()),r=t;}function B(n){var t=r;n.__c=n.__(),r=t;}function C(n,t){return !n||n.length!==t.length||t.some(function(t,r){return t!==n[r]})}function D(n,t){return "function"==typeof t?t(n):t}
|
|
17467
16632
|
|
|
17468
16633
|
/** Resolve a message template with parameters.
|
|
17469
16634
|
*
|
|
@@ -17485,19 +16650,19 @@
|
|
|
17485
16650
|
|
|
17486
16651
|
const OTP_LENGTH = 8;
|
|
17487
16652
|
function LoginDialog({ title, type, alerts, fields, submitLabel, cancelLabel, onCancel, onSubmit, }) {
|
|
17488
|
-
const [params, setParams] =
|
|
17489
|
-
const firstFieldRef =
|
|
17490
|
-
|
|
17491
|
-
return (
|
|
17492
|
-
|
|
17493
|
-
|
|
17494
|
-
alerts.map((alert) => (
|
|
17495
|
-
|
|
16653
|
+
const [params, setParams] = d({});
|
|
16654
|
+
const firstFieldRef = A(null);
|
|
16655
|
+
_(() => { var _a; return (_a = firstFieldRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, []);
|
|
16656
|
+
return (_$1(Dialog, { className: "dxc-login-dlg" },
|
|
16657
|
+
_$1(k$1, null,
|
|
16658
|
+
_$1("h3", { style: Styles.WindowHeader }, title),
|
|
16659
|
+
alerts.map((alert) => (_$1("p", { style: Styles.Alert[alert.type] }, resolveText(alert)))),
|
|
16660
|
+
_$1("form", { onSubmit: (ev) => {
|
|
17496
16661
|
ev.preventDefault();
|
|
17497
16662
|
onSubmit(params);
|
|
17498
|
-
} }, Object.entries(fields).map(([fieldName, { type, label, placeholder }], idx) => (
|
|
16663
|
+
} }, Object.entries(fields).map(([fieldName, { type, label, placeholder }], idx) => (_$1("label", { style: Styles.Label, key: idx },
|
|
17499
16664
|
label ? `${label}: ` : '',
|
|
17500
|
-
|
|
16665
|
+
_$1("input", { ref: idx === 0 ? firstFieldRef : undefined, type: type, name: fieldName, autoComplete: "on", style: Styles.Input, autoFocus: true, placeholder: placeholder, value: params[fieldName] || '', onInput: (ev) => {
|
|
17501
16666
|
var _a;
|
|
17502
16667
|
const value = valueTransformer(type, (_a = ev.target) === null || _a === void 0 ? void 0 : _a['value']);
|
|
17503
16668
|
let updatedParams = Object.assign(Object.assign({}, params), { [fieldName]: value });
|
|
@@ -17507,10 +16672,10 @@
|
|
|
17507
16672
|
onSubmit(updatedParams);
|
|
17508
16673
|
}
|
|
17509
16674
|
} })))))),
|
|
17510
|
-
|
|
17511
|
-
|
|
17512
|
-
|
|
17513
|
-
cancelLabel && (
|
|
16675
|
+
_$1("div", { style: Styles.ButtonsDiv },
|
|
16676
|
+
_$1(k$1, null,
|
|
16677
|
+
_$1("button", { type: "submit", style: Styles.PrimaryButton, onClick: () => onSubmit(params) }, submitLabel),
|
|
16678
|
+
cancelLabel && (_$1("button", { style: Styles.Button, onClick: onCancel }, cancelLabel))))));
|
|
17514
16679
|
}
|
|
17515
16680
|
function valueTransformer(type, value) {
|
|
17516
16681
|
switch (type) {
|
|
@@ -17523,7 +16688,7 @@
|
|
|
17523
16688
|
}
|
|
17524
16689
|
}
|
|
17525
16690
|
|
|
17526
|
-
class LoginGui extends
|
|
16691
|
+
class LoginGui extends x {
|
|
17527
16692
|
constructor(props) {
|
|
17528
16693
|
super(props);
|
|
17529
16694
|
this.observer = (userInteraction) => this.setState({ userInteraction });
|
|
@@ -17542,7 +16707,7 @@
|
|
|
17542
16707
|
if (!userInteraction)
|
|
17543
16708
|
return null;
|
|
17544
16709
|
//if (props.db.cloud.userInteraction.observers.length > 1) return null; // Someone else subscribes.
|
|
17545
|
-
return
|
|
16710
|
+
return _$1(LoginDialog, Object.assign({}, userInteraction));
|
|
17546
16711
|
}
|
|
17547
16712
|
}
|
|
17548
16713
|
function setupDefaultGUI(db) {
|
|
@@ -17550,13 +16715,13 @@
|
|
|
17550
16715
|
const el = document.createElement('div');
|
|
17551
16716
|
if (document.body) {
|
|
17552
16717
|
document.body.appendChild(el);
|
|
17553
|
-
|
|
16718
|
+
G(_$1(LoginGui, { db: db.vip }), el);
|
|
17554
16719
|
}
|
|
17555
16720
|
else {
|
|
17556
16721
|
addEventListener('DOMContentLoaded', () => {
|
|
17557
16722
|
if (!closed) {
|
|
17558
16723
|
document.body.appendChild(el);
|
|
17559
|
-
|
|
16724
|
+
G(_$1(LoginGui, { db: db.vip }), el);
|
|
17560
16725
|
}
|
|
17561
16726
|
});
|
|
17562
16727
|
}
|
|
@@ -18311,7 +17476,7 @@
|
|
|
18311
17476
|
const syncComplete = new rxjs.Subject();
|
|
18312
17477
|
dexie.cloud = {
|
|
18313
17478
|
// @ts-ignore
|
|
18314
|
-
version: "4.2.
|
|
17479
|
+
version: "4.2.5",
|
|
18315
17480
|
options: Object.assign({}, DEFAULT_OPTIONS),
|
|
18316
17481
|
schema: null,
|
|
18317
17482
|
get currentUserId() {
|
|
@@ -18628,7 +17793,7 @@
|
|
|
18628
17793
|
}
|
|
18629
17794
|
}
|
|
18630
17795
|
// @ts-ignore
|
|
18631
|
-
dexieCloud.version = "4.2.
|
|
17796
|
+
dexieCloud.version = "4.2.5";
|
|
18632
17797
|
Dexie.Cloud = dexieCloud;
|
|
18633
17798
|
|
|
18634
17799
|
exports.default = dexieCloud;
|