@rocicorp/zero 0.17.2025031100 → 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 (106) hide show
  1. package/out/advanced.js +1 -1
  2. package/out/chunk-5X3DESC6.js +45 -0
  3. package/out/chunk-5X3DESC6.js.map +7 -0
  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-2TJNN7K4.js → chunk-APXCO5Z2.js} +436 -207
  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 +18 -9
  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 +1 -1
  56. package/out/zero-react/src/use-query.d.ts.map +1 -1
  57. package/out/zero-solid/src/use-query.d.ts.map +1 -1
  58. package/out/zero.js +5 -4
  59. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  60. package/out/zql/src/ivm/exists.js +1 -5
  61. package/out/zql/src/ivm/exists.js.map +1 -1
  62. package/out/zql/src/ivm/join.d.ts.map +1 -1
  63. package/out/zql/src/ivm/join.js +123 -15
  64. package/out/zql/src/ivm/join.js.map +1 -1
  65. package/out/zql/src/ivm/memory-source.d.ts +3 -3
  66. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  67. package/out/zql/src/ivm/memory-source.js +16 -0
  68. package/out/zql/src/ivm/memory-source.js.map +1 -1
  69. package/out/zql/src/ivm/source.d.ts +5 -1
  70. package/out/zql/src/ivm/source.d.ts.map +1 -1
  71. package/out/zql/src/ivm/take.d.ts.map +1 -1
  72. package/out/zql/src/ivm/take.js +7 -11
  73. package/out/zql/src/ivm/take.js.map +1 -1
  74. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  75. package/out/zql/src/ivm/view-apply-change.js +40 -8
  76. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  77. package/out/zql/src/query/expression.d.ts +20 -0
  78. package/out/zql/src/query/expression.d.ts.map +1 -1
  79. package/out/zql/src/query/expression.js +1 -1
  80. package/out/zql/src/query/expression.js.map +1 -1
  81. package/out/zql/src/query/query-impl.d.ts +5 -2
  82. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  83. package/out/zql/src/query/query-impl.js +5 -1
  84. package/out/zql/src/query/query-impl.js.map +1 -1
  85. package/out/zql/src/query/query-internal.d.ts +1 -0
  86. package/out/zql/src/query/query-internal.d.ts.map +1 -1
  87. package/out/zql/src/query/query.d.ts +0 -1
  88. package/out/zql/src/query/query.d.ts.map +1 -1
  89. package/out/zql/src/query/query.js +1 -1
  90. package/out/zql/src/query/query.js.map +1 -1
  91. package/out/zql/src/query/static-query.d.ts +2 -0
  92. package/out/zql/src/query/static-query.d.ts.map +1 -1
  93. package/out/zql/src/query/static-query.js +3 -0
  94. package/out/zql/src/query/static-query.js.map +1 -1
  95. package/out/zql/src/query/ttl.d.ts +1 -0
  96. package/out/zql/src/query/ttl.d.ts.map +1 -1
  97. package/out/zql/src/query/ttl.js +22 -0
  98. package/out/zql/src/query/ttl.js.map +1 -1
  99. package/out/zqlite/src/table-source.d.ts +3 -3
  100. package/out/zqlite/src/table-source.d.ts.map +1 -1
  101. package/out/zqlite/src/table-source.js +17 -0
  102. package/out/zqlite/src/table-source.js.map +1 -1
  103. package/package.json +1 -1
  104. package/out/chunk-2TJNN7K4.js.map +0 -7
  105. package/out/chunk-HLTH2AYN.js +0 -12
  106. package/out/chunk-HLTH2AYN.js.map +0 -7
@@ -1,7 +1,9 @@
1
1
  import {
2
2
  DEFAULT_TTL,
3
- hasOwn
4
- } from "./chunk-HLTH2AYN.js";
3
+ compareTTL,
4
+ hasOwn,
5
+ parseTTL
6
+ } from "./chunk-5X3DESC6.js";
5
7
  import {
6
8
  applyChange,
7
9
  assert,
@@ -19,7 +21,7 @@ import {
19
21
  throwInvalidType,
20
22
  unreachable,
21
23
  valuesEqual
22
- } from "./chunk-6CQ6CUML.js";
24
+ } from "./chunk-7ARRNDLF.js";
23
25
  import {
24
26
  __export,
25
27
  __reExport
@@ -2227,7 +2229,7 @@ var LazyStore = class {
2227
2229
  this.#chunkHasher = chunkHasher;
2228
2230
  this.#assertValidHash = assertValidHash;
2229
2231
  }
2230
- async read() {
2232
+ async read(sourceRead) {
2231
2233
  const release = await this.#rwLock.read();
2232
2234
  return new LazyRead(
2233
2235
  this.#heads,
@@ -2235,7 +2237,8 @@ var LazyStore = class {
2235
2237
  this._sourceChunksCache,
2236
2238
  this.#sourceStore,
2237
2239
  release,
2238
- this.#assertValidHash
2240
+ this.#assertValidHash,
2241
+ sourceRead
2239
2242
  );
2240
2243
  }
2241
2244
  async write() {
@@ -2274,13 +2277,16 @@ var LazyRead = class {
2274
2277
  #release;
2275
2278
  #closed = false;
2276
2279
  assertValidHash;
2277
- constructor(heads, memOnlyChunks, sourceChunksCache, sourceStore, release, assertValidHash) {
2280
+ #sourceReadOwnedByCaller;
2281
+ constructor(heads, memOnlyChunks, sourceChunksCache, sourceStore, release, assertValidHash, sourceRead) {
2278
2282
  this._heads = heads;
2279
2283
  this._memOnlyChunks = memOnlyChunks;
2280
2284
  this._sourceChunksCache = sourceChunksCache;
2281
2285
  this._sourceStore = sourceStore;
2282
2286
  this.#release = release;
2283
2287
  this.assertValidHash = assertValidHash;
2288
+ this.#sourceRead = sourceRead !== void 0 ? Promise.resolve(sourceRead) : void 0;
2289
+ this.#sourceReadOwnedByCaller = sourceRead !== void 0;
2284
2290
  }
2285
2291
  isMemOnlyChunkHash(hash2) {
2286
2292
  return this._memOnlyChunks.has(hash2);
@@ -2311,8 +2317,10 @@ var LazyRead = class {
2311
2317
  release() {
2312
2318
  if (!this.#closed) {
2313
2319
  this.#release();
2314
- this.#sourceRead?.then((read) => read.release()).catch((_) => {
2315
- });
2320
+ if (!this.#sourceReadOwnedByCaller) {
2321
+ this.#sourceRead?.then((read) => read.release()).catch((_) => {
2322
+ });
2323
+ }
2316
2324
  this.#closed = true;
2317
2325
  }
2318
2326
  }
@@ -3844,6 +3852,10 @@ async function readFromHead(name, dagRead, formatVersion) {
3844
3852
  const commit = await commitFromHead(name, dagRead);
3845
3853
  return readFromCommit(commit, dagRead, formatVersion);
3846
3854
  }
3855
+ async function readFromHash(hash2, dagRead, formatVersion) {
3856
+ const commit = await commitFromHash(hash2, dagRead);
3857
+ return readFromCommit(commit, dagRead, formatVersion);
3858
+ }
3847
3859
  function readFromCommit(commit, dagRead, formatVersion) {
3848
3860
  const indexes = readIndexesForRead(commit, dagRead, formatVersion);
3849
3861
  const map = new BTreeRead(dagRead, formatVersion, commit.valueHash);
@@ -4561,7 +4573,7 @@ var Write = class extends Read {
4561
4573
  const commitHash = (await commit).chunk.hash;
4562
4574
  await this.#dagWrite.setHead(headName, commitHash);
4563
4575
  await this.#dagWrite.commit();
4564
- return diffMap;
4576
+ return [commitHash, diffMap];
4565
4577
  }
4566
4578
  async #generateDiffs(diffConfig) {
4567
4579
  const diffsMap = new DiffsMap();
@@ -5323,6 +5335,8 @@ function maybeEndPull(store, lc, expectedSyncHead, clientID, diffConfig, formatV
5323
5335
  if (pending.length > 0) {
5324
5336
  return {
5325
5337
  syncHead: syncHeadHash,
5338
+ oldMainHead: mainHeadHash,
5339
+ mainHead: mainHeadHash,
5326
5340
  replayMutations: pending,
5327
5341
  // The changed keys are not reported when further replays are
5328
5342
  // needed. The diffs will be reported at the end when there
@@ -5359,6 +5373,7 @@ function maybeEndPull(store, lc, expectedSyncHead, clientID, diffConfig, formatV
5359
5373
  dagWrite.removeHead(SYNC_HEAD_NAME)
5360
5374
  ]);
5361
5375
  await dagWrite.commit();
5376
+ const newMainHeadHash = syncHeadHash;
5362
5377
  if (lc.debug) {
5363
5378
  const [oldLastMutationID, oldCookie] = snapshotMetaParts(
5364
5379
  mainSnapshot,
@@ -5389,6 +5404,8 @@ function maybeEndPull(store, lc, expectedSyncHead, clientID, diffConfig, formatV
5389
5404
  }
5390
5405
  return {
5391
5406
  syncHead: syncHeadHash,
5407
+ oldMainHead: mainHeadHash,
5408
+ mainHead: newMainHeadHash,
5392
5409
  replayMutations: [],
5393
5410
  diffs: diffsMap
5394
5411
  };
@@ -6234,7 +6251,7 @@ var GatherMemoryOnlyVisitor = class extends Visitor {
6234
6251
  };
6235
6252
 
6236
6253
  // ../replicache/src/persist/persist.ts
6237
- 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()) {
6238
6255
  if (closed()) {
6239
6256
  return;
6240
6257
  }
@@ -6298,6 +6315,7 @@ async function persistDD31(lc, clientID, memdag, perdag, mutators, closed, forma
6298
6315
  return;
6299
6316
  }
6300
6317
  let memdagBaseSnapshotPersisted = false;
6318
+ const zeroDataForMemdagBaseSnapshot = getZeroData && await getZeroData("rebase", memdagBaseSnapshot.chunk.hash);
6301
6319
  await withWrite(perdag, async (perdagWrite) => {
6302
6320
  const [mainClientGroup, latestPerdagMainClientGroupHeadCommit] = await getClientGroupInfo(perdagWrite, mainClientGroupID);
6303
6321
  let newMainClientGroupHeadHash = latestPerdagMainClientGroupHeadCommit.chunk.hash;
@@ -6343,10 +6361,17 @@ async function persistDD31(lc, clientID, memdag, perdag, mutators, closed, forma
6343
6361
  mutators,
6344
6362
  mutationIDs,
6345
6363
  lc,
6346
- formatVersion
6364
+ formatVersion,
6365
+ zeroDataForMemdagBaseSnapshot
6347
6366
  );
6348
6367
  }
6349
6368
  }
6369
+ let zeroDataForPerdagHeadCommit;
6370
+ if (!memdagBaseSnapshotPersisted) {
6371
+ zeroDataForPerdagHeadCommit = getZeroData && await getZeroData("rebase", newMainClientGroupHeadHash, {
6372
+ openLazySourceRead: perdagWrite
6373
+ });
6374
+ }
6350
6375
  newMainClientGroupHeadHash = await rebase(
6351
6376
  newMemdagMutations,
6352
6377
  newMainClientGroupHeadHash,
@@ -6354,7 +6379,8 @@ async function persistDD31(lc, clientID, memdag, perdag, mutators, closed, forma
6354
6379
  mutators,
6355
6380
  mutationIDs,
6356
6381
  lc,
6357
- formatVersion
6382
+ formatVersion,
6383
+ zeroDataForPerdagHeadCommit ?? zeroDataForMemdagBaseSnapshot
6358
6384
  );
6359
6385
  const newMainClientGroup = {
6360
6386
  ...mainClientGroup,
@@ -6376,7 +6402,7 @@ async function getClientGroupInfo(perdagRead, clientGroupID) {
6376
6402
  assert(clientGroup, `No client group for clientGroupID: ${clientGroupID}`);
6377
6403
  return [clientGroup, await commitFromHash(clientGroup.headHash, perdagRead)];
6378
6404
  }
6379
- async function rebase(mutations, basis, write, mutators, mutationIDs, lc, formatVersion) {
6405
+ async function rebase(mutations, basis, write, mutators, mutationIDs, lc, formatVersion, zeroData2) {
6380
6406
  for (let i = mutations.length - 1; i >= 0; i--) {
6381
6407
  const mutationCommit = mutations[i];
6382
6408
  const { meta } = mutationCommit;
@@ -6391,7 +6417,7 @@ async function rebase(mutations, basis, write, mutators, mutationIDs, lc, format
6391
6417
  lc,
6392
6418
  meta.clientID,
6393
6419
  formatVersion,
6394
- void 0
6420
+ zeroData2
6395
6421
  )).chunk.hash;
6396
6422
  }
6397
6423
  }
@@ -6433,7 +6459,7 @@ var GatherNotCachedVisitor = class extends Visitor {
6433
6459
  // ../replicache/src/persist/refresh.ts
6434
6460
  var GATHER_SIZE_LIMIT = 5 * 2 ** 20;
6435
6461
  var DELAY_MS = 300;
6436
- async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, closed, formatVersion) {
6462
+ async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, closed, formatVersion, zero) {
6437
6463
  if (closed()) {
6438
6464
  return;
6439
6465
  }
@@ -6548,17 +6574,26 @@ async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, close
6548
6574
  }
6549
6575
  await Promise.all(ps);
6550
6576
  let newMemdagHeadHash = perdagClientGroupHeadHash;
6551
- for (let i = newMemdagMutations.length - 1; i >= 0; i--) {
6552
- newMemdagHeadHash = (await rebaseMutationAndPutCommit(
6553
- newMemdagMutations[i],
6554
- memdagWrite,
6577
+ if (newMemdagMutations.length > 0) {
6578
+ const zeroData2 = await zero?.getTxData?.(
6579
+ "rebase",
6555
6580
  newMemdagHeadHash,
6556
- mutators,
6557
- lc,
6558
- newMemdagMutations[i].meta.clientID,
6559
- formatVersion,
6560
- void 0
6561
- )).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
+ }
6562
6597
  }
6563
6598
  const newMemdagHeadCommit = await commitFromHash(
6564
6599
  newMemdagHeadHash,
@@ -6575,6 +6610,8 @@ async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, close
6575
6610
  return {
6576
6611
  type: "complete",
6577
6612
  diffs,
6613
+ oldHead: memdagHeadCommit.chunk.hash,
6614
+ newHead: newMemdagHeadHash,
6578
6615
  newPerdagClientHeadHash: perdagClientGroupHeadHash
6579
6616
  };
6580
6617
  });
@@ -6596,8 +6633,13 @@ async function refresh(lc, memdag, perdag, clientID, mutators, diffConfig, close
6596
6633
  }
6597
6634
  return void 0;
6598
6635
  }
6636
+ zero?.advance(result.oldHead, result.newHead, result.diffs.get("") ?? []);
6599
6637
  await setRefreshHashes([result.newPerdagClientHeadHash]);
6600
- return result.diffs;
6638
+ return {
6639
+ oldHead: result.oldHead,
6640
+ newHead: result.newHead,
6641
+ diffs: result.diffs
6642
+ };
6601
6643
  }
6602
6644
  function shouldAbortRefresh(memdagBaseSnapshot, perdagClientGroupBaseSnapshot, perdagClientGroupHeadHash) {
6603
6645
  const baseSnapshotCookieCompareResult = compareCookiesForSnapshots(
@@ -7185,6 +7227,7 @@ var ReplicacheImpl = class {
7185
7227
  perdag;
7186
7228
  #idbDatabases;
7187
7229
  #lc;
7230
+ #zero;
7188
7231
  #closeAbortController = new AbortController();
7189
7232
  #persistLock = new Lock2();
7190
7233
  #enableScheduledPersist;
@@ -7294,6 +7337,7 @@ var ReplicacheImpl = class {
7294
7337
  onClientsDeleted = () => {
7295
7338
  }
7296
7339
  } = implOptions;
7340
+ this.#zero = implOptions.zero;
7297
7341
  this.auth = auth ?? "";
7298
7342
  this.pullURL = pullURL;
7299
7343
  this.pushURL = pushURL;
@@ -7399,6 +7443,7 @@ var ReplicacheImpl = class {
7399
7443
  this.memdag,
7400
7444
  (write) => write.setHead(DEFAULT_HEAD_NAME, headHash)
7401
7445
  );
7446
+ await this.#zero?.init(headHash, this.memdag);
7402
7447
  resolveReady();
7403
7448
  if (this.#enablePullAndPushInOpen) {
7404
7449
  this.pull().catch(noop2);
@@ -7565,7 +7610,7 @@ var ReplicacheImpl = class {
7565
7610
  await this.#ready;
7566
7611
  const { clientID } = this;
7567
7612
  const lc = this.#lc.withContext("maybeEndPull").withContext("requestID", requestID);
7568
- const { replayMutations, diffs } = await maybeEndPull(
7613
+ const { replayMutations, diffs, oldMainHead, mainHead } = await maybeEndPull(
7569
7614
  this.memdag,
7570
7615
  lc,
7571
7616
  syncHead,
@@ -7574,10 +7619,12 @@ var ReplicacheImpl = class {
7574
7619
  Latest
7575
7620
  );
7576
7621
  if (!replayMutations || replayMutations.length === 0) {
7622
+ this.#zero?.advance(oldMainHead, mainHead, diffs.get("") ?? []);
7577
7623
  await this.#subscriptions.fire(diffs);
7578
7624
  void this.#schedulePersist();
7579
7625
  return;
7580
7626
  }
7627
+ const zeroData2 = await this.#zero?.getTxData?.("rebase", syncHead);
7581
7628
  for (const mutation of replayMutations) {
7582
7629
  if (this.#subscriptions.hasPendingSubscriptionRuns) {
7583
7630
  await Promise.resolve();
@@ -7594,7 +7641,7 @@ var ReplicacheImpl = class {
7594
7641
  lc,
7595
7642
  isLocalMetaDD31(meta) ? meta.clientID : clientID,
7596
7643
  Latest,
7597
- void 0
7644
+ zeroData2
7598
7645
  )
7599
7646
  );
7600
7647
  }
@@ -7906,7 +7953,8 @@ var ReplicacheImpl = class {
7906
7953
  this.perdag,
7907
7954
  this.#mutatorRegistry,
7908
7955
  () => this.#closed,
7909
- Latest
7956
+ Latest,
7957
+ this.#zero?.getTxData
7910
7958
  );
7911
7959
  } catch (e) {
7912
7960
  if (e instanceof ClientStateNotFoundError) {
@@ -7928,9 +7976,9 @@ var ReplicacheImpl = class {
7928
7976
  if (this.#closed) {
7929
7977
  return;
7930
7978
  }
7931
- let diffs;
7979
+ let refreshResult;
7932
7980
  try {
7933
- diffs = await refresh(
7981
+ refreshResult = await refresh(
7934
7982
  this.#lc,
7935
7983
  this.memdag,
7936
7984
  this.perdag,
@@ -7938,7 +7986,8 @@ var ReplicacheImpl = class {
7938
7986
  this.#mutatorRegistry,
7939
7987
  this.#subscriptions,
7940
7988
  () => this.closed,
7941
- Latest
7989
+ Latest,
7990
+ this.#zero
7942
7991
  );
7943
7992
  } catch (e) {
7944
7993
  if (e instanceof ClientStateNotFoundError) {
@@ -7949,8 +7998,8 @@ var ReplicacheImpl = class {
7949
7998
  throw e;
7950
7999
  }
7951
8000
  }
7952
- if (diffs !== void 0) {
7953
- await this.#subscriptions.fire(diffs);
8001
+ if (refreshResult !== void 0) {
8002
+ await this.#subscriptions.fire(refreshResult.diffs);
7954
8003
  }
7955
8004
  }
7956
8005
  #fireOnClientStateNotFound() {
@@ -8141,18 +8190,21 @@ var ReplicacheImpl = class {
8141
8190
  clientID,
8142
8191
  await dbWrite.getMutationID(),
8143
8192
  "initial",
8144
- void 0,
8193
+ await this.#zero?.getTxData("initial", headHash, {
8194
+ openLazyRead: dagWrite
8195
+ }),
8145
8196
  dbWrite,
8146
8197
  this.#lc
8147
8198
  );
8148
8199
  const result = await mutatorImpl(tx, args);
8149
8200
  throwIfClosed(dbWrite);
8150
8201
  const lastMutationID = await dbWrite.getMutationID();
8151
- const diffs = await dbWrite.commitWithDiffs(
8202
+ const [newHead, diffs] = await dbWrite.commitWithDiffs(
8152
8203
  DEFAULT_HEAD_NAME,
8153
8204
  this.#subscriptions
8154
8205
  );
8155
8206
  this.lastMutationID = lastMutationID;
8207
+ this.#zero?.advance(headHash, newHead, diffs.get("") ?? []);
8156
8208
  this.#pushConnectionLoop.send(false).catch(() => void 0);
8157
8209
  await this.#subscriptions.fire(diffs);
8158
8210
  void this.#schedulePersist();
@@ -9219,9 +9271,7 @@ var Exists = class {
9219
9271
  case "remove": {
9220
9272
  let size = this.#getSize(change.node);
9221
9273
  if (size !== void 0) {
9222
- if (size === 0) {
9223
- return;
9224
- }
9274
+ assert(size > 0);
9225
9275
  size--;
9226
9276
  this.#setSize(change.node, size);
9227
9277
  } else {
@@ -9617,6 +9667,7 @@ var Join = class {
9617
9667
  #relationshipName;
9618
9668
  #schema;
9619
9669
  #output = throwOutput;
9670
+ #inprogressChildChange;
9620
9671
  constructor({
9621
9672
  parent,
9622
9673
  child,
@@ -9749,25 +9800,34 @@ var Join = class {
9749
9800
  }
9750
9801
  #pushChild(change) {
9751
9802
  const pushChildChange = (childRow, change2) => {
9752
- const parentNodes = this.#parent.fetch({
9753
- constraint: Object.fromEntries(
9754
- this.#parentKey.map((key, i) => [key, childRow[this.#childKey[i]]])
9755
- )
9756
- });
9757
- for (const parentNode of parentNodes) {
9758
- const childChange = {
9759
- type: "child",
9760
- node: this.#processParentNode(
9761
- parentNode.row,
9762
- parentNode.relationships,
9763
- "fetch"
9764
- ),
9765
- child: {
9766
- relationshipName: this.#relationshipName,
9767
- change: change2
9768
- }
9769
- };
9770
- this.#output.push(childChange);
9803
+ this.#inprogressChildChange = {
9804
+ change: change2,
9805
+ position: void 0
9806
+ };
9807
+ try {
9808
+ const parentNodes = this.#parent.fetch({
9809
+ constraint: Object.fromEntries(
9810
+ this.#parentKey.map((key, i) => [key, childRow[this.#childKey[i]]])
9811
+ )
9812
+ });
9813
+ for (const parentNode of parentNodes) {
9814
+ this.#inprogressChildChange.position = parentNode.row;
9815
+ const childChange = {
9816
+ type: "child",
9817
+ node: this.#processParentNode(
9818
+ parentNode.row,
9819
+ parentNode.relationships,
9820
+ "fetch"
9821
+ ),
9822
+ child: {
9823
+ relationshipName: this.#relationshipName,
9824
+ change: change2
9825
+ }
9826
+ };
9827
+ this.#output.push(childChange);
9828
+ }
9829
+ } finally {
9830
+ this.#inprogressChildChange = void 0;
9771
9831
  }
9772
9832
  };
9773
9833
  switch (change.type) {
@@ -9792,6 +9852,81 @@ var Join = class {
9792
9852
  unreachable(change);
9793
9853
  }
9794
9854
  }
9855
+ *#generateChildStreamWithOverlay(stream, overlay) {
9856
+ let applied = false;
9857
+ let editOldApplied = false;
9858
+ let editNewApplied = false;
9859
+ for (const child of stream) {
9860
+ let yieldChild = true;
9861
+ if (!applied) {
9862
+ switch (overlay.type) {
9863
+ case "add": {
9864
+ if (this.#child.getSchema().compareRows(overlay.node.row, child.row) === 0) {
9865
+ applied = true;
9866
+ yieldChild = false;
9867
+ }
9868
+ break;
9869
+ }
9870
+ case "remove": {
9871
+ if (this.#child.getSchema().compareRows(overlay.node.row, child.row) < 0) {
9872
+ applied = true;
9873
+ yield overlay.node;
9874
+ }
9875
+ break;
9876
+ }
9877
+ case "edit": {
9878
+ if (this.#child.getSchema().compareRows(overlay.oldNode.row, child.row) < 0) {
9879
+ editOldApplied = true;
9880
+ if (editNewApplied) {
9881
+ applied = true;
9882
+ }
9883
+ yield overlay.oldNode;
9884
+ }
9885
+ if (this.#child.getSchema().compareRows(overlay.node.row, child.row) === 0) {
9886
+ editNewApplied = true;
9887
+ if (editOldApplied) {
9888
+ applied = true;
9889
+ }
9890
+ yieldChild = false;
9891
+ }
9892
+ break;
9893
+ }
9894
+ case "child": {
9895
+ if (this.#child.getSchema().compareRows(overlay.node.row, child.row) === 0) {
9896
+ applied = true;
9897
+ yield {
9898
+ row: child.row,
9899
+ relationships: {
9900
+ ...child.relationships,
9901
+ [overlay.child.relationshipName]: () => this.#generateChildStreamWithOverlay(
9902
+ child.relationships[overlay.child.relationshipName](),
9903
+ overlay.child.change
9904
+ )
9905
+ }
9906
+ };
9907
+ yieldChild = false;
9908
+ }
9909
+ break;
9910
+ }
9911
+ }
9912
+ }
9913
+ if (yieldChild) {
9914
+ yield child;
9915
+ }
9916
+ }
9917
+ if (!applied) {
9918
+ if (overlay.type === "remove") {
9919
+ applied = true;
9920
+ yield overlay.node;
9921
+ } else if (overlay.type === "edit") {
9922
+ assert(editNewApplied);
9923
+ editOldApplied = true;
9924
+ applied = true;
9925
+ yield overlay.oldNode;
9926
+ }
9927
+ }
9928
+ assert(applied);
9929
+ }
9795
9930
  #processParentNode(parentNodeRow, parentNodeRelations, mode) {
9796
9931
  let method = mode;
9797
9932
  let storageUpdated = false;
@@ -9827,7 +9962,7 @@ var Join = class {
9827
9962
  );
9828
9963
  }
9829
9964
  }
9830
- return this.#child[method]({
9965
+ const stream = this.#child[method]({
9831
9966
  constraint: Object.fromEntries(
9832
9967
  this.#childKey.map((key, i) => [
9833
9968
  key,
@@ -9835,6 +9970,19 @@ var Join = class {
9835
9970
  ])
9836
9971
  )
9837
9972
  });
9973
+ if (this.#inprogressChildChange && this.#isJoinMatch(
9974
+ parentNodeRow,
9975
+ this.#inprogressChildChange.change.node.row
9976
+ ) && this.#inprogressChildChange.position && this.#schema.compareRows(
9977
+ parentNodeRow,
9978
+ this.#inprogressChildChange.position
9979
+ ) > 0) {
9980
+ return this.#generateChildStreamWithOverlay(
9981
+ stream,
9982
+ this.#inprogressChildChange.change
9983
+ );
9984
+ }
9985
+ return stream;
9838
9986
  };
9839
9987
  return {
9840
9988
  row: parentNodeRow,
@@ -9844,6 +9992,14 @@ var Join = class {
9844
9992
  }
9845
9993
  };
9846
9994
  }
9995
+ #isJoinMatch(parent, child) {
9996
+ for (let i = 0; i < this.#parentKey.length; i++) {
9997
+ if (!valuesEqual(parent[this.#parentKey[i]], child[this.#childKey[i]])) {
9998
+ return false;
9999
+ }
10000
+ }
10001
+ return true;
10002
+ }
9847
10003
  };
9848
10004
  function makeStorageKeyForValues(values) {
9849
10005
  const json2 = JSON.stringify(["pKeySet", ...values]);
@@ -10153,6 +10309,7 @@ var Take = class {
10153
10309
  type: "remove",
10154
10310
  node: boundNode
10155
10311
  };
10312
+ this.#output.push(change);
10156
10313
  this.#setTakeState(
10157
10314
  takeStateKey,
10158
10315
  takeState.size,
@@ -10160,7 +10317,6 @@ var Take = class {
10160
10317
  maxBound
10161
10318
  );
10162
10319
  this.#output.push(removeChange);
10163
- this.#output.push(change);
10164
10320
  } else if (change.type === "remove") {
10165
10321
  if (takeState.bound === void 0) {
10166
10322
  return;
@@ -10207,13 +10363,13 @@ var Take = class {
10207
10363
  }
10208
10364
  }
10209
10365
  if (newBound?.push) {
10366
+ this.#output.push(change);
10210
10367
  this.#setTakeState(
10211
10368
  takeStateKey,
10212
10369
  takeState.size,
10213
10370
  newBound.node.row,
10214
10371
  maxBound
10215
10372
  );
10216
- this.#output.push(change);
10217
10373
  this.#output.push({
10218
10374
  type: "add",
10219
10375
  node: newBound.node
@@ -10308,10 +10464,6 @@ var Take = class {
10308
10464
  newBoundNode.row,
10309
10465
  maxBound
10310
10466
  );
10311
- this.#output.push({
10312
- type: "remove",
10313
- node: change.oldNode
10314
- });
10315
10467
  this.#output.push({
10316
10468
  type: "add",
10317
10469
  node: newBoundNode
@@ -10335,6 +10487,10 @@ var Take = class {
10335
10487
  }),
10336
10488
  2
10337
10489
  );
10490
+ this.#output.push({
10491
+ type: "add",
10492
+ node: change.node
10493
+ });
10338
10494
  this.#setTakeState(
10339
10495
  takeStateKey,
10340
10496
  takeState.size,
@@ -10345,10 +10501,6 @@ var Take = class {
10345
10501
  type: "remove",
10346
10502
  node: oldBoundNode
10347
10503
  });
10348
- this.#output.push({
10349
- type: "add",
10350
- node: change.node
10351
- });
10352
10504
  return;
10353
10505
  }
10354
10506
  if (oldCmp < 0) {
@@ -10373,16 +10525,16 @@ var Take = class {
10373
10525
  replaceBoundAndForwardChange();
10374
10526
  return;
10375
10527
  }
10528
+ this.#output.push({
10529
+ type: "remove",
10530
+ node: change.oldNode
10531
+ });
10376
10532
  this.#setTakeState(
10377
10533
  takeStateKey,
10378
10534
  takeState.size,
10379
10535
  afterBoundNode.row,
10380
10536
  maxBound
10381
10537
  );
10382
- this.#output.push({
10383
- type: "remove",
10384
- node: change.oldNode
10385
- });
10386
10538
  this.#output.push({
10387
10539
  type: "add",
10388
10540
  node: afterBoundNode
@@ -11649,6 +11801,9 @@ var QueryImpl = class extends AbstractQuery {
11649
11801
  );
11650
11802
  return view;
11651
11803
  }
11804
+ updateTTL(ttl) {
11805
+ this.#delegate.updateServerQuery(this._completeAst(), ttl);
11806
+ }
11652
11807
  run() {
11653
11808
  const v2 = this.materialize();
11654
11809
  const ret = v2.data;
@@ -11727,6 +11882,9 @@ var StaticQuery = class _StaticQuery extends AbstractQuery {
11727
11882
  preload() {
11728
11883
  throw new Error("StaticQuery cannot be preloaded");
11729
11884
  }
11885
+ updateTTL(_ttl) {
11886
+ throw new Error("StaticQuery cannot have a TTL");
11887
+ }
11730
11888
  };
11731
11889
 
11732
11890
  // ../zero-schema/src/name-mapper.ts
@@ -11992,40 +12150,6 @@ function escapeLike(val) {
11992
12150
  return val.replace(/[%_]/g, "\\$&");
11993
12151
  }
11994
12152
 
11995
- // ../zql/src/query/ttl.ts
11996
- var DEFAULT_TTL2 = "none";
11997
- var multiplier = {
11998
- s: 1e3,
11999
- m: 60 * 1e3,
12000
- h: 60 * 60 * 1e3,
12001
- d: 24 * 60 * 60 * 1e3,
12002
- y: 365 * 24 * 60 * 60 * 1e3
12003
- };
12004
- function parseTTL(ttl) {
12005
- if (typeof ttl === "number") {
12006
- return Number.isNaN(ttl) ? 0 : !Number.isFinite(ttl) || ttl < 0 ? -1 : ttl;
12007
- }
12008
- if (ttl === "none") {
12009
- return 0;
12010
- }
12011
- if (ttl === "forever") {
12012
- return -1;
12013
- }
12014
- const multi = multiplier[ttl[ttl.length - 1]];
12015
- return Number(ttl.slice(0, -1)) * multi;
12016
- }
12017
- function compareTTL(a, b) {
12018
- const ap = parseTTL(a);
12019
- const bp = parseTTL(b);
12020
- if (ap === -1 && bp !== -1) {
12021
- return 1;
12022
- }
12023
- if (ap !== -1 && bp === -1) {
12024
- return -1;
12025
- }
12026
- return ap - bp;
12027
- }
12028
-
12029
12153
  // ../zero-client/src/client/zero.ts
12030
12154
  import { LogContext as LogContext4 } from "@rocicorp/logger";
12031
12155
  import { resolver as resolver8 } from "@rocicorp/resolver";
@@ -13188,6 +13312,21 @@ var MemorySource = class _MemorySource {
13188
13312
  const exists = (row) => data.has(row);
13189
13313
  const setOverlay = (o) => this.#overlay = o;
13190
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
+ }
13191
13330
  for (const x of genPush(
13192
13331
  change,
13193
13332
  exists,
@@ -13547,16 +13686,19 @@ var IVMSourceBranch = class _IVMSourceBranch {
13547
13686
  /**
13548
13687
  * Fork the branch and patch it up to match the desired head.
13549
13688
  */
13550
- 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
+ }
13551
13697
  const fork = this.fork();
13552
- assert(
13553
- expectedHead === fork.hash,
13554
- () => `Expected head must match the main head. Got: ${expectedHead}, expected: ${fork.hash}`
13555
- );
13556
13698
  if (fork.hash === desiredHead) {
13557
13699
  return fork;
13558
13700
  }
13559
- await patchBranch(desiredHead, store, fork);
13701
+ await patchBranch(desiredHead, store, fork, readOptions);
13560
13702
  fork.hash = desiredHead;
13561
13703
  return fork;
13562
13704
  }
@@ -13581,14 +13723,19 @@ var IVMSourceBranch = class _IVMSourceBranch {
13581
13723
  );
13582
13724
  }
13583
13725
  };
13584
- async function patchBranch(desiredHead, store, fork) {
13585
- 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
+ );
13586
13733
  if (!diffs) {
13587
13734
  return;
13588
13735
  }
13589
13736
  applyDiffs(diffs, fork);
13590
13737
  }
13591
- async function computeDiffs(startHash, endHash, store) {
13738
+ async function computeDiffs(startHash, endHash, store, readOptions) {
13592
13739
  const readFn = (dagRead) => diff2(
13593
13740
  startHash,
13594
13741
  endHash,
@@ -13601,7 +13748,14 @@ async function computeDiffs(startHash, endHash, store) {
13601
13748
  },
13602
13749
  Latest
13603
13750
  );
13604
- 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
+ }
13605
13759
  return diffs.get("");
13606
13760
  }
13607
13761
  function applyDiffs(diffs, branch) {
@@ -13645,14 +13799,16 @@ var ZeroContext = class {
13645
13799
  // that needs to be fixed.
13646
13800
  #mainSources;
13647
13801
  #addQuery;
13802
+ #updateQuery;
13648
13803
  #batchViewUpdates;
13649
13804
  #commitListeners = /* @__PURE__ */ new Set();
13650
13805
  slowMaterializeThreshold;
13651
13806
  lc;
13652
13807
  staticQueryParameters = void 0;
13653
- constructor(lc, mainSources, addQuery, batchViewUpdates, slowMaterializeThreshold) {
13808
+ constructor(lc, mainSources, addQuery, updateQuery, batchViewUpdates, slowMaterializeThreshold) {
13654
13809
  this.#mainSources = mainSources;
13655
13810
  this.#addQuery = addQuery;
13811
+ this.#updateQuery = updateQuery;
13656
13812
  this.#batchViewUpdates = batchViewUpdates;
13657
13813
  this.lc = lc;
13658
13814
  this.slowMaterializeThreshold = slowMaterializeThreshold;
@@ -13663,6 +13819,9 @@ var ZeroContext = class {
13663
13819
  addServerQuery(ast, ttl, gotCallback) {
13664
13820
  return this.#addQuery(ast, ttl, gotCallback);
13665
13821
  }
13822
+ updateServerQuery(ast, ttl) {
13823
+ this.#updateQuery(ast, ttl);
13824
+ }
13666
13825
  onQueryMaterialized(hash2, ast, duration) {
13667
13826
  if (this.slowMaterializeThreshold !== void 0 && duration > this.slowMaterializeThreshold) {
13668
13827
  this.lc.warn?.(
@@ -13705,45 +13864,10 @@ var ZeroContext = class {
13705
13864
  );
13706
13865
  return result;
13707
13866
  }
13708
- processChanges(changes) {
13867
+ processChanges(expectedHead, newHead, changes) {
13709
13868
  this.batchViewUpdates(() => {
13710
13869
  try {
13711
- for (const diff3 of changes) {
13712
- const { key } = diff3;
13713
- assert(key.startsWith(ENTITIES_KEY_PREFIX));
13714
- const name = sourceNameFromKey(key);
13715
- const source = this.getSource(name);
13716
- if (!source) {
13717
- continue;
13718
- }
13719
- switch (diff3.op) {
13720
- case "del":
13721
- assert(typeof diff3.oldValue === "object");
13722
- source.push({
13723
- type: "remove",
13724
- row: diff3.oldValue
13725
- });
13726
- break;
13727
- case "add":
13728
- assert(typeof diff3.newValue === "object");
13729
- source.push({
13730
- type: "add",
13731
- row: diff3.newValue
13732
- });
13733
- break;
13734
- case "change":
13735
- assert(typeof diff3.newValue === "object");
13736
- assert(typeof diff3.oldValue === "object");
13737
- source.push({
13738
- type: "edit",
13739
- row: diff3.newValue,
13740
- oldRow: diff3.oldValue
13741
- });
13742
- break;
13743
- default:
13744
- unreachable(diff3);
13745
- }
13746
- }
13870
+ this.#mainSources.advance(expectedHead, newHead, changes);
13747
13871
  } finally {
13748
13872
  this.#endTransaction();
13749
13873
  }
@@ -13751,7 +13875,11 @@ var ZeroContext = class {
13751
13875
  }
13752
13876
  #endTransaction() {
13753
13877
  for (const listener of this.#commitListeners) {
13754
- listener();
13878
+ try {
13879
+ listener();
13880
+ } catch (e) {
13881
+ this.lc.error?.("Failed notifying a commit listener of IVM updates", e);
13882
+ }
13755
13883
  }
13756
13884
  }
13757
13885
  };
@@ -13925,7 +14053,7 @@ async function upsertImpl(tx, arg, schema, ivmBranch) {
13925
14053
  await tx.set(key, val);
13926
14054
  if (ivmBranch) {
13927
14055
  must(ivmBranch.getSource(arg.tableName)).push({
13928
- type: "add",
14056
+ type: "set",
13929
14057
  row: arg.value
13930
14058
  });
13931
14059
  }
@@ -13977,7 +14105,7 @@ async function deleteImpl(tx, arg, schema, ivmBranch) {
13977
14105
 
13978
14106
  // ../zero-client/src/client/custom.ts
13979
14107
  var TransactionImpl = class {
13980
- constructor(repTx, schema) {
14108
+ constructor(lc, repTx, schema, slowMaterializeThreshold) {
13981
14109
  const castedRepTx = repTx;
13982
14110
  must(repTx.reason === "initial" || repTx.reason === "rebase");
13983
14111
  this.clientID = repTx.clientID;
@@ -13986,9 +14114,25 @@ var TransactionImpl = class {
13986
14114
  this.mutate = makeSchemaCRUD(
13987
14115
  schema,
13988
14116
  repTx,
13989
- 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
13990
14135
  );
13991
- this.query = {};
13992
14136
  }
13993
14137
  clientID;
13994
14138
  mutationID;
@@ -13997,18 +14141,49 @@ var TransactionImpl = class {
13997
14141
  mutate;
13998
14142
  query;
13999
14143
  };
14000
- function makeReplicacheMutator(mutator, schema) {
14144
+ function makeReplicacheMutator(lc, mutator, schema, slowMaterializeThreshold) {
14001
14145
  return (repTx, args) => {
14002
- const tx = new TransactionImpl(repTx, schema);
14146
+ const tx = new TransactionImpl(lc, repTx, schema, slowMaterializeThreshold);
14003
14147
  return mutator(tx, args);
14004
14148
  };
14005
14149
  }
14006
14150
  function makeSchemaCRUD(schema, tx, ivmBranch) {
14007
- const mutate = {};
14008
- for (const [name] of Object.entries(schema.tables)) {
14009
- mutate[name] = makeTableCRUD(schema, name, tx, ivmBranch);
14010
- }
14011
- 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
+ );
14012
14187
  }
14013
14188
  function makeTableCRUD(schema, tableName, tx, ivmBranch) {
14014
14189
  const table2 = must(schema.tables[tableName]);
@@ -14340,7 +14515,7 @@ function makeMessage(message, context, logLevel) {
14340
14515
  }
14341
14516
 
14342
14517
  // ../zero-client/src/client/version.ts
14343
- var version2 = "0.17.2025031100";
14518
+ var version2 = "0.17.2025031300";
14344
14519
 
14345
14520
  // ../zero-client/src/client/log-options.ts
14346
14521
  var LevelFilterLogSink = class {
@@ -14751,22 +14926,7 @@ var QueryManager = class {
14751
14926
  ]);
14752
14927
  } else {
14753
14928
  ++entry.count;
14754
- if (compareTTL(ttl, entry.ttl) > 0) {
14755
- entry.ttl = ttl;
14756
- this.#send([
14757
- "changeDesiredQueries",
14758
- {
14759
- desiredQueriesPatch: [
14760
- {
14761
- op: "put",
14762
- hash: astHash,
14763
- ast: entry.normalized,
14764
- ttl: parseTTL(ttl)
14765
- }
14766
- ]
14767
- }
14768
- ]);
14769
- }
14929
+ this.#updateEntry(entry, astHash, ttl);
14770
14930
  if (gotCallback) {
14771
14931
  entry.gotCallbacks.push(gotCallback);
14772
14932
  }
@@ -14783,6 +14943,30 @@ var QueryManager = class {
14783
14943
  this.#remove(entry, astHash, gotCallback);
14784
14944
  };
14785
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
+ }
14786
14970
  #remove(entry, astHash, gotCallback) {
14787
14971
  if (gotCallback) {
14788
14972
  const index = entry.gotCallbacks.indexOf(gotCallback);
@@ -15254,6 +15438,51 @@ function rafFallback(callback) {
15254
15438
  setTimeout(callback, 0);
15255
15439
  }
15256
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
+
15257
15486
  // ../zero-client/src/client/zero.ts
15258
15487
  var onSetConnectionStateSymbol = Symbol();
15259
15488
  var exposedToTestingSymbol = Symbol();
@@ -15444,13 +15673,19 @@ var Zero = class {
15444
15673
  [CRUD_MUTATION_NAME]: makeCRUDMutator(schema)
15445
15674
  };
15446
15675
  this.#ivmMain = new IVMSourceBranch(schema.tables);
15676
+ const lc = new LogContext4(logOptions.logLevel, {}, logOptions.logSink);
15447
15677
  for (const [namespace, mutatorsForNamespace] of Object.entries(
15448
15678
  options.mutators ?? {}
15449
15679
  )) {
15450
15680
  for (const [name, mutator] of Object.entries(
15451
15681
  mutatorsForNamespace
15452
15682
  )) {
15453
- replicacheMutators[customMutatorKey(namespace, name)] = makeReplicacheMutator(mutator, schema);
15683
+ replicacheMutators[customMutatorKey(namespace, name)] = makeReplicacheMutator(
15684
+ lc,
15685
+ mutator,
15686
+ schema,
15687
+ slowMaterializeThreshold
15688
+ );
15454
15689
  }
15455
15690
  }
15456
15691
  this.storageKey = storageKey ?? "";
@@ -15474,10 +15709,23 @@ var Zero = class {
15474
15709
  licenseKey: "zero-client-static-key",
15475
15710
  kvStore
15476
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
+ );
15477
15720
  const replicacheImplOptions = {
15478
15721
  enableClientGroupForking: false,
15479
15722
  enableMutationRecovery: false,
15480
- 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
+ )
15481
15729
  };
15482
15730
  const rep = new ReplicacheImpl(replicacheOptions, replicacheImplOptions);
15483
15731
  this.#rep = rep;
@@ -15486,11 +15734,7 @@ var Zero = class {
15486
15734
  }
15487
15735
  this.#server = server;
15488
15736
  this.userID = userID;
15489
- this.#lc = new LogContext4(
15490
- logOptions.logLevel,
15491
- { clientID: rep.clientID },
15492
- logOptions.logSink
15493
- );
15737
+ this.#lc = lc.withContext("clientID", rep.clientID);
15494
15738
  const onUpdateNeededCallback = onUpdateNeeded ?? ((reason, serverErrorMsg) => {
15495
15739
  reloadWithReason(
15496
15740
  this.#lc,
@@ -15545,20 +15789,6 @@ var Zero = class {
15545
15789
  rep.perdag,
15546
15790
  this.#lc
15547
15791
  );
15548
- this.#zeroContext = new ZeroContext(
15549
- this.#lc,
15550
- this.#ivmMain,
15551
- (ast, ttl, gotCallback) => this.#queryManager.add(ast, ttl, gotCallback),
15552
- batchViewUpdates,
15553
- slowMaterializeThreshold
15554
- );
15555
- rep.experimentalWatch(
15556
- (diff3) => this.#zeroContext.processChanges(diff3),
15557
- {
15558
- prefix: ENTITIES_KEY_PREFIX,
15559
- initialValuesInFirstDiff: true
15560
- }
15561
- );
15562
15792
  this.query = this.#registerQueries(schema);
15563
15793
  reportReloadReason(this.#lc);
15564
15794
  this.#metrics = new MetricManager({
@@ -16559,7 +16789,6 @@ export {
16559
16789
  NOBODY_CAN,
16560
16790
  definePermissions,
16561
16791
  escapeLike,
16562
- DEFAULT_TTL2 as DEFAULT_TTL,
16563
16792
  Zero
16564
16793
  };
16565
- //# sourceMappingURL=chunk-2TJNN7K4.js.map
16794
+ //# sourceMappingURL=chunk-APXCO5Z2.js.map