dexie-cloud-addon 4.4.6 → 4.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/modern/DXCWebSocketStatus.d.ts +1 -1
  2. package/dist/modern/DexieCloudAPI.d.ts +1 -1
  3. package/dist/modern/authentication/AuthPersistedContext.d.ts +2 -2
  4. package/dist/modern/currentUserEmitter.d.ts +3 -3
  5. package/dist/modern/db/entities/Member.d.ts +3 -3
  6. package/dist/modern/db/entities/PersistedSyncState.d.ts +1 -1
  7. package/dist/modern/db/entities/Role.d.ts +3 -3
  8. package/dist/modern/default-ui/Dialog.d.ts +1 -1
  9. package/dist/modern/default-ui/index.d.ts +5 -5
  10. package/dist/modern/dexie-cloud-addon.js +653 -531
  11. package/dist/modern/dexie-cloud-addon.js.map +1 -1
  12. package/dist/modern/dexie-cloud-addon.min.js +1 -1
  13. package/dist/modern/dexie-cloud-addon.min.js.map +1 -1
  14. package/dist/modern/dexie-cloud-client.d.ts +1 -1
  15. package/dist/modern/helpers/BroadcastedAndLocalEvent.d.ts +2 -2
  16. package/dist/modern/helpers/getSyncableTables.d.ts +3 -3
  17. package/dist/modern/helpers/resolveText.d.ts +1 -1
  18. package/dist/modern/middleware-helpers/guardedTable.d.ts +1 -1
  19. package/dist/modern/service-worker.js +655 -533
  20. package/dist/modern/service-worker.js.map +1 -1
  21. package/dist/modern/service-worker.min.js +1 -1
  22. package/dist/modern/service-worker.min.js.map +1 -1
  23. package/dist/modern/sync/BlobDownloadTracker.d.ts +7 -4
  24. package/dist/modern/sync/extractRealm.d.ts +1 -1
  25. package/dist/modern/sync/getTablesToSyncify.d.ts +2 -2
  26. package/dist/modern/sync/isSyncNeeded.d.ts +1 -1
  27. package/dist/modern/sync/messageConsumerIsReady.d.ts +1 -1
  28. package/dist/modern/sync/modifyLocalObjectsWithNewUserId.d.ts +3 -3
  29. package/dist/modern/sync/numUnsyncedMutations.d.ts +1 -1
  30. package/dist/modern/sync/performGuardedJob.d.ts +1 -1
  31. package/dist/modern/sync/registerSyncEvent.d.ts +1 -1
  32. package/dist/modern/sync/triggerSync.d.ts +2 -2
  33. package/dist/modern/types/DXCUserInteraction.d.ts +2 -2
  34. package/dist/modern/types/SyncState.d.ts +2 -2
  35. package/dist/modern/types/TXExpandos.d.ts +1 -1
  36. package/dist/modern/updateSchemaFromOptions.d.ts +2 -2
  37. package/dist/modern/verifyConfig.d.ts +1 -1
  38. package/dist/modern/verifySchema.d.ts +1 -1
  39. package/dist/modern/yjs/YTable.d.ts +3 -3
  40. package/dist/modern/yjs/getUpdatesTable.d.ts +2 -2
  41. package/dist/modern/yjs/reopenDocSignal.d.ts +2 -2
  42. package/dist/umd/dexie-cloud-addon.js +661 -539
  43. package/dist/umd/dexie-cloud-addon.js.map +1 -1
  44. package/dist/umd/dexie-cloud-addon.min.js +1 -1
  45. package/dist/umd/dexie-cloud-addon.min.js.map +1 -1
  46. package/dist/umd/service-worker.js +663 -541
  47. package/dist/umd/service-worker.js.map +1 -1
  48. package/dist/umd/service-worker.min.js +1 -1
  49. package/dist/umd/service-worker.min.js.map +1 -1
  50. package/package.json +2 -2
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * ==========================================================================
10
10
  *
11
- * Version 4.4.6, Thu Mar 26 2026
11
+ * Version 4.4.8, Tue Mar 31 2026
12
12
  *
13
13
  * https://dexie.org
14
14
  *
@@ -111,7 +111,7 @@
111
111
  const keys = Object.keys(value);
112
112
  let dollarKeys = null;
113
113
  for (let i = 0, l = keys.length; i < l; ++i) {
114
- if (keys[i][0] === "$") {
114
+ if (keys[i][0] === '$') {
115
115
  dollarKeys = dollarKeys || [];
116
116
  dollarKeys.push(keys[i]);
117
117
  }
@@ -123,7 +123,7 @@
123
123
  delete clone[k];
124
124
  }
125
125
  for (const k of dollarKeys) {
126
- clone["$" + k] = value[k];
126
+ clone['$' + k] = value[k];
127
127
  }
128
128
  return clone;
129
129
  }
@@ -174,7 +174,7 @@
174
174
  //
175
175
  // Child part
176
176
  //
177
- if (value === undefined || (key[0] === "$" && key !== "$t")) {
177
+ if (value === undefined || (key[0] === '$' && key !== '$t')) {
178
178
  top = stack[stack.length - 1];
179
179
  let deletes;
180
180
  let mods;
@@ -185,7 +185,7 @@
185
185
  else {
186
186
  stack.push([this, (deletes = []), (mods = {})]);
187
187
  }
188
- if (key[0] === "$" && key !== "$t") {
188
+ if (key[0] === '$' && key !== '$t') {
189
189
  // Unescape props (also preserves undefined if this is a combo)
190
190
  deletes.push(key);
191
191
  mods[key.substr(1)] = value;
@@ -202,8 +202,8 @@
202
202
  function getTypeDef(realVal) {
203
203
  const type = typeof realVal;
204
204
  switch (typeof realVal) {
205
- case "object":
206
- case "function": {
205
+ case 'object':
206
+ case 'function': {
207
207
  // "object", "function", null
208
208
  if (realVal === null)
209
209
  return null;
@@ -219,7 +219,7 @@
219
219
  if (!typeDef) {
220
220
  typeDef = Array.isArray(realVal)
221
221
  ? null
222
- : typeof realVal === "function"
222
+ : typeof realVal === 'function'
223
223
  ? typeDefs.function || null
224
224
  : ObjectDef;
225
225
  }
@@ -395,13 +395,13 @@
395
395
 
396
396
  function readBlobSync(b) {
397
397
  const req = new XMLHttpRequest();
398
- req.overrideMimeType("text/plain; charset=x-user-defined");
398
+ req.overrideMimeType('text/plain; charset=x-user-defined');
399
399
  const url = URL.createObjectURL(b);
400
400
  try {
401
- req.open("GET", url, false); // Sync
401
+ req.open('GET', url, false); // Sync
402
402
  req.send();
403
403
  if (req.status !== 200 && req.status !== 0) {
404
- throw new Error("Bad Blob access: " + req.status);
404
+ throw new Error('Bad Blob access: ' + req.status);
405
405
  }
406
406
  return req.responseText;
407
407
  }
@@ -415,11 +415,11 @@
415
415
  replace: (num) => {
416
416
  switch (true) {
417
417
  case isNaN(num):
418
- return { $t: "number", v: "NaN" };
418
+ return { $t: 'number', v: 'NaN' };
419
419
  case num === Infinity:
420
- return { $t: "number", v: "Infinity" };
420
+ return { $t: 'number', v: 'Infinity' };
421
421
  case num === -Infinity:
422
- return { $t: "number", v: "-Infinity" };
422
+ return { $t: 'number', v: '-Infinity' };
423
423
  default:
424
424
  return num;
425
425
  }
@@ -431,17 +431,17 @@
431
431
  const dateTypeDef = {
432
432
  Date: {
433
433
  replace: (date) => ({
434
- $t: "Date",
435
- v: isNaN(date.getTime()) ? "NaN" : date.toISOString(),
434
+ $t: 'Date',
435
+ v: isNaN(date.getTime()) ? 'NaN' : date.toISOString(),
436
436
  }),
437
- revive: ({ v }) => new Date(v === "NaN" ? NaN : Date.parse(v)),
437
+ revive: ({ v }) => new Date(v === 'NaN' ? NaN : Date.parse(v)),
438
438
  },
439
439
  };
440
440
 
441
441
  const setTypeDef = {
442
442
  Set: {
443
443
  replace: (set) => ({
444
- $t: "Set",
444
+ $t: 'Set',
445
445
  v: Array.from(set),
446
446
  }),
447
447
  revive: ({ v }) => new Set(v),
@@ -451,34 +451,34 @@
451
451
  const mapTypeDef = {
452
452
  Map: {
453
453
  replace: (map) => ({
454
- $t: "Map",
454
+ $t: 'Map',
455
455
  v: Array.from(map.entries()),
456
456
  }),
457
457
  revive: ({ v }) => new Map(v),
458
458
  },
459
459
  };
460
460
 
461
- const _global = typeof globalThis !== "undefined" // All modern environments (node, bun, deno, browser, workers, webview etc)
461
+ const _global = typeof globalThis !== 'undefined' // All modern environments (node, bun, deno, browser, workers, webview etc)
462
462
  ? globalThis
463
- : typeof self !== "undefined" // Older browsers, workers, webview, window etc
463
+ : typeof self !== 'undefined' // Older browsers, workers, webview, window etc
464
464
  ? self
465
- : typeof global !== "undefined" // Older versions of node
465
+ : typeof global !== 'undefined' // Older versions of node
466
466
  ? global
467
467
  : undefined; // Unsupported environment. No idea to return 'this' since we are in a module or a function scope anyway.
468
468
 
469
469
  const typedArrayTypeDefs = [
470
- "Int8Array",
471
- "Uint8Array",
472
- "Uint8ClampedArray",
473
- "Int16Array",
474
- "Uint16Array",
475
- "Int32Array",
476
- "Uint32Array",
477
- "Float32Array",
478
- "Float64Array",
479
- "DataView",
480
- "BigInt64Array",
481
- "BigUint64Array",
470
+ 'Int8Array',
471
+ 'Uint8Array',
472
+ 'Uint8ClampedArray',
473
+ 'Int16Array',
474
+ 'Uint16Array',
475
+ 'Int32Array',
476
+ 'Uint32Array',
477
+ 'Float32Array',
478
+ 'Float64Array',
479
+ 'DataView',
480
+ 'BigInt64Array',
481
+ 'BigUint64Array',
482
482
  ].reduce((specs, typeName) => ({
483
483
  ...specs,
484
484
  [typeName]: {
@@ -506,10 +506,10 @@
506
506
  },
507
507
  }), {});
508
508
 
509
- const hasArrayBufferFromBase64 = "fromBase64" in Uint8Array; // https://github.com/tc39/proposal-arraybuffer-base64;
510
- const hasArrayBufferToBase64 = "toBase64" in Uint8Array.prototype; // https://github.com/tc39/proposal-arraybuffer-base64;
511
- const b64decode = typeof Buffer !== "undefined"
512
- ? (base64) => Buffer.from(base64, "base64") // Node
509
+ const hasArrayBufferFromBase64 = 'fromBase64' in Uint8Array; // https://github.com/tc39/proposal-arraybuffer-base64;
510
+ const hasArrayBufferToBase64 = 'toBase64' in Uint8Array.prototype; // https://github.com/tc39/proposal-arraybuffer-base64;
511
+ const b64decode = typeof Buffer !== 'undefined'
512
+ ? (base64) => Buffer.from(base64, 'base64') // Node
513
513
  : hasArrayBufferFromBase64
514
514
  ? // @ts-ignore: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/fromBase64
515
515
  (base64) => Uint8Array.fromBase64(base64) // Modern javascript standard
@@ -523,14 +523,14 @@
523
523
  }
524
524
  return bytes;
525
525
  };
526
- const b64encode = typeof Buffer !== "undefined"
526
+ const b64encode = typeof Buffer !== 'undefined'
527
527
  ? (b) => {
528
528
  // Node
529
529
  if (ArrayBuffer.isView(b)) {
530
- return Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString("base64");
530
+ return Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString('base64');
531
531
  }
532
532
  else {
533
- return Buffer.from(b).toString("base64");
533
+ return Buffer.from(b).toString('base64');
534
534
  }
535
535
  }
536
536
  : hasArrayBufferToBase64
@@ -549,7 +549,7 @@
549
549
  const chunk = u8a.subarray(i, i + CHUNK_SIZE);
550
550
  strs.push(String.fromCharCode.apply(null, Array.from(chunk)));
551
551
  }
552
- return btoa(strs.join(""));
552
+ return btoa(strs.join(''));
553
553
  };
554
554
 
555
555
  function b64LexEncode(b) {
@@ -559,7 +559,7 @@
559
559
  return b64decode(lexToB64(b64Lex));
560
560
  }
561
561
  function b64ToLex(base64) {
562
- var encoded = "";
562
+ var encoded = '';
563
563
  for (var i = 0, length = base64.length; i < length; i++) {
564
564
  encoded += ENCODE_TABLE[base64[i]];
565
565
  }
@@ -567,81 +567,81 @@
567
567
  }
568
568
  function lexToB64(base64lex) {
569
569
  // only accept string input
570
- if (typeof base64lex !== "string") {
571
- throw new Error("invalid decoder input: " + base64lex);
570
+ if (typeof base64lex !== 'string') {
571
+ throw new Error('invalid decoder input: ' + base64lex);
572
572
  }
573
- var base64 = "";
573
+ var base64 = '';
574
574
  for (var i = 0, length = base64lex.length; i < length; i++) {
575
575
  base64 += DECODE_TABLE[base64lex[i]];
576
576
  }
577
577
  return base64;
578
578
  }
579
579
  const DECODE_TABLE = {
580
- "-": "=",
581
- "0": "A",
582
- "1": "B",
583
- "2": "C",
584
- "3": "D",
585
- "4": "E",
586
- "5": "F",
587
- "6": "G",
588
- "7": "H",
589
- "8": "I",
590
- "9": "J",
591
- A: "K",
592
- B: "L",
593
- C: "M",
594
- D: "N",
595
- E: "O",
596
- F: "P",
597
- G: "Q",
598
- H: "R",
599
- I: "S",
600
- J: "T",
601
- K: "U",
602
- L: "V",
603
- M: "W",
604
- N: "X",
605
- O: "Y",
606
- P: "Z",
607
- Q: "a",
608
- R: "b",
609
- S: "c",
610
- T: "d",
611
- U: "e",
612
- V: "f",
613
- W: "g",
614
- X: "h",
615
- Y: "i",
616
- Z: "j",
617
- _: "k",
618
- a: "l",
619
- b: "m",
620
- c: "n",
621
- d: "o",
622
- e: "p",
623
- f: "q",
624
- g: "r",
625
- h: "s",
626
- i: "t",
627
- j: "u",
628
- k: "v",
629
- l: "w",
630
- m: "x",
631
- n: "y",
632
- o: "z",
633
- p: "0",
634
- q: "1",
635
- r: "2",
636
- s: "3",
637
- t: "4",
638
- u: "5",
639
- v: "6",
640
- w: "7",
641
- x: "8",
642
- y: "9",
643
- z: "+",
644
- "|": "/",
580
+ '-': '=',
581
+ '0': 'A',
582
+ '1': 'B',
583
+ '2': 'C',
584
+ '3': 'D',
585
+ '4': 'E',
586
+ '5': 'F',
587
+ '6': 'G',
588
+ '7': 'H',
589
+ '8': 'I',
590
+ '9': 'J',
591
+ A: 'K',
592
+ B: 'L',
593
+ C: 'M',
594
+ D: 'N',
595
+ E: 'O',
596
+ F: 'P',
597
+ G: 'Q',
598
+ H: 'R',
599
+ I: 'S',
600
+ J: 'T',
601
+ K: 'U',
602
+ L: 'V',
603
+ M: 'W',
604
+ N: 'X',
605
+ O: 'Y',
606
+ P: 'Z',
607
+ Q: 'a',
608
+ R: 'b',
609
+ S: 'c',
610
+ T: 'd',
611
+ U: 'e',
612
+ V: 'f',
613
+ W: 'g',
614
+ X: 'h',
615
+ Y: 'i',
616
+ Z: 'j',
617
+ _: 'k',
618
+ a: 'l',
619
+ b: 'm',
620
+ c: 'n',
621
+ d: 'o',
622
+ e: 'p',
623
+ f: 'q',
624
+ g: 'r',
625
+ h: 's',
626
+ i: 't',
627
+ j: 'u',
628
+ k: 'v',
629
+ l: 'w',
630
+ m: 'x',
631
+ n: 'y',
632
+ o: 'z',
633
+ p: '0',
634
+ q: '1',
635
+ r: '2',
636
+ s: '3',
637
+ t: '4',
638
+ u: '5',
639
+ v: '6',
640
+ w: '7',
641
+ x: '8',
642
+ y: '9',
643
+ z: '+',
644
+ '|': '/',
645
645
  };
646
646
  const ENCODE_TABLE = {};
647
647
  for (const c of Object.keys(DECODE_TABLE)) {
@@ -651,7 +651,7 @@
651
651
  const arrayBufferTypeDef = {
652
652
  ArrayBuffer: {
653
653
  replace: (ab) => ({
654
- $t: "ArrayBuffer",
654
+ $t: 'ArrayBuffer',
655
655
  v: b64LexEncode(ab),
656
656
  }),
657
657
  revive: ({ v }) => {
@@ -674,9 +674,9 @@
674
674
 
675
675
  const blobTypeDef = {
676
676
  Blob: {
677
- test: (blob, toStringTag) => toStringTag === "Blob" || blob instanceof FakeBlob,
677
+ test: (blob, toStringTag) => toStringTag === 'Blob' || blob instanceof FakeBlob,
678
678
  replace: (blob) => ({
679
- $t: "Blob",
679
+ $t: 'Blob',
680
680
  v: blob instanceof FakeBlob
681
681
  ? b64encode(blob.buf)
682
682
  : b64encode(string2ArrayBuffer(readBlobSync(blob))),
@@ -687,7 +687,7 @@
687
687
  const buf = ab.buffer.byteLength === ab.byteLength
688
688
  ? ab.buffer
689
689
  : ab.buffer.slice(ab.byteOffset, ab.byteOffset + ab.byteLength);
690
- return typeof Blob !== "undefined"
690
+ return typeof Blob !== 'undefined'
691
691
  ? new Blob([new Uint8Array(buf)], { type })
692
692
  : new FakeBlob(buf, type);
693
693
  },
@@ -706,15 +706,15 @@
706
706
 
707
707
  const fileTypeDef = {
708
708
  File: {
709
- test: (file, toStringTag) => toStringTag === "File",
709
+ test: (file, toStringTag) => toStringTag === 'File',
710
710
  replace: (file) => ({
711
- $t: "File",
711
+ $t: 'File',
712
712
  v: b64encode(string2ArrayBuffer(readBlobSync(file))),
713
713
  type: file.type,
714
714
  name: file.name,
715
715
  lastModified: new Date(file.lastModified).toISOString(),
716
716
  }),
717
- revive: ({ type, v, name, lastModified }) => {
717
+ revive: ({ type, v, name, lastModified, }) => {
718
718
  const ab = b64decode(v);
719
719
  const buf = ab.buffer.byteLength === ab.byteLength
720
720
  ? ab.buffer
@@ -738,13 +738,13 @@
738
738
  const undefinedTypeDef = {
739
739
  undefined: {
740
740
  replace: () => ({
741
- $t: "undefined",
741
+ $t: 'undefined',
742
742
  }),
743
743
  revive: () => undefined,
744
744
  },
745
745
  };
746
746
 
747
- const getRandomValues$1 = typeof crypto !== "undefined"
747
+ const getRandomValues$1 = typeof crypto !== 'undefined'
748
748
  ? crypto.getRandomValues.bind(crypto)
749
749
  : (buf) => {
750
750
  for (let i = 0; i < buf.length; ++i) {
@@ -845,7 +845,7 @@
845
845
  var innerObj = obj[currentKeyPath];
846
846
  //@ts-ignore: even if currentKeyPath would be numeric string and obj would be array - it works.
847
847
  if (!innerObj || !hasOwn(obj, currentKeyPath))
848
- innerObj = (obj[currentKeyPath] = {});
848
+ innerObj = obj[currentKeyPath] = {};
849
849
  setByKeyPath(innerObj, remainingKeyPath, value);
850
850
  }
851
851
  }
@@ -864,17 +864,23 @@
864
864
  }
865
865
  }
866
866
  }
867
- const randomString$1 = typeof self !== 'undefined' && typeof crypto !== 'undefined' ? (bytes, randomFill = crypto.getRandomValues.bind(crypto)) => {
868
- // Web
869
- const buf = new Uint8Array(bytes);
870
- randomFill(buf);
871
- return self.btoa(String.fromCharCode.apply(null, buf));
872
- } : typeof Buffer !== 'undefined' ? (bytes, randomFill = simpleRandomFill) => {
873
- // Node
874
- const buf = Buffer.alloc(bytes);
875
- randomFill(buf);
876
- return buf.toString("base64");
877
- } : () => { throw new Error("No implementation of randomString was found"); };
867
+ const randomString$1 = typeof self !== 'undefined' && typeof crypto !== 'undefined'
868
+ ? (bytes, randomFill = crypto.getRandomValues.bind(crypto)) => {
869
+ // Web
870
+ const buf = new Uint8Array(bytes);
871
+ randomFill(buf);
872
+ return self.btoa(String.fromCharCode.apply(null, buf));
873
+ }
874
+ : typeof Buffer !== 'undefined'
875
+ ? (bytes, randomFill = simpleRandomFill) => {
876
+ // Node
877
+ const buf = Buffer.alloc(bytes);
878
+ randomFill(buf);
879
+ return buf.toString('base64');
880
+ }
881
+ : () => {
882
+ throw new Error('No implementation of randomString was found');
883
+ };
878
884
  function simpleRandomFill(buf) {
879
885
  for (let i = 0; i < buf.length; ++i) {
880
886
  buf[i] = Math.floor(Math.random() * 256);
@@ -893,11 +899,13 @@
893
899
  * @returns
894
900
  */
895
901
  function isValidSyncableID(id) {
896
- if (typeof id === "string")
902
+ if (typeof id === 'string')
897
903
  return true;
898
904
  //if (validIDTypes[toStringTag(id)]) return true;
899
905
  //if (Array.isArray(id)) return id.every((part) => isValidSyncableID(part));
900
- if (Array.isArray(id) && id.some(key => isValidSyncableID(key)) && id.every(isValidSyncableIDPart))
906
+ if (Array.isArray(id) &&
907
+ id.some((key) => isValidSyncableID(key)) &&
908
+ id.every(isValidSyncableIDPart))
901
909
  return true;
902
910
  return false;
903
911
  }
@@ -906,53 +914,53 @@
906
914
  * For example, ArrayBuffer cannot be used (gives "object ArrayBuffer") but Uint8Array can be
907
915
  * used (gives comma-delimited list of included bytes).
908
916
  * 2: Since we store the key as a VARCHAR server side in current version, try not promote types that stringifies to become very long server side.
909
- */
917
+ */
910
918
  function isValidSyncableIDPart(part) {
911
- return typeof part === "string" || typeof part === "number" || Array.isArray(part) && part.every(isValidSyncableIDPart);
919
+ return (typeof part === 'string' ||
920
+ typeof part === 'number' ||
921
+ (Array.isArray(part) && part.every(isValidSyncableIDPart)));
912
922
  }
913
923
  function isValidAtID(id, idPrefix) {
914
- return !idPrefix || (typeof id === "string" && id.startsWith(idPrefix));
924
+ return !idPrefix || (typeof id === 'string' && id.startsWith(idPrefix));
915
925
  }
916
926
 
917
927
  function applyOperation(target, table, op) {
918
928
  const tbl = target[table] || (target[table] = {});
919
- const keys = op.keys.map(key => typeof key === 'string' ? key : JSON.stringify(key));
929
+ const keys = op.keys.map((key) => typeof key === 'string' ? key : JSON.stringify(key));
920
930
  switch (op.type) {
921
- case "insert":
931
+ case 'insert':
922
932
  // TODO: Don't treat insert and upsert the same?
923
- case "upsert":
933
+ case 'upsert':
924
934
  keys.forEach((key, idx) => {
925
935
  tbl[key] = {
926
- type: "ups",
936
+ type: 'ups',
927
937
  val: op.values[idx],
928
938
  };
929
939
  });
930
940
  break;
931
- case "update":
932
- case "modify": {
941
+ case 'update':
942
+ case 'modify': {
933
943
  keys.forEach((key, idx) => {
934
- const changeSpec = op.type === "update"
935
- ? op.changeSpecs[idx]
936
- : op.changeSpec;
944
+ const changeSpec = op.type === 'update' ? op.changeSpecs[idx] : op.changeSpec;
937
945
  const entry = tbl[key];
938
946
  if (!entry) {
939
947
  tbl[key] = {
940
- type: "upd",
948
+ type: 'upd',
941
949
  mod: changeSpec,
942
950
  };
943
951
  }
944
952
  else {
945
953
  switch (entry.type) {
946
- case "ups":
954
+ case 'ups':
947
955
  // Adjust the existing upsert with additional updates
948
956
  for (const [propPath, value] of Object.entries(changeSpec)) {
949
957
  setByKeyPath(entry.val, propPath, value);
950
958
  }
951
959
  break;
952
- case "del":
960
+ case 'del':
953
961
  // No action.
954
962
  break;
955
- case "upd":
963
+ case 'upd':
956
964
  // Adjust existing update with additional updates
957
965
  Object.assign(entry.mod, changeSpec); // May work for deep props as well - new keys is added later, right? Does the prop order persist along TSON and all? But it will not be 100% when combined with some server code (seach for "address.city": "Stockholm" comment)
958
966
  break;
@@ -961,10 +969,10 @@
961
969
  });
962
970
  break;
963
971
  }
964
- case "delete":
972
+ case 'delete':
965
973
  keys.forEach((key) => {
966
974
  tbl[key] = {
967
- type: "del",
975
+ type: 'del',
968
976
  };
969
977
  });
970
978
  break;
@@ -1061,30 +1069,30 @@
1061
1069
  };
1062
1070
  for (const [optype, muts] of Object.entries(ops)) {
1063
1071
  switch (optype) {
1064
- case "ups": {
1072
+ case 'ups': {
1065
1073
  const op = {
1066
- type: "upsert",
1067
- keys: muts.map(mut => mut.key),
1068
- values: muts.map(mut => mut.val),
1069
- txid
1074
+ type: 'upsert',
1075
+ keys: muts.map((mut) => mut.key),
1076
+ values: muts.map((mut) => mut.val),
1077
+ txid,
1070
1078
  };
1071
1079
  resultEntry.muts.push(op);
1072
1080
  break;
1073
1081
  }
1074
- case "upd": {
1082
+ case 'upd': {
1075
1083
  const op = {
1076
- type: "update",
1077
- keys: muts.map(mut => mut.key),
1078
- changeSpecs: muts.map(mut => mut.mod),
1079
- txid
1084
+ type: 'update',
1085
+ keys: muts.map((mut) => mut.key),
1086
+ changeSpecs: muts.map((mut) => mut.mod),
1087
+ txid,
1080
1088
  };
1081
1089
  resultEntry.muts.push(op);
1082
1090
  break;
1083
1091
  }
1084
- case "del": {
1092
+ case 'del': {
1085
1093
  const op = {
1086
- type: "delete",
1087
- keys: muts.map(mut => mut.key),
1094
+ type: 'delete',
1095
+ keys: muts.map((mut) => mut.key),
1088
1096
  txid,
1089
1097
  };
1090
1098
  resultEntry.muts.push(op);
@@ -1099,7 +1107,7 @@
1099
1107
 
1100
1108
  function getDbNameFromDbUrl(dbUrl) {
1101
1109
  const url = new URL(dbUrl);
1102
- return url.pathname === "/"
1110
+ return url.pathname === '/'
1103
1111
  ? url.hostname.split('.')[0]
1104
1112
  : url.pathname.split('/')[1];
1105
1113
  }
@@ -2520,7 +2528,8 @@
2520
2528
  prop,
2521
2529
  k,
2522
2530
  u: readVarUint8Array(decoder),
2523
- r: (decoder.pos < decoder.arr.length && readVarString(decoder)) || undefined,
2531
+ r: (decoder.pos < decoder.arr.length && readVarString(decoder)) ||
2532
+ undefined,
2524
2533
  };
2525
2534
  default:
2526
2535
  throw new TypeError(`Unknown message type: ${type}`);
@@ -2537,7 +2546,8 @@
2537
2546
  }
2538
2547
  // Start running the machine. If the last stage is a sink, it will consume the data and never emit anything
2539
2548
  // to us here...
2540
- for await (const chunk of result) { }
2549
+ for await (const chunk of result) {
2550
+ }
2541
2551
  }
2542
2552
 
2543
2553
  async function* consumeChunkedBinaryStream(source) {
@@ -2591,7 +2601,7 @@
2591
2601
  }
2592
2602
  if (pos + len > chunk.byteLength) {
2593
2603
  bufs.push(chunk.slice(pos));
2594
- len -= (chunk.byteLength - pos);
2604
+ len -= chunk.byteLength - pos;
2595
2605
  state = 2;
2596
2606
  pos = chunk.byteLength; // will break while loop.
2597
2607
  }
@@ -2622,7 +2632,7 @@
2622
2632
  function getFetchResponseBodyGenerator(res) {
2623
2633
  return async function* () {
2624
2634
  if (!res.body)
2625
- throw new Error("Response body is not readable");
2635
+ throw new Error('Response body is not readable');
2626
2636
  const reader = res.body.getReader();
2627
2637
  try {
2628
2638
  while (true) {
@@ -2691,11 +2701,11 @@
2691
2701
  return false;
2692
2702
  }
2693
2703
  if (Array.isArray(obj)) {
2694
- return obj.some(item => hasBlobRefs(item, visited));
2704
+ return obj.some((item) => hasBlobRefs(item, visited));
2695
2705
  }
2696
2706
  // Only traverse POJOs
2697
2707
  if (obj.constructor === Object) {
2698
- return Object.values(obj).some(value => hasBlobRefs(value, visited));
2708
+ return Object.values(obj).some((value) => hasBlobRefs(value, visited));
2699
2709
  }
2700
2710
  return false;
2701
2711
  }
@@ -2759,7 +2769,8 @@
2759
2769
  */
2760
2770
  function resolveAllBlobRefs(obj_1, dbUrl_1) {
2761
2771
  return __awaiter(this, arguments, void 0, function* (obj, dbUrl, resolvedBlobs = [], currentPath = '', visited = new WeakMap(), tracker) {
2762
- if (obj == null) { // null or undefined
2772
+ if (obj == null) {
2773
+ // null or undefined
2763
2774
  return obj;
2764
2775
  }
2765
2776
  // Check if this is a BlobRef - resolve it and track it
@@ -2808,9 +2819,7 @@
2808
2819
  * Check if an object has unresolved BlobRefs
2809
2820
  */
2810
2821
  function hasUnresolvedBlobRefs(obj) {
2811
- return (typeof obj === 'object' &&
2812
- obj !== null &&
2813
- obj._hasBlobRefs === 1);
2822
+ return (typeof obj === 'object' && obj !== null && obj._hasBlobRefs === 1);
2814
2823
  }
2815
2824
 
2816
2825
  function getSyncableTables(db) {
@@ -2875,7 +2884,7 @@
2875
2884
  isDownloading: isDownloading && stats.blobsRemaining > 0,
2876
2885
  blobsRemaining: stats.blobsRemaining,
2877
2886
  bytesRemaining: stats.bytesRemaining,
2878
- })), operators.share({ resetOnRefCountZero: () => rxjs.timer(2000) }) // Keep alive for 2s after last unsubscription to avoid rapid re-subscriptions during UI updates
2887
+ })), operators.share({ resetOnRefCountZero: () => rxjs.timer(2000) }) // Keep alive for 2s after last unsubscription to avoid rapid re-subscriptions during UI updates
2879
2888
  );
2880
2889
  }
2881
2890
  /**
@@ -2959,13 +2968,13 @@
2959
2968
  }
2960
2969
  setDownloadingState(downloading$, true);
2961
2970
  try {
2962
- debugLog(`Eager download: Found ${syncedTables.length} syncable tables: ${syncedTables.map(t => t.name).join(', ')}`);
2971
+ debugLog(`Eager download: Found ${syncedTables.length} syncable tables: ${syncedTables.map((t) => t.name).join(', ')}`);
2963
2972
  for (const table of syncedTables) {
2964
2973
  if (signal === null || signal === void 0 ? void 0 : signal.aborted)
2965
2974
  ;
2966
2975
  try {
2967
2976
  // Check if table has _hasBlobRefs index
2968
- const hasIndex = table.schema.indexes.some(idx => idx.name === '_hasBlobRefs');
2977
+ const hasIndex = table.schema.indexes.some((idx) => idx.name === '_hasBlobRefs');
2969
2978
  if (!hasIndex)
2970
2979
  continue;
2971
2980
  // Query objects with _hasBlobRefs marker
@@ -2981,7 +2990,7 @@
2981
2990
  const MAX_CONCURRENT = 6;
2982
2991
  const primaryKey = table.schema.primKey;
2983
2992
  // Filter to actionable objects first
2984
- const pending = unresolvedObjects.filter(obj => {
2993
+ const pending = unresolvedObjects.filter((obj) => {
2985
2994
  if (!hasUnresolvedBlobRefs(obj))
2986
2995
  return false;
2987
2996
  const key = primaryKey.keyPath
@@ -3042,7 +3051,7 @@
3042
3051
  try {
3043
3052
  // Send sync event to SW:
3044
3053
  const sw = yield navigator.serviceWorker.ready;
3045
- if (purpose === "push" && sw.sync) {
3054
+ if (purpose === 'push' && sw.sync) {
3046
3055
  yield sw.sync.register(`dexie-cloud:${db.name}`);
3047
3056
  }
3048
3057
  if (sw.active) {
@@ -3051,7 +3060,7 @@
3051
3060
  sw.active.postMessage({
3052
3061
  type: 'dexie-cloud-sync',
3053
3062
  dbName: db.name,
3054
- purpose
3063
+ purpose,
3055
3064
  });
3056
3065
  }
3057
3066
  else {
@@ -3176,14 +3185,15 @@
3176
3185
  // the domain extension like .com, .net, etc.
3177
3186
  // (\sas\s[\w-+.]+@([\w-]+\.)+[\w-]{2,10})?$ : This part is optional (due to the ? at the end).
3178
3187
  // If present, it matches " as " followed by another valid email address. This allows for the
3179
- // input to be either a single email address or two email addresses separated by " as ".
3188
+ // input to be either a single email address or two email addresses separated by " as ".
3180
3189
  //
3181
3190
  // The use case for "<email1> as <email2>"" is for when a database owner with full access to the
3182
3191
  // database needs to impersonate another user in the database in order to troubleshoot. This
3183
3192
  // format will only be possible to use when email1 is the owner of an API client with GLOBAL_READ
3184
3193
  // and GLOBAL_WRITE permissions on the database. The email will be checked on the server before
3185
3194
  // allowing it and giving out a token for email2, using the OTP sent to email1.
3186
- while (!email || !/^[\w-+.]+@([\w-]+\.)+[\w-]{2,10}(\sas\s[\w-+.]+@([\w-]+\.)+[\w-]{2,10})?$/.test(email)) {
3195
+ while (!email ||
3196
+ !/^[\w-+.]+@([\w-]+\.)+[\w-]{2,10}(\sas\s[\w-+.]+@([\w-]+\.)+[\w-]{2,10})?$/.test(email)) {
3187
3197
  const alerts = [];
3188
3198
  if (firstPrompt && initialAlert)
3189
3199
  alerts.push(initialAlert);
@@ -3249,7 +3259,7 @@
3249
3259
  messageParams: {
3250
3260
  currentUserId,
3251
3261
  numUnsyncedChanges: numUnsyncedChanges.toString(),
3252
- }
3262
+ },
3253
3263
  },
3254
3264
  ];
3255
3265
  return yield interactWithUser(userInteraction, {
@@ -3258,7 +3268,7 @@
3258
3268
  alerts,
3259
3269
  fields: {},
3260
3270
  submitLabel: 'Confirm logout',
3261
- cancelLabel: 'Cancel'
3271
+ cancelLabel: 'Cancel',
3262
3272
  })
3263
3273
  .then(() => true)
3264
3274
  .catch(() => false);
@@ -3375,7 +3385,8 @@
3375
3385
  if (!accessToken)
3376
3386
  return null;
3377
3387
  const expTime = (_a = accessTokenExpiration === null || accessTokenExpiration === void 0 ? void 0 : accessTokenExpiration.getTime()) !== null && _a !== void 0 ? _a : Infinity;
3378
- if (expTime > (Date.now() + 5 * MINUTES) && (((_b = currentUser.license) === null || _b === void 0 ? void 0 : _b.status) || 'ok') === 'ok') {
3388
+ if (expTime > Date.now() + 5 * MINUTES &&
3389
+ (((_b = currentUser.license) === null || _b === void 0 ? void 0 : _b.status) || 'ok') === 'ok') {
3379
3390
  return currentUser;
3380
3391
  }
3381
3392
  if (!refreshToken) {
@@ -3535,11 +3546,13 @@
3535
3546
  }
3536
3547
  catch (error) {
3537
3548
  // OAuth redirect is not an error - page is navigating away
3538
- if (error instanceof OAuthRedirectError || (error === null || error === void 0 ? void 0 : error.name) === 'OAuthRedirectError') {
3549
+ if (error instanceof OAuthRedirectError ||
3550
+ (error === null || error === void 0 ? void 0 : error.name) === 'OAuthRedirectError') {
3539
3551
  throw error; // Re-throw without logging
3540
3552
  }
3541
3553
  // Policy rejections have already been shown to the user as a challenge
3542
- if (error instanceof PolicyRejectionError || (error === null || error === void 0 ? void 0 : error.name) === 'PolicyRejectionError') {
3554
+ if (error instanceof PolicyRejectionError ||
3555
+ (error === null || error === void 0 ? void 0 : error.name) === 'PolicyRejectionError') {
3543
3556
  throw error;
3544
3557
  }
3545
3558
  if (error instanceof TokenErrorResponseError) {
@@ -3558,7 +3571,10 @@
3558
3571
  if (isOffline) {
3559
3572
  message = `You seem to be offline. Please connect to the internet and try again.`;
3560
3573
  }
3561
- else if (typeof location !== 'undefined' && (Dexie.debug || location.hostname === 'localhost' || location.hostname === '127.0.0.1')) {
3574
+ else if (typeof location !== 'undefined' &&
3575
+ (Dexie.debug ||
3576
+ location.hostname === 'localhost' ||
3577
+ location.hostname === '127.0.0.1')) {
3562
3578
  // The audience is most likely the developer. Suggest to whitelist the localhost origin:
3563
3579
  const whitelistCommand = `npx dexie-cloud whitelist ${location.origin}`;
3564
3580
  message = `Could not connect to server. Please verify that your origin '${location.origin}' is whitelisted using \`npx dexie-cloud whitelist\``;
@@ -3608,31 +3624,31 @@
3608
3624
  }
3609
3625
  static load(db, userId) {
3610
3626
  return db
3611
- .table("$logins")
3627
+ .table('$logins')
3612
3628
  .get(userId)
3613
3629
  .then((userLogin) => new AuthPersistedContext(db, userLogin || {
3614
3630
  userId,
3615
3631
  claims: {
3616
- sub: userId
3632
+ sub: userId,
3617
3633
  },
3618
- lastLogin: new Date(0)
3634
+ lastLogin: new Date(0),
3619
3635
  }));
3620
3636
  }
3621
3637
  save() {
3622
3638
  return __awaiter(this, void 0, void 0, function* () {
3623
3639
  const db = wm$4.get(this);
3624
- db.table("$logins").put(this);
3640
+ db.table('$logins').put(this);
3625
3641
  });
3626
3642
  }
3627
3643
  }
3628
3644
 
3629
3645
  const UNAUTHORIZED_USER = {
3630
- userId: "unauthorized",
3631
- name: "Unauthorized",
3646
+ userId: 'unauthorized',
3647
+ name: 'Unauthorized',
3632
3648
  claims: {
3633
- sub: "unauthorized",
3649
+ sub: 'unauthorized',
3634
3650
  },
3635
- lastLogin: new Date(0)
3651
+ lastLogin: new Date(0),
3636
3652
  };
3637
3653
  try {
3638
3654
  Object.freeze(UNAUTHORIZED_USER);
@@ -3701,7 +3717,7 @@
3701
3717
  this.httpStatus = res.status;
3702
3718
  }
3703
3719
  get name() {
3704
- return "HttpError";
3720
+ return 'HttpError';
3705
3721
  }
3706
3722
  }
3707
3723
 
@@ -3740,7 +3756,7 @@
3740
3756
  */
3741
3757
  function exchangeOAuthCode(options) {
3742
3758
  return __awaiter(this, void 0, void 0, function* () {
3743
- const { databaseUrl, code, publicKey, scopes = ['ACCESS_DB'], intent } = options;
3759
+ const { databaseUrl, code, publicKey, scopes = ['ACCESS_DB'], intent, } = options;
3744
3760
  const tokenRequest = Object.assign({ grant_type: 'authorization_code', code, public_key: publicKey, scopes }, (intent !== undefined ? { intent } : {}));
3745
3761
  try {
3746
3762
  const res = yield fetch(`${databaseUrl}/token`, {
@@ -3798,7 +3814,8 @@
3798
3814
  return response;
3799
3815
  }
3800
3816
  catch (error) {
3801
- if (error instanceof OAuthError || error instanceof TokenErrorResponseError) {
3817
+ if (error instanceof OAuthError ||
3818
+ error instanceof TokenErrorResponseError) {
3802
3819
  throw error;
3803
3820
  }
3804
3821
  if (error instanceof TypeError) {
@@ -3836,7 +3853,7 @@
3836
3853
  try {
3837
3854
  const res = yield fetch(`${databaseUrl}/auth-providers`, {
3838
3855
  method: 'GET',
3839
- headers: { 'Accept': 'application/json' },
3856
+ headers: { Accept: 'application/json' },
3840
3857
  mode: 'cors',
3841
3858
  });
3842
3859
  if (res.status === 404) {
@@ -4166,7 +4183,7 @@
4166
4183
  * @param args
4167
4184
  */
4168
4185
  function prodLog(level, ...args) {
4169
- globalThis["con" + "sole"][level](...args);
4186
+ globalThis['con' + 'sole'][level](...args);
4170
4187
  }
4171
4188
 
4172
4189
  /** This function changes or sets the current user as requested.
@@ -4278,8 +4295,10 @@
4278
4295
  }
4279
4296
 
4280
4297
  const swHolder = {};
4281
- const swContainer = typeof self !== 'undefined' && self.document && // self.document is to verify we're not the SW ourself
4282
- typeof navigator !== 'undefined' && navigator.serviceWorker;
4298
+ const swContainer = typeof self !== 'undefined' &&
4299
+ self.document && // self.document is to verify we're not the SW ourself
4300
+ typeof navigator !== 'undefined' &&
4301
+ navigator.serviceWorker;
4283
4302
  if (swContainer)
4284
4303
  swContainer.ready.then((registration) => (swHolder.registration = registration));
4285
4304
  if (typeof self !== 'undefined' && 'clients' in self && !self.document) {
@@ -4333,7 +4352,8 @@
4333
4352
  }
4334
4353
  }
4335
4354
 
4336
- const events = globalThis['lbc-events'] || (globalThis['lbc-events'] = new Map());
4355
+ const events = globalThis['lbc-events'] ||
4356
+ (globalThis['lbc-events'] = new Map());
4337
4357
  function addListener(name, listener) {
4338
4358
  if (events.has(name)) {
4339
4359
  events.get(name).push(listener);
@@ -4354,25 +4374,25 @@
4354
4374
  function dispatch(ev) {
4355
4375
  const listeners = events.get(ev.type);
4356
4376
  if (listeners) {
4357
- listeners.forEach(listener => {
4377
+ listeners.forEach((listener) => {
4358
4378
  try {
4359
4379
  listener(ev);
4360
4380
  }
4361
- catch (_a) {
4362
- }
4381
+ catch (_a) { }
4363
4382
  });
4364
4383
  }
4365
4384
  }
4366
4385
  class BroadcastedAndLocalEvent extends rxjs.Observable {
4367
4386
  constructor(name) {
4368
- const bc = typeof BroadcastChannel === "undefined"
4369
- ? new SWBroadcastChannel(name) : new BroadcastChannel(name);
4370
- super(subscriber => {
4387
+ const bc = typeof BroadcastChannel === 'undefined'
4388
+ ? new SWBroadcastChannel(name)
4389
+ : new BroadcastChannel(name);
4390
+ super((subscriber) => {
4371
4391
  function onCustomEvent(ev) {
4372
4392
  subscriber.next(ev.detail);
4373
4393
  }
4374
4394
  function onMessageEvent(ev) {
4375
- console.debug("BroadcastedAndLocalEvent: onMessageEvent", ev);
4395
+ console.debug('BroadcastedAndLocalEvent: onMessageEvent', ev);
4376
4396
  subscriber.next(ev.data);
4377
4397
  }
4378
4398
  let unsubscribe;
@@ -4380,11 +4400,11 @@
4380
4400
  addListener(`lbc-${name}`, onCustomEvent); // Works better in service worker
4381
4401
  try {
4382
4402
  if (bc instanceof SWBroadcastChannel) {
4383
- unsubscribe = bc.subscribe(message => subscriber.next(message));
4403
+ unsubscribe = bc.subscribe((message) => subscriber.next(message));
4384
4404
  }
4385
4405
  else {
4386
- console.debug("BroadcastedAndLocalEvent: bc.addEventListener()", name, "bc is a", bc);
4387
- bc.addEventListener("message", onMessageEvent);
4406
+ console.debug('BroadcastedAndLocalEvent: bc.addEventListener()', name, 'bc is a', bc);
4407
+ bc.addEventListener('message', onMessageEvent);
4388
4408
  }
4389
4409
  }
4390
4410
  catch (err) {
@@ -4398,7 +4418,7 @@
4398
4418
  unsubscribe();
4399
4419
  }
4400
4420
  else {
4401
- bc.removeEventListener("message", onMessageEvent);
4421
+ bc.removeEventListener('message', onMessageEvent);
4402
4422
  }
4403
4423
  };
4404
4424
  });
@@ -4406,7 +4426,7 @@
4406
4426
  this.bc = bc;
4407
4427
  }
4408
4428
  next(message) {
4409
- console.debug("BroadcastedAndLocalEvent: bc.postMessage()", Object.assign({}, message), "bc is a", this.bc);
4429
+ console.debug('BroadcastedAndLocalEvent: bc.postMessage()', Object.assign({}, message), 'bc is a', this.bc);
4410
4430
  this.bc.postMessage(message);
4411
4431
  const ev = new CustomEvent(`lbc-${this.name}`, { detail: message });
4412
4432
  //self.dispatchEvent(ev);
@@ -4499,7 +4519,7 @@
4499
4519
  }
4500
4520
  const strKey = '' + mut.keys[0];
4501
4521
  const changeSpecs = mut.changeSpecs[0];
4502
- if (Object.values(changeSpecs).some(v => typeof v === "object" && v && "@@propmod" in v)) {
4522
+ if (Object.values(changeSpecs).some((v) => typeof v === 'object' && v && '@@propmod' in v)) {
4503
4523
  continue; // Cannot optimize if any PropModification is present
4504
4524
  }
4505
4525
  let keyCoverage = updateCoverage.get(strKey);
@@ -4507,11 +4527,13 @@
4507
4527
  keyCoverage.push({ txid: mut.txid, updateSpec: changeSpecs });
4508
4528
  }
4509
4529
  else {
4510
- updateCoverage.set(strKey, [{ txid: mut.txid, updateSpec: changeSpecs }]);
4530
+ updateCoverage.set(strKey, [
4531
+ { txid: mut.txid, updateSpec: changeSpecs },
4532
+ ]);
4511
4533
  }
4512
4534
  }
4513
4535
  }
4514
- muts = muts.filter(mut => {
4536
+ muts = muts.filter((mut) => {
4515
4537
  // Only apply optimization to update mutations that are single-key
4516
4538
  if (mut.type !== 'update')
4517
4539
  return true;
@@ -4519,7 +4541,7 @@
4519
4541
  return true;
4520
4542
  // Check if this has PropModifications - if so, skip optimization
4521
4543
  const changeSpecs = mut.changeSpecs[0];
4522
- if (Object.values(changeSpecs).some(v => typeof v === "object" && v && "@@propmod" in v)) {
4544
+ if (Object.values(changeSpecs).some((v) => typeof v === 'object' && v && '@@propmod' in v)) {
4523
4545
  return true; // Cannot optimize if any PropModification is present
4524
4546
  }
4525
4547
  // Keep track of properties that aren't overlapped by later transactions
@@ -4547,7 +4569,7 @@
4547
4569
  return muts;
4548
4570
  }
4549
4571
  function canonicalizeToUpdateOps(muts) {
4550
- muts = muts.map(mut => {
4572
+ muts = muts.map((mut) => {
4551
4573
  if (mut.type === 'modify' && mut.criteria.index === null) {
4552
4574
  // The criteria is on primary key. Convert to an update operation instead.
4553
4575
  // It is simpler for the server to handle and also more efficient.
@@ -4769,7 +4791,7 @@
4769
4791
  const delatMilliseconds = ((_b = (_a = syncRatelimitDelays.get(db)) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0) - Date.now();
4770
4792
  if (delatMilliseconds > 0) {
4771
4793
  console.debug(`Stalling sync request ${delatMilliseconds} ms to spare ratelimits`);
4772
- yield new Promise(resolve => setTimeout(resolve, delatMilliseconds));
4794
+ yield new Promise((resolve) => setTimeout(resolve, delatMilliseconds));
4773
4795
  }
4774
4796
  });
4775
4797
  }
@@ -4834,7 +4856,7 @@
4834
4856
  baseRevs,
4835
4857
  changes: encodeIdsForServer(db.dx.core.schema, currentUser, changes),
4836
4858
  y,
4837
- dxcv: db.cloud.version
4859
+ dxcv: db.cloud.version,
4838
4860
  };
4839
4861
  console.debug('Sync request', syncRequest);
4840
4862
  db.syncStateChangedEvent.next({
@@ -4874,19 +4896,22 @@
4874
4896
  return __awaiter(this, void 0, void 0, function* () {
4875
4897
  const ignoredRealms = new Set(alreadySyncedRealms || []);
4876
4898
  for (const table of syncifiedTables) {
4877
- if (table.name === "members") {
4899
+ if (table.name === 'members') {
4878
4900
  // members
4879
4901
  yield table.toCollection().modify((member) => {
4880
- if (!ignoredRealms.has(member.realmId) && (!member.userId || member.userId === UNAUTHORIZED_USER.userId)) {
4902
+ if (!ignoredRealms.has(member.realmId) &&
4903
+ (!member.userId || member.userId === UNAUTHORIZED_USER.userId)) {
4881
4904
  member.userId = currentUser.userId;
4882
4905
  }
4883
4906
  });
4884
4907
  }
4885
- else if (table.name === "roles") ;
4886
- else if (table.name === "realms") {
4908
+ else if (table.name === 'roles') ;
4909
+ else if (table.name === 'realms') {
4887
4910
  // realms
4888
4911
  yield table.toCollection().modify((realm) => {
4889
- if (!ignoredRealms.has(realm.realmId) && (realm.owner === undefined || realm.owner === UNAUTHORIZED_USER.userId)) {
4912
+ if (!ignoredRealms.has(realm.realmId) &&
4913
+ (realm.owner === undefined ||
4914
+ realm.owner === UNAUTHORIZED_USER.userId)) {
4890
4915
  realm.owner = currentUser.userId;
4891
4916
  }
4892
4917
  });
@@ -4919,8 +4944,8 @@
4919
4944
  let isOnline = false;
4920
4945
  if (typeof self !== 'undefined' && typeof navigator !== 'undefined') {
4921
4946
  isOnline = navigator.onLine;
4922
- self.addEventListener('online', () => isOnline = true);
4923
- self.addEventListener('offline', () => isOnline = false);
4947
+ self.addEventListener('online', () => (isOnline = true));
4948
+ self.addEventListener('offline', () => (isOnline = false));
4924
4949
  }
4925
4950
 
4926
4951
  function updateBaseRevs(db, schema, latestRevisions, serverRev) {
@@ -4937,7 +4962,10 @@
4937
4962
  }));
4938
4963
  // Clean up baseRevs for tables that do not exist anymore or are no longer marked for sync
4939
4964
  // Resolve #2168 by also cleaning up baseRevs for tables that are not marked for sync
4940
- yield db.$baseRevs.where('tableName').noneOf(Object.keys(schema).filter((table) => schema[table].markedForSync)).delete();
4965
+ yield db.$baseRevs
4966
+ .where('tableName')
4967
+ .noneOf(Object.keys(schema).filter((table) => schema[table].markedForSync))
4968
+ .delete();
4941
4969
  });
4942
4970
  }
4943
4971
 
@@ -5083,10 +5111,7 @@
5083
5111
  const DEXIE_CLOUD_SYNCER_ID = 'dexie-cloud-syncer';
5084
5112
 
5085
5113
  function listUpdatesSince(yTable, sinceIncluding) {
5086
- return yTable
5087
- .where('i')
5088
- .between(sinceIncluding, Infinity, true)
5089
- .toArray();
5114
+ return yTable.where('i').between(sinceIncluding, Infinity, true).toArray();
5090
5115
  }
5091
5116
 
5092
5117
  /**
@@ -14438,7 +14463,7 @@
14438
14463
  }
14439
14464
  return {
14440
14465
  yMessages: result,
14441
- lastUpdateIds
14466
+ lastUpdateIds,
14442
14467
  };
14443
14468
  });
14444
14469
  }
@@ -14447,7 +14472,8 @@
14447
14472
  var _a, _b, _c;
14448
14473
  if (!db.dx._allTables[table])
14449
14474
  return undefined;
14450
- const utbl = (_c = (_b = (_a = db.table(table)) === null || _a === void 0 ? void 0 : _a.schema.yProps) === null || _b === void 0 ? void 0 : _b.find(p => p.prop === ydocProp)) === null || _c === void 0 ? void 0 : _c.updatesTable;
14475
+ const utbl = (_c = (_b = (_a = db
14476
+ .table(table)) === null || _a === void 0 ? void 0 : _a.schema.yProps) === null || _b === void 0 ? void 0 : _b.find((p) => p.prop === ydocProp)) === null || _c === void 0 ? void 0 : _c.updatesTable;
14451
14477
  if (!utbl) {
14452
14478
  console.debug(`No updatesTable found for ${table}.${ydocProp}`);
14453
14479
  return undefined;
@@ -14467,7 +14493,7 @@
14467
14493
  *
14468
14494
  * ==========================================================================
14469
14495
  *
14470
- * Version 4.4.0, Thu Mar 26 2026
14496
+ * Version 4.4.0, Tue Mar 31 2026
14471
14497
  *
14472
14498
  * https://dexie.org
14473
14499
  *
@@ -14484,7 +14510,7 @@
14484
14510
  function getDocCache(db) {
14485
14511
  var _a;
14486
14512
  var _b;
14487
- return (_a = (_b = db._novip)['_docCache']) !== null && _a !== void 0 ? _a : (_b['_docCache'] = {
14513
+ return ((_a = (_b = db._novip)['_docCache']) !== null && _a !== void 0 ? _a : (_b['_docCache'] = {
14488
14514
  cache: {},
14489
14515
  get size() {
14490
14516
  return Object.keys(this.cache).length;
@@ -14515,7 +14541,7 @@
14515
14541
  delete this.cache[cacheKey]; // Remove the entry from the cache only if it is the same doc.
14516
14542
  }
14517
14543
  },
14518
- });
14544
+ }));
14519
14545
  }
14520
14546
  // Emulate a private boolean property "destroyed" on Y.Doc instances that we manage
14521
14547
  // in createYDocProperty.ts:
@@ -14831,7 +14857,7 @@
14831
14857
  }
14832
14858
  throwIfDestroyed(doc);
14833
14859
  this.stopObserving = observeYDocUpdates(this, doc, db, parentTable, updatesTable, parentId);
14834
- DexieYProvider.on("new").fire(this); // Allow for addons to invoke their sync- and awareness providers here.
14860
+ DexieYProvider.on('new').fire(this); // Allow for addons to invoke their sync- and awareness providers here.
14835
14861
  }
14836
14862
  destroy() {
14837
14863
  var _a, _b, _c;
@@ -14856,16 +14882,16 @@
14856
14882
  });
14857
14883
  DexieYProvider.getDocCache = getDocCache;
14858
14884
  //
14859
- // Eliminate dual package hazard
14885
+ // Eliminate dual package hazard
14860
14886
  //
14861
14887
  // Since we're holding static state, make sure to singletonize DexieYProvider
14862
14888
  //
14863
- if (Dexie.Dexie["DexieYProvider"]) {
14889
+ if (Dexie.Dexie['DexieYProvider']) {
14864
14890
  // @ts-ignore
14865
- DexieYProvider = Dexie.Dexie["DexieYProvider"] || DexieYProvider;
14891
+ DexieYProvider = Dexie.Dexie['DexieYProvider'] || DexieYProvider;
14866
14892
  }
14867
14893
  else {
14868
- Dexie.Dexie["DexieYProvider"] = DexieYProvider;
14894
+ Dexie.Dexie['DexieYProvider'] = DexieYProvider;
14869
14895
  }
14870
14896
 
14871
14897
  function applyYServerMessages(yMessages, db) {
@@ -14991,10 +15017,18 @@
14991
15017
  */
14992
15018
  // TypedArray/DataView tags for size check
14993
15019
  const ARRAYBUFFER_VIEW_TAGS = new Set([
14994
- 'Int8Array', 'Uint8Array', 'Uint8ClampedArray',
14995
- 'Int16Array', 'Uint16Array', 'Int32Array', 'Uint32Array',
14996
- 'Float32Array', 'Float64Array', 'BigInt64Array', 'BigUint64Array',
14997
- 'DataView'
15020
+ 'Int8Array',
15021
+ 'Uint8Array',
15022
+ 'Uint8ClampedArray',
15023
+ 'Int16Array',
15024
+ 'Uint16Array',
15025
+ 'Int32Array',
15026
+ 'Uint32Array',
15027
+ 'Float32Array',
15028
+ 'Float64Array',
15029
+ 'BigInt64Array',
15030
+ 'BigUint64Array',
15031
+ 'DataView',
14998
15032
  ]);
14999
15033
  // Static Set for O(1) lookup of binary type tags
15000
15034
  const BINARY_TYPE_TAGS = new Set([
@@ -15094,7 +15128,7 @@
15094
15128
  const response = yield fetch(uploadUrl, {
15095
15129
  method: 'PUT',
15096
15130
  headers: {
15097
- 'Authorization': `Bearer ${accessToken}`,
15131
+ Authorization: `Bearer ${accessToken}`,
15098
15132
  'Content-Type': contentType,
15099
15133
  },
15100
15134
  body,
@@ -15110,8 +15144,7 @@
15110
15144
  // The server returns the ref with version prefix (e.g., "1:blobId")
15111
15145
  const result = yield response.json();
15112
15146
  // Return BlobRef with server's ref (includes version) and original type preserved in _bt
15113
- return Object.assign({ _bt: origType, ref: result.ref, size: size }, (origType === 'Blob' ? { ct: contentType } : {}) // Only include content type for Blobs
15114
- );
15147
+ return Object.assign({ _bt: origType, ref: result.ref, size: size }, (origType === 'Blob' ? { ct: contentType } : {}));
15115
15148
  });
15116
15149
  }
15117
15150
  function offloadBlobsAndMarkDirty(obj_1, databaseUrl_1, getCachedAccessToken_1) {
@@ -15119,7 +15152,10 @@
15119
15152
  const dirtyFlag = { dirty: false };
15120
15153
  const result = yield offloadBlobs(obj, databaseUrl, getCachedAccessToken, maxStringLength, dirtyFlag);
15121
15154
  // Mark the object as dirty for sync if any blobs were offloaded
15122
- if (dirtyFlag.dirty && typeof result === 'object' && result !== null && result.constructor === Object) {
15155
+ if (dirtyFlag.dirty &&
15156
+ typeof result === 'object' &&
15157
+ result !== null &&
15158
+ result.constructor === Object) {
15123
15159
  result._hasBlobRefs = 1;
15124
15160
  }
15125
15161
  return result;
@@ -15135,7 +15171,9 @@
15135
15171
  return obj;
15136
15172
  }
15137
15173
  // Check if this is a long string that should be offloaded
15138
- if (typeof obj === 'string' && obj.length > maxStringLength && maxStringLength !== Infinity) {
15174
+ if (typeof obj === 'string' &&
15175
+ obj.length > maxStringLength &&
15176
+ maxStringLength !== Infinity) {
15139
15177
  if (blobEndpointSupported.get(databaseUrl) === false) {
15140
15178
  return obj;
15141
15179
  }
@@ -15221,11 +15259,11 @@
15221
15259
  switch (op.type) {
15222
15260
  case 'insert':
15223
15261
  case 'upsert': {
15224
- const processedValues = yield Promise.all(op.values.map(value => offloadBlobsAndMarkDirty(value, databaseUrl, getCachedAccessToken, maxStringLength)));
15262
+ const processedValues = yield Promise.all(op.values.map((value) => offloadBlobsAndMarkDirty(value, databaseUrl, getCachedAccessToken, maxStringLength)));
15225
15263
  return Object.assign(Object.assign({}, op), { values: processedValues });
15226
15264
  }
15227
15265
  case 'update': {
15228
- const processedChangeSpecs = yield Promise.all(op.changeSpecs.map(spec => offloadBlobsAndMarkDirty(spec, databaseUrl, getCachedAccessToken, maxStringLength)));
15266
+ const processedChangeSpecs = yield Promise.all(op.changeSpecs.map((spec) => offloadBlobsAndMarkDirty(spec, databaseUrl, getCachedAccessToken, maxStringLength)));
15229
15267
  return Object.assign(Object.assign({}, op), { changeSpecs: processedChangeSpecs });
15230
15268
  }
15231
15269
  case 'modify': {
@@ -15258,9 +15296,9 @@
15258
15296
  switch (op.type) {
15259
15297
  case 'insert':
15260
15298
  case 'upsert':
15261
- return op.values.some(value => hasLargeBlobs(value, maxStringLength));
15299
+ return op.values.some((value) => hasLargeBlobs(value, maxStringLength));
15262
15300
  case 'update':
15263
- return op.changeSpecs.some(spec => hasLargeBlobs(spec, maxStringLength));
15301
+ return op.changeSpecs.some((spec) => hasLargeBlobs(spec, maxStringLength));
15264
15302
  case 'modify':
15265
15303
  return hasLargeBlobs(op.changeSpec, maxStringLength);
15266
15304
  default:
@@ -15272,7 +15310,9 @@
15272
15310
  return false;
15273
15311
  }
15274
15312
  // Check long strings
15275
- if (typeof obj === 'string' && obj.length > maxStringLength && maxStringLength !== Infinity) {
15313
+ if (typeof obj === 'string' &&
15314
+ obj.length > maxStringLength &&
15315
+ maxStringLength !== Infinity) {
15276
15316
  return true;
15277
15317
  }
15278
15318
  if (shouldOffloadBlob(obj)) {
@@ -15287,13 +15327,13 @@
15287
15327
  }
15288
15328
  visited.add(obj);
15289
15329
  if (Array.isArray(obj)) {
15290
- return obj.some(item => hasLargeBlobs(item, maxStringLength, visited));
15330
+ return obj.some((item) => hasLargeBlobs(item, maxStringLength, visited));
15291
15331
  }
15292
15332
  // Traverse plain objects (POJO-like) - use duck typing since IndexedDB
15293
15333
  // may return objects where constructor !== Object
15294
15334
  const proto = Object.getPrototypeOf(obj);
15295
15335
  if (proto === Object.prototype || proto === null) {
15296
- return Object.values(obj).some(value => hasLargeBlobs(value, maxStringLength, visited));
15336
+ return Object.values(obj).some((value) => hasLargeBlobs(value, maxStringLength, visited));
15297
15337
  }
15298
15338
  return false;
15299
15339
  }
@@ -15347,7 +15387,7 @@
15347
15387
  yield db.table(yTable).add({
15348
15388
  i: DEXIE_CLOUD_SYNCER_ID,
15349
15389
  unsentFrom,
15350
- receivedUntil
15390
+ receivedUntil,
15351
15391
  });
15352
15392
  }
15353
15393
  else {
@@ -15487,19 +15527,30 @@
15487
15527
  return Promise.resolve(cached.accessToken);
15488
15528
  }
15489
15529
  const currentUser = db.cloud.currentUser.value;
15490
- if (currentUser && currentUser.accessToken && ((_b = (_a = currentUser.accessTokenExpiration) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : Infinity) > Date.now() + 5 * MINUTES) {
15530
+ if (currentUser &&
15531
+ currentUser.accessToken &&
15532
+ ((_b = (_a = currentUser.accessTokenExpiration) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : Infinity) >
15533
+ Date.now() + 5 * MINUTES) {
15491
15534
  wm$2.set(db, {
15492
15535
  accessToken: currentUser.accessToken,
15493
- expiration: (_d = (_c = currentUser.accessTokenExpiration) === null || _c === void 0 ? void 0 : _c.getTime()) !== null && _d !== void 0 ? _d : Infinity
15536
+ expiration: (_d = (_c = currentUser.accessTokenExpiration) === null || _c === void 0 ? void 0 : _c.getTime()) !== null && _d !== void 0 ? _d : Infinity,
15494
15537
  });
15495
15538
  return Promise.resolve(currentUser.accessToken);
15496
15539
  }
15497
- return Dexie.ignoreTransaction(() => loadAccessToken(db).then(user => {
15540
+ // If the current user is not logged in (no isLoggedIn flag), there's no
15541
+ // token to load from the database — skip the Dexie.ignoreTransaction() call.
15542
+ // This avoids a crash in service worker context where Dexie's Promise zone
15543
+ // (PSD.transless.env) may be undefined when called from within an active
15544
+ // rw transaction (e.g. during applyServerChanges).
15545
+ if (!(currentUser === null || currentUser === void 0 ? void 0 : currentUser.isLoggedIn)) {
15546
+ return Promise.resolve(null);
15547
+ }
15548
+ return Dexie.ignoreTransaction(() => loadAccessToken(db).then((user) => {
15498
15549
  var _a, _b;
15499
15550
  if (user === null || user === void 0 ? void 0 : user.accessToken) {
15500
15551
  wm$2.set(db, {
15501
15552
  accessToken: user.accessToken,
15502
- expiration: (_b = (_a = user.accessTokenExpiration) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : Infinity
15553
+ expiration: (_b = (_a = user.accessTokenExpiration) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : Infinity,
15503
15554
  });
15504
15555
  }
15505
15556
  return (user === null || user === void 0 ? void 0 : user.accessToken) || null;
@@ -15510,7 +15561,8 @@
15510
15561
  function sync(db, options, schema, syncOptions) {
15511
15562
  return _sync(db, options, schema, syncOptions)
15512
15563
  .then((result) => {
15513
- if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) { // && syncOptions?.purpose !== 'push') {
15564
+ if (!(syncOptions === null || syncOptions === void 0 ? void 0 : syncOptions.justCheckIfNeeded)) {
15565
+ // && syncOptions?.purpose !== 'push') {
15514
15566
  db.syncStateChangedEvent.next({
15515
15567
  phase: 'in-sync',
15516
15568
  });
@@ -15597,7 +15649,7 @@
15597
15649
  const syncState = yield db.getPersistedSyncState();
15598
15650
  let baseRevs = yield db.$baseRevs.toArray();
15599
15651
  // Resolve #2168
15600
- baseRevs = baseRevs.filter(br => tablesToSync.some(tbl => tbl.name === br.tableName));
15652
+ baseRevs = baseRevs.filter((br) => tablesToSync.some((tbl) => tbl.name === br.tableName));
15601
15653
  let clientChanges = yield listClientChanges(mutationTables, db);
15602
15654
  const yResults = yield listYClientMessagesAndStateVector(db, tablesToSync);
15603
15655
  throwIfCancelled(cancelToken);
@@ -15613,7 +15665,7 @@
15613
15665
  }
15614
15666
  return [clientChanges, syncState, baseRevs, yResults];
15615
15667
  }));
15616
- const pushSyncIsNeeded = clientChangeSet.some((set) => set.muts.some((mut) => mut.keys.length > 0)) || yMessages.some(m => m.type === 'u-c');
15668
+ const pushSyncIsNeeded = clientChangeSet.some((set) => set.muts.some((mut) => mut.keys.length > 0)) || yMessages.some((m) => m.type === 'u-c');
15617
15669
  if (justCheckIfNeeded) {
15618
15670
  console.debug('Sync is needed:', pushSyncIsNeeded);
15619
15671
  return pushSyncIsNeeded;
@@ -15757,7 +15809,7 @@
15757
15809
  db.$syncState.put(newSyncState, 'syncState');
15758
15810
  return {
15759
15811
  done: addedClientChanges.length === 0,
15760
- newSyncState
15812
+ newSyncState,
15761
15813
  };
15762
15814
  }));
15763
15815
  if (!done) {
@@ -15765,7 +15817,7 @@
15765
15817
  yield checkSyncRateLimitDelay(db);
15766
15818
  return yield _sync(db, options, schema, { isInitialSync, cancelToken });
15767
15819
  }
15768
- const usingYProps = Object.values(schema).some(tbl => { var _a; return (_a = tbl.yProps) === null || _a === void 0 ? void 0 : _a.length; });
15820
+ const usingYProps = Object.values(schema).some((tbl) => { var _a; return (_a = tbl.yProps) === null || _a === void 0 ? void 0 : _a.length; });
15769
15821
  const serverSupportsYprops = !!res.yMessages;
15770
15822
  if (usingYProps && serverSupportsYprops) {
15771
15823
  try {
@@ -16072,11 +16124,14 @@
16072
16124
  download(blobRef, dbUrl) {
16073
16125
  let promise = this.inFlight.get(blobRef.ref);
16074
16126
  if (!promise) {
16075
- promise = loadCachedAccessToken(this.db).then(accessToken => {
16076
- if (!accessToken)
16077
- throw new Error("No access token available for blob download");
16127
+ promise = loadCachedAccessToken(this.db)
16128
+ .then((accessToken) => {
16129
+ // accessToken may be null for anonymous/unauthenticated users.
16130
+ // Public realm blobs (rlm-public) are accessible without auth.
16131
+ // downloadBlob will omit the Authorization header when token is null.
16078
16132
  return downloadBlob(blobRef, dbUrl, accessToken);
16079
- }).finally(() => this.inFlight.delete(blobRef.ref));
16133
+ })
16134
+ .finally(() => this.inFlight.delete(blobRef.ref));
16080
16135
  // When the promise settles (either fulfilled or rejected), remove it from the in-flight map
16081
16136
  this.inFlight.set(blobRef.ref, promise);
16082
16137
  }
@@ -16086,19 +16141,22 @@
16086
16141
  /**
16087
16142
  * Download blob data from server via proxy endpoint.
16088
16143
  * Uses auth header for authentication (same as sync).
16144
+ * When accessToken is null, the request is made without Authorization header —
16145
+ * this allows downloading blobs from public realms (rlm-public) for
16146
+ * unauthenticated users.
16089
16147
  *
16090
16148
  * @param blobRef - The BlobRef to download
16091
16149
  * @param dbUrl - Base URL for the database (e.g., 'https://mydb.dexie.cloud')
16092
- * @param accessToken - Access token for authentication
16150
+ * @param accessToken - Access token for authentication, or null for anonymous access
16093
16151
  */
16094
16152
  function downloadBlob(blobRef, dbUrl, accessToken) {
16095
16153
  return __awaiter(this, void 0, void 0, function* () {
16096
16154
  const downloadUrl = `${dbUrl}/blob/${blobRef.ref}`;
16097
- const response = yield fetch(downloadUrl, {
16098
- headers: {
16099
- 'Authorization': `Bearer ${accessToken}`
16100
- }
16101
- });
16155
+ const headers = {};
16156
+ if (accessToken) {
16157
+ headers['Authorization'] = `Bearer ${accessToken}`;
16158
+ }
16159
+ const response = yield fetch(downloadUrl, { headers });
16102
16160
  if (!response.ok) {
16103
16161
  throw new Error(`Failed to download blob ${blobRef.ref}: ${response.status} ${response.statusText}`);
16104
16162
  }
@@ -16189,7 +16247,9 @@
16189
16247
  return db.$syncState.get('schema').then((schema) => {
16190
16248
  if (schema) {
16191
16249
  for (const table of db.tables) {
16192
- if (table.schema.primKey && table.schema.primKey.keyPath && schema[table.name]) {
16250
+ if (table.schema.primKey &&
16251
+ table.schema.primKey.keyPath &&
16252
+ schema[table.name]) {
16193
16253
  schema[table.name].primaryKey = nameFromKeyPath(table.schema.primKey.keyPath);
16194
16254
  }
16195
16255
  }
@@ -16217,9 +16277,11 @@
16217
16277
  return db;
16218
16278
  }
16219
16279
  function nameFromKeyPath(keyPath) {
16220
- return typeof keyPath === 'string' ?
16221
- keyPath :
16222
- keyPath ? ('[' + [].join.call(keyPath, '+') + ']') : "";
16280
+ return typeof keyPath === 'string'
16281
+ ? keyPath
16282
+ : keyPath
16283
+ ? '[' + [].join.call(keyPath, '+') + ']'
16284
+ : '';
16223
16285
  }
16224
16286
 
16225
16287
  // @ts-ignore
@@ -16241,7 +16303,7 @@
16241
16303
  const DISABLE_SERVICEWORKER_STRATEGY = (isSafari && safariVersion <= 605) || // Disable for Safari for now.
16242
16304
  isFirefox; // Disable for Firefox for now. Seems to have a bug in reading CryptoKeys from IDB from service workers
16243
16305
 
16244
- const IS_SERVICE_WORKER = typeof self !== "undefined" && "clients" in self && !self.document;
16306
+ const IS_SERVICE_WORKER = typeof self !== 'undefined' && 'clients' in self && !self.document;
16245
16307
 
16246
16308
  function throwVersionIncrementNeeded() {
16247
16309
  throw new Dexie.SchemaError(`Version increment needed to allow dexie-cloud change tracking`);
@@ -16487,7 +16549,7 @@
16487
16549
  // We must also degrade from consistent modify operations for the
16488
16550
  // same reason - object might be there on server. Must but put up instead.
16489
16551
  // FUTURE: This clumpsy behavior of private IDs could be refined later.
16490
- // Suggestion is to in future, treat private IDs as we treat all objects
16552
+ // Suggestion is to in future, treat private IDs as we treat all objects
16491
16553
  // and sync operations normally. Only that deletions should become soft deletes
16492
16554
  // for them - so that server knows when a private ID has been deleted on server
16493
16555
  // not accept insert/upserts on them.
@@ -16510,19 +16572,20 @@
16510
16572
  }
16511
16573
 
16512
16574
  function allSettled(possiblePromises) {
16513
- return new Promise(resolve => {
16575
+ return new Promise((resolve) => {
16514
16576
  if (possiblePromises.length === 0)
16515
16577
  resolve([]);
16516
16578
  let remaining = possiblePromises.length;
16517
16579
  const results = new Array(remaining);
16518
- possiblePromises.forEach((p, i) => Promise.resolve(p).then(value => results[i] = { status: "fulfilled", value }, reason => results[i] = { status: "rejected", reason })
16580
+ possiblePromises.forEach((p, i) => Promise.resolve(p)
16581
+ .then((value) => (results[i] = { status: 'fulfilled', value }), (reason) => (results[i] = { status: 'rejected', reason }))
16519
16582
  .then(() => --remaining || resolve(results)));
16520
16583
  });
16521
16584
  }
16522
16585
 
16523
16586
  let counter$1 = 0;
16524
16587
  function guardedTable(table) {
16525
- const prop = "$lock" + (++counter$1);
16588
+ const prop = '$lock' + ++counter$1;
16526
16589
  return Object.assign(Object.assign({}, table), { count: readLock(table.count, prop), get: readLock(table.get, prop), getMany: readLock(table.getMany, prop), openCursor: readLock(table.openCursor, prop), query: readLock(table.query, prop), mutate: writeLock(table.mutate, prop) });
16527
16590
  }
16528
16591
  function readLock(fn, prop) {
@@ -16531,7 +16594,9 @@
16531
16594
  const numWriters = writers.length;
16532
16595
  const promise = (numWriters > 0
16533
16596
  ? writers[numWriters - 1].then(() => fn(req), () => fn(req))
16534
- : fn(req)).finally(() => { readers.splice(readers.indexOf(promise)); });
16597
+ : fn(req)).finally(() => {
16598
+ readers.splice(readers.indexOf(promise));
16599
+ });
16535
16600
  readers.push(promise);
16536
16601
  return promise;
16537
16602
  };
@@ -16543,7 +16608,9 @@
16543
16608
  ? writers[writers.length - 1].then(() => fn(req), () => fn(req))
16544
16609
  : readers.length > 0
16545
16610
  ? allSettled(readers).then(() => fn(req))
16546
- : fn(req)).finally(() => { writers.shift(); });
16611
+ : fn(req)).finally(() => {
16612
+ writers.shift();
16613
+ });
16547
16614
  writers.push(promise);
16548
16615
  return promise;
16549
16616
  };
@@ -16821,16 +16888,17 @@
16821
16888
  userId,
16822
16889
  values,
16823
16890
  }
16824
- : upsert && updates ? {
16825
- type: 'upsert',
16826
- ts,
16827
- opNo,
16828
- keys,
16829
- values,
16830
- changeSpecs: updates.changeSpecs.filter((_, idx) => !failures[idx]),
16831
- txid,
16832
- userId,
16833
- }
16891
+ : upsert && updates
16892
+ ? {
16893
+ type: 'upsert',
16894
+ ts,
16895
+ opNo,
16896
+ keys,
16897
+ values,
16898
+ changeSpecs: updates.changeSpecs.filter((_, idx) => !failures[idx]),
16899
+ txid,
16900
+ userId,
16901
+ }
16834
16902
  : criteria && changeSpec
16835
16903
  ? {
16836
16904
  // Common changeSpec for all keys
@@ -16943,7 +17011,8 @@
16943
17011
  return;
16944
17012
  }
16945
17013
  // Atomic update of just the blob property
16946
- this.db.transaction('rw', item.tableName, (tx) => {
17014
+ this.db
17015
+ .transaction('rw', item.tableName, (tx) => {
16947
17016
  const trans = tx.idbtrans;
16948
17017
  trans.disableChangeTracking = true; // Don't regard this as a change for sync purposes
16949
17018
  trans.disableAccessControl = true; // Bypass any access control checks since this is an internal operation
@@ -16952,7 +17021,7 @@
16952
17021
  for (const blob of item.resolvedBlobs) {
16953
17022
  updateSpec[blob.keyPath] = blob.data;
16954
17023
  }
16955
- tx.table(item.tableName).update(item.primaryKey, obj => {
17024
+ tx.table(item.tableName).update(item.primaryKey, (obj) => {
16956
17025
  // Check that object still has the same unresolved blob refs before applying update (i.e. it hasn't been modified since we read it)
16957
17026
  for (const blob of item.resolvedBlobs) {
16958
17027
  // Verify atomicity - none of the blob properties has been modified since we read it. If any of them was modified, skip updating this item to avoid overwriting user changes.
@@ -16973,9 +17042,11 @@
16973
17042
  }
16974
17043
  delete obj._hasBlobRefs; // Clear the _hasBlobRefs marker if all refs was resolved.
16975
17044
  });
16976
- }).catch((error) => {
17045
+ })
17046
+ .catch((error) => {
16977
17047
  console.error(`Error saving resolved blobs on ${item.tableName}:${item.primaryKey}:`, error);
16978
- }).finally(() => {
17048
+ })
17049
+ .finally(() => {
16979
17050
  // Process next item in the queue
16980
17051
  return this.processQueue();
16981
17052
  });
@@ -17026,7 +17097,7 @@
17026
17097
  if ((_a = req.trans) === null || _a === void 0 ? void 0 : _a.disableBlobResolve) {
17027
17098
  return downlevelTable.get(req);
17028
17099
  }
17029
- return downlevelTable.get(req).then(result => {
17100
+ return downlevelTable.get(req).then((result) => {
17030
17101
  if (result && hasUnresolvedBlobRefs(result)) {
17031
17102
  return resolveAndSave(downlevelTable, req.trans, req.key, result, blobSavingQueue, db);
17032
17103
  }
@@ -17038,9 +17109,9 @@
17038
17109
  if ((_a = req.trans) === null || _a === void 0 ? void 0 : _a.disableBlobResolve) {
17039
17110
  return downlevelTable.getMany(req);
17040
17111
  }
17041
- return downlevelTable.getMany(req).then(results => {
17112
+ return downlevelTable.getMany(req).then((results) => {
17042
17113
  // Check if any results need resolution
17043
- const needsResolution = results.some(r => r && hasUnresolvedBlobRefs(r));
17114
+ const needsResolution = results.some((r) => r && hasUnresolvedBlobRefs(r));
17044
17115
  if (!needsResolution)
17045
17116
  return results;
17046
17117
  return Dexie.Promise.all(results.map((result, index) => {
@@ -17056,19 +17127,19 @@
17056
17127
  if ((_a = req.trans) === null || _a === void 0 ? void 0 : _a.disableBlobResolve) {
17057
17128
  return downlevelTable.query(req);
17058
17129
  }
17059
- return downlevelTable.query(req).then(result => {
17130
+ return downlevelTable.query(req).then((result) => {
17060
17131
  if (!result.result || !Array.isArray(result.result))
17061
17132
  return result;
17062
17133
  // Check if any results need resolution
17063
- const needsResolution = result.result.some(r => r && hasUnresolvedBlobRefs(r));
17134
+ const needsResolution = result.result.some((r) => r && hasUnresolvedBlobRefs(r));
17064
17135
  if (!needsResolution)
17065
17136
  return result;
17066
- return Dexie.Promise.all(result.result.map(item => {
17137
+ return Dexie.Promise.all(result.result.map((item) => {
17067
17138
  if (item && hasUnresolvedBlobRefs(item)) {
17068
17139
  return resolveAndSave(downlevelTable, req.trans, undefined, item, blobSavingQueue, db);
17069
17140
  }
17070
17141
  return item;
17071
- })).then(resolved => (Object.assign(Object.assign({}, result), { result: resolved })));
17142
+ })).then((resolved) => (Object.assign(Object.assign({}, result), { result: resolved })));
17072
17143
  });
17073
17144
  },
17074
17145
  openCursor(req) {
@@ -17076,7 +17147,7 @@
17076
17147
  if ((_a = req.trans) === null || _a === void 0 ? void 0 : _a.disableBlobResolve) {
17077
17148
  return downlevelTable.openCursor(req);
17078
17149
  }
17079
- return downlevelTable.openCursor(req).then(cursor => {
17150
+ return downlevelTable.openCursor(req).then((cursor) => {
17080
17151
  if (!cursor)
17081
17152
  return cursor; // No results, so no resolution needed
17082
17153
  if (!req.values)
@@ -17106,7 +17177,7 @@
17106
17177
  value: {
17107
17178
  value: cursor.value,
17108
17179
  enumerable: true,
17109
- writable: true
17180
+ writable: true,
17110
17181
  },
17111
17182
  start: {
17112
17183
  value(onNext) {
@@ -17118,17 +17189,17 @@
17118
17189
  onNext();
17119
17190
  return;
17120
17191
  }
17121
- resolveAndSave(table, cursor.trans, cursor.primaryKey, rawValue, blobSavingQueue, db, true).then(resolved => {
17192
+ resolveAndSave(table, cursor.trans, cursor.primaryKey, rawValue, blobSavingQueue, db, true).then((resolved) => {
17122
17193
  wrappedCursor.value = resolved;
17123
17194
  onNext();
17124
- }, err => {
17195
+ }, (err) => {
17125
17196
  console.error('Failed to resolve BlobRefs for cursor value:', err);
17126
17197
  wrappedCursor.value = rawValue;
17127
17198
  onNext();
17128
17199
  });
17129
17200
  });
17130
- }
17131
- }
17201
+ },
17202
+ },
17132
17203
  });
17133
17204
  return wrappedCursor;
17134
17205
  }
@@ -17173,12 +17244,15 @@
17173
17244
  const resolvePromise = needsWaitFor
17174
17245
  ? Dexie.waitFor(resolutionPromise)
17175
17246
  : Dexie.Promise.resolve(resolutionPromise);
17176
- return resolvePromise.then(resolved => {
17247
+ return resolvePromise
17248
+ .then((resolved) => {
17177
17249
  // Get primary key from the object
17178
17250
  const primaryKey = table.schema.primaryKey;
17179
- const key = pKey !== undefined ? pKey : primaryKey.keyPath
17180
- ? Dexie.getByKeyPath(obj, primaryKey.keyPath)
17181
- : undefined;
17251
+ const key = pKey !== undefined
17252
+ ? pKey
17253
+ : primaryKey.keyPath
17254
+ ? Dexie.getByKeyPath(obj, primaryKey.keyPath)
17255
+ : undefined;
17182
17256
  if (key !== undefined) {
17183
17257
  // Queue each resolved blob individually for atomic update
17184
17258
  // This uses setTimeout(fn, 0) to completely isolate from
@@ -17189,13 +17263,16 @@
17189
17263
  else {
17190
17264
  // For rw transactions, we can save directly without queueing
17191
17265
  // since we're still in the same transaction context
17192
- table.mutate({ type: 'put', keys: [key], values: [resolved], trans }).catch(err => {
17266
+ table
17267
+ .mutate({ type: 'put', keys: [key], values: [resolved], trans })
17268
+ .catch((err) => {
17193
17269
  console.error(`Failed to save resolved blob on ${table.name}:${key}:`, err);
17194
17270
  });
17195
17271
  }
17196
17272
  }
17197
17273
  return resolved;
17198
- }).catch(err => {
17274
+ })
17275
+ .catch((err) => {
17199
17276
  console.error(`[dexie-cloud:blobResolve] Failed to resolve BlobRefs on ${table.name}:`, err);
17200
17277
  return obj; // Return original object on error - never block the read pipeline
17201
17278
  });
@@ -17224,9 +17301,13 @@
17224
17301
  return; // Continue
17225
17302
  }
17226
17303
  // They have declared this table. Merge indexes in case they didn't declare all indexes we need.
17227
- const requestedIndexes = schemaSrc.split(',').map(spec => spec.trim());
17228
- const builtInIndexes = DEXIE_CLOUD_SCHEMA[tableName].split(',').map(spec => spec.trim());
17229
- const requestedIndexSet = new Set(requestedIndexes.map(index => index.replace(/([&*]|\+\+)/g, "")));
17304
+ const requestedIndexes = schemaSrc
17305
+ .split(',')
17306
+ .map((spec) => spec.trim());
17307
+ const builtInIndexes = DEXIE_CLOUD_SCHEMA[tableName]
17308
+ .split(',')
17309
+ .map((spec) => spec.trim());
17310
+ const requestedIndexSet = new Set(requestedIndexes.map((index) => index.replace(/([&*]|\+\+)/g, '')));
17230
17311
  // Verify that primary key is unchanged
17231
17312
  if (requestedIndexes[0] !== builtInIndexes[0]) {
17232
17313
  // Primary key must match exactly
@@ -17235,7 +17316,7 @@
17235
17316
  // Merge indexes
17236
17317
  for (let i = 1; i < builtInIndexes.length; ++i) {
17237
17318
  const builtInIndex = builtInIndexes[i];
17238
- if (!requestedIndexSet.has(builtInIndex.replace(/([&*]|\+\+)/g, ""))) {
17319
+ if (!requestedIndexSet.has(builtInIndex.replace(/([&*]|\+\+)/g, ''))) {
17239
17320
  // Add built-in index if not already requested
17240
17321
  storesClone[tableName] += `,${builtInIndex}`;
17241
17322
  }
@@ -17244,7 +17325,7 @@
17244
17325
  // Populate dexie.cloud.schema
17245
17326
  const cloudSchema = dexie.cloud.schema || (dexie.cloud.schema = {});
17246
17327
  const allPrefixes = new Set();
17247
- Object.keys(storesClone).forEach(tableName => {
17328
+ Object.keys(storesClone).forEach((tableName) => {
17248
17329
  var _a;
17249
17330
  const schemaSrc = (_a = storesClone[tableName]) === null || _a === void 0 ? void 0 : _a.trim();
17250
17331
  const cloudTableSchema = cloudSchema[tableName] || (cloudSchema[tableName] = {});
@@ -17373,7 +17454,7 @@
17373
17454
  class TokenExpiredError extends Error {
17374
17455
  constructor() {
17375
17456
  super(...arguments);
17376
- this.name = "TokenExpiredError";
17457
+ this.name = 'TokenExpiredError';
17377
17458
  }
17378
17459
  }
17379
17460
 
@@ -17859,7 +17940,7 @@
17859
17940
  // Connect the WebSocket to given url:
17860
17941
  console.debug('dexie-cloud WebSocket create');
17861
17942
  const ws = (this.ws = new WebSocket(`${wsUrl}/changes?${searchParams}`));
17862
- ws.binaryType = "arraybuffer";
17943
+ ws.binaryType = 'arraybuffer';
17863
17944
  ws.onclose = (event) => {
17864
17945
  if (!this.pinger)
17865
17946
  return;
@@ -17898,10 +17979,17 @@
17898
17979
  getOpenDocSignal(doc).next(); // Make yHandler reopen the document on server.
17899
17980
  }
17900
17981
  }
17901
- else if (msg.type === 'u-ack' || msg.type === 'u-reject' || msg.type === 'u-s' || msg.type === 'in-sync' || msg.type === 'outdated-server-rev' || msg.type === 'y-complete-sync-done') {
17982
+ else if (msg.type === 'u-ack' ||
17983
+ msg.type === 'u-reject' ||
17984
+ msg.type === 'u-s' ||
17985
+ msg.type === 'in-sync' ||
17986
+ msg.type === 'outdated-server-rev' ||
17987
+ msg.type === 'y-complete-sync-done') {
17902
17988
  applyYServerMessages([msg], this.db).then((_a) => __awaiter(this, [_a], void 0, function* ({ resyncNeeded, yServerRevision, receivedUntils }) {
17903
17989
  if (yServerRevision) {
17904
- yield this.db.$syncState.update('syncState', { yServerRevision: yServerRevision });
17990
+ yield this.db.$syncState.update('syncState', {
17991
+ yServerRevision: yServerRevision,
17992
+ });
17905
17993
  }
17906
17994
  if (msg.type === 'u-s' && receivedUntils) {
17907
17995
  const utbl = getUpdatesTable(this.db, msg.table, msg.prop);
@@ -18104,7 +18192,9 @@
18104
18192
  return __awaiter(this, void 0, void 0, function* () {
18105
18193
  var _a;
18106
18194
  return ((_a = db.cloud.options) === null || _a === void 0 ? void 0 : _a.databaseUrl) && db.cloud.schema
18107
- ? yield sync(db, db.cloud.options, db.cloud.schema, { justCheckIfNeeded: true })
18195
+ ? yield sync(db, db.cloud.options, db.cloud.schema, {
18196
+ justCheckIfNeeded: true,
18197
+ })
18108
18198
  : false;
18109
18199
  });
18110
18200
  }
@@ -18316,243 +18406,243 @@
18316
18406
  const Styles = {
18317
18407
  Alert: {
18318
18408
  error: {
18319
- color: "red",
18320
- fontWeight: "bold"
18409
+ color: 'red',
18410
+ fontWeight: 'bold',
18321
18411
  },
18322
18412
  warning: {
18323
- color: "#f80",
18324
- fontWeight: "bold"
18413
+ color: '#f80',
18414
+ fontWeight: 'bold',
18325
18415
  },
18326
18416
  info: {
18327
- color: "black"
18328
- }
18417
+ color: 'black',
18418
+ },
18329
18419
  },
18330
18420
  Darken: {
18331
- position: "fixed",
18421
+ position: 'fixed',
18332
18422
  top: 0,
18333
18423
  left: 0,
18334
18424
  opacity: 0.5,
18335
- backgroundColor: "#000",
18336
- width: "100vw",
18337
- height: "100vh",
18425
+ backgroundColor: '#000',
18426
+ width: '100vw',
18427
+ height: '100vh',
18338
18428
  zIndex: 150,
18339
- webkitBackdropFilter: "blur(2px)",
18340
- backdropFilter: "blur(2px)",
18429
+ webkitBackdropFilter: 'blur(2px)',
18430
+ backdropFilter: 'blur(2px)',
18341
18431
  },
18342
18432
  DialogOuter: {
18343
- position: "fixed",
18433
+ position: 'fixed',
18344
18434
  top: 0,
18345
18435
  left: 0,
18346
- width: "100vw",
18347
- height: "100vh",
18436
+ width: '100vw',
18437
+ height: '100vh',
18348
18438
  zIndex: 150,
18349
- alignItems: "center",
18350
- display: "flex",
18351
- justifyContent: "center",
18352
- padding: "16px",
18353
- boxSizing: "border-box"
18439
+ alignItems: 'center',
18440
+ display: 'flex',
18441
+ justifyContent: 'center',
18442
+ padding: '16px',
18443
+ boxSizing: 'border-box',
18354
18444
  },
18355
18445
  DialogInner: {
18356
- position: "relative",
18357
- color: "#222",
18358
- backgroundColor: "#fff",
18359
- padding: "24px",
18360
- marginBottom: "2em",
18361
- maxWidth: "400px",
18362
- width: "100%",
18363
- maxHeight: "90%",
18364
- overflowY: "auto",
18365
- border: "3px solid #3d3d5d",
18366
- borderRadius: "8px",
18367
- boxShadow: "0 0 80px 10px #666",
18368
- fontFamily: "sans-serif",
18369
- boxSizing: "border-box"
18446
+ position: 'relative',
18447
+ color: '#222',
18448
+ backgroundColor: '#fff',
18449
+ padding: '24px',
18450
+ marginBottom: '2em',
18451
+ maxWidth: '400px',
18452
+ width: '100%',
18453
+ maxHeight: '90%',
18454
+ overflowY: 'auto',
18455
+ border: '3px solid #3d3d5d',
18456
+ borderRadius: '8px',
18457
+ boxShadow: '0 0 80px 10px #666',
18458
+ fontFamily: 'sans-serif',
18459
+ boxSizing: 'border-box',
18370
18460
  },
18371
18461
  Input: {
18372
- height: "35px",
18373
- width: "100%",
18374
- maxWidth: "100%",
18375
- borderColor: "#ccf4",
18376
- outline: "none",
18377
- fontSize: "16px",
18378
- padding: "8px",
18379
- boxSizing: "border-box",
18380
- backgroundColor: "#f9f9f9",
18381
- borderRadius: "4px",
18382
- border: "1px solid #ccc",
18383
- marginTop: "6px",
18384
- fontFamily: "inherit"
18462
+ height: '35px',
18463
+ width: '100%',
18464
+ maxWidth: '100%',
18465
+ borderColor: '#ccf4',
18466
+ outline: 'none',
18467
+ fontSize: '16px',
18468
+ padding: '8px',
18469
+ boxSizing: 'border-box',
18470
+ backgroundColor: '#f9f9f9',
18471
+ borderRadius: '4px',
18472
+ border: '1px solid #ccc',
18473
+ marginTop: '6px',
18474
+ fontFamily: 'inherit',
18385
18475
  },
18386
18476
  Button: {
18387
- padding: "10px 20px",
18388
- margin: "0 4px",
18389
- border: "1px solid #d1d5db",
18390
- borderRadius: "6px",
18391
- backgroundColor: "#ffffff",
18392
- cursor: "pointer",
18393
- fontSize: "14px",
18394
- fontWeight: "500",
18395
- color: "#374151",
18396
- transition: "all 0.2s ease"
18477
+ padding: '10px 20px',
18478
+ margin: '0 4px',
18479
+ border: '1px solid #d1d5db',
18480
+ borderRadius: '6px',
18481
+ backgroundColor: '#ffffff',
18482
+ cursor: 'pointer',
18483
+ fontSize: '14px',
18484
+ fontWeight: '500',
18485
+ color: '#374151',
18486
+ transition: 'all 0.2s ease',
18397
18487
  },
18398
18488
  PrimaryButton: {
18399
- padding: "10px 20px",
18400
- margin: "0 4px",
18401
- border: "1px solid #3b82f6",
18402
- borderRadius: "6px",
18403
- backgroundColor: "#3b82f6",
18404
- color: "white",
18405
- cursor: "pointer",
18406
- fontSize: "14px",
18407
- fontWeight: "500",
18408
- transition: "all 0.2s ease"
18489
+ padding: '10px 20px',
18490
+ margin: '0 4px',
18491
+ border: '1px solid #3b82f6',
18492
+ borderRadius: '6px',
18493
+ backgroundColor: '#3b82f6',
18494
+ color: 'white',
18495
+ cursor: 'pointer',
18496
+ fontSize: '14px',
18497
+ fontWeight: '500',
18498
+ transition: 'all 0.2s ease',
18409
18499
  },
18410
18500
  ButtonsDiv: {
18411
- display: "flex",
18412
- justifyContent: "flex-end",
18413
- gap: "12px",
18414
- marginTop: "24px",
18415
- paddingTop: "20px"
18501
+ display: 'flex',
18502
+ justifyContent: 'flex-end',
18503
+ gap: '12px',
18504
+ marginTop: '24px',
18505
+ paddingTop: '20px',
18416
18506
  },
18417
18507
  Label: {
18418
- display: "block",
18419
- marginBottom: "12px",
18420
- fontSize: "14px",
18421
- fontWeight: "500",
18422
- color: "#333"
18508
+ display: 'block',
18509
+ marginBottom: '12px',
18510
+ fontSize: '14px',
18511
+ fontWeight: '500',
18512
+ color: '#333',
18423
18513
  },
18424
18514
  WindowHeader: {
18425
- margin: "0 0 20px 0",
18426
- fontSize: "18px",
18427
- fontWeight: "600",
18428
- color: "#333",
18429
- borderBottom: "1px solid #eee",
18430
- paddingBottom: "10px"
18515
+ margin: '0 0 20px 0',
18516
+ fontSize: '18px',
18517
+ fontWeight: '600',
18518
+ color: '#333',
18519
+ borderBottom: '1px solid #eee',
18520
+ paddingBottom: '10px',
18431
18521
  },
18432
18522
  // OAuth Provider Button Styles
18433
18523
  ProviderButton: {
18434
- display: "flex",
18435
- alignItems: "center",
18436
- justifyContent: "center",
18437
- width: "100%",
18438
- padding: "12px 16px",
18439
- marginBottom: "10px",
18440
- border: "1px solid #d1d5db",
18441
- borderRadius: "6px",
18442
- backgroundColor: "#ffffff",
18443
- cursor: "pointer",
18444
- fontSize: "14px",
18445
- fontWeight: "500",
18446
- color: "#374151",
18447
- transition: "all 0.2s ease",
18448
- gap: "12px"
18524
+ display: 'flex',
18525
+ alignItems: 'center',
18526
+ justifyContent: 'center',
18527
+ width: '100%',
18528
+ padding: '12px 16px',
18529
+ marginBottom: '10px',
18530
+ border: '1px solid #d1d5db',
18531
+ borderRadius: '6px',
18532
+ backgroundColor: '#ffffff',
18533
+ cursor: 'pointer',
18534
+ fontSize: '14px',
18535
+ fontWeight: '500',
18536
+ color: '#374151',
18537
+ transition: 'all 0.2s ease',
18538
+ gap: '12px',
18449
18539
  },
18450
18540
  ProviderButtonIcon: {
18451
- width: "20px",
18452
- height: "20px",
18541
+ width: '20px',
18542
+ height: '20px',
18453
18543
  flexShrink: 0,
18454
- display: "flex",
18455
- alignItems: "center",
18456
- justifyContent: "center"
18544
+ display: 'flex',
18545
+ alignItems: 'center',
18546
+ justifyContent: 'center',
18457
18547
  },
18458
18548
  ProviderButtonText: {
18459
18549
  flex: 1,
18460
- textAlign: "left"
18550
+ textAlign: 'left',
18461
18551
  },
18462
18552
  // Provider-specific colors
18463
18553
  ProviderGoogle: {
18464
- backgroundColor: "#ffffff",
18465
- border: "1px solid #dadce0",
18466
- color: "#3c4043"
18554
+ backgroundColor: '#ffffff',
18555
+ border: '1px solid #dadce0',
18556
+ color: '#3c4043',
18467
18557
  },
18468
18558
  ProviderGitHub: {
18469
- backgroundColor: "#ffffff",
18470
- border: "1px solid #dadce0",
18471
- color: "#181717"
18559
+ backgroundColor: '#ffffff',
18560
+ border: '1px solid #dadce0',
18561
+ color: '#181717',
18472
18562
  },
18473
18563
  ProviderMicrosoft: {
18474
- backgroundColor: "#ffffff",
18475
- border: "1px solid #dadce0",
18476
- color: "#5e5e5e"
18564
+ backgroundColor: '#ffffff',
18565
+ border: '1px solid #dadce0',
18566
+ color: '#5e5e5e',
18477
18567
  },
18478
18568
  ProviderApple: {
18479
- backgroundColor: "#000000",
18480
- border: "1px solid #000000",
18481
- color: "#ffffff"
18569
+ backgroundColor: '#000000',
18570
+ border: '1px solid #000000',
18571
+ color: '#ffffff',
18482
18572
  },
18483
18573
  ProviderCustom: {
18484
- backgroundColor: "#ffffff",
18485
- border: "1px solid #dadce0",
18486
- color: "#181717"
18574
+ backgroundColor: '#ffffff',
18575
+ border: '1px solid #dadce0',
18576
+ color: '#181717',
18487
18577
  },
18488
18578
  // Divider styles
18489
18579
  Divider: {
18490
- display: "flex",
18491
- alignItems: "center",
18492
- margin: "20px 0",
18493
- color: "#6b7280",
18494
- fontSize: "13px"
18580
+ display: 'flex',
18581
+ alignItems: 'center',
18582
+ margin: '20px 0',
18583
+ color: '#6b7280',
18584
+ fontSize: '13px',
18495
18585
  },
18496
18586
  DividerLine: {
18497
18587
  flex: 1,
18498
- height: "1px",
18499
- backgroundColor: "#e5e7eb"
18588
+ height: '1px',
18589
+ backgroundColor: '#e5e7eb',
18500
18590
  },
18501
18591
  DividerText: {
18502
- padding: "0 12px",
18503
- color: "#9ca3af"
18592
+ padding: '0 12px',
18593
+ color: '#9ca3af',
18504
18594
  },
18505
18595
  // OTP Button (Continue with email)
18506
18596
  OtpButton: {
18507
- display: "flex",
18508
- alignItems: "center",
18509
- justifyContent: "center",
18510
- width: "100%",
18511
- padding: "12px 16px",
18512
- border: "1px solid #d1d5db",
18513
- borderRadius: "6px",
18514
- backgroundColor: "#f9fafb",
18515
- cursor: "pointer",
18516
- fontSize: "14px",
18517
- fontWeight: "500",
18518
- color: "#374151",
18519
- transition: "all 0.2s ease",
18520
- gap: "12px"
18597
+ display: 'flex',
18598
+ alignItems: 'center',
18599
+ justifyContent: 'center',
18600
+ width: '100%',
18601
+ padding: '12px 16px',
18602
+ border: '1px solid #d1d5db',
18603
+ borderRadius: '6px',
18604
+ backgroundColor: '#f9fafb',
18605
+ cursor: 'pointer',
18606
+ fontSize: '14px',
18607
+ fontWeight: '500',
18608
+ color: '#374151',
18609
+ transition: 'all 0.2s ease',
18610
+ gap: '12px',
18521
18611
  },
18522
18612
  // Copy button for alerts with copyText
18523
18613
  CopyButton: {
18524
- display: "inline-flex",
18525
- alignItems: "center",
18526
- gap: "4px",
18527
- padding: "4px 10px",
18528
- marginTop: "8px",
18529
- border: "1px solid #d1d5db",
18530
- borderRadius: "4px",
18531
- backgroundColor: "#f9fafb",
18532
- cursor: "pointer",
18533
- fontSize: "12px",
18534
- fontWeight: "500",
18535
- color: "#374151",
18536
- transition: "all 0.15s ease",
18537
- fontFamily: "monospace"
18614
+ display: 'inline-flex',
18615
+ alignItems: 'center',
18616
+ gap: '4px',
18617
+ padding: '4px 10px',
18618
+ marginTop: '8px',
18619
+ border: '1px solid #d1d5db',
18620
+ borderRadius: '4px',
18621
+ backgroundColor: '#f9fafb',
18622
+ cursor: 'pointer',
18623
+ fontSize: '12px',
18624
+ fontWeight: '500',
18625
+ color: '#374151',
18626
+ transition: 'all 0.15s ease',
18627
+ fontFamily: 'monospace',
18538
18628
  },
18539
18629
  CopyButtonCopied: {
18540
- display: "inline-flex",
18541
- alignItems: "center",
18542
- gap: "4px",
18543
- padding: "4px 10px",
18544
- marginTop: "8px",
18545
- border: "1px solid #22c55e",
18546
- borderRadius: "4px",
18547
- backgroundColor: "#f0fdf4",
18548
- cursor: "default",
18549
- fontSize: "12px",
18550
- fontWeight: "500",
18551
- color: "#16a34a",
18552
- fontFamily: "monospace"
18630
+ display: 'inline-flex',
18631
+ alignItems: 'center',
18632
+ gap: '4px',
18633
+ padding: '4px 10px',
18634
+ marginTop: '8px',
18635
+ border: '1px solid #22c55e',
18636
+ borderRadius: '4px',
18637
+ backgroundColor: '#f0fdf4',
18638
+ cursor: 'default',
18639
+ fontSize: '12px',
18640
+ fontWeight: '500',
18641
+ color: '#16a34a',
18642
+ fontFamily: 'monospace',
18553
18643
  }};
18554
18644
 
18555
- function Dialog({ children, className }) {
18645
+ function Dialog({ children, className, }) {
18556
18646
  return (_$1("div", { className: `dexie-dialog ${className || ''}` },
18557
18647
  _$1("div", { style: Styles.Darken }),
18558
18648
  _$1("div", { style: Styles.DialogOuter },
@@ -18576,7 +18666,7 @@
18576
18666
  * @returns A final message where parameters have been replaced with values.
18577
18667
  */
18578
18668
  function resolveText({ message, messageCode, messageParams }) {
18579
- return message.replace(/\{\w+\}/ig, n => messageParams[n.substring(1, n.length - 1)]);
18669
+ return message.replace(/\{\w+\}/gi, (n) => messageParams[n.substring(1, n.length - 1)]);
18580
18670
  }
18581
18671
 
18582
18672
  /** Get style based on styleHint (for provider branding, etc.) */
@@ -18663,13 +18753,13 @@
18663
18753
  alerts.map((alert, idx) => (_$1("div", { key: idx },
18664
18754
  _$1("p", { style: Styles.Alert[alert.type] }, resolveText(alert)),
18665
18755
  alert.copyText && _$1(CopyButton, { text: alert.copyText })))),
18666
- hasOptions && (_$1("div", { class: "dxc-options" }, hasMultipleGroups ? (
18667
- // Render with dividers between groups
18668
- Array.from(optionGroups.entries()).map(([groupName, groupOptions], groupIdx) => (_$1(k$1, { key: groupName },
18669
- groupIdx > 0 && _$1(Divider, null),
18670
- groupOptions.map((option) => (_$1(OptionButton, { key: `${option.name}-${option.value}`, option: option, onClick: () => handleOptionClick(option) }))))))) : (
18671
- // Simple case: all options in one group
18672
- options.map((option) => (_$1(OptionButton, { key: `${option.name}-${option.value}`, option: option, onClick: () => handleOptionClick(option) })))))),
18756
+ hasOptions && (_$1("div", { class: "dxc-options" }, hasMultipleGroups
18757
+ ? // Render with dividers between groups
18758
+ Array.from(optionGroups.entries()).map(([groupName, groupOptions], groupIdx) => (_$1(k$1, { key: groupName },
18759
+ groupIdx > 0 && _$1(Divider, null),
18760
+ groupOptions.map((option) => (_$1(OptionButton, { key: `${option.name}-${option.value}`, option: option, onClick: () => handleOptionClick(option) }))))))
18761
+ : // Simple case: all options in one group
18762
+ options.map((option) => (_$1(OptionButton, { key: `${option.name}-${option.value}`, option: option, onClick: () => handleOptionClick(option) }))))),
18673
18763
  hasOptions && hasFields && _$1(Divider, null),
18674
18764
  hasFields && (_$1("form", { onSubmit: (ev) => {
18675
18765
  ev.preventDefault();
@@ -18681,7 +18771,8 @@
18681
18771
  const value = valueTransformer(type, (_a = ev.target) === null || _a === void 0 ? void 0 : _a['value']);
18682
18772
  let updatedParams = Object.assign(Object.assign({}, params), { [fieldName]: value });
18683
18773
  setParams(updatedParams);
18684
- if (type === 'otp' && (value === null || value === void 0 ? void 0 : value.trim().length) === OTP_LENGTH) {
18774
+ if (type === 'otp' &&
18775
+ (value === null || value === void 0 ? void 0 : value.trim().length) === OTP_LENGTH) {
18685
18776
  // Auto-submit when OTP is filled in.
18686
18777
  onSubmit(updatedParams);
18687
18778
  }
@@ -18723,7 +18814,10 @@
18723
18814
  const handleClick = () => {
18724
18815
  var _a;
18725
18816
  if (typeof navigator !== 'undefined' && ((_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.writeText)) {
18726
- navigator.clipboard.writeText(text).then(scheduleCopiedReset).catch(() => {
18817
+ navigator.clipboard
18818
+ .writeText(text)
18819
+ .then(scheduleCopiedReset)
18820
+ .catch(() => {
18727
18821
  fallbackCopy(text, scheduleCopiedReset);
18728
18822
  });
18729
18823
  }
@@ -18794,7 +18888,7 @@
18794
18888
  },
18795
18889
  get closed() {
18796
18890
  return closed;
18797
- }
18891
+ },
18798
18892
  };
18799
18893
  }
18800
18894
 
@@ -18839,14 +18933,14 @@
18839
18933
  lazyWebSocketStatus,
18840
18934
  db.syncStateChangedEvent.pipe(operators.startWith({ phase: 'initial' })),
18841
18935
  getCurrentUserEmitter(db.dx._novip),
18842
- userIsReallyActive
18936
+ userIsReallyActive,
18843
18937
  ]).pipe(operators.map(([status, syncState, user, userIsActive]) => {
18844
18938
  var _a;
18845
18939
  if (((_a = user.license) === null || _a === void 0 ? void 0 : _a.status) && user.license.status !== 'ok') {
18846
18940
  return {
18847
18941
  phase: 'offline',
18848
18942
  status: 'offline',
18849
- license: user.license.status
18943
+ license: user.license.status,
18850
18944
  };
18851
18945
  }
18852
18946
  let { phase, error, progress } = syncState;
@@ -18866,7 +18960,8 @@
18866
18960
  }
18867
18961
  const previousPhase = db.cloud.syncState.value.phase;
18868
18962
  //const previousStatus = db.cloud.syncState.value.status;
18869
- if (previousPhase === 'error' && (syncState.phase === 'pushing' || syncState.phase === 'pulling')) {
18963
+ if (previousPhase === 'error' &&
18964
+ (syncState.phase === 'pushing' || syncState.phase === 'pulling')) {
18870
18965
  // We were in an errored state but is now doing sync. Show "connecting" icon.
18871
18966
  adjustedStatus = 'connecting';
18872
18967
  }
@@ -18881,7 +18976,7 @@
18881
18976
  error,
18882
18977
  progress,
18883
18978
  status: isOnline ? adjustedStatus : 'offline',
18884
- license: 'ok'
18979
+ license: 'ok',
18885
18980
  };
18886
18981
  return retState;
18887
18982
  }));
@@ -18902,7 +18997,7 @@
18902
18997
  },
18903
18998
  complete() {
18904
18999
  observer.complete();
18905
- }
19000
+ },
18906
19001
  });
18907
19002
  if (!didEmit && !subscription.closed) {
18908
19003
  observer.next(currentValue);
@@ -19143,7 +19238,9 @@
19143
19238
  const realm = permissionsLookup[realmId || dexie.cloud.currentUserId];
19144
19239
  if (!realm)
19145
19240
  return new PermissionChecker({}, tableName, !owner || owner === dexie.cloud.currentUserId);
19146
- return new PermissionChecker(realm.permissions, tableName, realmId === undefined || realmId === dexie.cloud.currentUserId || owner === dexie.cloud.currentUserId);
19241
+ return new PermissionChecker(realm.permissions, tableName, realmId === undefined ||
19242
+ realmId === dexie.cloud.currentUserId ||
19243
+ owner === dexie.cloud.currentUserId);
19147
19244
  };
19148
19245
  const o = source.pipe(operators.map(mapper));
19149
19246
  o.getValue = () => mapper(source.getValue());
@@ -19185,7 +19282,19 @@
19185
19282
  return; // The table that holds the doc is not marked for sync - leave it to dexie. No syncing, no awareness.
19186
19283
  }
19187
19284
  let awareness;
19285
+ const existingDescriptor = Object.getOwnPropertyDescriptor(provider, 'awareness');
19286
+ if (existingDescriptor) {
19287
+ // Provider already initialized — likely a leaked handler from a previous db instance
19288
+ // (e.g. HMR where db.close() didn't fire). Destroy the stale awareness so the new
19289
+ // handler can take over cleanly.
19290
+ const staleAwareness = provider.awareness;
19291
+ if (staleAwareness) {
19292
+ staleAwareness.destroy();
19293
+ awarenessWeakMap.delete(doc);
19294
+ }
19295
+ }
19188
19296
  Object.defineProperty(provider, 'awareness', {
19297
+ configurable: true,
19189
19298
  get() {
19190
19299
  if (awareness)
19191
19300
  return awareness;
@@ -19368,10 +19477,12 @@
19368
19477
  const { code, provider, state, error } = payload;
19369
19478
  // Check for error first
19370
19479
  if (error) {
19371
- if (error.toLowerCase().includes('access_denied') || error.toLowerCase().includes('access denied')) {
19480
+ if (error.toLowerCase().includes('access_denied') ||
19481
+ error.toLowerCase().includes('access denied')) {
19372
19482
  throw new OAuthError('access_denied', provider, error);
19373
19483
  }
19374
- if (error.toLowerCase().includes('email') && error.toLowerCase().includes('verif')) {
19484
+ if (error.toLowerCase().includes('email') &&
19485
+ error.toLowerCase().includes('verif')) {
19375
19486
  throw new OAuthError('email_not_verified', provider, error);
19376
19487
  }
19377
19488
  throw new OAuthError('provider_error', provider, error);
@@ -19397,7 +19508,9 @@
19397
19508
  return;
19398
19509
  }
19399
19510
  url.searchParams.delete('dxc-auth');
19400
- const cleanUrl = url.pathname + (url.searchParams.toString() ? `?${url.searchParams.toString()}` : '') + url.hash;
19511
+ const cleanUrl = url.pathname +
19512
+ (url.searchParams.toString() ? `?${url.searchParams.toString()}` : '') +
19513
+ url.hash;
19401
19514
  window.history.replaceState(null, '', cleanUrl);
19402
19515
  }
19403
19516
 
@@ -19410,8 +19523,8 @@
19410
19523
 
19411
19524
  const ydocTriggers = {};
19412
19525
  const middlewares = new WeakMap();
19413
- const txRunner = TriggerRunner("tx"); // Trigger registry for transaction completion. Avoids open docs.
19414
- const unloadRunner = TriggerRunner("unload"); // Trigger registry for unload. Runs when a document is closed.
19526
+ const txRunner = TriggerRunner('tx'); // Trigger registry for transaction completion. Avoids open docs.
19527
+ const unloadRunner = TriggerRunner('unload'); // Trigger registry for unload. Runs when a document is closed.
19415
19528
  function TriggerRunner(name) {
19416
19529
  let triggerExecPromise = null;
19417
19530
  let triggerScheduled = false;
@@ -19450,7 +19563,7 @@
19450
19563
  yield triggerExecPromise.catch(() => { });
19451
19564
  setTimeout(() => {
19452
19565
  // setTimeout() is to escape from Promise.PSD zones and never run within liveQueries or transaction scopes
19453
- console.log("Running trigger really!", name);
19566
+ console.log('Running trigger really!', name);
19454
19567
  triggerScheduled = false;
19455
19568
  const registryCopy = registry;
19456
19569
  registry = new Map();
@@ -19617,7 +19730,7 @@
19617
19730
  const downloading$ = createDownloadingState();
19618
19731
  dexie.cloud = {
19619
19732
  // @ts-ignore
19620
- version: "4.4.6",
19733
+ version: "4.4.8",
19621
19734
  options: Object.assign({}, DEFAULT_OPTIONS),
19622
19735
  schema: null,
19623
19736
  get currentUserId() {
@@ -19673,7 +19786,10 @@
19673
19786
  const callback = parseOAuthCallback();
19674
19787
  if (callback) {
19675
19788
  // Store the pending auth code for processing when db is ready
19676
- pendingOAuthCode = { code: callback.code, provider: callback.provider };
19789
+ pendingOAuthCode = {
19790
+ code: callback.code,
19791
+ provider: callback.provider,
19792
+ };
19677
19793
  console.debug('[dexie-cloud] OAuth callback detected, auth code stored for processing');
19678
19794
  }
19679
19795
  }
@@ -19790,7 +19906,7 @@
19790
19906
  if (eagerBlobDownloadInFlight)
19791
19907
  return;
19792
19908
  eagerBlobDownloadInFlight = Dexie.ignoreTransaction(() => downloadUnresolvedBlobs(db, downloading$))
19793
- .catch(err => {
19909
+ .catch((err) => {
19794
19910
  console.error('[dexie-cloud] Eager blob download failed:', err);
19795
19911
  })
19796
19912
  .finally(() => {
@@ -19883,7 +19999,10 @@
19883
19999
  // Let's assign all props as the newPersistedSchems should be what we should be working with.
19884
20000
  Object.assign(schema, newPersistedSchema);
19885
20001
  }
19886
- return [persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.initiallySynced, persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.realms];
20002
+ return [
20003
+ persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.initiallySynced,
20004
+ persistedSyncState === null || persistedSyncState === void 0 ? void 0 : persistedSyncState.realms,
20005
+ ];
19887
20006
  }));
19888
20007
  if (initiallySynced) {
19889
20008
  db.setInitiallySynced(true);
@@ -19892,8 +20011,10 @@
19892
20011
  // Manage CurrentUser observable:
19893
20012
  throwIfClosed();
19894
20013
  if (!db.cloud.isServiceWorkerDB) {
19895
- subscriptions.push(Dexie.liveQuery(() => db.getCurrentUser().then(user => {
19896
- if (!user.isLoggedIn && typeof location !== 'undefined' && /dxc-auth\=/.test(location.search)) {
20014
+ subscriptions.push(Dexie.liveQuery(() => db.getCurrentUser().then((user) => {
20015
+ if (!user.isLoggedIn &&
20016
+ typeof location !== 'undefined' &&
20017
+ /dxc-auth\=/.test(location.search)) {
19897
20018
  // Still loading user because OAuth redirect just happened.
19898
20019
  // Keep isLoading true.
19899
20020
  return Object.assign(Object.assign({}, user), { isLoading: true });
@@ -19931,7 +20052,7 @@
19931
20052
  type: 'error',
19932
20053
  messageCode: 'GENERIC_ERROR',
19933
20054
  message: error.message,
19934
- messageParams: { provider: error.provider || 'unknown' }
20055
+ messageParams: { provider: error.provider || 'unknown' },
19935
20056
  });
19936
20057
  // Clean up URL (remove dxc-auth param)
19937
20058
  cleanupOAuthUrl();
@@ -19981,7 +20102,8 @@
19981
20102
  }
19982
20103
  }
19983
20104
  }
19984
- if (user.isLoggedIn && (!lastSyncedRealms || !lastSyncedRealms.includes(user.userId))) {
20105
+ if (user.isLoggedIn &&
20106
+ (!lastSyncedRealms || !lastSyncedRealms.includes(user.userId))) {
19985
20107
  // User has been logged in but this is not reflected in the sync state.
19986
20108
  // This can happen if page is reloaded after login but before the sync call following
19987
20109
  // the login was complete.
@@ -20044,7 +20166,7 @@
20044
20166
  }
20045
20167
  }
20046
20168
  // @ts-ignore
20047
- dexieCloud.version = "4.4.6";
20169
+ dexieCloud.version = "4.4.8";
20048
20170
  Dexie.Cloud = dexieCloud;
20049
20171
 
20050
20172
  exports.default = dexieCloud;