@rocicorp/zero 0.24.2025091100 → 0.24.2025091200

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 (109) hide show
  1. package/out/{chunk-V2KPKXLX.js → chunk-6XNI6IVJ.js} +217 -133
  2. package/out/chunk-6XNI6IVJ.js.map +7 -0
  3. package/out/chunk-ASRS2LFV.js +35 -0
  4. package/out/chunk-ASRS2LFV.js.map +7 -0
  5. package/out/{chunk-MLYQCVBG.js → chunk-K5ZSWG54.js} +324 -318
  6. package/out/chunk-K5ZSWG54.js.map +7 -0
  7. package/out/{chunk-FH5Q72JS.js → chunk-KXV3BZ4U.js} +3 -3
  8. package/out/{inspector-NC6TPMRA.js → inspector-ZZSIUMBB.js} +36 -6
  9. package/out/inspector-ZZSIUMBB.js.map +7 -0
  10. package/out/react-native.js +276 -278
  11. package/out/react-native.js.map +4 -4
  12. package/out/react.js +13 -25
  13. package/out/react.js.map +2 -2
  14. package/out/replicache/src/deleted-clients.d.ts +17 -10
  15. package/out/replicache/src/deleted-clients.d.ts.map +1 -1
  16. package/out/replicache/src/kv/expo-sqlite/store.d.ts +11 -0
  17. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -0
  18. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  19. package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
  20. package/out/replicache/src/kv/op-sqlite/store.d.ts +14 -0
  21. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -0
  22. package/out/replicache/src/kv/op-sqlite/types.d.ts +13 -0
  23. package/out/replicache/src/kv/op-sqlite/types.d.ts.map +1 -0
  24. package/out/replicache/src/kv/read-impl.d.ts.map +1 -1
  25. package/out/replicache/src/kv/sqlite-store.d.ts +37 -63
  26. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  27. package/out/replicache/src/kv/throw-if-closed.d.ts +12 -0
  28. package/out/replicache/src/kv/throw-if-closed.d.ts.map +1 -0
  29. package/out/replicache/src/kv/write-impl-base.d.ts.map +1 -1
  30. package/out/replicache/src/kv/write-impl.d.ts.map +1 -1
  31. package/out/replicache/src/persist/client-gc.d.ts.map +1 -1
  32. package/out/replicache/src/persist/client-group-gc.d.ts +2 -3
  33. package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
  34. package/out/replicache/src/persist/clients.d.ts +2 -1
  35. package/out/replicache/src/persist/clients.d.ts.map +1 -1
  36. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  37. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  38. package/out/solid.js +4 -4
  39. package/out/zero/package.json +1 -1
  40. package/out/zero/src/zero-cache-dev.js +4 -0
  41. package/out/zero/src/zero-cache-dev.js.map +1 -1
  42. package/out/zero-cache/src/config/normalize.d.ts +1 -0
  43. package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
  44. package/out/zero-cache/src/config/normalize.js +6 -0
  45. package/out/zero-cache/src/config/normalize.js.map +1 -1
  46. package/out/zero-cache/src/config/zero-config.d.ts +3 -0
  47. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  48. package/out/zero-cache/src/config/zero-config.js +35 -1
  49. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  50. package/out/zero-cache/src/server/inspector-delegate.d.ts +9 -0
  51. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  52. package/out/zero-cache/src/server/inspector-delegate.js +18 -0
  53. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  54. package/out/zero-cache/src/server/syncer.js +2 -2
  55. package/out/zero-cache/src/server/syncer.js.map +1 -1
  56. package/out/zero-cache/src/services/analyze.d.ts +1 -1
  57. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  58. package/out/zero-cache/src/services/analyze.js +6 -6
  59. package/out/zero-cache/src/services/analyze.js.map +1 -1
  60. package/out/zero-cache/src/services/heapz.d.ts +1 -1
  61. package/out/zero-cache/src/services/heapz.d.ts.map +1 -1
  62. package/out/zero-cache/src/services/heapz.js +2 -2
  63. package/out/zero-cache/src/services/heapz.js.map +1 -1
  64. package/out/zero-cache/src/services/mutagen/pusher.d.ts +8 -0
  65. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  66. package/out/zero-cache/src/services/statz.d.ts +1 -1
  67. package/out/zero-cache/src/services/statz.d.ts.map +1 -1
  68. package/out/zero-cache/src/services/statz.js +3 -3
  69. package/out/zero-cache/src/services/statz.js.map +1 -1
  70. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -1
  71. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  72. package/out/zero-cache/src/services/view-syncer/view-syncer.js +29 -1
  73. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  74. package/out/zero-client/src/client/active-clients-manager.d.ts +2 -1
  75. package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
  76. package/out/zero-client/src/client/delete-clients-manager.d.ts +3 -3
  77. package/out/zero-client/src/client/delete-clients-manager.d.ts.map +1 -1
  78. package/out/zero-client/src/client/inspector/inspector.d.ts.map +1 -1
  79. package/out/zero-client/src/client/zero.d.ts +2 -2
  80. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  81. package/out/zero-protocol/src/down.d.ts +5 -0
  82. package/out/zero-protocol/src/down.d.ts.map +1 -1
  83. package/out/zero-protocol/src/inspect-down.d.ts +17 -0
  84. package/out/zero-protocol/src/inspect-down.d.ts.map +1 -1
  85. package/out/zero-protocol/src/inspect-down.js +5 -1
  86. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  87. package/out/zero-protocol/src/inspect-up.d.ts +39 -10
  88. package/out/zero-protocol/src/inspect-up.d.ts.map +1 -1
  89. package/out/zero-protocol/src/inspect-up.js +10 -3
  90. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  91. package/out/zero-protocol/src/protocol-version.d.ts +1 -1
  92. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  93. package/out/zero-protocol/src/protocol-version.js +2 -1
  94. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  95. package/out/zero-protocol/src/up.d.ts +10 -1
  96. package/out/zero-protocol/src/up.d.ts.map +1 -1
  97. package/out/zero-react/src/use-query.d.ts.map +1 -1
  98. package/out/zero-react-native/src/mod.d.ts +2 -2
  99. package/out/zero-react-native/src/mod.d.ts.map +1 -1
  100. package/out/zero.js +4 -4
  101. package/package.json +1 -1
  102. package/out/chunk-MKB4RXL3.js +0 -15
  103. package/out/chunk-MKB4RXL3.js.map +0 -7
  104. package/out/chunk-MLYQCVBG.js.map +0 -7
  105. package/out/chunk-V2KPKXLX.js.map +0 -7
  106. package/out/inspector-NC6TPMRA.js.map +0 -7
  107. package/out/replicache/src/expo/store.d.ts +0 -4
  108. package/out/replicache/src/expo/store.d.ts.map +0 -1
  109. /package/out/{chunk-FH5Q72JS.js.map → chunk-KXV3BZ4U.js.map} +0 -0
@@ -1,8 +1,9 @@
1
1
  import {
2
- promiseFalse,
3
- promiseTrue,
4
- promiseVoid
5
- } from "./chunk-MKB4RXL3.js";
2
+ maybeTransactionIsClosedRejection,
3
+ storeIsClosedRejection,
4
+ throwIfStoreClosed,
5
+ transactionIsClosedRejection
6
+ } from "./chunk-ASRS2LFV.js";
6
7
  import {
7
8
  BTreeRead,
8
9
  Chunk,
@@ -128,7 +129,7 @@ import {
128
129
  withWrite,
129
130
  withWriteNoImplicitCommit,
130
131
  wrapIterable
131
- } from "./chunk-MLYQCVBG.js";
132
+ } from "./chunk-K5ZSWG54.js";
132
133
  import {
133
134
  assert,
134
135
  assertArray,
@@ -329,6 +330,14 @@ function mustGetBrowserGlobal(name) {
329
330
  return r;
330
331
  }
331
332
 
333
+ // ../shared/src/resolved-promises.ts
334
+ var promiseTrue = Promise.resolve(true);
335
+ var promiseFalse = Promise.resolve(false);
336
+ var promiseUndefined = Promise.resolve(void 0);
337
+ var promiseVoid = Promise.resolve();
338
+ var promiseNever = new Promise(() => {
339
+ });
340
+
332
341
  // ../replicache/src/kv/write-impl-base.ts
333
342
  var deleteSentinel = Symbol();
334
343
  var WriteImplBase = class {
@@ -338,6 +347,9 @@ var WriteImplBase = class {
338
347
  this.#read = read;
339
348
  }
340
349
  has(key) {
350
+ if (this.#read.closed) {
351
+ return transactionIsClosedRejection();
352
+ }
341
353
  switch (this._pending.get(key)) {
342
354
  case void 0:
343
355
  return this.#read.has(key);
@@ -348,6 +360,9 @@ var WriteImplBase = class {
348
360
  }
349
361
  }
350
362
  async get(key) {
363
+ if (this.#read.closed) {
364
+ return transactionIsClosedRejection();
365
+ }
351
366
  const v = this._pending.get(key);
352
367
  switch (v) {
353
368
  case deleteSentinel:
@@ -361,12 +376,10 @@ var WriteImplBase = class {
361
376
  }
362
377
  }
363
378
  put(key, value) {
364
- this._pending.set(key, deepFreeze(value));
365
- return promiseVoid;
379
+ return maybeTransactionIsClosedRejection(this.#read) ?? (this._pending.set(key, deepFreeze(value)), promiseVoid);
366
380
  }
367
381
  del(key) {
368
- this._pending.set(key, deleteSentinel);
369
- return promiseVoid;
382
+ return maybeTransactionIsClosedRejection(this.#read) ?? (this._pending.set(key, deleteSentinel), promiseVoid);
370
383
  }
371
384
  release() {
372
385
  this.#read.release();
@@ -387,9 +400,15 @@ var IDBStore = class {
387
400
  this.#db = openDatabase(name);
388
401
  }
389
402
  read() {
403
+ if (this.#closed) {
404
+ return storeIsClosedRejection();
405
+ }
390
406
  return this.#withReopen(readImpl);
391
407
  }
392
408
  write() {
409
+ if (this.#closed) {
410
+ return storeIsClosedRejection();
411
+ }
393
412
  return this.#withReopen(writeImpl);
394
413
  }
395
414
  async close() {
@@ -451,6 +470,9 @@ var ReadImpl = class {
451
470
  this.#tx = tx;
452
471
  }
453
472
  has(key) {
473
+ if (this.#closed) {
474
+ return transactionIsClosedRejection();
475
+ }
454
476
  return new Promise((resolve, reject) => {
455
477
  const req = objectStore(this.#tx).count(key);
456
478
  req.onsuccess = () => resolve(req.result > 0);
@@ -458,6 +480,9 @@ var ReadImpl = class {
458
480
  });
459
481
  }
460
482
  get(key) {
483
+ if (this.#closed) {
484
+ return transactionIsClosedRejection();
485
+ }
461
486
  return new Promise((resolve, reject) => {
462
487
  const req = objectStore(this.#tx).get(key);
463
488
  req.onsuccess = () => resolve(deepFreezeAllowUndefined(req.result));
@@ -479,6 +504,9 @@ var WriteImpl = class extends WriteImplBase {
479
504
  this.#tx = tx;
480
505
  }
481
506
  commit() {
507
+ if (this.#closed) {
508
+ return transactionIsClosedRejection();
509
+ }
482
510
  if (this._pending.size === 0) {
483
511
  return promiseVoid;
484
512
  }
@@ -498,6 +526,7 @@ var WriteImpl = class extends WriteImplBase {
498
526
  }
499
527
  release() {
500
528
  this.#closed = true;
529
+ super.release();
501
530
  }
502
531
  get closed() {
503
532
  return this.#closed;
@@ -550,7 +579,7 @@ var AbortError = class extends Error {
550
579
  // ../shared/src/sleep.ts
551
580
  import { resolver as resolver2 } from "@rocicorp/resolver";
552
581
  var promiseVoid2 = Promise.resolve();
553
- var promiseNever = new Promise(() => void 0);
582
+ var promiseNever2 = new Promise(() => void 0);
554
583
  function sleep(ms, signal) {
555
584
  const newAbortError = () => new AbortError("Aborted");
556
585
  if (signal?.aborted) {
@@ -576,7 +605,7 @@ function sleep(ms, signal) {
576
605
  }
577
606
  function sleepWithAbort(ms, signal) {
578
607
  if (ms === 0) {
579
- return [promiseVoid2, promiseNever];
608
+ return [promiseVoid2, promiseNever2];
580
609
  }
581
610
  const { promise: abortedPromise, resolve: abortedResolve } = resolver2();
582
611
  const sleepPromise = new Promise((resolve) => {
@@ -927,17 +956,46 @@ var WriteImpl2 = class extends ReadImpl2 {
927
956
  };
928
957
 
929
958
  // ../replicache/src/deleted-clients.ts
930
- var DELETED_CLIENTS_HEAD_NAME = "deleted-clients";
931
- var deletedClientsSchema = readonlyObject({
932
- clientIDs: readonlyArray(valita_exports.string()),
933
- clientGroupIDs: readonlyArray(valita_exports.string())
934
- });
935
- var legacyDeletedClientsSchema = readonlyArray(valita_exports.string());
936
- async function setDeletedClients(dagWrite, clientIDs, clientGroupIDs) {
937
- const data = {
938
- clientIDs: normalize(clientIDs),
939
- clientGroupIDs: normalize(clientGroupIDs)
940
- };
959
+ var DELETED_CLIENTS_HEAD_NAME = "deleted-clients-v2";
960
+ var deletedClientsSchema = readonlyArray(
961
+ readonlyObject({
962
+ clientGroupID: clientGroupIDSchema,
963
+ clientID: clientIDSchema
964
+ })
965
+ );
966
+ function compare(a, b) {
967
+ const cg = stringCompare(a.clientGroupID, b.clientGroupID);
968
+ if (cg !== 0) {
969
+ return cg;
970
+ }
971
+ return stringCompare(a.clientID, b.clientID);
972
+ }
973
+ function normalizeDeletedClients(deletedClients) {
974
+ return [...deletedClients].sort(compare).filter(
975
+ (item, index) => index === 0 || compare(item, [...deletedClients].sort(compare)[index - 1]) !== 0
976
+ );
977
+ }
978
+ function mergeDeletedClients(a, b) {
979
+ const merged = [];
980
+ a = normalizeDeletedClients(a);
981
+ b = normalizeDeletedClients(b);
982
+ for (let i = 0, j = 0; i < a.length || j < b.length; ) {
983
+ if (i < a.length && (j >= b.length || compare(a[i], b[j]) < 0)) {
984
+ merged.push(a[i]);
985
+ i++;
986
+ } else if (j < b.length && (i >= a.length || compare(b[j], a[i]) < 0)) {
987
+ merged.push(b[j]);
988
+ j++;
989
+ } else {
990
+ merged.push(a[i]);
991
+ i++;
992
+ j++;
993
+ }
994
+ }
995
+ return merged;
996
+ }
997
+ async function setDeletedClients(dagWrite, deletedClients) {
998
+ const data = normalizeDeletedClients(deletedClients);
941
999
  const chunkData = deepFreeze(data);
942
1000
  const chunk = dagWrite.createChunk(chunkData, []);
943
1001
  await dagWrite.putChunk(chunk);
@@ -947,35 +1005,44 @@ async function setDeletedClients(dagWrite, clientIDs, clientGroupIDs) {
947
1005
  async function getDeletedClients(dagRead) {
948
1006
  const hash = await dagRead.getHead(DELETED_CLIENTS_HEAD_NAME);
949
1007
  if (hash === void 0) {
950
- return { clientIDs: [], clientGroupIDs: [] };
1008
+ return [];
951
1009
  }
952
1010
  const chunk = await dagRead.mustGetChunk(hash);
953
- const res = test(chunk.data, legacyDeletedClientsSchema);
954
- if (res.ok) {
955
- return { clientIDs: res.value, clientGroupIDs: [] };
1011
+ const res = test(chunk.data, deletedClientsSchema);
1012
+ if (!res.ok) {
1013
+ return [];
956
1014
  }
957
- return parse(chunk.data, deletedClientsSchema);
1015
+ return res.value;
958
1016
  }
959
- async function addDeletedClients(dagWrite, clientIDs, clientGroupIDs) {
960
- const { clientIDs: oldClientIDs, clientGroupIDs: oldClientGroupIDs } = await getDeletedClients(dagWrite);
1017
+ async function addDeletedClients(dagWrite, deletedClientsToAdd) {
1018
+ const oldDeletedClients = await getDeletedClients(dagWrite);
961
1019
  return setDeletedClients(
962
1020
  dagWrite,
963
- [...oldClientIDs, ...clientIDs],
964
- [...oldClientGroupIDs, ...clientGroupIDs]
1021
+ mergeDeletedClients(oldDeletedClients, deletedClientsToAdd)
965
1022
  );
966
1023
  }
967
- async function removeDeletedClients(dagWrite, clientIDs, clientGroupIDs) {
968
- const { clientIDs: oldClientIDs, clientGroupIDs: oldClientGroupIDs } = await getDeletedClients(dagWrite);
969
- const newDeletedClients = oldClientIDs.filter(
970
- (clientID) => !clientIDs.includes(clientID)
971
- );
972
- const newDeletedClientGroups = oldClientGroupIDs.filter(
973
- (clientGroupID) => !clientGroupIDs.includes(clientGroupID)
1024
+ async function confirmDeletedClients(dagWrite, deletedClientIds, deletedClientGroupIds) {
1025
+ const deletedClientIDSet = new Set(deletedClientIds);
1026
+ const deletedClientGroupIDSet = new Set(deletedClientGroupIds);
1027
+ const oldDeletedClients = await getDeletedClients(dagWrite);
1028
+ const clients = new Map(await getClients(dagWrite));
1029
+ for (const clientID of deletedClientIds) {
1030
+ clients.delete(clientID);
1031
+ }
1032
+ for (const clientGroupID of deletedClientGroupIds) {
1033
+ for (const [clientID, client] of clients) {
1034
+ if (client.clientGroupID === clientGroupID) {
1035
+ clients.delete(clientID);
1036
+ }
1037
+ }
1038
+ }
1039
+ await setClients(clients, dagWrite);
1040
+ return setDeletedClients(
1041
+ dagWrite,
1042
+ oldDeletedClients.filter(
1043
+ ({ clientGroupID, clientID }) => !deletedClientGroupIDSet.has(clientGroupID) && !deletedClientIDSet.has(clientID)
1044
+ )
974
1045
  );
975
- return setDeletedClients(dagWrite, newDeletedClients, newDeletedClientGroups);
976
- }
977
- function normalize(arr) {
978
- return [...new Set(arr)].sort();
979
1046
  }
980
1047
 
981
1048
  // ../shared/src/navigator.ts
@@ -1001,10 +1068,10 @@ var ReadImpl3 = class {
1001
1068
  return this.#closed;
1002
1069
  }
1003
1070
  has(key) {
1004
- return Promise.resolve(this.#map.has(key));
1071
+ return maybeTransactionIsClosedRejection(this) ?? Promise.resolve(this.#map.has(key));
1005
1072
  }
1006
1073
  get(key) {
1007
- return Promise.resolve(this.#map.get(key));
1074
+ return maybeTransactionIsClosedRejection(this) ?? Promise.resolve(this.#map.get(key));
1008
1075
  }
1009
1076
  };
1010
1077
 
@@ -1016,6 +1083,9 @@ var WriteImpl3 = class extends WriteImplBase {
1016
1083
  this.#map = map;
1017
1084
  }
1018
1085
  commit() {
1086
+ if (this.closed) {
1087
+ return transactionIsClosedRejection();
1088
+ }
1019
1089
  this._pending.forEach((value, key) => {
1020
1090
  if (value === deleteSentinel) {
1021
1091
  this.#map.delete(key);
@@ -1054,10 +1124,12 @@ var MemStore = class {
1054
1124
  this.#map = map;
1055
1125
  }
1056
1126
  async read() {
1127
+ throwIfStoreClosed(this);
1057
1128
  const release = await this.#rwLock.read();
1058
1129
  return new ReadImpl3(this.#map, release);
1059
1130
  }
1060
1131
  async write() {
1132
+ throwIfStoreClosed(this);
1061
1133
  const release = await this.#rwLock.write();
1062
1134
  return new WriteImpl3(this.#map, release);
1063
1135
  }
@@ -1312,16 +1384,11 @@ async function collectIDBDatabases(idbDatabasesStore, now, maxAge, kvDropStore,
1312
1384
  );
1313
1385
  const dbNamesToRemove = [];
1314
1386
  const dbNamesToKeep = [];
1315
- const clientIDsToRemove = [];
1316
- const clientGroupIDsToRemove = [];
1317
- for (const [
1318
- dbName,
1319
- [canCollect, clientIDs, clientGroupIDs]
1320
- ] of collectResults) {
1387
+ const deletedClientsToRemove = [];
1388
+ for (const [dbName, [canCollect, deletedClients]] of collectResults) {
1321
1389
  if (canCollect) {
1322
1390
  dbNamesToRemove.push(dbName);
1323
- clientIDsToRemove.push(...clientIDs);
1324
- clientGroupIDsToRemove.push(...clientGroupIDs);
1391
+ deletedClientsToRemove.push(...deletedClients);
1325
1392
  } else {
1326
1393
  dbNamesToKeep.push(dbName);
1327
1394
  }
@@ -1334,24 +1401,22 @@ async function collectIDBDatabases(idbDatabasesStore, now, maxAge, kvDropStore,
1334
1401
  if (errors.length) {
1335
1402
  throw errors[0];
1336
1403
  }
1337
- if (clientIDsToRemove.length || clientGroupIDsToRemove.length) {
1338
- const newClientIDsToRemove = clientIDsToRemove;
1339
- const newClientGroupIDsToRemove = clientGroupIDsToRemove;
1404
+ if (deletedClientsToRemove.length > 0) {
1405
+ let allDeletedClients = deletedClientsToRemove;
1340
1406
  for (const name of dbNamesToKeep) {
1341
1407
  await withWrite(newDagStore(name), async (dagWrite) => {
1342
- const { clientIDs, clientGroupIDs } = await addDeletedClients(
1408
+ const newDeletedClients = await addDeletedClients(
1343
1409
  dagWrite,
1344
- clientIDsToRemove,
1345
- clientGroupIDsToRemove
1410
+ deletedClientsToRemove
1411
+ );
1412
+ allDeletedClients = mergeDeletedClients(
1413
+ allDeletedClients,
1414
+ newDeletedClients
1346
1415
  );
1347
- newClientIDsToRemove.push(...clientIDs);
1348
- newClientGroupIDsToRemove.push(...clientGroupIDs);
1349
1416
  });
1350
1417
  }
1351
- onClientsDeleted(
1352
- normalize(newClientIDsToRemove),
1353
- normalize(newClientGroupIDsToRemove)
1354
- );
1418
+ const normalizedDeletedClients = normalizeDeletedClients(allDeletedClients);
1419
+ await onClientsDeleted(normalizedDeletedClients);
1355
1420
  }
1356
1421
  }
1357
1422
  async function dropDatabaseInternal(name, idbDatabasesStore, kvDropStore) {
@@ -1428,14 +1493,15 @@ function canDatabaseBeCollectedAndGetDeletedClientIDs(enableMutationRecovery, pe
1428
1493
  }
1429
1494
  }
1430
1495
  const clients = await getClients(read);
1431
- const { clientIDs, clientGroupIDs } = await getDeletedClients(read);
1432
- const newClientIDs = [...clientIDs];
1433
- const newClientGroupIDs = [...clientGroupIDs];
1496
+ const existingDeletedClients = await getDeletedClients(read);
1497
+ const deletedClients = [...existingDeletedClients];
1434
1498
  for (const [clientID, client] of clients) {
1435
- newClientIDs.push(clientID);
1436
- newClientGroupIDs.push(client.clientGroupID);
1499
+ deletedClients.push({
1500
+ clientID,
1501
+ clientGroupID: client.clientGroupID
1502
+ });
1437
1503
  }
1438
- return [true, newClientIDs, newClientGroupIDs];
1504
+ return [true, deletedClients];
1439
1505
  });
1440
1506
  }
1441
1507
 
@@ -1554,7 +1620,7 @@ function table(name) {
1554
1620
  primaryKey: []
1555
1621
  });
1556
1622
  }
1557
- function string3() {
1623
+ function string2() {
1558
1624
  return new ColumnBuilder({
1559
1625
  type: "string",
1560
1626
  optional: false,
@@ -3702,20 +3768,21 @@ function gcClients(clientID, dagStore, clientMaxInactiveTime, onClientsDeleted)
3702
3768
  if (id === clientID || now - client.heartbeatTimestampMs <= clientMaxInactiveTime) {
3703
3769
  newClients.set(id, client);
3704
3770
  } else {
3705
- deletedClients.push(id);
3771
+ deletedClients.push({
3772
+ clientGroupID: client.clientGroupID,
3773
+ clientID: id
3774
+ });
3706
3775
  }
3707
3776
  }
3708
3777
  if (newClients.size === clients.size) {
3709
3778
  return clients;
3710
3779
  }
3711
3780
  await setClients(newClients, dagWrite);
3712
- const { clientIDs, clientGroupIDs } = await addDeletedClients(
3781
+ const normalizedDeletedClients = await addDeletedClients(
3713
3782
  dagWrite,
3714
- deletedClients,
3715
- // gcClients does not delete client groups
3716
- []
3783
+ deletedClients
3717
3784
  );
3718
- onClientsDeleted(clientIDs, clientGroupIDs);
3785
+ await onClientsDeleted(normalizedDeletedClients);
3719
3786
  return newClients;
3720
3787
  });
3721
3788
  }
@@ -3723,15 +3790,11 @@ function gcClients(clientID, dagStore, clientMaxInactiveTime, onClientsDeleted)
3723
3790
  // ../replicache/src/persist/client-group-gc.ts
3724
3791
  var GC_INTERVAL_MS = 5 * 60 * 1e3;
3725
3792
  var latestGCUpdate2;
3726
- function initClientGroupGC(dagStore, enableMutationRecovery, onClientsDeleted, lc, signal) {
3793
+ function initClientGroupGC(dagStore, enableMutationRecovery, lc, signal) {
3727
3794
  initBgIntervalProcess(
3728
3795
  "ClientGroupGC",
3729
3796
  () => {
3730
- latestGCUpdate2 = gcClientGroups(
3731
- dagStore,
3732
- enableMutationRecovery,
3733
- onClientsDeleted
3734
- );
3797
+ latestGCUpdate2 = gcClientGroups(dagStore, enableMutationRecovery);
3735
3798
  return latestGCUpdate2;
3736
3799
  },
3737
3800
  () => GC_INTERVAL_MS,
@@ -3739,7 +3802,7 @@ function initClientGroupGC(dagStore, enableMutationRecovery, onClientsDeleted, l
3739
3802
  signal
3740
3803
  );
3741
3804
  }
3742
- function gcClientGroups(dagStore, enableMutationRecovery, onClientsDeleted) {
3805
+ function gcClientGroups(dagStore, enableMutationRecovery) {
3743
3806
  return withWrite(dagStore, async (tx) => {
3744
3807
  const clients = await getClients(tx);
3745
3808
  const clientGroupIDs = /* @__PURE__ */ new Set();
@@ -3756,7 +3819,6 @@ function gcClientGroups(dagStore, enableMutationRecovery, onClientsDeleted) {
3756
3819
  }
3757
3820
  }
3758
3821
  await setClientGroups(clientGroups, tx);
3759
- onClientsDeleted([], [...removeClientGroups].sort());
3760
3822
  return clientGroups;
3761
3823
  });
3762
3824
  }
@@ -4922,8 +4984,7 @@ var ReplicacheImpl = class {
4922
4984
  enableScheduledRefresh = true,
4923
4985
  enablePullAndPushInOpen = true,
4924
4986
  enableClientGroupForking = true,
4925
- onClientsDeleted = () => {
4926
- }
4987
+ onClientsDeleted = () => promiseVoid
4927
4988
  } = implOptions;
4928
4989
  this.#zero = implOptions.zero;
4929
4990
  this.#auth = auth ?? "";
@@ -5068,13 +5129,7 @@ var ReplicacheImpl = class {
5068
5129
  this.#lc,
5069
5130
  signal
5070
5131
  );
5071
- initClientGroupGC(
5072
- this.perdag,
5073
- enableMutationRecovery,
5074
- onClientsDeleted,
5075
- this.#lc,
5076
- signal
5077
- );
5132
+ initClientGroupGC(this.perdag, enableMutationRecovery, this.#lc, signal);
5078
5133
  initNewClientChannel(
5079
5134
  this.name,
5080
5135
  this.idbName,
@@ -5906,6 +5961,11 @@ function validateOptions(options) {
5906
5961
  }
5907
5962
  }
5908
5963
 
5964
+ // ../shared/src/sentinels.ts
5965
+ function emptyFunction() {
5966
+ }
5967
+ var emptyObject = Object.freeze({});
5968
+
5909
5969
  // ../shared/src/subscribable.ts
5910
5970
  var Subscribable = class {
5911
5971
  _listeners = /* @__PURE__ */ new Set();
@@ -6364,7 +6424,7 @@ var downstreamSchema = valita_exports.union(
6364
6424
  );
6365
6425
 
6366
6426
  // ../zero-protocol/src/protocol-version.ts
6367
- var PROTOCOL_VERSION = 30;
6427
+ var PROTOCOL_VERSION = 31;
6368
6428
  var MIN_SERVER_SUPPORTED_SYNC_PROTOCOL = 18;
6369
6429
  assert(MIN_SERVER_SUPPORTED_SYNC_PROTOCOL < PROTOCOL_VERSION);
6370
6430
 
@@ -6591,7 +6651,7 @@ var ActiveClientsManager = class _ActiveClientsManager {
6591
6651
  }
6592
6652
  #removeClient(clientID) {
6593
6653
  if (this.#activeClients.delete(clientID)) {
6594
- this.onDelete?.(clientID);
6654
+ this.onDelete?.(clientID, this.clientGroupID);
6595
6655
  }
6596
6656
  }
6597
6657
  };
@@ -7433,8 +7493,8 @@ var MemorySource = class _MemorySource {
7433
7493
  indexSort.push(...requestedSort);
7434
7494
  }
7435
7495
  const index = this.#getOrCreateIndex(indexSort, from);
7436
- const { data, comparator: compare } = index;
7437
- const comparator2 = (r1, r2) => compare(r1, r2) * (req.reverse ? -1 : 1);
7496
+ const { data, comparator: compare2 } = index;
7497
+ const comparator2 = (r1, r2) => compare2(r1, r2) * (req.reverse ? -1 : 1);
7438
7498
  const startAt = req.start?.row;
7439
7499
  let scanStart;
7440
7500
  if (fetchOrPkConstraint) {
@@ -7634,7 +7694,7 @@ function* genPush(change, exists, connections, setOverlay, setSplitEditOverlay)
7634
7694
  }
7635
7695
  setOverlay(void 0);
7636
7696
  }
7637
- function* generateWithStart(nodes, start, compare) {
7697
+ function* generateWithStart(nodes, start, compare2) {
7638
7698
  if (!start) {
7639
7699
  yield* nodes;
7640
7700
  return;
@@ -7643,11 +7703,11 @@ function* generateWithStart(nodes, start, compare) {
7643
7703
  for (const node of nodes) {
7644
7704
  if (!started) {
7645
7705
  if (start.basis === "at") {
7646
- if (compare(node.row, start.row) >= 0) {
7706
+ if (compare2(node.row, start.row) >= 0) {
7647
7707
  started = true;
7648
7708
  }
7649
7709
  } else if (start.basis === "after") {
7650
- if (compare(node.row, start.row) > 0) {
7710
+ if (compare2(node.row, start.row) > 0) {
7651
7711
  started = true;
7652
7712
  }
7653
7713
  }
@@ -7657,7 +7717,7 @@ function* generateWithStart(nodes, start, compare) {
7657
7717
  }
7658
7718
  }
7659
7719
  }
7660
- function* generateWithOverlay(startAt, rows, constraint, overlay, splitEditOverlay, connectionIndex, compare, filterPredicate) {
7720
+ function* generateWithOverlay(startAt, rows, constraint, overlay, splitEditOverlay, connectionIndex, compare2, filterPredicate) {
7661
7721
  let overlayToApply = void 0;
7662
7722
  if (splitEditOverlay && splitEditOverlay.outputIndex === connectionIndex) {
7663
7723
  overlayToApply = splitEditOverlay;
@@ -7668,12 +7728,12 @@ function* generateWithOverlay(startAt, rows, constraint, overlay, splitEditOverl
7668
7728
  startAt,
7669
7729
  constraint,
7670
7730
  overlayToApply,
7671
- compare,
7731
+ compare2,
7672
7732
  filterPredicate
7673
7733
  );
7674
- yield* generateWithOverlayInner(rows, overlays, compare);
7734
+ yield* generateWithOverlayInner(rows, overlays, compare2);
7675
7735
  }
7676
- function computeOverlays(startAt, constraint, overlay, compare, filterPredicate) {
7736
+ function computeOverlays(startAt, constraint, overlay, compare2, filterPredicate) {
7677
7737
  let overlays = {
7678
7738
  add: void 0,
7679
7739
  remove: void 0
@@ -7699,7 +7759,7 @@ function computeOverlays(startAt, constraint, overlay, compare, filterPredicate)
7699
7759
  break;
7700
7760
  }
7701
7761
  if (startAt) {
7702
- overlays = overlaysForStartAt(overlays, startAt, compare);
7762
+ overlays = overlaysForStartAt(overlays, startAt, compare2);
7703
7763
  }
7704
7764
  if (constraint) {
7705
7765
  overlays = overlaysForConstraint(overlays, constraint);
@@ -7709,8 +7769,8 @@ function computeOverlays(startAt, constraint, overlay, compare, filterPredicate)
7709
7769
  }
7710
7770
  return overlays;
7711
7771
  }
7712
- function overlaysForStartAt({ add, remove }, startAt, compare) {
7713
- const undefinedIfBeforeStartAt = (row) => row === void 0 || compare(row, startAt) < 0 ? void 0 : row;
7772
+ function overlaysForStartAt({ add, remove }, startAt, compare2) {
7773
+ const undefinedIfBeforeStartAt = (row) => row === void 0 || compare2(row, startAt) < 0 ? void 0 : row;
7714
7774
  return {
7715
7775
  add: undefinedIfBeforeStartAt(add),
7716
7776
  remove: undefinedIfBeforeStartAt(remove)
@@ -7730,19 +7790,19 @@ function overlaysForFilterPredicate({ add, remove }, filterPredicate) {
7730
7790
  remove: undefinedIfDoesntMatchFilter(remove)
7731
7791
  };
7732
7792
  }
7733
- function* generateWithOverlayInner(rowIterator, overlays, compare) {
7793
+ function* generateWithOverlayInner(rowIterator, overlays, compare2) {
7734
7794
  let addOverlayYielded = false;
7735
7795
  let removeOverlaySkipped = false;
7736
7796
  for (const row of rowIterator) {
7737
7797
  if (!addOverlayYielded && overlays.add) {
7738
- const cmp = compare(overlays.add, row);
7798
+ const cmp = compare2(overlays.add, row);
7739
7799
  if (cmp < 0) {
7740
7800
  addOverlayYielded = true;
7741
7801
  yield { row: overlays.add, relationships: {} };
7742
7802
  }
7743
7803
  }
7744
7804
  if (!removeOverlaySkipped && overlays.remove) {
7745
- const cmp = compare(overlays.remove, row);
7805
+ const cmp = compare2(overlays.remove, row);
7746
7806
  if (cmp === 0) {
7747
7807
  removeOverlaySkipped = true;
7748
7808
  continue;
@@ -8249,11 +8309,6 @@ async function deleteImpl(tx, arg, schema, ivmBranch) {
8249
8309
  }
8250
8310
  }
8251
8311
 
8252
- // ../shared/src/sentinels.ts
8253
- function emptyFunction() {
8254
- }
8255
- var emptyObject = Object.freeze({});
8256
-
8257
8312
  // ../zero-client/src/client/custom.ts
8258
8313
  var TransactionImpl = class {
8259
8314
  constructor(lc, repTx, schema) {
@@ -8374,30 +8429,40 @@ var DeleteClientsManager = class {
8374
8429
  #send;
8375
8430
  #lc;
8376
8431
  #dagStore;
8377
- constructor(send2, dagStore, lc) {
8432
+ #clientGroupID;
8433
+ constructor(send2, dagStore, lc, clientGroupID) {
8378
8434
  this.#send = send2;
8379
8435
  this.#dagStore = dagStore;
8380
8436
  this.#lc = lc;
8437
+ this.#clientGroupID = clientGroupID;
8381
8438
  }
8382
8439
  /**
8383
8440
  * This gets called by Replicache when it deletes clients from the persistent
8384
8441
  * storage.
8385
8442
  */
8386
- onClientsDeleted(clientIDs, clientGroupIDs) {
8387
- this.#lc.debug?.("DeletedClientsManager, send:", clientIDs);
8388
- this.#send(["deleteClients", { clientIDs, clientGroupIDs }]);
8443
+ async onClientsDeleted(deletedClients) {
8444
+ this.#lc.debug?.("DeletedClientsManager, send:", deletedClients);
8445
+ const clientGroupID = await this.#clientGroupID;
8446
+ this.#send([
8447
+ "deleteClients",
8448
+ {
8449
+ clientIDs: deletedClients.filter((dc) => dc.clientGroupID === clientGroupID).map((dc) => dc.clientID)
8450
+ }
8451
+ ]);
8389
8452
  }
8390
8453
  /**
8391
8454
  * Zero calls this after it connects to ensure that the server knows about all
8392
8455
  * the clients that might have been deleted locally since the last connection.
8393
8456
  */
8394
8457
  async sendDeletedClientsToServer() {
8458
+ const clientGroupID = await this.#clientGroupID;
8395
8459
  const deleted = await withRead(
8396
8460
  this.#dagStore,
8397
8461
  (dagRead) => getDeletedClients(dagRead)
8398
8462
  );
8399
- if (deleted.clientIDs.length > 0 || deleted.clientGroupIDs.length > 0) {
8400
- this.#send(["deleteClients", deleted]);
8463
+ const clientIDs = deleted.filter((d) => d.clientGroupID === clientGroupID).map((d) => d.clientID);
8464
+ if (clientIDs.length > 0) {
8465
+ this.#send(["deleteClients", { clientIDs }]);
8401
8466
  this.#lc.debug?.("DeletedClientsManager, send:", deleted);
8402
8467
  }
8403
8468
  }
@@ -8410,13 +8475,18 @@ var DeleteClientsManager = class {
8410
8475
  if (clientIDs.length > 0 || clientGroupIDs.length > 0) {
8411
8476
  return withWrite(this.#dagStore, async (dagWrite) => {
8412
8477
  this.#lc.debug?.("clientsDeletedOnServer:", clientIDs, clientGroupIDs);
8413
- await removeDeletedClients(dagWrite, clientIDs, clientGroupIDs);
8478
+ await confirmDeletedClients(dagWrite, clientIDs, clientGroupIDs);
8414
8479
  });
8415
8480
  }
8416
8481
  return promiseVoid;
8417
8482
  }
8418
- getDeletedClients() {
8419
- return withRead(this.#dagStore, getDeletedClients);
8483
+ async getDeletedClients() {
8484
+ const deletedClients = await withRead(
8485
+ this.#dagStore,
8486
+ (read) => getDeletedClients(read)
8487
+ );
8488
+ const clientGroupID = await this.#clientGroupID;
8489
+ return deletedClients.filter((d) => d.clientGroupID === clientGroupID);
8420
8490
  }
8421
8491
  };
8422
8492
 
@@ -8668,7 +8738,7 @@ function makeMessage(message, context, logLevel) {
8668
8738
  }
8669
8739
 
8670
8740
  // ../zero-client/src/client/version.ts
8671
- var version2 = "0.24.2025091100";
8741
+ var version2 = "0.24.2025091200";
8672
8742
 
8673
8743
  // ../zero-client/src/client/log-options.ts
8674
8744
  var LevelFilterLogSink = class {
@@ -10422,7 +10492,7 @@ var Zero = class _Zero {
10422
10492
  enableMutationRecovery: false,
10423
10493
  enablePullAndPushInOpen: false,
10424
10494
  // Zero calls push in its connection management code
10425
- onClientsDeleted: (clientIDs, clientGroupIDs) => this.#deleteClientsManager.onClientsDeleted(clientIDs, clientGroupIDs),
10495
+ onClientsDeleted: (deletedClients) => this.#deleteClientsManager.onClientsDeleted(deletedClients),
10426
10496
  zero: new ZeroRep(
10427
10497
  this.#zeroContext,
10428
10498
  this.#ivmMain,
@@ -10446,7 +10516,9 @@ var Zero = class _Zero {
10446
10516
  rep.clientGroupID,
10447
10517
  this.clientID,
10448
10518
  this.#closeAbortController.signal,
10449
- (clientID) => this.#deleteClientsManager.onClientsDeleted([clientID], [])
10519
+ (clientID, clientGroupID) => this.#deleteClientsManager.onClientsDeleted([
10520
+ { clientGroupID, clientID }
10521
+ ])
10450
10522
  );
10451
10523
  const onUpdateNeededCallback = (reason, serverErrorMsg) => {
10452
10524
  if (onUpdateNeeded) {
@@ -10512,7 +10584,8 @@ var Zero = class _Zero {
10512
10584
  this.#deleteClientsManager = new DeleteClientsManager(
10513
10585
  (msg) => this.#send(msg),
10514
10586
  rep.perdag,
10515
- this.#lc
10587
+ this.#lc,
10588
+ this.#rep.clientGroupID
10516
10589
  );
10517
10590
  this.query = this.#registerQueries(schema);
10518
10591
  reportReloadReason(this.#lc);
@@ -11459,7 +11532,7 @@ var Zero = class _Zero {
11459
11532
  */
11460
11533
  async inspect() {
11461
11534
  BUNDLE_SIZE: {
11462
- const m = await import("./inspector-NC6TPMRA.js");
11535
+ const m = await import("./inspector-ZZSIUMBB.js");
11463
11536
  return m.newInspector(
11464
11537
  this.#rep,
11465
11538
  this.#queryManager,
@@ -11520,7 +11593,8 @@ async function createSocket(rep, queryManager, deleteClientsManager, socketOrigi
11520
11593
  lc.info?.("Connecting to", url.toString());
11521
11594
  const WS = mustGetBrowserGlobal("WebSocket");
11522
11595
  const queriesPatchP = rep.query((tx) => queryManager.getQueriesPatch(tx));
11523
- let deletedClients = await deleteClientsManager.getDeletedClients();
11596
+ const deletedClientsArray = await deleteClientsManager.getDeletedClients();
11597
+ let deletedClients = convertDeletedClientsToBody(deletedClientsArray, clientGroupID);
11524
11598
  let queriesPatch = await queriesPatchP;
11525
11599
  const { activeClients } = activeClientsManager;
11526
11600
  let secProtocol = encodeSecProtocols(
@@ -11576,6 +11650,16 @@ function skipEmptyDeletedClients(deletedClients) {
11576
11650
  data.clientGroupIDs = skipEmptyArray(clientGroupIDs);
11577
11651
  return data;
11578
11652
  }
11653
+ function convertDeletedClientsToBody(deletedClients, clientGroupID) {
11654
+ if (deletedClients.length === 0) {
11655
+ return void 0;
11656
+ }
11657
+ const clientIDs = deletedClients.filter((pair) => pair.clientID && pair.clientGroupID === clientGroupID).map((pair) => pair.clientID);
11658
+ if (clientIDs.length === 0) {
11659
+ return void 0;
11660
+ }
11661
+ return { clientIDs };
11662
+ }
11579
11663
  function addWebSocketIDFromSocketToLogContext({ url }, lc) {
11580
11664
  const wsid = new URL(url).searchParams.get("wsid") ?? nanoid();
11581
11665
  return addWebSocketIDToLogContext(wsid, lc);
@@ -11616,7 +11700,7 @@ export {
11616
11700
  transformResponseMessageSchema,
11617
11701
  error_kind_enum_exports,
11618
11702
  table,
11619
- string3 as string,
11703
+ string2 as string,
11620
11704
  number2 as number,
11621
11705
  boolean,
11622
11706
  json,
@@ -11626,4 +11710,4 @@ export {
11626
11710
  update_needed_reason_type_enum_exports,
11627
11711
  Zero
11628
11712
  };
11629
- //# sourceMappingURL=chunk-V2KPKXLX.js.map
11713
+ //# sourceMappingURL=chunk-6XNI6IVJ.js.map