@rocicorp/zero 0.17.2025031200 → 0.17.2025031300

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 (90) hide show
  1. package/out/advanced.js +1 -1
  2. package/out/{chunk-2Y24MEEQ.js → chunk-5X3DESC6.js} +1 -1
  3. package/out/{chunk-2Y24MEEQ.js.map → chunk-5X3DESC6.js.map} +1 -1
  4. package/out/{chunk-6CQ6CUML.js → chunk-7ARRNDLF.js} +37 -15
  5. package/out/{chunk-6CQ6CUML.js.map → chunk-7ARRNDLF.js.map} +3 -3
  6. package/out/{chunk-VNV6U5BQ.js → chunk-APXCO5Z2.js} +296 -134
  7. package/out/chunk-APXCO5Z2.js.map +7 -0
  8. package/out/react.js +7 -1
  9. package/out/react.js.map +2 -2
  10. package/out/replicache/src/dag/lazy-store.d.ts +2 -2
  11. package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
  12. package/out/replicache/src/db/write.d.ts +1 -1
  13. package/out/replicache/src/db/write.d.ts.map +1 -1
  14. package/out/replicache/src/persist/persist.d.ts +2 -1
  15. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  16. package/out/replicache/src/persist/refresh.d.ts +7 -1
  17. package/out/replicache/src/persist/refresh.d.ts.map +1 -1
  18. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  19. package/out/replicache/src/replicache-options.d.ts +10 -5
  20. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  21. package/out/replicache/src/sync/pull.d.ts +2 -0
  22. package/out/replicache/src/sync/pull.d.ts.map +1 -1
  23. package/out/solid.js +16 -8
  24. package/out/solid.js.map +2 -2
  25. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +3 -0
  26. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  27. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
  28. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  29. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  30. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +1 -0
  31. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  32. package/out/zero-client/src/client/context.d.ts +7 -3
  33. package/out/zero-client/src/client/context.d.ts.map +1 -1
  34. package/out/zero-client/src/client/custom.d.ts +5 -4
  35. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  36. package/out/zero-client/src/client/ivm-branch.d.ts +6 -3
  37. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  38. package/out/zero-client/src/client/query-manager.d.ts +1 -0
  39. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  40. package/out/zero-client/src/client/zero-rep.d.ts +15 -0
  41. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -0
  42. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  43. package/out/zero-pg/src/custom.d.ts +2 -1
  44. package/out/zero-pg/src/custom.d.ts.map +1 -1
  45. package/out/zero-pg/src/custom.js +4 -1
  46. package/out/zero-pg/src/custom.js.map +1 -1
  47. package/out/zero-pg/src/query.d.ts +4 -2
  48. package/out/zero-pg/src/query.d.ts.map +1 -1
  49. package/out/zero-pg/src/query.js +3 -0
  50. package/out/zero-pg/src/query.js.map +1 -1
  51. package/out/zero-pg/src/web.d.ts +2 -1
  52. package/out/zero-pg/src/web.d.ts.map +1 -1
  53. package/out/zero-pg/src/web.js +59 -35
  54. package/out/zero-pg/src/web.js.map +1 -1
  55. package/out/zero-react/src/use-query.d.ts.map +1 -1
  56. package/out/zero-solid/src/use-query.d.ts.map +1 -1
  57. package/out/zero.js +3 -3
  58. package/out/zql/src/ivm/memory-source.d.ts +3 -3
  59. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  60. package/out/zql/src/ivm/memory-source.js +16 -0
  61. package/out/zql/src/ivm/memory-source.js.map +1 -1
  62. package/out/zql/src/ivm/source.d.ts +5 -1
  63. package/out/zql/src/ivm/source.d.ts.map +1 -1
  64. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  65. package/out/zql/src/ivm/view-apply-change.js +40 -8
  66. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  67. package/out/zql/src/query/expression.d.ts +20 -0
  68. package/out/zql/src/query/expression.d.ts.map +1 -1
  69. package/out/zql/src/query/expression.js +1 -1
  70. package/out/zql/src/query/expression.js.map +1 -1
  71. package/out/zql/src/query/query-impl.d.ts +3 -0
  72. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  73. package/out/zql/src/query/query-impl.js +3 -0
  74. package/out/zql/src/query/query-impl.js.map +1 -1
  75. package/out/zql/src/query/query-internal.d.ts +1 -0
  76. package/out/zql/src/query/query-internal.d.ts.map +1 -1
  77. package/out/zql/src/query/static-query.d.ts +2 -0
  78. package/out/zql/src/query/static-query.d.ts.map +1 -1
  79. package/out/zql/src/query/static-query.js +3 -0
  80. package/out/zql/src/query/static-query.js.map +1 -1
  81. package/out/zql/src/query/ttl.d.ts +1 -0
  82. package/out/zql/src/query/ttl.d.ts.map +1 -1
  83. package/out/zql/src/query/ttl.js +22 -0
  84. package/out/zql/src/query/ttl.js.map +1 -1
  85. package/out/zqlite/src/table-source.d.ts +3 -3
  86. package/out/zqlite/src/table-source.d.ts.map +1 -1
  87. package/out/zqlite/src/table-source.js +17 -0
  88. package/out/zqlite/src/table-source.js.map +1 -1
  89. package/package.json +1 -1
  90. package/out/chunk-VNV6U5BQ.js.map +0 -7
@@ -3,7 +3,7 @@ import {
3
3
  compareTTL,
4
4
  hasOwn,
5
5
  parseTTL
6
- } from "./chunk-2Y24MEEQ.js";
6
+ } from "./chunk-5X3DESC6.js";
7
7
  import {
8
8
  applyChange,
9
9
  assert,
@@ -21,7 +21,7 @@ import {
21
21
  throwInvalidType,
22
22
  unreachable,
23
23
  valuesEqual
24
- } from "./chunk-6CQ6CUML.js";
24
+ } from "./chunk-7ARRNDLF.js";
25
25
  import {
26
26
  __export,
27
27
  __reExport
@@ -2229,7 +2229,7 @@ var LazyStore = class {
2229
2229
  this.#chunkHasher = chunkHasher;
2230
2230
  this.#assertValidHash = assertValidHash;
2231
2231
  }
2232
- async read() {
2232
+ async read(sourceRead) {
2233
2233
  const release = await this.#rwLock.read();
2234
2234
  return new LazyRead(
2235
2235
  this.#heads,
@@ -2237,7 +2237,8 @@ var LazyStore = class {
2237
2237
  this._sourceChunksCache,
2238
2238
  this.#sourceStore,
2239
2239
  release,
2240
- this.#assertValidHash
2240
+ this.#assertValidHash,
2241
+ sourceRead
2241
2242
  );
2242
2243
  }
2243
2244
  async write() {
@@ -2276,13 +2277,16 @@ var LazyRead = class {
2276
2277
  #release;
2277
2278
  #closed = false;
2278
2279
  assertValidHash;
2279
- constructor(heads, memOnlyChunks, sourceChunksCache, sourceStore, release, assertValidHash) {
2280
+ #sourceReadOwnedByCaller;
2281
+ constructor(heads, memOnlyChunks, sourceChunksCache, sourceStore, release, assertValidHash, sourceRead) {
2280
2282
  this._heads = heads;
2281
2283
  this._memOnlyChunks = memOnlyChunks;
2282
2284
  this._sourceChunksCache = sourceChunksCache;
2283
2285
  this._sourceStore = sourceStore;
2284
2286
  this.#release = release;
2285
2287
  this.assertValidHash = assertValidHash;
2288
+ this.#sourceRead = sourceRead !== void 0 ? Promise.resolve(sourceRead) : void 0;
2289
+ this.#sourceReadOwnedByCaller = sourceRead !== void 0;
2286
2290
  }
2287
2291
  isMemOnlyChunkHash(hash2) {
2288
2292
  return this._memOnlyChunks.has(hash2);
@@ -2313,8 +2317,10 @@ var LazyRead = class {
2313
2317
  release() {
2314
2318
  if (!this.#closed) {
2315
2319
  this.#release();
2316
- this.#sourceRead?.then((read) => read.release()).catch((_) => {
2317
- });
2320
+ if (!this.#sourceReadOwnedByCaller) {
2321
+ this.#sourceRead?.then((read) => read.release()).catch((_) => {
2322
+ });
2323
+ }
2318
2324
  this.#closed = true;
2319
2325
  }
2320
2326
  }
@@ -3846,6 +3852,10 @@ async function readFromHead(name, dagRead, formatVersion) {
3846
3852
  const commit = await commitFromHead(name, dagRead);
3847
3853
  return readFromCommit(commit, dagRead, formatVersion);
3848
3854
  }
3855
+ async function readFromHash(hash2, dagRead, formatVersion) {
3856
+ const commit = await commitFromHash(hash2, dagRead);
3857
+ return readFromCommit(commit, dagRead, formatVersion);
3858
+ }
3849
3859
  function readFromCommit(commit, dagRead, formatVersion) {
3850
3860
  const indexes = readIndexesForRead(commit, dagRead, formatVersion);
3851
3861
  const map = new BTreeRead(dagRead, formatVersion, commit.valueHash);
@@ -4563,7 +4573,7 @@ var Write = class extends Read {
4563
4573
  const commitHash = (await commit).chunk.hash;
4564
4574
  await this.#dagWrite.setHead(headName, commitHash);
4565
4575
  await this.#dagWrite.commit();
4566
- return diffMap;
4576
+ return [commitHash, diffMap];
4567
4577
  }
4568
4578
  async #generateDiffs(diffConfig) {
4569
4579
  const diffsMap = new DiffsMap();
@@ -5325,6 +5335,8 @@ function maybeEndPull(store, lc, expectedSyncHead, clientID, diffConfig, formatV
5325
5335
  if (pending.length > 0) {
5326
5336
  return {
5327
5337
  syncHead: syncHeadHash,
5338
+ oldMainHead: mainHeadHash,
5339
+ mainHead: mainHeadHash,
5328
5340
  replayMutations: pending,
5329
5341
  // The changed keys are not reported when further replays are
5330
5342
  // needed. The diffs will be reported at the end when there
@@ -5361,6 +5373,7 @@ function maybeEndPull(store, lc, expectedSyncHead, clientID, diffConfig, formatV
5361
5373
  dagWrite.removeHead(SYNC_HEAD_NAME)
5362
5374
  ]);
5363
5375
  await dagWrite.commit();
5376
+ const newMainHeadHash = syncHeadHash;
5364
5377
  if (lc.debug) {
5365
5378
  const [oldLastMutationID, oldCookie] = snapshotMetaParts(
5366
5379
  mainSnapshot,
@@ -5391,6 +5404,8 @@ function maybeEndPull(store, lc, expectedSyncHead, clientID, diffConfig, formatV
5391
5404
  }
5392
5405
  return {
5393
5406
  syncHead: syncHeadHash,
5407
+ oldMainHead: mainHeadHash,
5408
+ mainHead: newMainHeadHash,
5394
5409
  replayMutations: [],
5395
5410
  diffs: diffsMap
5396
5411
  };
@@ -6236,7 +6251,7 @@ var GatherMemoryOnlyVisitor = class extends Visitor {
6236
6251
  };
6237
6252
 
6238
6253
  // ../replicache/src/persist/persist.ts
6239
- async function persistDD31(lc, clientID, memdag, perdag, mutators, closed, formatVersion, onGatherMemOnlyChunksForTest = () => Promise.resolve()) {
6254
+ async function persistDD31(lc, clientID, memdag, perdag, mutators, closed, formatVersion, getZeroData, onGatherMemOnlyChunksForTest = () => Promise.resolve()) {
6240
6255
  if (closed()) {
6241
6256
  return;
6242
6257
  }
@@ -6300,6 +6315,7 @@ async function persistDD31(lc, clientID, memdag, perdag, mutators, closed, forma
6300
6315
  return;
6301
6316
  }
6302
6317
  let memdagBaseSnapshotPersisted = false;
6318
+ const zeroDataForMemdagBaseSnapshot = getZeroData && await getZeroData("rebase", memdagBaseSnapshot.chunk.hash);
6303
6319
  await withWrite(perdag, async (perdagWrite) => {
6304
6320
  const [mainClientGroup, latestPerdagMainClientGroupHeadCommit] = await getClientGroupInfo(perdagWrite, mainClientGroupID);
6305
6321
  let newMainClientGroupHeadHash = latestPerdagMainClientGroupHeadCommit.chunk.hash;
@@ -6345,10 +6361,17 @@ async function persistDD31(lc, clientID, memdag, perdag, mutators, closed, forma
6345
6361
  mutators,
6346
6362
  mutationIDs,
6347
6363
  lc,
6348
- formatVersion
6364
+ formatVersion,
6365
+ zeroDataForMemdagBaseSnapshot
6349
6366
  );
6350
6367
  }
6351
6368
  }
6369
+ let zeroDataForPerdagHeadCommit;
6370
+ if (!memdagBaseSnapshotPersisted) {
6371
+ zeroDataForPerdagHeadCommit = getZeroData && await getZeroData("rebase", newMainClientGroupHeadHash, {
6372
+ openLazySourceRead: perdagWrite
6373
+ });
6374
+ }
6352
6375
  newMainClientGroupHeadHash = await rebase(
6353
6376
  newMemdagMutations,
6354
6377
  newMainClientGroupHeadHash,
@@ -6356,7 +6379,8 @@ async function persistDD31(lc, clientID, memdag, perdag, mutators, closed, forma
6356
6379
  mutators,
6357
6380
  mutationIDs,
6358
6381
  lc,
6359
- formatVersion
6382
+ formatVersion,
6383
+ zeroDataForPerdagHeadCommit ?? zeroDataForMemdagBaseSnapshot
6360
6384
  );
6361
6385
  const newMainClientGroup = {
6362
6386
  ...mainClientGroup,
@@ -6378,7 +6402,7 @@ async function getClientGroupInfo(perdagRead, clientGroupID) {
6378
6402
  assert(clientGroup, `No client group for clientGroupID: ${clientGroupID}`);
6379
6403
  return [clientGroup, await commitFromHash(clientGroup.headHash, perdagRead)];
6380
6404
  }
6381
- async function rebase(mutations, basis, write, mutators, mutationIDs, lc, formatVersion) {
6405
+ async function rebase(mutations, basis, write, mutators, mutationIDs, lc, formatVersion, zeroData2) {
6382
6406
  for (let i = mutations.length - 1; i >= 0; i--) {
6383
6407
  const mutationCommit = mutations[i];
6384
6408
  const { meta } = mutationCommit;
@@ -6393,7 +6417,7 @@ async function rebase(mutations, basis, write, mutators, mutationIDs, lc, format
6393
6417
  lc,
6394
6418
  meta.clientID,
6395
6419
  formatVersion,
6396
- void 0
6420
+ zeroData2
6397
6421
  )).chunk.hash;
6398
6422
  }
6399
6423
  }
@@ -6435,7 +6459,7 @@ var GatherNotCachedVisitor = class extends Visitor {
6435
6459
  // ../replicache/src/persist/refresh.ts
6436
6460
  var GATHER_SIZE_LIMIT = 5 * 2 ** 20;
6437
6461
  var DELAY_MS = 300;
6438
- async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, closed, formatVersion) {
6462
+ async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, closed, formatVersion, zero) {
6439
6463
  if (closed()) {
6440
6464
  return;
6441
6465
  }
@@ -6550,17 +6574,26 @@ async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, close
6550
6574
  }
6551
6575
  await Promise.all(ps);
6552
6576
  let newMemdagHeadHash = perdagClientGroupHeadHash;
6553
- for (let i = newMemdagMutations.length - 1; i >= 0; i--) {
6554
- newMemdagHeadHash = (await rebaseMutationAndPutCommit(
6555
- newMemdagMutations[i],
6556
- memdagWrite,
6577
+ if (newMemdagMutations.length > 0) {
6578
+ const zeroData2 = await zero?.getTxData?.(
6579
+ "rebase",
6557
6580
  newMemdagHeadHash,
6558
- mutators,
6559
- lc,
6560
- newMemdagMutations[i].meta.clientID,
6561
- formatVersion,
6562
- void 0
6563
- )).chunk.hash;
6581
+ {
6582
+ openLazyRead: memdagWrite
6583
+ }
6584
+ );
6585
+ for (let i = newMemdagMutations.length - 1; i >= 0; i--) {
6586
+ newMemdagHeadHash = (await rebaseMutationAndPutCommit(
6587
+ newMemdagMutations[i],
6588
+ memdagWrite,
6589
+ newMemdagHeadHash,
6590
+ mutators,
6591
+ lc,
6592
+ newMemdagMutations[i].meta.clientID,
6593
+ formatVersion,
6594
+ zeroData2
6595
+ )).chunk.hash;
6596
+ }
6564
6597
  }
6565
6598
  const newMemdagHeadCommit = await commitFromHash(
6566
6599
  newMemdagHeadHash,
@@ -6577,6 +6610,8 @@ async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, close
6577
6610
  return {
6578
6611
  type: "complete",
6579
6612
  diffs,
6613
+ oldHead: memdagHeadCommit.chunk.hash,
6614
+ newHead: newMemdagHeadHash,
6580
6615
  newPerdagClientHeadHash: perdagClientGroupHeadHash
6581
6616
  };
6582
6617
  });
@@ -6598,8 +6633,13 @@ async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, close
6598
6633
  }
6599
6634
  return void 0;
6600
6635
  }
6636
+ zero?.advance(result.oldHead, result.newHead, result.diffs.get("") ?? []);
6601
6637
  await setRefreshHashes([result.newPerdagClientHeadHash]);
6602
- return result.diffs;
6638
+ return {
6639
+ oldHead: result.oldHead,
6640
+ newHead: result.newHead,
6641
+ diffs: result.diffs
6642
+ };
6603
6643
  }
6604
6644
  function shouldAbortRefresh(memdagBaseSnapshot, perdagClientGroupBaseSnapshot, perdagClientGroupHeadHash) {
6605
6645
  const baseSnapshotCookieCompareResult = compareCookiesForSnapshots(
@@ -7187,6 +7227,7 @@ var ReplicacheImpl = class {
7187
7227
  perdag;
7188
7228
  #idbDatabases;
7189
7229
  #lc;
7230
+ #zero;
7190
7231
  #closeAbortController = new AbortController();
7191
7232
  #persistLock = new Lock2();
7192
7233
  #enableScheduledPersist;
@@ -7296,6 +7337,7 @@ var ReplicacheImpl = class {
7296
7337
  onClientsDeleted = () => {
7297
7338
  }
7298
7339
  } = implOptions;
7340
+ this.#zero = implOptions.zero;
7299
7341
  this.auth = auth ?? "";
7300
7342
  this.pullURL = pullURL;
7301
7343
  this.pushURL = pushURL;
@@ -7401,6 +7443,7 @@ var ReplicacheImpl = class {
7401
7443
  this.memdag,
7402
7444
  (write) => write.setHead(DEFAULT_HEAD_NAME, headHash)
7403
7445
  );
7446
+ await this.#zero?.init(headHash, this.memdag);
7404
7447
  resolveReady();
7405
7448
  if (this.#enablePullAndPushInOpen) {
7406
7449
  this.pull().catch(noop2);
@@ -7567,7 +7610,7 @@ var ReplicacheImpl = class {
7567
7610
  await this.#ready;
7568
7611
  const { clientID } = this;
7569
7612
  const lc = this.#lc.withContext("maybeEndPull").withContext("requestID", requestID);
7570
- const { replayMutations, diffs } = await maybeEndPull(
7613
+ const { replayMutations, diffs, oldMainHead, mainHead } = await maybeEndPull(
7571
7614
  this.memdag,
7572
7615
  lc,
7573
7616
  syncHead,
@@ -7576,10 +7619,12 @@ var ReplicacheImpl = class {
7576
7619
  Latest
7577
7620
  );
7578
7621
  if (!replayMutations || replayMutations.length === 0) {
7622
+ this.#zero?.advance(oldMainHead, mainHead, diffs.get("") ?? []);
7579
7623
  await this.#subscriptions.fire(diffs);
7580
7624
  void this.#schedulePersist();
7581
7625
  return;
7582
7626
  }
7627
+ const zeroData2 = await this.#zero?.getTxData?.("rebase", syncHead);
7583
7628
  for (const mutation of replayMutations) {
7584
7629
  if (this.#subscriptions.hasPendingSubscriptionRuns) {
7585
7630
  await Promise.resolve();
@@ -7596,7 +7641,7 @@ var ReplicacheImpl = class {
7596
7641
  lc,
7597
7642
  isLocalMetaDD31(meta) ? meta.clientID : clientID,
7598
7643
  Latest,
7599
- void 0
7644
+ zeroData2
7600
7645
  )
7601
7646
  );
7602
7647
  }
@@ -7908,7 +7953,8 @@ var ReplicacheImpl = class {
7908
7953
  this.perdag,
7909
7954
  this.#mutatorRegistry,
7910
7955
  () => this.#closed,
7911
- Latest
7956
+ Latest,
7957
+ this.#zero?.getTxData
7912
7958
  );
7913
7959
  } catch (e) {
7914
7960
  if (e instanceof ClientStateNotFoundError) {
@@ -7930,9 +7976,9 @@ var ReplicacheImpl = class {
7930
7976
  if (this.#closed) {
7931
7977
  return;
7932
7978
  }
7933
- let diffs;
7979
+ let refreshResult;
7934
7980
  try {
7935
- diffs = await refresh(
7981
+ refreshResult = await refresh(
7936
7982
  this.#lc,
7937
7983
  this.memdag,
7938
7984
  this.perdag,
@@ -7940,7 +7986,8 @@ var ReplicacheImpl = class {
7940
7986
  this.#mutatorRegistry,
7941
7987
  this.#subscriptions,
7942
7988
  () => this.closed,
7943
- Latest
7989
+ Latest,
7990
+ this.#zero
7944
7991
  );
7945
7992
  } catch (e) {
7946
7993
  if (e instanceof ClientStateNotFoundError) {
@@ -7951,8 +7998,8 @@ var ReplicacheImpl = class {
7951
7998
  throw e;
7952
7999
  }
7953
8000
  }
7954
- if (diffs !== void 0) {
7955
- await this.#subscriptions.fire(diffs);
8001
+ if (refreshResult !== void 0) {
8002
+ await this.#subscriptions.fire(refreshResult.diffs);
7956
8003
  }
7957
8004
  }
7958
8005
  #fireOnClientStateNotFound() {
@@ -8143,18 +8190,21 @@ var ReplicacheImpl = class {
8143
8190
  clientID,
8144
8191
  await dbWrite.getMutationID(),
8145
8192
  "initial",
8146
- void 0,
8193
+ await this.#zero?.getTxData("initial", headHash, {
8194
+ openLazyRead: dagWrite
8195
+ }),
8147
8196
  dbWrite,
8148
8197
  this.#lc
8149
8198
  );
8150
8199
  const result = await mutatorImpl(tx, args);
8151
8200
  throwIfClosed(dbWrite);
8152
8201
  const lastMutationID = await dbWrite.getMutationID();
8153
- const diffs = await dbWrite.commitWithDiffs(
8202
+ const [newHead, diffs] = await dbWrite.commitWithDiffs(
8154
8203
  DEFAULT_HEAD_NAME,
8155
8204
  this.#subscriptions
8156
8205
  );
8157
8206
  this.lastMutationID = lastMutationID;
8207
+ this.#zero?.advance(headHash, newHead, diffs.get("") ?? []);
8158
8208
  this.#pushConnectionLoop.send(false).catch(() => void 0);
8159
8209
  await this.#subscriptions.fire(diffs);
8160
8210
  void this.#schedulePersist();
@@ -11751,6 +11801,9 @@ var QueryImpl = class extends AbstractQuery {
11751
11801
  );
11752
11802
  return view;
11753
11803
  }
11804
+ updateTTL(ttl) {
11805
+ this.#delegate.updateServerQuery(this._completeAst(), ttl);
11806
+ }
11754
11807
  run() {
11755
11808
  const v2 = this.materialize();
11756
11809
  const ret = v2.data;
@@ -11829,6 +11882,9 @@ var StaticQuery = class _StaticQuery extends AbstractQuery {
11829
11882
  preload() {
11830
11883
  throw new Error("StaticQuery cannot be preloaded");
11831
11884
  }
11885
+ updateTTL(_ttl) {
11886
+ throw new Error("StaticQuery cannot have a TTL");
11887
+ }
11832
11888
  };
11833
11889
 
11834
11890
  // ../zero-schema/src/name-mapper.ts
@@ -13256,6 +13312,21 @@ var MemorySource = class _MemorySource {
13256
13312
  const exists = (row) => data.has(row);
13257
13313
  const setOverlay = (o) => this.#overlay = o;
13258
13314
  const setSplitEditOverlay = (o) => this.#splitEditOverlay = o;
13315
+ if (change.type === "set") {
13316
+ const existing = data.get(change.row);
13317
+ if (existing !== void 0) {
13318
+ change = {
13319
+ type: "edit",
13320
+ row: change.row,
13321
+ oldRow: existing
13322
+ };
13323
+ } else {
13324
+ change = {
13325
+ type: "add",
13326
+ row: change.row
13327
+ };
13328
+ }
13329
+ }
13259
13330
  for (const x of genPush(
13260
13331
  change,
13261
13332
  exists,
@@ -13615,16 +13686,19 @@ var IVMSourceBranch = class _IVMSourceBranch {
13615
13686
  /**
13616
13687
  * Fork the branch and patch it up to match the desired head.
13617
13688
  */
13618
- async forkToHead(store, expectedHead, desiredHead) {
13689
+ async forkToHead(reason, store, desiredHead, readOptions) {
13690
+ if (reason === "initial") {
13691
+ assert(
13692
+ this.hash === desiredHead,
13693
+ "main branch must be at desired head for `initial`"
13694
+ );
13695
+ return this;
13696
+ }
13619
13697
  const fork = this.fork();
13620
- assert(
13621
- expectedHead === fork.hash,
13622
- () => `Expected head must match the main head. Got: ${expectedHead}, expected: ${fork.hash}`
13623
- );
13624
13698
  if (fork.hash === desiredHead) {
13625
13699
  return fork;
13626
13700
  }
13627
- await patchBranch(desiredHead, store, fork);
13701
+ await patchBranch(desiredHead, store, fork, readOptions);
13628
13702
  fork.hash = desiredHead;
13629
13703
  return fork;
13630
13704
  }
@@ -13649,14 +13723,19 @@ var IVMSourceBranch = class _IVMSourceBranch {
13649
13723
  );
13650
13724
  }
13651
13725
  };
13652
- async function patchBranch(desiredHead, store, fork) {
13653
- const diffs = await computeDiffs(must(fork.hash), desiredHead, store);
13726
+ async function patchBranch(desiredHead, store, fork, readOptions) {
13727
+ const diffs = await computeDiffs(
13728
+ must(fork.hash),
13729
+ desiredHead,
13730
+ store,
13731
+ readOptions
13732
+ );
13654
13733
  if (!diffs) {
13655
13734
  return;
13656
13735
  }
13657
13736
  applyDiffs(diffs, fork);
13658
13737
  }
13659
- async function computeDiffs(startHash, endHash, store) {
13738
+ async function computeDiffs(startHash, endHash, store, readOptions) {
13660
13739
  const readFn = (dagRead) => diff2(
13661
13740
  startHash,
13662
13741
  endHash,
@@ -13669,7 +13748,14 @@ async function computeDiffs(startHash, endHash, store) {
13669
13748
  },
13670
13749
  Latest
13671
13750
  );
13672
- const diffs = await withRead(store, readFn);
13751
+ let diffs;
13752
+ if (readOptions?.openLazySourceRead) {
13753
+ diffs = await using(store.read(readOptions.openLazySourceRead), readFn);
13754
+ } else if (readOptions?.openLazyRead) {
13755
+ diffs = await readFn(readOptions.openLazyRead);
13756
+ } else {
13757
+ diffs = await withRead(store, readFn);
13758
+ }
13673
13759
  return diffs.get("");
13674
13760
  }
13675
13761
  function applyDiffs(diffs, branch) {
@@ -13713,14 +13799,16 @@ var ZeroContext = class {
13713
13799
  // that needs to be fixed.
13714
13800
  #mainSources;
13715
13801
  #addQuery;
13802
+ #updateQuery;
13716
13803
  #batchViewUpdates;
13717
13804
  #commitListeners = /* @__PURE__ */ new Set();
13718
13805
  slowMaterializeThreshold;
13719
13806
  lc;
13720
13807
  staticQueryParameters = void 0;
13721
- constructor(lc, mainSources, addQuery, batchViewUpdates, slowMaterializeThreshold) {
13808
+ constructor(lc, mainSources, addQuery, updateQuery, batchViewUpdates, slowMaterializeThreshold) {
13722
13809
  this.#mainSources = mainSources;
13723
13810
  this.#addQuery = addQuery;
13811
+ this.#updateQuery = updateQuery;
13724
13812
  this.#batchViewUpdates = batchViewUpdates;
13725
13813
  this.lc = lc;
13726
13814
  this.slowMaterializeThreshold = slowMaterializeThreshold;
@@ -13731,6 +13819,9 @@ var ZeroContext = class {
13731
13819
  addServerQuery(ast, ttl, gotCallback) {
13732
13820
  return this.#addQuery(ast, ttl, gotCallback);
13733
13821
  }
13822
+ updateServerQuery(ast, ttl) {
13823
+ this.#updateQuery(ast, ttl);
13824
+ }
13734
13825
  onQueryMaterialized(hash2, ast, duration) {
13735
13826
  if (this.slowMaterializeThreshold !== void 0 && duration > this.slowMaterializeThreshold) {
13736
13827
  this.lc.warn?.(
@@ -13773,45 +13864,10 @@ var ZeroContext = class {
13773
13864
  );
13774
13865
  return result;
13775
13866
  }
13776
- processChanges(changes) {
13867
+ processChanges(expectedHead, newHead, changes) {
13777
13868
  this.batchViewUpdates(() => {
13778
13869
  try {
13779
- for (const diff3 of changes) {
13780
- const { key } = diff3;
13781
- assert(key.startsWith(ENTITIES_KEY_PREFIX));
13782
- const name = sourceNameFromKey(key);
13783
- const source = this.getSource(name);
13784
- if (!source) {
13785
- continue;
13786
- }
13787
- switch (diff3.op) {
13788
- case "del":
13789
- assert(typeof diff3.oldValue === "object");
13790
- source.push({
13791
- type: "remove",
13792
- row: diff3.oldValue
13793
- });
13794
- break;
13795
- case "add":
13796
- assert(typeof diff3.newValue === "object");
13797
- source.push({
13798
- type: "add",
13799
- row: diff3.newValue
13800
- });
13801
- break;
13802
- case "change":
13803
- assert(typeof diff3.newValue === "object");
13804
- assert(typeof diff3.oldValue === "object");
13805
- source.push({
13806
- type: "edit",
13807
- row: diff3.newValue,
13808
- oldRow: diff3.oldValue
13809
- });
13810
- break;
13811
- default:
13812
- unreachable(diff3);
13813
- }
13814
- }
13870
+ this.#mainSources.advance(expectedHead, newHead, changes);
13815
13871
  } finally {
13816
13872
  this.#endTransaction();
13817
13873
  }
@@ -13819,7 +13875,11 @@ var ZeroContext = class {
13819
13875
  }
13820
13876
  #endTransaction() {
13821
13877
  for (const listener of this.#commitListeners) {
13822
- listener();
13878
+ try {
13879
+ listener();
13880
+ } catch (e) {
13881
+ this.lc.error?.("Failed notifying a commit listener of IVM updates", e);
13882
+ }
13823
13883
  }
13824
13884
  }
13825
13885
  };
@@ -13993,7 +14053,7 @@ async function upsertImpl(tx, arg, schema, ivmBranch) {
13993
14053
  await tx.set(key, val);
13994
14054
  if (ivmBranch) {
13995
14055
  must(ivmBranch.getSource(arg.tableName)).push({
13996
- type: "add",
14056
+ type: "set",
13997
14057
  row: arg.value
13998
14058
  });
13999
14059
  }
@@ -14045,7 +14105,7 @@ async function deleteImpl(tx, arg, schema, ivmBranch) {
14045
14105
 
14046
14106
  // ../zero-client/src/client/custom.ts
14047
14107
  var TransactionImpl = class {
14048
- constructor(repTx, schema) {
14108
+ constructor(lc, repTx, schema, slowMaterializeThreshold) {
14049
14109
  const castedRepTx = repTx;
14050
14110
  must(repTx.reason === "initial" || repTx.reason === "rebase");
14051
14111
  this.clientID = repTx.clientID;
@@ -14054,9 +14114,25 @@ var TransactionImpl = class {
14054
14114
  this.mutate = makeSchemaCRUD(
14055
14115
  schema,
14056
14116
  repTx,
14057
- castedRepTx[zeroData]
14117
+ // CRUD operators should not mutate the IVM store directly
14118
+ // for `initial`. The IVM store will be updated via calls to `advance`
14119
+ // after the transaction has been committed to the Replicache b-tree.
14120
+ // Mutating the IVM store in the mutator would cause us to synchronously
14121
+ // notify listeners of IVM while we're inside of the Replicache DB transaction.
14122
+ repTx.reason === "initial" ? void 0 : must(
14123
+ castedRepTx[zeroData],
14124
+ "zero was not set on replicache internal options!"
14125
+ )
14126
+ );
14127
+ this.query = makeSchemaQuery(
14128
+ lc,
14129
+ schema,
14130
+ must(
14131
+ castedRepTx[zeroData],
14132
+ "zero was not set on replicache internal options!"
14133
+ ),
14134
+ slowMaterializeThreshold
14058
14135
  );
14059
- this.query = {};
14060
14136
  }
14061
14137
  clientID;
14062
14138
  mutationID;
@@ -14065,18 +14141,49 @@ var TransactionImpl = class {
14065
14141
  mutate;
14066
14142
  query;
14067
14143
  };
14068
- function makeReplicacheMutator(mutator, schema) {
14144
+ function makeReplicacheMutator(lc, mutator, schema, slowMaterializeThreshold) {
14069
14145
  return (repTx, args) => {
14070
- const tx = new TransactionImpl(repTx, schema);
14146
+ const tx = new TransactionImpl(lc, repTx, schema, slowMaterializeThreshold);
14071
14147
  return mutator(tx, args);
14072
14148
  };
14073
14149
  }
14074
14150
  function makeSchemaCRUD(schema, tx, ivmBranch) {
14075
- const mutate = {};
14076
- for (const [name] of Object.entries(schema.tables)) {
14077
- mutate[name] = makeTableCRUD(schema, name, tx, ivmBranch);
14078
- }
14079
- return mutate;
14151
+ return new Proxy(
14152
+ {},
14153
+ {
14154
+ get(target, prop) {
14155
+ if (prop in target) {
14156
+ return target[prop];
14157
+ }
14158
+ target[prop] = makeTableCRUD(schema, prop, tx, ivmBranch);
14159
+ return target[prop];
14160
+ }
14161
+ }
14162
+ );
14163
+ }
14164
+ function makeSchemaQuery(lc, schema, ivmBranch, slowMaterializeThreshold) {
14165
+ const context = new ZeroContext(
14166
+ lc,
14167
+ ivmBranch,
14168
+ () => () => {
14169
+ },
14170
+ () => {
14171
+ },
14172
+ (applyViewUpdates) => applyViewUpdates(),
14173
+ slowMaterializeThreshold
14174
+ );
14175
+ return new Proxy(
14176
+ {},
14177
+ {
14178
+ get(target, prop) {
14179
+ if (prop in target) {
14180
+ return target[prop];
14181
+ }
14182
+ target[prop] = newQuery(context, schema, prop);
14183
+ return target[prop];
14184
+ }
14185
+ }
14186
+ );
14080
14187
  }
14081
14188
  function makeTableCRUD(schema, tableName, tx, ivmBranch) {
14082
14189
  const table2 = must(schema.tables[tableName]);
@@ -14408,7 +14515,7 @@ function makeMessage(message, context, logLevel) {
14408
14515
  }
14409
14516
 
14410
14517
  // ../zero-client/src/client/version.ts
14411
- var version2 = "0.17.2025031200";
14518
+ var version2 = "0.17.2025031300";
14412
14519
 
14413
14520
  // ../zero-client/src/client/log-options.ts
14414
14521
  var LevelFilterLogSink = class {
@@ -14819,22 +14926,7 @@ var QueryManager = class {
14819
14926
  ]);
14820
14927
  } else {
14821
14928
  ++entry.count;
14822
- if (compareTTL(ttl, entry.ttl) > 0) {
14823
- entry.ttl = ttl;
14824
- this.#send([
14825
- "changeDesiredQueries",
14826
- {
14827
- desiredQueriesPatch: [
14828
- {
14829
- op: "put",
14830
- hash: astHash,
14831
- ast: entry.normalized,
14832
- ttl: parseTTL(ttl)
14833
- }
14834
- ]
14835
- }
14836
- ]);
14837
- }
14929
+ this.#updateEntry(entry, astHash, ttl);
14838
14930
  if (gotCallback) {
14839
14931
  entry.gotCallbacks.push(gotCallback);
14840
14932
  }
@@ -14851,6 +14943,30 @@ var QueryManager = class {
14851
14943
  this.#remove(entry, astHash, gotCallback);
14852
14944
  };
14853
14945
  }
14946
+ update(ast, ttl) {
14947
+ const normalized = normalizeAST(ast);
14948
+ const astHash = hashOfAST(normalized);
14949
+ const entry = must(this.#queries.get(astHash));
14950
+ this.#updateEntry(entry, astHash, ttl);
14951
+ }
14952
+ #updateEntry(entry, hash2, ttl) {
14953
+ if (compareTTL(ttl, entry.ttl) > 0) {
14954
+ entry.ttl = ttl;
14955
+ this.#send([
14956
+ "changeDesiredQueries",
14957
+ {
14958
+ desiredQueriesPatch: [
14959
+ {
14960
+ op: "put",
14961
+ hash: hash2,
14962
+ ast: entry.normalized,
14963
+ ttl: parseTTL(ttl)
14964
+ }
14965
+ ]
14966
+ }
14967
+ ]);
14968
+ }
14969
+ }
14854
14970
  #remove(entry, astHash, gotCallback) {
14855
14971
  if (gotCallback) {
14856
14972
  const index = entry.gotCallbacks.indexOf(gotCallback);
@@ -15322,6 +15438,51 @@ function rafFallback(callback) {
15322
15438
  setTimeout(callback, 0);
15323
15439
  }
15324
15440
 
15441
+ // ../zero-client/src/client/zero-rep.ts
15442
+ var ZeroRep = class {
15443
+ #context;
15444
+ #ivmMain;
15445
+ #customMutatorsEnabled;
15446
+ #store;
15447
+ constructor(context, ivmMain, customMutatorsEnabled) {
15448
+ this.#context = context;
15449
+ this.#ivmMain = ivmMain;
15450
+ this.#customMutatorsEnabled = customMutatorsEnabled;
15451
+ }
15452
+ async init(hash2, store) {
15453
+ const diffs = [];
15454
+ await withRead(store, async (dagRead) => {
15455
+ const read = await readFromHash(hash2, dagRead, Latest);
15456
+ for await (const entry of read.map.scan(ENTITIES_KEY_PREFIX)) {
15457
+ if (!entry[0].startsWith(ENTITIES_KEY_PREFIX)) {
15458
+ break;
15459
+ }
15460
+ diffs.push({
15461
+ op: "add",
15462
+ key: entry[0],
15463
+ newValue: entry[1]
15464
+ });
15465
+ }
15466
+ });
15467
+ this.#store = store;
15468
+ this.#context.processChanges(void 0, hash2, diffs);
15469
+ }
15470
+ getTxData = (reason, desiredHead, readOptions) => {
15471
+ if (!this.#customMutatorsEnabled) {
15472
+ return;
15473
+ }
15474
+ return this.#ivmMain.forkToHead(
15475
+ reason,
15476
+ must(this.#store),
15477
+ desiredHead,
15478
+ readOptions
15479
+ );
15480
+ };
15481
+ advance = (expectedHash, newHash, diffs) => {
15482
+ this.#context.processChanges(expectedHash, newHash, diffs);
15483
+ };
15484
+ };
15485
+
15325
15486
  // ../zero-client/src/client/zero.ts
15326
15487
  var onSetConnectionStateSymbol = Symbol();
15327
15488
  var exposedToTestingSymbol = Symbol();
@@ -15512,13 +15673,19 @@ var Zero = class {
15512
15673
  [CRUD_MUTATION_NAME]: makeCRUDMutator(schema)
15513
15674
  };
15514
15675
  this.#ivmMain = new IVMSourceBranch(schema.tables);
15676
+ const lc = new LogContext4(logOptions.logLevel, {}, logOptions.logSink);
15515
15677
  for (const [namespace, mutatorsForNamespace] of Object.entries(
15516
15678
  options.mutators ?? {}
15517
15679
  )) {
15518
15680
  for (const [name, mutator] of Object.entries(
15519
15681
  mutatorsForNamespace
15520
15682
  )) {
15521
- replicacheMutators[customMutatorKey(namespace, name)] = makeReplicacheMutator(mutator, schema);
15683
+ replicacheMutators[customMutatorKey(namespace, name)] = makeReplicacheMutator(
15684
+ lc,
15685
+ mutator,
15686
+ schema,
15687
+ slowMaterializeThreshold
15688
+ );
15522
15689
  }
15523
15690
  }
15524
15691
  this.storageKey = storageKey ?? "";
@@ -15542,10 +15709,23 @@ var Zero = class {
15542
15709
  licenseKey: "zero-client-static-key",
15543
15710
  kvStore
15544
15711
  };
15712
+ this.#zeroContext = new ZeroContext(
15713
+ lc,
15714
+ this.#ivmMain,
15715
+ (ast, ttl, gotCallback) => this.#queryManager.add(ast, ttl, gotCallback),
15716
+ (ast, ttl) => this.#queryManager.update(ast, ttl),
15717
+ batchViewUpdates,
15718
+ slowMaterializeThreshold
15719
+ );
15545
15720
  const replicacheImplOptions = {
15546
15721
  enableClientGroupForking: false,
15547
15722
  enableMutationRecovery: false,
15548
- onClientsDeleted: (clientIDs, clientGroupIDs) => this.#deleteClientsManager.onClientsDeleted(clientIDs, clientGroupIDs)
15723
+ onClientsDeleted: (clientIDs, clientGroupIDs) => this.#deleteClientsManager.onClientsDeleted(clientIDs, clientGroupIDs),
15724
+ zero: new ZeroRep(
15725
+ this.#zeroContext,
15726
+ this.#ivmMain,
15727
+ options.mutators !== void 0
15728
+ )
15549
15729
  };
15550
15730
  const rep = new ReplicacheImpl(replicacheOptions, replicacheImplOptions);
15551
15731
  this.#rep = rep;
@@ -15554,11 +15734,7 @@ var Zero = class {
15554
15734
  }
15555
15735
  this.#server = server;
15556
15736
  this.userID = userID;
15557
- this.#lc = new LogContext4(
15558
- logOptions.logLevel,
15559
- { clientID: rep.clientID },
15560
- logOptions.logSink
15561
- );
15737
+ this.#lc = lc.withContext("clientID", rep.clientID);
15562
15738
  const onUpdateNeededCallback = onUpdateNeeded ?? ((reason, serverErrorMsg) => {
15563
15739
  reloadWithReason(
15564
15740
  this.#lc,
@@ -15613,20 +15789,6 @@ var Zero = class {
15613
15789
  rep.perdag,
15614
15790
  this.#lc
15615
15791
  );
15616
- this.#zeroContext = new ZeroContext(
15617
- this.#lc,
15618
- this.#ivmMain,
15619
- (ast, ttl, gotCallback) => this.#queryManager.add(ast, ttl, gotCallback),
15620
- batchViewUpdates,
15621
- slowMaterializeThreshold
15622
- );
15623
- rep.experimentalWatch(
15624
- (diff3) => this.#zeroContext.processChanges(diff3),
15625
- {
15626
- prefix: ENTITIES_KEY_PREFIX,
15627
- initialValuesInFirstDiff: true
15628
- }
15629
- );
15630
15792
  this.query = this.#registerQueries(schema);
15631
15793
  reportReloadReason(this.#lc);
15632
15794
  this.#metrics = new MetricManager({
@@ -16629,4 +16791,4 @@ export {
16629
16791
  escapeLike,
16630
16792
  Zero
16631
16793
  };
16632
- //# sourceMappingURL=chunk-VNV6U5BQ.js.map
16794
+ //# sourceMappingURL=chunk-APXCO5Z2.js.map