@rocicorp/zero 0.19.2025040901 → 0.19.2025041100

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 (124) hide show
  1. package/out/advanced.js +1 -2
  2. package/out/analyze-query/src/bin-analyze.js +73 -13
  3. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  4. package/out/ast-to-zql/src/ast-to-zql.d.ts +1 -1
  5. package/out/ast-to-zql/src/ast-to-zql.js +2 -2
  6. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  7. package/out/{chunk-JW7AJ755.js → chunk-GTRWLUIW.js} +281 -3022
  8. package/out/chunk-GTRWLUIW.js.map +7 -0
  9. package/out/chunk-J3DNXL5V.js +2843 -0
  10. package/out/chunk-J3DNXL5V.js.map +7 -0
  11. package/out/{chunk-56G3QAI6.js → chunk-N7NOL5CH.js} +38 -41
  12. package/out/{chunk-56G3QAI6.js.map → chunk-N7NOL5CH.js.map} +2 -2
  13. package/out/{chunk-2NCGIK6G.js → chunk-SKR5JO2A.js} +21 -1
  14. package/out/{chunk-2NCGIK6G.js.map → chunk-SKR5JO2A.js.map} +1 -1
  15. package/out/{inspector-R2AXP2NY.js → inspector-YQC2D2E3.js} +9 -10
  16. package/out/inspector-YQC2D2E3.js.map +7 -0
  17. package/out/react.js +20 -9
  18. package/out/react.js.map +2 -2
  19. package/out/shared/src/options.d.ts +1 -0
  20. package/out/shared/src/options.d.ts.map +1 -1
  21. package/out/shared/src/options.js +12 -10
  22. package/out/shared/src/options.js.map +1 -1
  23. package/out/solid.js +31 -22
  24. package/out/solid.js.map +3 -3
  25. package/out/zero/src/cli.d.ts +1 -1
  26. package/out/zero/src/cli.d.ts.map +1 -1
  27. package/out/zero/src/cli.js +1 -1
  28. package/out/zero/src/cli.js.map +1 -1
  29. package/out/zero/src/server/runner/main.d.ts +2 -0
  30. package/out/zero/src/server/runner/main.d.ts.map +1 -0
  31. package/out/zero/src/server/runner/main.js +2 -0
  32. package/out/zero/src/server/runner/main.js.map +1 -0
  33. package/out/zero/src/zero-cache-dev.d.ts.map +1 -1
  34. package/out/zero/src/zero-cache-dev.js +1 -1
  35. package/out/zero/src/zero-cache-dev.js.map +1 -1
  36. package/out/zero-cache/src/config/zero-config.d.ts +7 -2
  37. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  38. package/out/zero-cache/src/config/zero-config.js +20 -4
  39. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  40. package/out/zero-cache/src/server/{multi → runner}/config.d.ts +7 -2
  41. package/out/zero-cache/src/server/runner/config.d.ts.map +1 -0
  42. package/out/zero-cache/src/server/{multi → runner}/config.js +2 -1
  43. package/out/zero-cache/src/server/runner/config.js.map +1 -0
  44. package/out/zero-cache/src/server/runner/main.d.ts.map +1 -0
  45. package/out/zero-cache/src/server/runner/main.js.map +1 -0
  46. package/out/zero-cache/src/server/runner/run-worker.d.ts.map +1 -0
  47. package/out/zero-cache/src/server/{multi → runner}/run-worker.js +27 -17
  48. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -0
  49. package/out/zero-cache/src/server/runner/runtime.d.ts.map +1 -0
  50. package/out/zero-cache/src/server/runner/runtime.js.map +1 -0
  51. package/out/zero-cache/src/server/{multi/tenant-dispatcher.d.ts → runner/zero-dispatcher.d.ts} +4 -4
  52. package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -0
  53. package/out/zero-cache/src/server/{multi/tenant-dispatcher.js → runner/zero-dispatcher.js} +25 -12
  54. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -0
  55. package/out/zero-cache/src/services/dispatcher/websocket-handoff.d.ts +10 -1
  56. package/out/zero-cache/src/services/dispatcher/websocket-handoff.d.ts.map +1 -1
  57. package/out/zero-cache/src/services/dispatcher/websocket-handoff.js +15 -3
  58. package/out/zero-cache/src/services/dispatcher/websocket-handoff.js.map +1 -1
  59. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -0
  60. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  61. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +9 -0
  62. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  63. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  64. package/out/zero-cache/src/services/view-syncer/view-syncer.js +66 -25
  65. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  66. package/out/zero-pg/src/query.d.ts +0 -2
  67. package/out/zero-pg/src/query.d.ts.map +1 -1
  68. package/out/zero-pg/src/query.js +0 -3
  69. package/out/zero-pg/src/query.js.map +1 -1
  70. package/out/zero-react/src/use-query.d.ts +3 -1
  71. package/out/zero-react/src/use-query.d.ts.map +1 -1
  72. package/out/zero-solid/src/create-query.d.ts +22 -0
  73. package/out/zero-solid/src/create-query.d.ts.map +1 -0
  74. package/out/zero-solid/src/mod.d.ts +1 -1
  75. package/out/zero-solid/src/mod.d.ts.map +1 -1
  76. package/out/zero-solid/src/solid-view.d.ts +4 -3
  77. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  78. package/out/zero.js +4 -5
  79. package/out/zql/src/ivm/array-view.d.ts +5 -1
  80. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  81. package/out/zql/src/ivm/array-view.js +8 -1
  82. package/out/zql/src/ivm/array-view.js.map +1 -1
  83. package/out/zql/src/ivm/view.d.ts +2 -1
  84. package/out/zql/src/ivm/view.d.ts.map +1 -1
  85. package/out/zql/src/query/query-impl.d.ts +5 -5
  86. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  87. package/out/zql/src/query/query-impl.js +15 -10
  88. package/out/zql/src/query/query-impl.js.map +1 -1
  89. package/out/zql/src/query/query.d.ts +8 -5
  90. package/out/zql/src/query/query.d.ts.map +1 -1
  91. package/out/zql/src/query/static-query.d.ts +0 -2
  92. package/out/zql/src/query/static-query.d.ts.map +1 -1
  93. package/out/zql/src/query/static-query.js +0 -3
  94. package/out/zql/src/query/static-query.js.map +1 -1
  95. package/out/zql/src/query/typed-view.d.ts +2 -0
  96. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  97. package/package.json +6 -2
  98. package/out/chunk-424PT5DM.js +0 -23
  99. package/out/chunk-424PT5DM.js.map +0 -7
  100. package/out/chunk-JW7AJ755.js.map +0 -7
  101. package/out/chunk-MB3DEFRC.js +0 -67
  102. package/out/chunk-MB3DEFRC.js.map +0 -7
  103. package/out/inspector-R2AXP2NY.js.map +0 -7
  104. package/out/zero/src/server/multi/main.d.ts +0 -2
  105. package/out/zero/src/server/multi/main.d.ts.map +0 -1
  106. package/out/zero/src/server/multi/main.js +0 -2
  107. package/out/zero/src/server/multi/main.js.map +0 -1
  108. package/out/zero-cache/src/server/multi/config.d.ts.map +0 -1
  109. package/out/zero-cache/src/server/multi/config.js.map +0 -1
  110. package/out/zero-cache/src/server/multi/main.d.ts.map +0 -1
  111. package/out/zero-cache/src/server/multi/main.js.map +0 -1
  112. package/out/zero-cache/src/server/multi/run-worker.d.ts.map +0 -1
  113. package/out/zero-cache/src/server/multi/run-worker.js.map +0 -1
  114. package/out/zero-cache/src/server/multi/runtime.d.ts.map +0 -1
  115. package/out/zero-cache/src/server/multi/runtime.js.map +0 -1
  116. package/out/zero-cache/src/server/multi/tenant-dispatcher.d.ts.map +0 -1
  117. package/out/zero-cache/src/server/multi/tenant-dispatcher.js.map +0 -1
  118. package/out/zero-solid/src/use-query.d.ts +0 -12
  119. package/out/zero-solid/src/use-query.d.ts.map +0 -1
  120. /package/out/zero-cache/src/server/{multi → runner}/main.d.ts +0 -0
  121. /package/out/zero-cache/src/server/{multi → runner}/main.js +0 -0
  122. /package/out/zero-cache/src/server/{multi → runner}/run-worker.d.ts +0 -0
  123. /package/out/zero-cache/src/server/{multi → runner}/runtime.d.ts +0 -0
  124. /package/out/zero-cache/src/server/{multi → runner}/runtime.js +0 -0
@@ -1,13 +1,8 @@
1
1
  import {
2
- DEFAULT_TTL,
3
- hasOwn
4
- } from "./chunk-MB3DEFRC.js";
5
- import {
2
+ __export,
3
+ __reExport,
6
4
  applyChange,
7
5
  assert,
8
- assertArray,
9
- assertBoolean,
10
- assertNumber,
11
6
  assertObject,
12
7
  assertString,
13
8
  compareValues,
@@ -17,11 +12,7 @@ import {
17
12
  throwInvalidType,
18
13
  unreachable,
19
14
  valuesEqual
20
- } from "./chunk-2NCGIK6G.js";
21
- import {
22
- __export,
23
- __reExport
24
- } from "./chunk-424PT5DM.js";
15
+ } from "./chunk-SKR5JO2A.js";
25
16
 
26
17
  // ../shared/src/valita.ts
27
18
  var valita_exports = {};
@@ -232,33 +223,101 @@ function deepPartial(s) {
232
223
  return v.object(shape);
233
224
  }
234
225
 
235
- // ../replicache/src/dag/store.ts
236
- var ChunkNotFoundError = class extends Error {
237
- name = "ChunkNotFoundError";
238
- hash;
239
- constructor(hash2) {
240
- super(`Chunk not found ${hash2}`);
241
- this.hash = hash2;
242
- }
226
+ // ../zql/src/query/ttl.ts
227
+ var DEFAULT_TTL = "none";
228
+ var multiplier = {
229
+ s: 1e3,
230
+ m: 60 * 1e3,
231
+ h: 60 * 60 * 1e3,
232
+ d: 24 * 60 * 60 * 1e3,
233
+ y: 365 * 24 * 60 * 60 * 1e3
243
234
  };
244
- async function mustGetChunk(store, hash2) {
245
- const chunk = await store.getChunk(hash2);
246
- if (chunk) {
247
- return chunk;
235
+ function parseTTL(ttl) {
236
+ if (typeof ttl === "number") {
237
+ return Number.isNaN(ttl) ? 0 : !Number.isFinite(ttl) || ttl < 0 ? -1 : ttl;
238
+ }
239
+ if (ttl === "none") {
240
+ return 0;
241
+ }
242
+ if (ttl === "forever") {
243
+ return -1;
244
+ }
245
+ const multi = multiplier[ttl[ttl.length - 1]];
246
+ return Number(ttl.slice(0, -1)) * multi;
247
+ }
248
+ function compareTTL(a, b) {
249
+ const ap = parseTTL(a);
250
+ const bp = parseTTL(b);
251
+ if (ap === -1 && bp !== -1) {
252
+ return 1;
253
+ }
254
+ if (ap !== -1 && bp === -1) {
255
+ return -1;
256
+ }
257
+ return ap - bp;
258
+ }
259
+ function normalizeTTL(ttl) {
260
+ if (typeof ttl === "string") {
261
+ return ttl;
262
+ }
263
+ if (ttl < 0) {
264
+ return "forever";
265
+ }
266
+ if (ttl === 0) {
267
+ return "none";
268
+ }
269
+ let shortest = ttl.toString();
270
+ const lengthOfNumber = shortest.length;
271
+ for (const unit of ["y", "d", "h", "m", "s"]) {
272
+ const multi = multiplier[unit];
273
+ const value = ttl / multi;
274
+ const candidate = `${value}${unit}`;
275
+ if (candidate.length < shortest.length) {
276
+ shortest = candidate;
277
+ }
248
278
  }
249
- throw new ChunkNotFoundError(hash2);
279
+ return shortest.length < lengthOfNumber ? shortest : ttl;
250
280
  }
251
- async function mustGetHeadHash(name, store) {
252
- const hash2 = await store.getHead(name);
253
- assert(hash2, `Missing head ${name}`);
281
+
282
+ // ../shared/src/has-own.ts
283
+ var { hasOwn } = Object;
284
+
285
+ // ../shared/src/hash.ts
286
+ import { xxHash32 } from "js-xxhash";
287
+ var h64 = (s) => hash(s, 2);
288
+ var h128 = (s) => hash(s, 4);
289
+ function hash(str, words) {
290
+ let hash2 = 0n;
291
+ for (let i = 0; i < words; i++) {
292
+ hash2 = (hash2 << 32n) + BigInt(xxHash32(str, i));
293
+ }
254
294
  return hash2;
255
295
  }
256
296
 
257
- // ../replicache/src/format-version-enum.ts
258
- var DD31 = 5;
259
- var V6 = 6;
260
- var V7 = 7;
261
- var Latest = V7;
297
+ // ../zero-protocol/src/ast.ts
298
+ import { compareUTF8 } from "compare-utf8";
299
+
300
+ // ../shared/src/arrays.ts
301
+ function defined(arr) {
302
+ let i = arr.findIndex((x) => x === void 0);
303
+ if (i < 0) {
304
+ return arr;
305
+ }
306
+ const defined2 = arr.slice(0, i);
307
+ for (i++; i < arr.length; i++) {
308
+ const x = arr[i];
309
+ if (x !== void 0) {
310
+ defined2.push(x);
311
+ }
312
+ }
313
+ return defined2;
314
+ }
315
+ function areEqual(arr1, arr2) {
316
+ return arr1.length === arr2.length && arr1.every((e, i) => e === arr2[i]);
317
+ }
318
+
319
+ // ../shared/src/json-schema.ts
320
+ import * as valita from "@badrap/valita";
262
321
 
263
322
  // ../shared/src/config.ts
264
323
  var isProd = process.env.NODE_ENV === "production";
@@ -298,2812 +357,112 @@ function deepEqual(a, b) {
298
357
  if (Array.isArray(b)) {
299
358
  return false;
300
359
  }
301
- a = a;
302
- b = b;
303
- let aSize = 0;
304
- for (const key in a) {
305
- if (hasOwn(a, key)) {
306
- if (!deepEqual(a[key], b[key])) {
307
- return false;
308
- }
309
- aSize++;
310
- }
311
- }
312
- let bSize = 0;
313
- for (const key in b) {
314
- if (hasOwn(b, key)) {
315
- bSize++;
316
- }
317
- }
318
- return aSize === bSize;
319
- }
320
- function assertJSONValue(v2) {
321
- if (isProd) {
322
- return;
323
- }
324
- switch (typeof v2) {
325
- case "boolean":
326
- case "number":
327
- case "string":
328
- return;
329
- case "object":
330
- if (v2 === null) {
331
- return;
332
- }
333
- if (Array.isArray(v2)) {
334
- return assertJSONArray(v2);
335
- }
336
- return assertObjectIsJSONObject(v2);
337
- }
338
- throwInvalidType(v2, "JSON value");
339
- }
340
- function assertJSONObject(v2) {
341
- assertObject(v2);
342
- assertObjectIsJSONObject(v2);
343
- }
344
- function assertObjectIsJSONObject(v2) {
345
- for (const k in v2) {
346
- if (hasOwn(v2, k)) {
347
- const value = v2[k];
348
- if (value !== void 0) {
349
- assertJSONValue(value);
350
- }
351
- }
352
- }
353
- }
354
- function assertJSONArray(v2) {
355
- for (const item of v2) {
356
- assertJSONValue(item);
357
- }
358
- }
359
- function isJSONValue(v2, path2) {
360
- switch (typeof v2) {
361
- case "boolean":
362
- case "number":
363
- case "string":
364
- return true;
365
- case "object":
366
- if (v2 === null) {
367
- return true;
368
- }
369
- if (Array.isArray(v2)) {
370
- return isJSONArray(v2, path2);
371
- }
372
- return objectIsJSONObject(v2, path2);
373
- }
374
- return false;
375
- }
376
- function isJSONObject(v2, path2) {
377
- if (typeof v2 !== "object" || v2 === null) {
378
- return false;
379
- }
380
- return objectIsJSONObject(v2, path2);
381
- }
382
- function objectIsJSONObject(v2, path2) {
383
- for (const k in v2) {
384
- if (hasOwn(v2, k)) {
385
- path2.push(k);
386
- const value = v2[k];
387
- if (value !== void 0 && !isJSONValue(value, path2)) {
388
- return false;
389
- }
390
- path2.pop();
391
- }
392
- }
393
- return true;
394
- }
395
- function isJSONArray(v2, path2) {
396
- for (let i = 0; i < v2.length; i++) {
397
- path2.push(i);
398
- if (!isJSONValue(v2[i], path2)) {
399
- return false;
400
- }
401
- path2.pop();
402
- }
403
- return true;
404
- }
405
-
406
- // ../shared/src/random-uint64.ts
407
- function randomUint64() {
408
- const high = Math.floor(Math.random() * 4294967295);
409
- const low = Math.floor(Math.random() * 4294967295);
410
- return BigInt(high) << 32n | BigInt(low);
411
- }
412
-
413
- // ../replicache/src/hash.ts
414
- var STRING_LENGTH = 22;
415
- var hashRe = /^[0-9a-v-]+$/;
416
- var emptyUUID = "0".repeat(STRING_LENGTH);
417
- var emptyHash = emptyUUID;
418
- var newRandomHash = makeNewRandomHashFunctionInternal();
419
- function toStringAndSlice(n, len) {
420
- return n.toString(32).slice(-len).padStart(len, "0");
421
- }
422
- function makeNewRandomHashFunctionInternal() {
423
- let base = "";
424
- let i = 0;
425
- return () => {
426
- if (!base) {
427
- base = toStringAndSlice(randomUint64(), 12);
428
- }
429
- const tail = toStringAndSlice(i++, 10);
430
- return base + tail;
431
- };
432
- }
433
- function isHash(value) {
434
- return typeof value === "string" && hashRe.test(value);
435
- }
436
- function assertHash(value) {
437
- assert2(value, hashSchema);
438
- }
439
- var hashSchema = valita_exports.string().assert(isHash, "Invalid hash");
440
-
441
- // ../replicache/src/size-of-value.ts
442
- var SIZE_TAG = 1;
443
- var SIZE_INT32 = 4;
444
- var SIZE_SMI = 5;
445
- var SIZE_DOUBLE = 8;
446
- function getSizeOfValue(value) {
447
- switch (typeof value) {
448
- case "string":
449
- return SIZE_TAG + SIZE_INT32 + value.length;
450
- case "number":
451
- if (isSmi(value)) {
452
- if (value <= -(2 ** 30) || value >= 2 ** 30 - 1) {
453
- return SIZE_TAG + SIZE_SMI;
454
- }
455
- return SIZE_TAG + SIZE_INT32;
456
- }
457
- return SIZE_TAG + SIZE_DOUBLE;
458
- case "boolean":
459
- return SIZE_TAG;
460
- case "object":
461
- if (value === null) {
462
- return SIZE_TAG;
463
- }
464
- if (Array.isArray(value)) {
465
- let sum = 2 * SIZE_TAG + SIZE_INT32;
466
- for (const element of value) {
467
- sum += getSizeOfValue(element);
468
- }
469
- return sum;
470
- }
471
- {
472
- const val = value;
473
- let sum = 2 * SIZE_TAG + SIZE_INT32;
474
- for (const k in val) {
475
- if (hasOwn(val, k)) {
476
- const propertyValue = val[k];
477
- if (propertyValue !== void 0) {
478
- sum += getSizeOfValue(k) + getSizeOfValue(propertyValue);
479
- }
480
- }
481
- }
482
- return sum;
483
- }
484
- }
485
- throw new Error(`Invalid value. type: ${typeof value}, value: ${value}`);
486
- }
487
- function isSmi(value) {
488
- return value === (value | 0);
489
- }
490
- var entryFixed = 2 * SIZE_TAG + SIZE_INT32 + SIZE_TAG + SIZE_INT32;
491
- function getSizeOfEntry(key, value) {
492
- return entryFixed + getSizeOfValue(key) + getSizeOfValue(value);
493
- }
494
-
495
- // ../replicache/src/btree/node.ts
496
- import { compareUTF8 } from "compare-utf8";
497
-
498
- // ../shared/src/iterables.ts
499
- function* joinIterables(...iters) {
500
- for (const iter of iters) {
501
- yield* iter;
502
- }
503
- }
504
- function* filterIter(iter, p) {
505
- let index = 0;
506
- for (const t of iter) {
507
- if (p(t, index++)) {
508
- yield t;
509
- }
510
- }
511
- }
512
- function* mapIter(iter, f) {
513
- let index = 0;
514
- for (const t of iter) {
515
- yield f(t, index++);
516
- }
517
- }
518
- var IterWrapper = class _IterWrapper {
519
- iter;
520
- constructor(iter) {
521
- this.iter = iter;
522
- }
523
- [Symbol.iterator]() {
524
- return this.iter[Symbol.iterator]();
525
- }
526
- map(f) {
527
- return new _IterWrapper(mapIter(this.iter, f));
528
- }
529
- filter(p) {
530
- return new _IterWrapper(filterIter(this.iter, p));
531
- }
532
- };
533
- function wrapIterable(iter) {
534
- return new IterWrapper(iter);
535
- }
536
- function* mergeIterables(iterables, comparator, distinct = false) {
537
- const iterators = iterables.map((i) => i[Symbol.iterator]());
538
- try {
539
- const current = iterators.map((i) => i.next());
540
- let lastYielded;
541
- while (current.some((c) => !c.done)) {
542
- const min = current.reduce(
543
- (acc, c, i) => {
544
- if (c.done) {
545
- return acc;
546
- }
547
- if (acc === void 0 || comparator(c.value, acc[0]) < 0) {
548
- return [c.value, i];
549
- }
550
- return acc;
551
- },
552
- void 0
553
- );
554
- assert(min !== void 0, "min is undefined");
555
- current[min[1]] = iterators[min[1]].next();
556
- if (lastYielded !== void 0 && distinct && comparator(lastYielded, min[0]) === 0) {
557
- continue;
558
- }
559
- lastYielded = min[0];
560
- yield min[0];
561
- }
562
- } finally {
563
- for (const it of iterators) {
564
- it.return?.();
565
- }
566
- }
567
- }
568
-
569
- // ../replicache/src/binary-search.ts
570
- function binarySearch(high, compare) {
571
- let low = 0;
572
- while (low < high) {
573
- const mid = low + (high - low >> 1);
574
- const i = compare(mid);
575
- if (i === 0) {
576
- return mid;
577
- }
578
- if (i > 0) {
579
- low = mid + 1;
580
- } else {
581
- high = mid;
582
- }
583
- }
584
- return low;
585
- }
586
-
587
- // ../replicache/src/frozen-json.ts
588
- var deepFrozenObjects = /* @__PURE__ */ new WeakSet();
589
- function deepFreeze(v2) {
590
- if (isProd) {
591
- return v2;
592
- }
593
- deepFreezeInternal(v2, []);
594
- return v2;
595
- }
596
- function deepFreezeInternal(v2, seen) {
597
- switch (typeof v2) {
598
- case "undefined":
599
- throw new TypeError("Unexpected value undefined");
600
- case "boolean":
601
- case "number":
602
- case "string":
603
- return;
604
- case "object": {
605
- if (v2 === null) {
606
- return;
607
- }
608
- if (deepFrozenObjects.has(v2)) {
609
- return;
610
- }
611
- deepFrozenObjects.add(v2);
612
- if (seen.includes(v2)) {
613
- throwInvalidType(v2, "Cyclic JSON object");
614
- }
615
- seen.push(v2);
616
- Object.freeze(v2);
617
- if (Array.isArray(v2)) {
618
- deepFreezeArray(v2, seen);
619
- } else {
620
- deepFreezeObject(v2, seen);
621
- }
622
- seen.pop();
623
- return;
624
- }
625
- default:
626
- throwInvalidType(v2, "JSON value");
627
- }
628
- }
629
- function deepFreezeArray(v2, seen) {
630
- for (const item of v2) {
631
- deepFreezeInternal(item, seen);
632
- }
633
- }
634
- function deepFreezeObject(v2, seen) {
635
- for (const k in v2) {
636
- if (hasOwn(v2, k)) {
637
- const value = v2[k];
638
- if (value !== void 0) {
639
- deepFreezeInternal(value, seen);
640
- }
641
- }
642
- }
643
- }
644
- function assertDeepFrozen(v2) {
645
- if (isProd) {
646
- return;
647
- }
648
- if (!isDeepFrozen(v2, [])) {
649
- throw new Error("Expected frozen object");
650
- }
651
- }
652
- function isDeepFrozen(v2, seen) {
653
- switch (typeof v2) {
654
- case "boolean":
655
- case "number":
656
- case "string":
657
- return true;
658
- case "object":
659
- if (v2 === null) {
660
- return true;
661
- }
662
- if (deepFrozenObjects.has(v2)) {
663
- return true;
664
- }
665
- if (!Object.isFrozen(v2)) {
666
- return false;
667
- }
668
- if (seen.includes(v2)) {
669
- throwInvalidType(v2, "Cyclic JSON object");
670
- }
671
- seen.push(v2);
672
- if (Array.isArray(v2)) {
673
- for (const item of v2) {
674
- if (!isDeepFrozen(item, seen)) {
675
- seen.pop();
676
- return false;
677
- }
678
- }
679
- } else {
680
- for (const k in v2) {
681
- if (hasOwn(v2, k)) {
682
- const value = v2[k];
683
- if (value !== void 0 && !isDeepFrozen(value, seen)) {
684
- seen.pop();
685
- return false;
686
- }
687
- }
688
- }
689
- }
690
- deepFrozenObjects.add(v2);
691
- seen.pop();
692
- return true;
693
- default:
694
- throwInvalidType(v2, "JSON value");
695
- }
696
- }
697
- function deepFreezeAllowUndefined(v2) {
698
- if (v2 === void 0) {
699
- return void 0;
700
- }
701
- return deepFreeze(v2);
702
- }
703
-
704
- // ../replicache/src/btree/node.ts
705
- var NODE_LEVEL = 0;
706
- var NODE_ENTRIES = 1;
707
- function makeNodeChunkData(level, entries, formatVersion) {
708
- return deepFreeze([
709
- level,
710
- formatVersion >= V7 ? entries : entries.map((e) => e.slice(0, 2))
711
- ]);
712
- }
713
- async function findLeaf(key, hash2, source, expectedRootHash) {
714
- const node = await source.getNode(hash2);
715
- if (expectedRootHash !== source.rootHash) {
716
- return findLeaf(key, source.rootHash, source, source.rootHash);
717
- }
718
- if (isDataNodeImpl(node)) {
719
- return node;
720
- }
721
- const { entries } = node;
722
- let i = binarySearch2(key, entries);
723
- if (i === entries.length) {
724
- i--;
725
- }
726
- const entry = entries[i];
727
- return findLeaf(key, entry[1], source, expectedRootHash);
728
- }
729
- function binarySearch2(key, entries) {
730
- return binarySearch(
731
- entries.length,
732
- (i) => compareUTF8(key, entries[i][0])
733
- );
734
- }
735
- function binarySearchFound(i, entries, key) {
736
- return i !== entries.length && entries[i][0] === key;
737
- }
738
- function parseBTreeNode(v2, formatVersion, getSizeOfEntry2) {
739
- if (isProd && formatVersion >= V7) {
740
- return v2;
741
- }
742
- assertArray(v2);
743
- assertDeepFrozen(v2);
744
- assert(v2.length >= 2);
745
- const [level, entries] = v2;
746
- assertNumber(level);
747
- assertArray(entries);
748
- const f = level > 0 ? assertString : assertJSONValue;
749
- if (formatVersion >= V7) {
750
- for (const e of entries) {
751
- assertEntry(e, f);
752
- }
753
- return v2;
754
- }
755
- const newEntries = entries.map((e) => convertNonV7Entry(e, f, getSizeOfEntry2));
756
- return [level, newEntries];
757
- }
758
- function assertEntry(entry, f) {
759
- assertArray(entry);
760
- assert(entry.length >= 3);
761
- assertString(entry[0]);
762
- f(entry[1]);
763
- assertNumber(entry[2]);
764
- }
765
- function convertNonV7Entry(entry, f, getSizeOfEntry2) {
766
- assertArray(entry);
767
- assert(entry.length >= 2);
768
- assertString(entry[0]);
769
- f(entry[1]);
770
- const entrySize = getSizeOfEntry2(entry[0], entry[1]);
771
- return [entry[0], entry[1], entrySize];
772
- }
773
- var NodeImpl = class {
774
- entries;
775
- hash;
776
- isMutable;
777
- #childNodeSize = -1;
778
- constructor(entries, hash2, isMutable) {
779
- this.entries = entries;
780
- this.hash = hash2;
781
- this.isMutable = isMutable;
782
- }
783
- maxKey() {
784
- return this.entries[this.entries.length - 1][0];
785
- }
786
- getChildNodeSize(tree) {
787
- if (this.#childNodeSize !== -1) {
788
- return this.#childNodeSize;
789
- }
790
- let sum = tree.chunkHeaderSize;
791
- for (const entry of this.entries) {
792
- sum += entry[2];
793
- }
794
- return this.#childNodeSize = sum;
795
- }
796
- _updateNode(tree) {
797
- this.#childNodeSize = -1;
798
- tree.updateNode(
799
- this
800
- );
801
- }
802
- };
803
- function toChunkData(node, formatVersion) {
804
- return makeNodeChunkData(node.level, node.entries, formatVersion);
805
- }
806
- var DataNodeImpl = class extends NodeImpl {
807
- level = 0;
808
- set(key, value, entrySize, tree) {
809
- let deleteCount;
810
- const i = binarySearch2(key, this.entries);
811
- if (!binarySearchFound(i, this.entries, key)) {
812
- deleteCount = 0;
813
- } else {
814
- deleteCount = 1;
815
- }
816
- return Promise.resolve(
817
- this.#splice(tree, i, deleteCount, [key, value, entrySize])
818
- );
819
- }
820
- #splice(tree, start, deleteCount, ...items) {
821
- if (this.isMutable) {
822
- this.entries.splice(start, deleteCount, ...items);
823
- this._updateNode(tree);
824
- return this;
825
- }
826
- const entries = readonlySplice(this.entries, start, deleteCount, ...items);
827
- return tree.newDataNodeImpl(entries);
828
- }
829
- del(key, tree) {
830
- const i = binarySearch2(key, this.entries);
831
- if (!binarySearchFound(i, this.entries, key)) {
832
- return Promise.resolve(this);
833
- }
834
- return Promise.resolve(this.#splice(tree, i, 1));
835
- }
836
- async *keys(_tree) {
837
- for (const entry of this.entries) {
838
- yield entry[0];
839
- }
840
- }
841
- async *entriesIter(_tree) {
842
- for (const entry of this.entries) {
843
- yield entry;
844
- }
845
- }
846
- };
847
- function readonlySplice(array5, start, deleteCount, ...items) {
848
- const arr = array5.slice(0, start);
849
- for (let i = 0; i < items.length; i++) {
850
- arr.push(items[i]);
851
- }
852
- for (let i = start + deleteCount; i < array5.length; i++) {
853
- arr.push(array5[i]);
854
- }
855
- return arr;
856
- }
857
- var InternalNodeImpl = class _InternalNodeImpl extends NodeImpl {
858
- level;
859
- constructor(entries, hash2, level, isMutable) {
860
- super(entries, hash2, isMutable);
861
- this.level = level;
862
- }
863
- async set(key, value, entrySize, tree) {
864
- let i = binarySearch2(key, this.entries);
865
- if (i === this.entries.length) {
866
- i--;
867
- }
868
- const childHash = this.entries[i][1];
869
- const oldChildNode = await tree.getNode(childHash);
870
- const childNode = await oldChildNode.set(key, value, entrySize, tree);
871
- const childNodeSize = childNode.getChildNodeSize(tree);
872
- if (childNodeSize > tree.maxSize || childNodeSize < tree.minSize) {
873
- return this.#mergeAndPartition(tree, i, childNode);
874
- }
875
- const newEntry = createNewInternalEntryForNode(
876
- childNode,
877
- tree.getEntrySize
878
- );
879
- return this.#replaceChild(tree, i, newEntry);
880
- }
881
- /**
882
- * This merges the child node entries with previous or next sibling and then
883
- * partitions the merged entries.
884
- */
885
- async #mergeAndPartition(tree, i, childNode) {
886
- const level = this.level - 1;
887
- const thisEntries = this.entries;
888
- let values;
889
- let startIndex;
890
- let removeCount;
891
- if (i > 0) {
892
- const hash2 = thisEntries[i - 1][1];
893
- const previousSibling = await tree.getNode(hash2);
894
- values = joinIterables(
895
- previousSibling.entries,
896
- childNode.entries
897
- );
898
- startIndex = i - 1;
899
- removeCount = 2;
900
- } else if (i < thisEntries.length - 1) {
901
- const hash2 = thisEntries[i + 1][1];
902
- const nextSibling = await tree.getNode(hash2);
903
- values = joinIterables(
904
- childNode.entries,
905
- nextSibling.entries
906
- );
907
- startIndex = i;
908
- removeCount = 2;
909
- } else {
910
- values = childNode.entries;
911
- startIndex = i;
912
- removeCount = 1;
913
- }
914
- const partitions = partition(
915
- values,
916
- (value) => value[2],
917
- tree.minSize - tree.chunkHeaderSize,
918
- tree.maxSize - tree.chunkHeaderSize
919
- );
920
- const newEntries = [];
921
- for (const entries2 of partitions) {
922
- const node = tree.newNodeImpl(entries2, level);
923
- const newHashEntry = createNewInternalEntryForNode(
924
- node,
925
- tree.getEntrySize
926
- );
927
- newEntries.push(newHashEntry);
928
- }
929
- if (this.isMutable) {
930
- this.entries.splice(startIndex, removeCount, ...newEntries);
931
- this._updateNode(tree);
932
- return this;
933
- }
934
- const entries = readonlySplice(
935
- thisEntries,
936
- startIndex,
937
- removeCount,
938
- ...newEntries
939
- );
940
- return tree.newInternalNodeImpl(entries, this.level);
941
- }
942
- #replaceChild(tree, index, newEntry) {
943
- if (this.isMutable) {
944
- this.entries.splice(index, 1, newEntry);
945
- this._updateNode(tree);
946
- return this;
947
- }
948
- const entries = readonlySplice(this.entries, index, 1, newEntry);
949
- return tree.newInternalNodeImpl(entries, this.level);
950
- }
951
- async del(key, tree) {
952
- const i = binarySearch2(key, this.entries);
953
- if (i === this.entries.length) {
954
- return this;
955
- }
956
- const childHash = this.entries[i][1];
957
- const oldChildNode = await tree.getNode(childHash);
958
- const oldHash = oldChildNode.hash;
959
- const childNode = await oldChildNode.del(key, tree);
960
- if (childNode.hash === oldHash) {
961
- return this;
962
- }
963
- if (childNode.entries.length === 0) {
964
- const entries = readonlySplice(this.entries, i, 1);
965
- return tree.newInternalNodeImpl(entries, this.level);
966
- }
967
- if (i === 0 && this.entries.length === 1) {
968
- return childNode;
969
- }
970
- if (childNode.getChildNodeSize(tree) > tree.minSize) {
971
- const entry = createNewInternalEntryForNode(childNode, tree.getEntrySize);
972
- return this.#replaceChild(tree, i, entry);
973
- }
974
- return this.#mergeAndPartition(tree, i, childNode);
975
- }
976
- async *keys(tree) {
977
- for (const entry of this.entries) {
978
- const childNode = await tree.getNode(entry[1]);
979
- yield* childNode.keys(tree);
980
- }
981
- }
982
- async *entriesIter(tree) {
983
- for (const entry of this.entries) {
984
- const childNode = await tree.getNode(entry[1]);
985
- yield* childNode.entriesIter(tree);
986
- }
987
- }
988
- getChildren(start, length, tree) {
989
- const ps = [];
990
- for (let i = start; i < length && i < this.entries.length; i++) {
991
- ps.push(tree.getNode(this.entries[i][1]));
992
- }
993
- return Promise.all(ps);
994
- }
995
- async getCompositeChildren(start, length, tree) {
996
- const { level } = this;
997
- if (length === 0) {
998
- return new _InternalNodeImpl([], newRandomHash(), level - 1, true);
999
- }
1000
- const output = await this.getChildren(start, start + length, tree);
1001
- if (level > 1) {
1002
- const entries2 = [];
1003
- for (const child of output) {
1004
- entries2.push(...child.entries);
1005
- }
1006
- return new _InternalNodeImpl(entries2, newRandomHash(), level - 1, true);
1007
- }
1008
- assert(level === 1);
1009
- const entries = [];
1010
- for (const child of output) {
1011
- entries.push(...child.entries);
1012
- }
1013
- return new DataNodeImpl(entries, newRandomHash(), true);
1014
- }
1015
- };
1016
- function newNodeImpl(entries, hash2, level, isMutable) {
1017
- if (level === 0) {
1018
- return new DataNodeImpl(
1019
- entries,
1020
- hash2,
1021
- isMutable
1022
- );
1023
- }
1024
- return new InternalNodeImpl(entries, hash2, level, isMutable);
1025
- }
1026
- function isDataNodeImpl(node) {
1027
- return node.level === 0;
1028
- }
1029
- function partition(values, getSizeOfEntry2, min, max) {
1030
- const partitions = [];
1031
- const sizes = [];
1032
- let sum = 0;
1033
- let accum = [];
1034
- for (const value of values) {
1035
- const size = getSizeOfEntry2(value);
1036
- if (size >= max) {
1037
- if (accum.length > 0) {
1038
- partitions.push(accum);
1039
- sizes.push(sum);
1040
- }
1041
- partitions.push([value]);
1042
- sizes.push(size);
1043
- sum = 0;
1044
- accum = [];
1045
- } else if (sum + size >= min) {
1046
- accum.push(value);
1047
- partitions.push(accum);
1048
- sizes.push(sum + size);
1049
- sum = 0;
1050
- accum = [];
1051
- } else {
1052
- sum += size;
1053
- accum.push(value);
1054
- }
1055
- }
1056
- if (sum > 0) {
1057
- if (sizes.length > 0 && sum + sizes[sizes.length - 1] <= max) {
1058
- partitions[partitions.length - 1].push(...accum);
1059
- } else {
1060
- partitions.push(accum);
1061
- }
1062
- }
1063
- return partitions;
1064
- }
1065
- var emptyDataNode = makeNodeChunkData(
1066
- 0,
1067
- [],
1068
- Latest
1069
- );
1070
- var emptyDataNodeImpl = new DataNodeImpl([], emptyHash, false);
1071
- function createNewInternalEntryForNode(node, getSizeOfEntry2) {
1072
- const key = node.maxKey();
1073
- const value = node.hash;
1074
- const size = getSizeOfEntry2(key, value);
1075
- return [key, value, size];
1076
- }
1077
-
1078
- // ../replicache/src/btree/splice.ts
1079
- var SPLICE_UNASSIGNED = -1;
1080
- var SPLICE_AT = 0;
1081
- var SPLICE_REMOVED = 1;
1082
- var SPLICE_ADDED = 2;
1083
- var SPLICE_FROM = 3;
1084
- var KEY = 0;
1085
- var VALUE = 1;
1086
- function* computeSplices(previous, current) {
1087
- let previousIndex = 0;
1088
- let currentIndex = 0;
1089
- let splice;
1090
- function ensureAssigned(splice2, index) {
1091
- if (splice2[SPLICE_FROM] === SPLICE_UNASSIGNED) {
1092
- splice2[SPLICE_FROM] = index;
1093
- }
1094
- }
1095
- function newSplice() {
1096
- return [previousIndex, 0, 0, SPLICE_UNASSIGNED];
1097
- }
1098
- while (previousIndex < previous.length && currentIndex < current.length) {
1099
- if (previous[previousIndex][KEY] === current[currentIndex][KEY]) {
1100
- if (deepEqual(
1101
- // These are really Hash | InternalValue
1102
- previous[previousIndex][VALUE],
1103
- current[currentIndex][VALUE]
1104
- )) {
1105
- if (splice) {
1106
- ensureAssigned(splice, 0);
1107
- yield splice;
1108
- splice = void 0;
1109
- }
1110
- } else {
1111
- if (!splice) {
1112
- splice = newSplice();
1113
- }
1114
- splice[SPLICE_ADDED]++;
1115
- splice[SPLICE_REMOVED]++;
1116
- ensureAssigned(splice, currentIndex);
1117
- }
1118
- previousIndex++;
1119
- currentIndex++;
1120
- } else if (previous[previousIndex][KEY] < current[currentIndex][KEY]) {
1121
- if (!splice) {
1122
- splice = newSplice();
1123
- }
1124
- splice[SPLICE_REMOVED]++;
1125
- previousIndex++;
1126
- } else {
1127
- if (!splice) {
1128
- splice = newSplice();
1129
- }
1130
- splice[SPLICE_ADDED]++;
1131
- ensureAssigned(splice, currentIndex);
1132
- currentIndex++;
1133
- }
1134
- }
1135
- if (currentIndex < current.length) {
1136
- if (!splice) {
1137
- splice = newSplice();
1138
- }
1139
- splice[SPLICE_ADDED] += current.length - currentIndex;
1140
- ensureAssigned(splice, currentIndex);
1141
- }
1142
- if (previousIndex < previous.length) {
1143
- if (!splice) {
1144
- splice = newSplice();
1145
- }
1146
- splice[SPLICE_REMOVED] += previous.length - previousIndex;
1147
- }
1148
- if (splice) {
1149
- ensureAssigned(splice, 0);
1150
- yield splice;
1151
- }
1152
- }
1153
-
1154
- // ../replicache/src/btree/read.ts
1155
- var NODE_HEADER_SIZE = 11;
1156
- var BTreeRead = class {
1157
- _cache = /* @__PURE__ */ new Map();
1158
- _dagRead;
1159
- _formatVersion;
1160
- rootHash;
1161
- getEntrySize;
1162
- chunkHeaderSize;
1163
- constructor(dagRead, formatVersion, root = emptyHash, getEntrySize = getSizeOfEntry, chunkHeaderSize = NODE_HEADER_SIZE) {
1164
- this._dagRead = dagRead;
1165
- this._formatVersion = formatVersion;
1166
- this.rootHash = root;
1167
- this.getEntrySize = getEntrySize;
1168
- this.chunkHeaderSize = chunkHeaderSize;
1169
- }
1170
- async getNode(hash2) {
1171
- if (hash2 === emptyHash) {
1172
- return emptyDataNodeImpl;
1173
- }
1174
- const cached = this._cache.get(hash2);
1175
- if (cached) {
1176
- return cached;
1177
- }
1178
- const chunk = await this._dagRead.mustGetChunk(hash2);
1179
- const data = parseBTreeNode(
1180
- chunk.data,
1181
- this._formatVersion,
1182
- this.getEntrySize
1183
- );
1184
- const impl = newNodeImpl(
1185
- data[NODE_ENTRIES],
1186
- hash2,
1187
- data[NODE_LEVEL],
1188
- false
1189
- );
1190
- this._cache.set(hash2, impl);
1191
- return impl;
1192
- }
1193
- async get(key) {
1194
- const leaf = await findLeaf(key, this.rootHash, this, this.rootHash);
1195
- const index = binarySearch2(key, leaf.entries);
1196
- if (!binarySearchFound(index, leaf.entries, key)) {
1197
- return void 0;
1198
- }
1199
- return leaf.entries[index][1];
1200
- }
1201
- async has(key) {
1202
- const leaf = await findLeaf(key, this.rootHash, this, this.rootHash);
1203
- const index = binarySearch2(key, leaf.entries);
1204
- return binarySearchFound(index, leaf.entries, key);
1205
- }
1206
- async isEmpty() {
1207
- const { rootHash } = this;
1208
- const node = await this.getNode(this.rootHash);
1209
- if (this.rootHash !== rootHash) {
1210
- return this.isEmpty();
1211
- }
1212
- return node.entries.length === 0;
1213
- }
1214
- // We don't do any encoding of the key in the map, so we have no way of
1215
- // determining from an entry.key alone whether it is a regular key or an
1216
- // encoded IndexKey in an index map. Without encoding regular map keys the
1217
- // caller has to deal with encoding and decoding the keys for the index map.
1218
- scan(fromKey) {
1219
- return scanForHash(
1220
- this.rootHash,
1221
- () => this.rootHash,
1222
- this.rootHash,
1223
- fromKey,
1224
- async (hash2) => {
1225
- const cached = await this.getNode(hash2);
1226
- if (cached) {
1227
- return [
1228
- cached.level,
1229
- cached.isMutable ? cached.entries.slice() : cached.entries
1230
- ];
1231
- }
1232
- const chunk = await this._dagRead.mustGetChunk(hash2);
1233
- return parseBTreeNode(
1234
- chunk.data,
1235
- this._formatVersion,
1236
- this.getEntrySize
1237
- );
1238
- }
1239
- );
1240
- }
1241
- async *keys() {
1242
- const node = await this.getNode(this.rootHash);
1243
- yield* node.keys(this);
1244
- }
1245
- async *entries() {
1246
- const node = await this.getNode(this.rootHash);
1247
- yield* node.entriesIter(this);
1248
- }
1249
- [Symbol.asyncIterator]() {
1250
- return this.entries();
1251
- }
1252
- async *diff(last) {
1253
- const [currentNode, lastNode] = await Promise.all([
1254
- this.getNode(this.rootHash),
1255
- last.getNode(last.rootHash)
1256
- ]);
1257
- yield* diffNodes(lastNode, currentNode, last, this);
1258
- }
1259
- };
1260
- async function* diffNodes(last, current, lastTree, currentTree) {
1261
- if (last.level > current.level) {
1262
- const lastChild = await last.getCompositeChildren(
1263
- 0,
1264
- last.entries.length,
1265
- lastTree
1266
- );
1267
- yield* diffNodes(lastChild, current, lastTree, currentTree);
1268
- return;
1269
- }
1270
- if (current.level > last.level) {
1271
- const currentChild = await current.getCompositeChildren(
1272
- 0,
1273
- current.entries.length,
1274
- currentTree
1275
- );
1276
- yield* diffNodes(last, currentChild, lastTree, currentTree);
1277
- return;
1278
- }
1279
- if (isDataNodeImpl(last) && isDataNodeImpl(current)) {
1280
- yield* diffEntries(
1281
- last.entries,
1282
- current.entries
1283
- );
1284
- return;
1285
- }
1286
- const initialSplices = computeSplices(
1287
- last.entries,
1288
- current.entries
1289
- );
1290
- for (const splice of initialSplices) {
1291
- const [lastChild, currentChild] = await Promise.all([
1292
- last.getCompositeChildren(
1293
- splice[SPLICE_AT],
1294
- splice[SPLICE_REMOVED],
1295
- lastTree
1296
- ),
1297
- current.getCompositeChildren(
1298
- splice[SPLICE_FROM],
1299
- splice[SPLICE_ADDED],
1300
- currentTree
1301
- )
1302
- ]);
1303
- yield* diffNodes(lastChild, currentChild, lastTree, currentTree);
1304
- }
1305
- }
1306
- function* diffEntries(lastEntries, currentEntries) {
1307
- const lastLength = lastEntries.length;
1308
- const currentLength = currentEntries.length;
1309
- let i = 0;
1310
- let j = 0;
1311
- while (i < lastLength && j < currentLength) {
1312
- const lastKey = lastEntries[i][0];
1313
- const currentKey = currentEntries[j][0];
1314
- if (lastKey === currentKey) {
1315
- if (!deepEqual(lastEntries[i][1], currentEntries[j][1])) {
1316
- yield {
1317
- op: "change",
1318
- key: lastKey,
1319
- oldValue: lastEntries[i][1],
1320
- newValue: currentEntries[j][1]
1321
- };
1322
- }
1323
- i++;
1324
- j++;
1325
- } else if (lastKey < currentKey) {
1326
- yield {
1327
- op: "del",
1328
- key: lastKey,
1329
- oldValue: lastEntries[i][1]
1330
- };
1331
- i++;
1332
- } else {
1333
- yield {
1334
- op: "add",
1335
- key: currentKey,
1336
- newValue: currentEntries[j][1]
1337
- };
1338
- j++;
1339
- }
1340
- }
1341
- for (; i < lastLength; i++) {
1342
- yield {
1343
- op: "del",
1344
- key: lastEntries[i][0],
1345
- oldValue: lastEntries[i][1]
1346
- };
1347
- }
1348
- for (; j < currentLength; j++) {
1349
- yield {
1350
- op: "add",
1351
- key: currentEntries[j][0],
1352
- newValue: currentEntries[j][1]
1353
- };
1354
- }
1355
- }
1356
- async function* scanForHash(expectedRootHash, getRootHash, hash2, fromKey, readNode) {
1357
- if (hash2 === emptyHash) {
1358
- return;
1359
- }
1360
- const data = await readNode(hash2);
1361
- const entries = data[NODE_ENTRIES];
1362
- let i = 0;
1363
- if (fromKey) {
1364
- i = binarySearch2(fromKey, entries);
1365
- }
1366
- if (data[NODE_LEVEL] > 0) {
1367
- for (; i < entries.length; i++) {
1368
- yield* scanForHash(
1369
- expectedRootHash,
1370
- getRootHash,
1371
- entries[i][1],
1372
- fromKey,
1373
- readNode
1374
- );
1375
- fromKey = "";
1376
- }
1377
- } else {
1378
- for (; i < entries.length; i++) {
1379
- const rootHash = getRootHash();
1380
- if (expectedRootHash !== rootHash) {
1381
- yield* scanForHash(
1382
- rootHash,
1383
- getRootHash,
1384
- rootHash,
1385
- entries[i][0],
1386
- readNode
1387
- );
1388
- return;
1389
- }
1390
- yield entries[i];
1391
- }
1392
- }
1393
- }
1394
- async function allEntriesAsDiff(map, op) {
1395
- const diff3 = [];
1396
- const make = op === "add" ? (entry) => ({
1397
- op: "add",
1398
- key: entry[0],
1399
- newValue: entry[1]
1400
- }) : (entry) => ({
1401
- op: "del",
1402
- key: entry[0],
1403
- oldValue: entry[1]
1404
- });
1405
- for await (const entry of map.entries()) {
1406
- diff3.push(make(entry));
1407
- }
1408
- return diff3;
1409
- }
1410
-
1411
- // ../shared/src/string-compare.ts
1412
- function stringCompare(a, b) {
1413
- if (a === b) {
1414
- return 0;
1415
- }
1416
- if (a < b) {
1417
- return -1;
1418
- }
1419
- return 1;
1420
- }
1421
-
1422
- // ../replicache/src/cookies.ts
1423
- function compareCookies(a, b) {
1424
- if (a === b) {
1425
- return 0;
1426
- }
1427
- if (a === null) {
1428
- return -1;
1429
- }
1430
- if (b === null) {
1431
- return 1;
1432
- }
1433
- const cva = getCompareValue(a);
1434
- const cvb = getCompareValue(b);
1435
- if (typeof cva === "string" || typeof cvb === "string") {
1436
- return stringCompare(String(cva), String(cvb));
1437
- }
1438
- return cva - cvb;
1439
- }
1440
- function getCompareValue(cookie) {
1441
- if (typeof cookie === "string" || typeof cookie === "number") {
1442
- return cookie;
1443
- }
1444
- return cookie.order;
1445
- }
1446
- function assertCookie(v2) {
1447
- if (v2 === null || typeof v2 === "string" || typeof v2 === "number") {
1448
- return;
1449
- }
1450
- assertJSONObject(v2);
1451
- if (typeof v2.order === "string" || typeof v2.order === "number") {
1452
- return;
1453
- }
1454
- throw new Error("Invalid cookie");
1455
- }
1456
-
1457
- // ../replicache/src/dag/chunk.ts
1458
- function asRefs(sortedRefs) {
1459
- return sortedRefs;
1460
- }
1461
- function toRefs(refs) {
1462
- if (Array.isArray(refs)) {
1463
- refs.sort();
1464
- for (let i = 1; i < refs.length; i++) {
1465
- assert(refs[i - 1] !== refs[i], "Refs must not have duplicates");
1466
- }
1467
- return asRefs(refs);
1468
- }
1469
- const refsArray = [...refs];
1470
- refsArray.sort();
1471
- return asRefs(refsArray);
1472
- }
1473
- var Chunk = class {
1474
- hash;
1475
- data;
1476
- /**
1477
- * Meta is an array of refs. If there are no refs we do not write a meta
1478
- * chunk.
1479
- */
1480
- meta;
1481
- constructor(hash2, data, refs) {
1482
- assert(
1483
- !refs.includes(hash2),
1484
- "Chunk cannot reference itself"
1485
- );
1486
- assertDeepFrozen(data);
1487
- this.hash = hash2;
1488
- this.data = data;
1489
- this.meta = refs;
1490
- }
1491
- };
1492
- function assertRefs(v2) {
1493
- if (!Array.isArray(v2)) {
1494
- throw new Error("Refs must be an array");
1495
- }
1496
- if (v2.length > 0) {
1497
- assertString(v2[0]);
1498
- for (let i = 1; i < v2.length; i++) {
1499
- assertString(v2[i]);
1500
- }
1501
- }
1502
- }
1503
- function createChunk(data, refs, chunkHasher) {
1504
- const hash2 = chunkHasher();
1505
- return new Chunk(hash2, data, refs);
1506
- }
1507
-
1508
- // ../replicache/src/db/meta-type-enum.ts
1509
- var LocalDD31 = 4;
1510
- var SnapshotDD31 = 5;
1511
-
1512
- // ../replicache/src/db/commit.ts
1513
- var DEFAULT_HEAD_NAME = "main";
1514
- function commitIsLocalDD31(commit) {
1515
- return isLocalMetaDD31(commit.meta);
1516
- }
1517
- function commitIsLocal(commit) {
1518
- return commitIsLocalDD31(commit);
1519
- }
1520
- function commitIsSnapshot(commit) {
1521
- return isSnapshotMetaDD31(commit.meta);
1522
- }
1523
- var Commit = class {
1524
- chunk;
1525
- constructor(chunk) {
1526
- this.chunk = chunk;
1527
- }
1528
- get meta() {
1529
- return this.chunk.data.meta;
1530
- }
1531
- get valueHash() {
1532
- return this.chunk.data.valueHash;
1533
- }
1534
- getMutationID(clientID, dagRead) {
1535
- return getMutationID(clientID, dagRead, this.meta);
1536
- }
1537
- async getNextMutationID(clientID, dagRead) {
1538
- return await this.getMutationID(clientID, dagRead) + 1;
1539
- }
1540
- get indexes() {
1541
- return this.chunk.data.indexes;
1542
- }
1543
- };
1544
- async function getMutationID(clientID, dagRead, meta) {
1545
- switch (meta.type) {
1546
- case SnapshotDD31:
1547
- return meta.lastMutationIDs[clientID] ?? 0;
1548
- case LocalDD31: {
1549
- if (meta.clientID === clientID) {
1550
- return meta.mutationID;
1551
- }
1552
- const { basisHash } = meta;
1553
- const basisCommit = await commitFromHash(basisHash, dagRead);
1554
- return getMutationID(clientID, dagRead, basisCommit.meta);
1555
- }
1556
- default:
1557
- unreachable(meta);
1558
- }
1559
- }
1560
- async function localMutations(fromCommitHash, dagRead) {
1561
- const commits = await commitChain(fromCommitHash, dagRead);
1562
- return commits.filter((c) => commitIsLocal(c));
1563
- }
1564
- async function localMutationsDD31(fromCommitHash, dagRead) {
1565
- const commits = await commitChain(fromCommitHash, dagRead);
1566
- return commits.filter((c) => commitIsLocalDD31(c));
1567
- }
1568
- async function localMutationsGreaterThan(commit, mutationIDLimits, dagRead) {
1569
- const commits = [];
1570
- const remainingMutationIDLimits = new Map(Object.entries(mutationIDLimits));
1571
- while (!commitIsSnapshot(commit) && remainingMutationIDLimits.size > 0) {
1572
- if (commitIsLocalDD31(commit)) {
1573
- const { meta } = commit;
1574
- const mutationIDLowerLimit = remainingMutationIDLimits.get(meta.clientID);
1575
- if (mutationIDLowerLimit !== void 0) {
1576
- if (meta.mutationID <= mutationIDLowerLimit) {
1577
- remainingMutationIDLimits.delete(meta.clientID);
1578
- } else {
1579
- commits.push(commit);
1580
- }
1581
- }
1582
- }
1583
- const { basisHash } = commit.meta;
1584
- if (basisHash === null) {
1585
- throw new Error(`Commit ${commit.chunk.hash} has no basis`);
1586
- }
1587
- commit = await commitFromHash(basisHash, dagRead);
1588
- }
1589
- return commits;
1590
- }
1591
- async function baseSnapshotFromHead(name, dagRead) {
1592
- const hash2 = await dagRead.getHead(name);
1593
- assert(hash2, `Missing head ${name}`);
1594
- return baseSnapshotFromHash(hash2, dagRead);
1595
- }
1596
- async function baseSnapshotHashFromHash(hash2, dagRead) {
1597
- return (await baseSnapshotFromHash(hash2, dagRead)).chunk.hash;
1598
- }
1599
- async function baseSnapshotFromHash(hash2, dagRead) {
1600
- const commit = await commitFromHash(hash2, dagRead);
1601
- return baseSnapshotFromCommit(commit, dagRead);
1602
- }
1603
- async function baseSnapshotFromCommit(commit, dagRead) {
1604
- while (!commitIsSnapshot(commit)) {
1605
- const { meta } = commit;
1606
- if (isLocalMetaDD31(meta)) {
1607
- commit = await commitFromHash(meta.baseSnapshotHash, dagRead);
1608
- } else {
1609
- const { basisHash } = meta;
1610
- if (basisHash === null) {
1611
- throw new Error(`Commit ${commit.chunk.hash} has no basis`);
1612
- }
1613
- commit = await commitFromHash(basisHash, dagRead);
1614
- }
1615
- }
1616
- return commit;
1617
- }
1618
- function snapshotMetaParts(c, clientID) {
1619
- const m = c.meta;
1620
- const lmid = m.lastMutationIDs[clientID] ?? 0;
1621
- return [lmid, m.cookieJSON];
1622
- }
1623
- function compareCookiesForSnapshots(a, b) {
1624
- return compareCookies(a.meta.cookieJSON, b.meta.cookieJSON);
1625
- }
1626
- async function commitChain(fromCommitHash, dagRead) {
1627
- let commit = await commitFromHash(fromCommitHash, dagRead);
1628
- const commits = [];
1629
- while (!commitIsSnapshot(commit)) {
1630
- const { meta } = commit;
1631
- const { basisHash } = meta;
1632
- if (basisHash === null) {
1633
- throw new Error(`Commit ${commit.chunk.hash} has no basis`);
1634
- }
1635
- commits.push(commit);
1636
- commit = await commitFromHash(basisHash, dagRead);
1637
- }
1638
- commits.push(commit);
1639
- return commits;
1640
- }
1641
- async function commitFromHash(hash2, dagRead) {
1642
- const chunk = await dagRead.mustGetChunk(hash2);
1643
- return fromChunk(chunk);
1644
- }
1645
- async function commitFromHead(name, dagRead) {
1646
- const hash2 = await mustGetHeadHash(name, dagRead);
1647
- return commitFromHash(hash2, dagRead);
1648
- }
1649
- function assertLocalMetaDD31(v2) {
1650
- assertString(v2.clientID);
1651
- assertNumber(v2.mutationID);
1652
- assertString(v2.mutatorName);
1653
- if (!v2.mutatorName) {
1654
- throw new Error("Missing mutator name");
1655
- }
1656
- assertJSONValue(v2.mutatorArgsJSON);
1657
- if (v2.originalHash !== null) {
1658
- assertHash(v2.originalHash);
1659
- }
1660
- assertNumber(v2.timestamp);
1661
- }
1662
- function isLocalMetaDD31(meta) {
1663
- return meta.type === LocalDD31;
1664
- }
1665
- function assertSnapshotMetaDD31(v2) {
1666
- if (v2.basisHash !== null) {
1667
- assertHash(v2.basisHash);
1668
- }
1669
- assertJSONValue(v2.cookieJSON);
1670
- assertLastMutationIDs(v2.lastMutationIDs);
1671
- }
1672
- function assertLastMutationIDs(v2) {
1673
- assertObject(v2);
1674
- for (const e of Object.values(v2)) {
1675
- assertNumber(e);
1676
- }
1677
- }
1678
- function assertSnapshotCommitDD31(c) {
1679
- assertSnapshotMetaDD31(c.meta);
1680
- }
1681
- function isSnapshotMetaDD31(meta) {
1682
- return meta.type === SnapshotDD31;
1683
- }
1684
- function assertMeta(v2) {
1685
- assertObject(v2);
1686
- assertDeepFrozen(v2);
1687
- if (v2.basisHash !== null) {
1688
- assertString(v2.basisHash);
1689
- }
1690
- assertNumber(v2.type);
1691
- switch (v2.type) {
1692
- case LocalDD31:
1693
- assertLocalMetaDD31(v2);
1694
- break;
1695
- case SnapshotDD31:
1696
- assertSnapshotMetaDD31(v2);
1697
- break;
1698
- default:
1699
- throw new Error(`Invalid enum value ${v2.type}`);
1700
- }
1701
- }
1702
- function chunkIndexDefinitionEqualIgnoreName(a, b) {
1703
- return a.jsonPointer === b.jsonPointer && (a.allowEmpty ?? false) === (b.allowEmpty ?? false) && a.keyPrefix === b.keyPrefix;
1704
- }
1705
- function assertChunkIndexDefinition(v2) {
1706
- assertObject(v2);
1707
- assertDeepFrozen(v2);
1708
- assertString(v2.name);
1709
- assertString(v2.keyPrefix);
1710
- assertString(v2.jsonPointer);
1711
- if (v2.allowEmpty !== void 0) {
1712
- assertBoolean(v2.allowEmpty);
1713
- }
1714
- }
1715
- function toChunkIndexDefinition(name, indexDefinition) {
1716
- return {
1717
- name,
1718
- keyPrefix: indexDefinition.prefix ?? "",
1719
- jsonPointer: indexDefinition.jsonPointer,
1720
- allowEmpty: indexDefinition.allowEmpty ?? false
1721
- };
1722
- }
1723
- function assertIndexRecord(v2) {
1724
- assertObject(v2);
1725
- assertDeepFrozen(v2);
1726
- assertChunkIndexDefinition(v2.definition);
1727
- assertString(v2.valueHash);
1728
- }
1729
- function assertIndexRecords(v2) {
1730
- assertArray(v2);
1731
- assertDeepFrozen(v2);
1732
- for (const ir of v2) {
1733
- assertIndexRecord(ir);
1734
- }
1735
- }
1736
- function newLocalDD31(createChunk2, basisHash, baseSnapshotHash, mutationID, mutatorName, mutatorArgsJSON, originalHash, valueHash, indexes, timestamp, clientID) {
1737
- const meta = {
1738
- type: LocalDD31,
1739
- basisHash,
1740
- baseSnapshotHash,
1741
- mutationID,
1742
- mutatorName,
1743
- mutatorArgsJSON,
1744
- originalHash,
1745
- timestamp,
1746
- clientID
1747
- };
1748
- return commitFromCommitData(
1749
- createChunk2,
1750
- makeCommitData(meta, valueHash, indexes)
1751
- );
1752
- }
1753
- function newSnapshotDD31(createChunk2, basisHash, lastMutationIDs, cookieJSON, valueHash, indexes) {
1754
- return commitFromCommitData(
1755
- createChunk2,
1756
- newSnapshotCommitDataDD31(
1757
- basisHash,
1758
- lastMutationIDs,
1759
- cookieJSON,
1760
- valueHash,
1761
- indexes
1762
- )
1763
- );
1764
- }
1765
- function newSnapshotCommitDataDD31(basisHash, lastMutationIDs, cookieJSON, valueHash, indexes) {
1766
- const meta = {
1767
- type: SnapshotDD31,
1768
- basisHash,
1769
- lastMutationIDs,
1770
- cookieJSON
1771
- };
1772
- return makeCommitData(meta, valueHash, indexes);
1773
- }
1774
- function fromChunk(chunk) {
1775
- validateChunk(chunk);
1776
- return new Commit(chunk);
1777
- }
1778
- function commitFromCommitData(createChunk2, data) {
1779
- return new Commit(createChunk2(data, getRefs(data)));
1780
- }
1781
- function getRefs(data) {
1782
- const refs = /* @__PURE__ */ new Set();
1783
- refs.add(data.valueHash);
1784
- const { meta } = data;
1785
- switch (meta.type) {
1786
- case LocalDD31:
1787
- meta.basisHash && refs.add(meta.basisHash);
1788
- break;
1789
- case SnapshotDD31:
1790
- break;
1791
- default:
1792
- unreachable(meta);
1793
- }
1794
- for (const index of data.indexes) {
1795
- refs.add(index.valueHash);
1796
- }
1797
- return toRefs(refs);
1798
- }
1799
- function makeCommitData(meta, valueHash, indexes) {
1800
- return deepFreeze({
1801
- meta,
1802
- valueHash,
1803
- indexes
1804
- });
1805
- }
1806
- function assertCommitData(v2) {
1807
- if (isProd) {
1808
- return;
1809
- }
1810
- assertObject(v2);
1811
- assertDeepFrozen(v2);
1812
- assertMeta(v2.meta);
1813
- assertString(v2.valueHash);
1814
- assertIndexRecords(v2.indexes);
1815
- }
1816
- function validateChunk(chunk) {
1817
- const { data } = chunk;
1818
- assertCommitData(data);
1819
- const seen = /* @__PURE__ */ new Set();
1820
- for (const index of data.indexes) {
1821
- const { name } = index.definition;
1822
- if (seen.has(name)) {
1823
- throw new Error(`Duplicate index ${name}`);
1824
- }
1825
- seen.add(name);
1826
- }
1827
- }
1828
-
1829
- // ../replicache/src/db/index-operation-enum.ts
1830
- var Add = 0;
1831
- var Remove = 1;
1832
-
1833
- // ../replicache/src/db/index.ts
1834
- var IndexRead = class {
1835
- meta;
1836
- map;
1837
- constructor(meta, map) {
1838
- this.meta = meta;
1839
- this.map = map;
1840
- }
1841
- };
1842
- var IndexWrite = class extends IndexRead {
1843
- // Note: does not update self.meta.valueHash (doesn't need to at this point as flush
1844
- // is only called during commit.)
1845
- flush() {
1846
- return this.map.flush();
1847
- }
1848
- clear() {
1849
- return this.map.clear();
1850
- }
1851
- };
1852
- async function indexValue(lc, index, op, key, val, jsonPointer, allowEmpty) {
1853
- try {
1854
- for (const entry of getIndexKeys(key, val, jsonPointer, allowEmpty)) {
1855
- switch (op) {
1856
- case Add:
1857
- await index.put(entry, val);
1858
- break;
1859
- case Remove:
1860
- await index.del(entry);
1861
- break;
1862
- }
1863
- }
1864
- } catch (e) {
1865
- lc.info?.("Not indexing value", val, ":", e);
1866
- }
1867
- }
1868
- function getIndexKeys(primary, value, jsonPointer, allowEmpty) {
1869
- const target = evaluateJSONPointer(value, jsonPointer);
1870
- if (target === void 0) {
1871
- if (allowEmpty) {
1872
- return [];
1873
- }
1874
- throw new Error(`No value at path: ${jsonPointer}`);
1875
- }
1876
- const values = Array.isArray(target) ? target : [target];
1877
- const indexKeys = [];
1878
- for (const value2 of values) {
1879
- if (typeof value2 === "string") {
1880
- indexKeys.push(encodeIndexKey([value2, primary]));
1881
- } else {
1882
- throw new Error("Unsupported target type");
1883
- }
1884
- }
1885
- return indexKeys;
1886
- }
1887
- var KEY_VERSION_0 = "\0";
1888
- var KEY_SEPARATOR = "\0";
1889
- function encodeIndexKey(indexKey) {
1890
- const secondary = indexKey[0];
1891
- const primary = indexKey[1];
1892
- if (secondary.includes("\0")) {
1893
- throw new Error("Secondary key cannot contain null byte");
1894
- }
1895
- return KEY_VERSION_0 + secondary + KEY_SEPARATOR + primary;
1896
- }
1897
- function encodeIndexScanKey(secondary, primary) {
1898
- const k = encodeIndexKey([secondary, primary || ""]);
1899
- if (primary === void 0) {
1900
- return k.slice(0, k.length - 1);
1901
- }
1902
- return k;
1903
- }
1904
- function decodeIndexKey(encodedIndexKey) {
1905
- if (encodedIndexKey[0] !== KEY_VERSION_0) {
1906
- throw new Error("Invalid version");
1907
- }
1908
- const versionLen = KEY_VERSION_0.length;
1909
- const separatorLen = KEY_SEPARATOR.length;
1910
- const separatorOffset = encodedIndexKey.indexOf(KEY_SEPARATOR, versionLen);
1911
- if (separatorOffset === -1) {
1912
- throw new Error("Invalid formatting");
1913
- }
1914
- const secondary = encodedIndexKey.slice(versionLen, separatorOffset);
1915
- const primary = encodedIndexKey.slice(separatorOffset + separatorLen);
1916
- return [secondary, primary];
1917
- }
1918
- function evaluateJSONPointer(value, pointer) {
1919
- function parseIndex(s) {
1920
- if (s.startsWith("+") || s.startsWith("0") && s.length !== 1) {
1921
- return void 0;
1922
- }
1923
- return parseInt(s, 10);
1924
- }
1925
- if (pointer === "") {
1926
- return value;
1927
- }
1928
- if (!pointer.startsWith("/")) {
1929
- throw new Error(`Invalid JSON pointer: ${pointer}`);
1930
- }
1931
- const tokens = pointer.split("/").slice(1).map((x) => x.replace(/~1/g, "/").replace(/~0/g, "~"));
1932
- let target = value;
1933
- for (const token of tokens) {
1934
- let targetOpt;
1935
- if (Array.isArray(target)) {
1936
- const i = parseIndex(token);
1937
- if (i === void 0) {
1938
- return void 0;
1939
- }
1940
- targetOpt = target[i];
1941
- } else if (target === null) {
1942
- return void 0;
1943
- } else if (typeof target === "object") {
1944
- target = target;
1945
- targetOpt = target[token];
1946
- }
1947
- if (targetOpt === void 0) {
1948
- return void 0;
1949
- }
1950
- target = targetOpt;
1951
- }
1952
- return target;
1953
- }
1954
-
1955
- // ../replicache/src/db/read.ts
1956
- var Read = class {
1957
- #dagRead;
1958
- map;
1959
- indexes;
1960
- constructor(dagRead, map, indexes) {
1961
- this.#dagRead = dagRead;
1962
- this.map = map;
1963
- this.indexes = indexes;
1964
- }
1965
- has(key) {
1966
- return this.map.has(key);
1967
- }
1968
- get(key) {
1969
- return this.map.get(key);
1970
- }
1971
- isEmpty() {
1972
- return this.map.isEmpty();
1973
- }
1974
- getMapForIndex(indexName) {
1975
- const idx = this.indexes.get(indexName);
1976
- if (idx === void 0) {
1977
- throw new Error(`Unknown index name: ${indexName}`);
1978
- }
1979
- return idx.map;
1980
- }
1981
- get closed() {
1982
- return this.#dagRead.closed;
1983
- }
1984
- close() {
1985
- this.#dagRead.release();
1986
- }
1987
- };
1988
- function readFromDefaultHead(dagRead, formatVersion) {
1989
- return readFromHead(DEFAULT_HEAD_NAME, dagRead, formatVersion);
1990
- }
1991
- async function readFromHead(name, dagRead, formatVersion) {
1992
- const commit = await commitFromHead(name, dagRead);
1993
- return readFromCommit(commit, dagRead, formatVersion);
1994
- }
1995
- async function readFromHash(hash2, dagRead, formatVersion) {
1996
- const commit = await commitFromHash(hash2, dagRead);
1997
- return readFromCommit(commit, dagRead, formatVersion);
1998
- }
1999
- function readFromCommit(commit, dagRead, formatVersion) {
2000
- const indexes = readIndexesForRead(commit, dagRead, formatVersion);
2001
- const map = new BTreeRead(dagRead, formatVersion, commit.valueHash);
2002
- return new Read(dagRead, map, indexes);
2003
- }
2004
- function readIndexesForRead(commit, dagRead, formatVersion) {
2005
- const m = /* @__PURE__ */ new Map();
2006
- for (const index of commit.indexes) {
2007
- m.set(
2008
- index.definition.name,
2009
- new IndexRead(
2010
- index,
2011
- new BTreeRead(dagRead, formatVersion, index.valueHash)
2012
- )
2013
- );
2014
- }
2015
- return m;
2016
- }
2017
-
2018
- // ../replicache/src/index-defs.ts
2019
- var indexDefinitionSchema = readonlyObject({
2020
- prefix: valita_exports.string().optional(),
2021
- jsonPointer: valita_exports.string(),
2022
- allowEmpty: valita_exports.boolean().optional()
2023
- });
2024
- var indexDefinitionsSchema = readonlyRecord(
2025
- indexDefinitionSchema
2026
- );
2027
- function indexDefinitionEqual(a, b) {
2028
- return a.jsonPointer === b.jsonPointer && (a.allowEmpty ?? false) === (b.allowEmpty ?? false) && (a.prefix ?? "") === (b.prefix ?? "");
2029
- }
2030
- function indexDefinitionsEqual(a, b) {
2031
- if (Object.keys(a).length !== Object.keys(b).length) {
2032
- return false;
2033
- }
2034
- for (const [aKey, aValue] of Object.entries(a)) {
2035
- const bValue = b[aKey];
2036
- if (!bValue || !indexDefinitionEqual(aValue, bValue)) {
2037
- return false;
2038
- }
2039
- }
2040
- return true;
2041
- }
2042
-
2043
- // ../replicache/src/persist/client-groups.ts
2044
- var clientGroupSchema = readonlyObject({
2045
- /**
2046
- * The hash of the commit in the perdag last persisted to this client group.
2047
- * Should only be updated by clients assigned to this client group.
2048
- */
2049
- headHash: hashSchema,
2050
- /**
2051
- * Set of mutator names common to all clients assigned to this client group.
2052
- */
2053
- mutatorNames: readonlyArray(valita_exports.string()),
2054
- /**
2055
- * Index definitions common to all clients assigned to this client group.
2056
- */
2057
- indexes: indexDefinitionsSchema,
2058
- /**
2059
- * The highest mutation ID of every client assigned to this client group.
2060
- * Should only be updated by clients assigned to this client group. Read by
2061
- * other clients to determine if there are unacknowledged pending mutations
2062
- * for them to try to recover. This is redundant with information in the
2063
- * commit graph at `headHash`, but allows other clients to determine if there
2064
- * are unacknowledged pending mutations without having to load the commit
2065
- * graph.
2066
- */
2067
- mutationIDs: readonlyRecord(valita_exports.number()),
2068
- /**
2069
- * The highest lastMutationID received from the server for every client
2070
- * assigned to this client group.
2071
- *
2072
- * Should be updated by the clients assigned to this client group whenever
2073
- * they persist to this client group. Read by other clients to determine if
2074
- * there are unacknowledged pending mutations for them to recover and
2075
- * *updated* by other clients upon successfully recovering pending mutations
2076
- * to avoid redundant pushes of pending mutations.
2077
- *
2078
- * Note: This will be the same as the `lastMutationIDs` of the base snapshot
2079
- * of the client group's commit graph when written by clients assigned to this
2080
- * client group. However, when written by another client recovering mutations
2081
- * it may be different because the other client does not update the commit
2082
- * graph.
2083
- */
2084
- lastServerAckdMutationIDs: valita_exports.record(valita_exports.number()),
2085
- /**
2086
- * If the server deletes this client group it can signal that the client group
2087
- * was deleted. If that happens we mark this client group as disabled so that
2088
- * we do not use it again when creating new clients.
2089
- */
2090
- disabled: valita_exports.boolean()
2091
- });
2092
- var CLIENT_GROUPS_HEAD_NAME = "client-groups";
2093
- function assertClientGroup(value) {
2094
- assert2(value, clientGroupSchema);
2095
- }
2096
- function chunkDataToClientGroupMap(chunkData) {
2097
- assertObject(chunkData);
2098
- const clientGroups = /* @__PURE__ */ new Map();
2099
- for (const [key, value] of Object.entries(chunkData)) {
2100
- if (value !== void 0) {
2101
- assertClientGroup(value);
2102
- clientGroups.set(key, value);
2103
- }
2104
- }
2105
- return clientGroups;
2106
- }
2107
- function clientGroupMapToChunkData(clientGroups, dagWrite) {
2108
- const chunkData = {};
2109
- for (const [clientGroupID, clientGroup] of clientGroups.entries()) {
2110
- dagWrite.assertValidHash(clientGroup.headHash);
2111
- chunkData[clientGroupID] = {
2112
- ...clientGroup,
2113
- mutatorNames: [...clientGroup.mutatorNames.values()]
2114
- };
2115
- }
2116
- return deepFreeze(chunkData);
2117
- }
2118
- async function getClientGroupsAtHash(hash2, dagRead) {
2119
- const chunk = await dagRead.getChunk(hash2);
2120
- return chunkDataToClientGroupMap(chunk?.data);
2121
- }
2122
- async function getClientGroups(dagRead) {
2123
- const hash2 = await dagRead.getHead(CLIENT_GROUPS_HEAD_NAME);
2124
- if (!hash2) {
2125
- return /* @__PURE__ */ new Map();
2126
- }
2127
- return getClientGroupsAtHash(hash2, dagRead);
2128
- }
2129
- async function setClientGroups(clientGroups, dagWrite) {
2130
- const currClientGroups = await getClientGroups(dagWrite);
2131
- for (const [clientGroupID, clientGroup] of clientGroups) {
2132
- const currClientGroup = currClientGroups.get(clientGroupID);
2133
- validateClientGroupUpdate(clientGroup, currClientGroup);
2134
- }
2135
- return setValidatedClientGroups(clientGroups, dagWrite);
2136
- }
2137
- async function setClientGroup(clientGroupID, clientGroup, dagWrite) {
2138
- const currClientGroups = await getClientGroups(dagWrite);
2139
- const currClientGroup = currClientGroups.get(clientGroupID);
2140
- validateClientGroupUpdate(clientGroup, currClientGroup);
2141
- const newClientGroups = new Map(currClientGroups);
2142
- newClientGroups.set(clientGroupID, clientGroup);
2143
- return setValidatedClientGroups(newClientGroups, dagWrite);
2144
- }
2145
- function validateClientGroupUpdate(clientGroup, currClientGroup) {
2146
- const mutatorNamesSet = new Set(clientGroup.mutatorNames);
2147
- assert(
2148
- mutatorNamesSet.size === clientGroup.mutatorNames.length,
2149
- "A client group's mutatorNames must be a set."
2150
- );
2151
- if (currClientGroup !== void 0) {
2152
- assert(
2153
- indexDefinitionsEqual(currClientGroup.indexes, clientGroup.indexes),
2154
- "A client group's index definitions must never change."
2155
- );
2156
- assert(
2157
- mutatorNamesEqual(mutatorNamesSet, currClientGroup.mutatorNames),
2158
- "A client group's mutatorNames must never change."
2159
- );
2160
- }
2161
- }
2162
- async function setValidatedClientGroups(clientGroups, dagWrite) {
2163
- const chunkData = clientGroupMapToChunkData(clientGroups, dagWrite);
2164
- const refs = /* @__PURE__ */ new Set();
2165
- for (const clientGroup of clientGroups.values()) {
2166
- refs.add(clientGroup.headHash);
2167
- }
2168
- const chunk = dagWrite.createChunk(chunkData, toRefs(refs));
2169
- await dagWrite.putChunk(chunk);
2170
- await dagWrite.setHead(CLIENT_GROUPS_HEAD_NAME, chunk.hash);
2171
- return clientGroups;
2172
- }
2173
- function mutatorNamesEqual(mutatorNamesSet, mutatorNames) {
2174
- if (mutatorNames.length !== mutatorNamesSet.size) {
2175
- return false;
2176
- }
2177
- for (const mutatorName of mutatorNames) {
2178
- if (!mutatorNamesSet.has(mutatorName)) {
2179
- return false;
2180
- }
2181
- }
2182
- return true;
2183
- }
2184
- async function getClientGroup(id, dagRead) {
2185
- const clientGroups = await getClientGroups(dagRead);
2186
- return clientGroups.get(id);
2187
- }
2188
- function clientGroupHasPendingMutations(clientGroup) {
2189
- for (const [clientID, mutationID] of Object.entries(
2190
- clientGroup.mutationIDs
2191
- )) {
2192
- const lastServerAckdMutationID = clientGroup.lastServerAckdMutationIDs[clientID];
2193
- if (lastServerAckdMutationID === void 0 && mutationID !== 0 || lastServerAckdMutationID < mutationID) {
2194
- return true;
2195
- }
2196
- }
2197
- return false;
2198
- }
2199
- async function disableClientGroup(clientGroupID, dagWrite) {
2200
- const clientGroup = await getClientGroup(clientGroupID, dagWrite);
2201
- if (!clientGroup) {
2202
- return;
2203
- }
2204
- const disabledClientGroup = {
2205
- ...clientGroup,
2206
- disabled: true
2207
- };
2208
- await setClientGroup(clientGroupID, disabledClientGroup, dagWrite);
2209
- }
2210
-
2211
- // ../replicache/src/with-transactions.ts
2212
- function withRead(store, fn) {
2213
- return using(store.read(), fn);
2214
- }
2215
- function withWriteNoImplicitCommit(store, fn) {
2216
- return using(store.write(), fn);
2217
- }
2218
- function withWrite(store, fn) {
2219
- return using(store.write(), async (write) => {
2220
- const result = await fn(write);
2221
- await write.commit();
2222
- return result;
2223
- });
2224
- }
2225
- async function using(x, fn) {
2226
- const write = await x;
2227
- try {
2228
- return await fn(write);
2229
- } finally {
2230
- write.release();
2231
- }
2232
- }
2233
-
2234
- // ../replicache/src/async-iterable-to-array.ts
2235
- async function asyncIterableToArray(it) {
2236
- const arr = [];
2237
- for await (const v2 of it) {
2238
- arr.push(v2);
2239
- }
2240
- return arr;
2241
- }
2242
-
2243
- // ../replicache/src/btree/diff.ts
2244
- function diff(oldMap, newMap) {
2245
- return asyncIterableToArray(newMap.diff(oldMap));
2246
- }
2247
-
2248
- // ../replicache/src/btree/write.ts
2249
- import { Lock } from "@rocicorp/lock";
2250
- var BTreeWrite = class extends BTreeRead {
2251
- /**
2252
- * This rw lock is used to ensure we do not mutate the btree in parallel. It
2253
- * would be a problem if we didn't have the lock in cases like this:
2254
- *
2255
- * ```ts
2256
- * const p1 = tree.put('a', 0);
2257
- * const p2 = tree.put('b', 1);
2258
- * await p1;
2259
- * await p2;
2260
- * ```
2261
- *
2262
- * because both `p1` and `p2` would start from the old root hash but a put
2263
- * changes the root hash so the two concurrent puts would lead to only one of
2264
- * them actually working, and it is not deterministic which one would finish
2265
- * last.
2266
- */
2267
- #lock = new Lock();
2268
- #modified = /* @__PURE__ */ new Map();
2269
- minSize;
2270
- maxSize;
2271
- constructor(dagWrite, formatVersion, root = emptyHash, minSize = 8 * 1024, maxSize = 16 * 1024, getEntrySize = getSizeOfEntry, chunkHeaderSize) {
2272
- super(dagWrite, formatVersion, root, getEntrySize, chunkHeaderSize);
2273
- this.minSize = minSize;
2274
- this.maxSize = maxSize;
2275
- }
2276
- #addToModified(node) {
2277
- assert(node.isMutable);
2278
- this.#modified.set(node.hash, node);
2279
- this._cache.set(node.hash, node);
2280
- }
2281
- updateNode(node) {
2282
- assert(node.isMutable);
2283
- this.#modified.delete(node.hash);
2284
- node.hash = newRandomHash();
2285
- this.#addToModified(node);
2286
- }
2287
- newInternalNodeImpl(entries, level) {
2288
- const n = new InternalNodeImpl(entries, newRandomHash(), level, true);
2289
- this.#addToModified(n);
2290
- return n;
2291
- }
2292
- newDataNodeImpl(entries) {
2293
- const n = new DataNodeImpl(entries, newRandomHash(), true);
2294
- this.#addToModified(n);
2295
- return n;
2296
- }
2297
- newNodeImpl(entries, level) {
2298
- const n = newNodeImpl(entries, newRandomHash(), level, true);
2299
- this.#addToModified(n);
2300
- return n;
2301
- }
2302
- put(key, value) {
2303
- return this.#lock.withLock(async () => {
2304
- const oldRootNode = await this.getNode(this.rootHash);
2305
- const entrySize = this.getEntrySize(key, value);
2306
- const rootNode = await oldRootNode.set(key, value, entrySize, this);
2307
- if (rootNode.getChildNodeSize(this) > this.maxSize) {
2308
- const headerSize = this.chunkHeaderSize;
2309
- const partitions = partition(
2310
- rootNode.entries,
2311
- (value2) => value2[2],
2312
- this.minSize - headerSize,
2313
- this.maxSize - headerSize
2314
- );
2315
- const { level } = rootNode;
2316
- const entries = partitions.map((entries2) => {
2317
- const node = this.newNodeImpl(entries2, level);
2318
- return createNewInternalEntryForNode(node, this.getEntrySize);
2319
- });
2320
- const newRoot = this.newInternalNodeImpl(entries, level + 1);
2321
- this.rootHash = newRoot.hash;
2322
- return;
2323
- }
2324
- this.rootHash = rootNode.hash;
2325
- });
2326
- }
2327
- del(key) {
2328
- return this.#lock.withLock(async () => {
2329
- const oldRootNode = await this.getNode(this.rootHash);
2330
- const newRootNode = await oldRootNode.del(key, this);
2331
- const found = this.rootHash !== newRootNode.hash;
2332
- if (found) {
2333
- if (newRootNode.level > 0 && newRootNode.entries.length === 1) {
2334
- this.rootHash = newRootNode.entries[0][1];
2335
- } else {
2336
- this.rootHash = newRootNode.hash;
2337
- }
2338
- }
2339
- return found;
2340
- });
2341
- }
2342
- clear() {
2343
- return this.#lock.withLock(() => {
2344
- this.#modified.clear();
2345
- this.rootHash = emptyHash;
2346
- });
2347
- }
2348
- flush() {
2349
- return this.#lock.withLock(async () => {
2350
- const dagWrite = this._dagRead;
2351
- if (this.rootHash === emptyHash) {
2352
- const chunk = dagWrite.createChunk(emptyDataNode, []);
2353
- await dagWrite.putChunk(chunk);
2354
- return chunk.hash;
2355
- }
2356
- const newChunks = [];
2357
- const newRoot = gatherNewChunks(
2358
- this.rootHash,
2359
- newChunks,
2360
- dagWrite.createChunk,
2361
- this.#modified,
2362
- this._formatVersion
2363
- );
2364
- await Promise.all(newChunks.map((chunk) => dagWrite.putChunk(chunk)));
2365
- this.#modified.clear();
2366
- this.rootHash = newRoot;
2367
- return newRoot;
2368
- });
2369
- }
2370
- };
2371
- function gatherNewChunks(hash2, newChunks, createChunk2, modified, formatVersion) {
2372
- const node = modified.get(hash2);
2373
- if (node === void 0) {
2374
- return hash2;
2375
- }
2376
- if (isDataNodeImpl(node)) {
2377
- const chunk2 = createChunk2(toChunkData(node, formatVersion), []);
2378
- newChunks.push(chunk2);
2379
- return chunk2.hash;
2380
- }
2381
- const refs = [];
2382
- const { entries } = node;
2383
- for (let i = 0; i < entries.length; i++) {
2384
- const entry = entries[i];
2385
- const childHash = entry[1];
2386
- const newChildHash = gatherNewChunks(
2387
- childHash,
2388
- newChunks,
2389
- createChunk2,
2390
- modified,
2391
- formatVersion
2392
- );
2393
- if (newChildHash !== childHash) {
2394
- entries[i] = [entry[0], newChildHash, entry[2]];
2395
- }
2396
- refs.push(newChildHash);
2397
- }
2398
- const chunk = createChunk2(toChunkData(node, formatVersion), toRefs(refs));
2399
- newChunks.push(chunk);
2400
- return chunk.hash;
2401
- }
2402
-
2403
- // ../replicache/src/lazy.ts
2404
- function lazy(factory) {
2405
- let value;
2406
- return () => {
2407
- if (value === void 0) {
2408
- value = factory();
2409
- }
2410
- return value;
2411
- };
2412
- }
2413
-
2414
- // ../replicache/src/sync/diff.ts
2415
- var DiffsMap = class extends Map {
2416
- set(key, value) {
2417
- if (value.length === 0) {
2418
- return this;
2419
- }
2420
- return super.set(key, value);
2421
- }
2422
- };
2423
- async function diff2(oldHash, newHash, read, diffConfig, formatVersion) {
2424
- const [oldCommit, newCommit] = await Promise.all([
2425
- commitFromHash(oldHash, read),
2426
- commitFromHash(newHash, read)
2427
- ]);
2428
- return diffCommits(oldCommit, newCommit, read, diffConfig, formatVersion);
2429
- }
2430
- async function diffCommits(oldCommit, newCommit, read, diffConfig, formatVersion) {
2431
- const diffsMap = new DiffsMap();
2432
- if (!diffConfig.shouldComputeDiffs()) {
2433
- return diffsMap;
2434
- }
2435
- const oldMap = new BTreeRead(read, formatVersion, oldCommit.valueHash);
2436
- const newMap = new BTreeRead(read, formatVersion, newCommit.valueHash);
2437
- const valueDiff = await diff(oldMap, newMap);
2438
- diffsMap.set("", valueDiff);
2439
- await addDiffsForIndexes(
2440
- oldCommit,
2441
- newCommit,
2442
- read,
2443
- diffsMap,
2444
- diffConfig,
2445
- formatVersion
2446
- );
2447
- return diffsMap;
2448
- }
2449
- async function addDiffsForIndexes(mainCommit, syncCommit, read, diffsMap, diffConfig, formatVersion) {
2450
- const oldIndexes = readIndexesForRead(mainCommit, read, formatVersion);
2451
- const newIndexes = readIndexesForRead(syncCommit, read, formatVersion);
2452
- for (const [oldIndexName, oldIndex] of oldIndexes) {
2453
- if (!diffConfig.shouldComputeDiffsForIndex(oldIndexName)) {
2454
- continue;
2455
- }
2456
- const newIndex = newIndexes.get(oldIndexName);
2457
- if (newIndex !== void 0) {
2458
- assert(newIndex !== oldIndex);
2459
- const diffs = await diff(oldIndex.map, newIndex.map);
2460
- newIndexes.delete(oldIndexName);
2461
- diffsMap.set(oldIndexName, diffs);
2462
- } else {
2463
- const diffs = await allEntriesAsDiff(oldIndex.map, "del");
2464
- diffsMap.set(oldIndexName, diffs);
2465
- }
2466
- }
2467
- for (const [newIndexName, newIndex] of newIndexes) {
2468
- if (!diffConfig.shouldComputeDiffsForIndex(newIndexName)) {
2469
- continue;
2470
- }
2471
- const diffs = await allEntriesAsDiff(newIndex.map, "add");
2472
- diffsMap.set(newIndexName, diffs);
2473
- }
2474
- }
2475
-
2476
- // ../replicache/src/db/write.ts
2477
- var Write = class extends Read {
2478
- #dagWrite;
2479
- #basis;
2480
- #meta;
2481
- #clientID;
2482
- #formatVersion;
2483
- constructor(dagWrite, map, basis, meta, indexes, clientID, formatVersion) {
2484
- super(dagWrite, map, indexes);
2485
- this.#dagWrite = dagWrite;
2486
- this.#basis = basis;
2487
- this.#meta = meta;
2488
- this.#clientID = clientID;
2489
- this.#formatVersion = formatVersion;
2490
- if (basis === void 0) {
2491
- assert(meta.basisHash === emptyHash);
2492
- } else {
2493
- assert(meta.basisHash === basis.chunk.hash);
2494
- }
2495
- }
2496
- /**
2497
- * The value needs to be frozen since it is kept in memory and used later for
2498
- * comparison as well as returned in `get`.
2499
- */
2500
- async put(lc, key, value) {
2501
- const oldVal = lazy(() => this.map.get(key));
2502
- await updateIndexes(lc, this.indexes, key, oldVal, value);
2503
- await this.map.put(key, value);
2504
- }
2505
- getMutationID() {
2506
- return getMutationID(this.#clientID, this.#dagWrite, this.#meta);
2507
- }
2508
- async del(lc, key) {
2509
- const oldVal = lazy(() => this.map.get(key));
2510
- if (oldVal !== void 0) {
2511
- await updateIndexes(lc, this.indexes, key, oldVal, void 0);
2512
- }
2513
- return this.map.del(key);
2514
- }
2515
- async clear() {
2516
- await this.map.clear();
2517
- const ps = [];
2518
- for (const idx of this.indexes.values()) {
2519
- ps.push(idx.clear());
2520
- }
2521
- await Promise.all(ps);
2522
- }
2523
- async putCommit() {
2524
- const valueHash = await this.map.flush();
2525
- const indexRecords = [];
2526
- for (const index of this.indexes.values()) {
2527
- const valueHash2 = await index.flush();
2528
- const indexRecord = {
2529
- definition: index.meta.definition,
2530
- valueHash: valueHash2
2531
- };
2532
- indexRecords.push(indexRecord);
2533
- }
2534
- let commit;
2535
- const meta = this.#meta;
2536
- switch (meta.type) {
2537
- case LocalDD31: {
2538
- assert(this.#formatVersion >= DD31);
2539
- const {
2540
- basisHash,
2541
- mutationID,
2542
- mutatorName,
2543
- mutatorArgsJSON,
2544
- originalHash,
2545
- timestamp
2546
- } = meta;
2547
- commit = newLocalDD31(
2548
- this.#dagWrite.createChunk,
2549
- basisHash,
2550
- await baseSnapshotHashFromHash(basisHash, this.#dagWrite),
2551
- mutationID,
2552
- mutatorName,
2553
- mutatorArgsJSON,
2554
- originalHash,
2555
- valueHash,
2556
- indexRecords,
2557
- timestamp,
2558
- this.#clientID
2559
- );
2560
- break;
2561
- }
2562
- case SnapshotDD31: {
2563
- assert(this.#formatVersion > DD31);
2564
- const { basisHash, lastMutationIDs, cookieJSON } = meta;
2565
- commit = newSnapshotDD31(
2566
- this.#dagWrite.createChunk,
2567
- basisHash,
2568
- lastMutationIDs,
2569
- cookieJSON,
2570
- valueHash,
2571
- indexRecords
2572
- );
2573
- break;
2574
- }
2575
- }
2576
- await this.#dagWrite.putChunk(commit.chunk);
2577
- return commit;
2578
- }
2579
- // Return value is the hash of the new commit.
2580
- async commit(headName) {
2581
- const commit = await this.putCommit();
2582
- const commitHash = commit.chunk.hash;
2583
- await this.#dagWrite.setHead(headName, commitHash);
2584
- await this.#dagWrite.commit();
2585
- return commitHash;
2586
- }
2587
- async commitWithDiffs(headName, diffConfig) {
2588
- const commit = this.putCommit();
2589
- const diffMap = await this.#generateDiffs(diffConfig);
2590
- const commitHash = (await commit).chunk.hash;
2591
- await this.#dagWrite.setHead(headName, commitHash);
2592
- await this.#dagWrite.commit();
2593
- return [commitHash, diffMap];
2594
- }
2595
- async #generateDiffs(diffConfig) {
2596
- const diffsMap = new DiffsMap();
2597
- if (!diffConfig.shouldComputeDiffs()) {
2598
- return diffsMap;
2599
- }
2600
- let valueDiff = [];
2601
- if (this.#basis) {
2602
- const basisMap = new BTreeRead(
2603
- this.#dagWrite,
2604
- this.#formatVersion,
2605
- this.#basis.valueHash
2606
- );
2607
- valueDiff = await diff(basisMap, this.map);
2608
- }
2609
- diffsMap.set("", valueDiff);
2610
- let basisIndexes;
2611
- if (this.#basis) {
2612
- basisIndexes = readIndexesForRead(
2613
- this.#basis,
2614
- this.#dagWrite,
2615
- this.#formatVersion
2616
- );
2617
- } else {
2618
- basisIndexes = /* @__PURE__ */ new Map();
2619
- }
2620
- for (const [name, index] of this.indexes) {
2621
- if (!diffConfig.shouldComputeDiffsForIndex(name)) {
2622
- continue;
2623
- }
2624
- const basisIndex = basisIndexes.get(name);
2625
- assert(index !== basisIndex);
2626
- const indexDiffResult = await (basisIndex ? diff(basisIndex.map, index.map) : (
2627
- // No basis. All keys are new.
2628
- allEntriesAsDiff(index.map, "add")
2629
- ));
2630
- diffsMap.set(name, indexDiffResult);
2631
- }
2632
- for (const [name, basisIndex] of basisIndexes) {
2633
- if (!this.indexes.has(name) && diffConfig.shouldComputeDiffsForIndex(name)) {
2634
- const indexDiffResult = await allEntriesAsDiff(basisIndex.map, "del");
2635
- diffsMap.set(name, indexDiffResult);
2636
- }
2637
- }
2638
- return diffsMap;
2639
- }
2640
- close() {
2641
- this.#dagWrite.release();
2642
- }
2643
- };
2644
- async function newWriteLocal(basisHash, mutatorName, mutatorArgsJSON, originalHash, dagWrite, timestamp, clientID, formatVersion) {
2645
- const basis = await commitFromHash(basisHash, dagWrite);
2646
- const bTreeWrite = new BTreeWrite(dagWrite, formatVersion, basis.valueHash);
2647
- const mutationID = await basis.getNextMutationID(clientID, dagWrite);
2648
- const indexes = readIndexesForWrite(basis, dagWrite, formatVersion);
2649
- assert(formatVersion >= DD31);
2650
- return new Write(
2651
- dagWrite,
2652
- bTreeWrite,
2653
- basis,
2654
- {
2655
- type: LocalDD31,
2656
- basisHash,
2657
- baseSnapshotHash: await baseSnapshotHashFromHash(basisHash, dagWrite),
2658
- mutatorName,
2659
- mutatorArgsJSON,
2660
- mutationID,
2661
- originalHash,
2662
- timestamp,
2663
- clientID
2664
- },
2665
- indexes,
2666
- clientID,
2667
- formatVersion
2668
- );
2669
- }
2670
- async function newWriteSnapshotDD31(basisHash, lastMutationIDs, cookieJSON, dagWrite, clientID, formatVersion) {
2671
- const basis = await commitFromHash(basisHash, dagWrite);
2672
- const bTreeWrite = new BTreeWrite(dagWrite, formatVersion, basis.valueHash);
2673
- return new Write(
2674
- dagWrite,
2675
- bTreeWrite,
2676
- basis,
2677
- { basisHash, type: SnapshotDD31, lastMutationIDs, cookieJSON },
2678
- readIndexesForWrite(basis, dagWrite, formatVersion),
2679
- clientID,
2680
- formatVersion
2681
- );
2682
- }
2683
- async function updateIndexes(lc, indexes, key, oldValGetter, newVal) {
2684
- const ps = [];
2685
- for (const idx of indexes.values()) {
2686
- const { keyPrefix } = idx.meta.definition;
2687
- if (!keyPrefix || key.startsWith(keyPrefix)) {
2688
- const oldVal = await oldValGetter();
2689
- if (oldVal !== void 0) {
2690
- ps.push(
2691
- indexValue(
2692
- lc,
2693
- idx.map,
2694
- Remove,
2695
- key,
2696
- oldVal,
2697
- idx.meta.definition.jsonPointer,
2698
- idx.meta.definition.allowEmpty ?? false
2699
- )
2700
- );
2701
- }
2702
- if (newVal !== void 0) {
2703
- ps.push(
2704
- indexValue(
2705
- lc,
2706
- idx.map,
2707
- Add,
2708
- key,
2709
- newVal,
2710
- idx.meta.definition.jsonPointer,
2711
- idx.meta.definition.allowEmpty ?? false
2712
- )
2713
- );
2714
- }
2715
- }
2716
- }
2717
- await Promise.all(ps);
2718
- }
2719
- function readIndexesForWrite(commit, dagWrite, formatVersion) {
2720
- const m = /* @__PURE__ */ new Map();
2721
- for (const index of commit.indexes) {
2722
- m.set(
2723
- index.definition.name,
2724
- new IndexWrite(
2725
- index,
2726
- new BTreeWrite(dagWrite, formatVersion, index.valueHash)
2727
- )
2728
- );
2729
- }
2730
- return m;
2731
- }
2732
- async function createIndexBTree(lc, dagWrite, valueMap, prefix, jsonPointer, allowEmpty, formatVersion) {
2733
- const indexMap = new BTreeWrite(dagWrite, formatVersion);
2734
- for await (const entry of valueMap.scan(prefix)) {
2735
- const key = entry[0];
2736
- if (!key.startsWith(prefix)) {
2737
- break;
2738
- }
2739
- await indexValue(
2740
- lc,
2741
- indexMap,
2742
- Add,
2743
- key,
2744
- entry[1],
2745
- jsonPointer,
2746
- allowEmpty
2747
- );
2748
- }
2749
- return indexMap;
2750
- }
2751
-
2752
- // ../replicache/src/sync/ids.ts
2753
- var clientGroupIDSchema = valita_exports.string();
2754
- var clientIDSchema = valita_exports.string();
2755
-
2756
- // ../replicache/src/persist/make-client-id.ts
2757
- function makeClientID() {
2758
- const length = 18;
2759
- const high = randomUint64();
2760
- const low = randomUint64();
2761
- const combined = high << 64n | low;
2762
- return combined.toString(32).slice(-length).padStart(length, "0");
2763
- }
2764
-
2765
- // ../replicache/src/persist/clients.ts
2766
- var clientV5Schema = readonlyObject({
2767
- heartbeatTimestampMs: valita_exports.number(),
2768
- headHash: hashSchema,
2769
- /**
2770
- * The hash of a commit we are in the middle of refreshing into this client's
2771
- * memdag.
2772
- */
2773
- tempRefreshHash: hashSchema.nullable(),
2774
- /**
2775
- * ID of this client's perdag client group. This needs to be sent in pull
2776
- * request (to enable syncing all last mutation ids in the client group).
2777
- */
2778
- clientGroupID: clientGroupIDSchema
2779
- });
2780
- var clientV6Schema = readonlyObject({
2781
- heartbeatTimestampMs: valita_exports.number(),
2782
- /**
2783
- * A set of hashes, which contains:
2784
- * 1. The hash of the last commit this client refreshed from its client group
2785
- * (this is the commit it bootstrapped from until it completes its first
2786
- * refresh).
2787
- * 2. One or more hashes that were added to retain chunks of a commit while it
2788
- * was being refreshed into this client's memdag. (This can be one or more
2789
- * because refresh's cleanup step is a separate transaction and can fail).
2790
- * Upon refresh completing and successfully running its clean up step, this
2791
- * set will contain a single hash: the hash of the last commit this client
2792
- * refreshed.
2793
- */
2794
- refreshHashes: readonlyArray(hashSchema),
2795
- /**
2796
- * The hash of the last snapshot commit persisted by this client to this
2797
- * client's client group, or null if has never persisted a snapshot.
2798
- */
2799
- persistHash: hashSchema.nullable(),
2800
- /**
2801
- * ID of this client's perdag client group. This needs to be sent in pull
2802
- * request (to enable syncing all last mutation ids in the client group).
2803
- */
2804
- clientGroupID: clientGroupIDSchema
2805
- });
2806
- function isClientV6(client) {
2807
- return client.refreshHashes !== void 0;
2808
- }
2809
- var CLIENTS_HEAD_NAME = "clients";
2810
- var clientSchema = valita_exports.union(clientV5Schema, clientV6Schema);
2811
- function assertClient(value) {
2812
- assert2(value, clientSchema);
2813
- }
2814
- function assertClientV6(value) {
2815
- assert2(value, clientV6Schema);
2816
- }
2817
- function chunkDataToClientMap(chunkData) {
2818
- assertObject(chunkData);
2819
- const clients = /* @__PURE__ */ new Map();
2820
- for (const key in chunkData) {
2821
- if (hasOwn(chunkData, key)) {
2822
- const value = chunkData[key];
2823
- if (value !== void 0) {
2824
- assertClient(value);
2825
- clients.set(key, value);
2826
- }
2827
- }
2828
- }
2829
- return clients;
2830
- }
2831
- function clientMapToChunkData(clients, dagWrite) {
2832
- for (const client of clients.values()) {
2833
- if (isClientV6(client)) {
2834
- client.refreshHashes.forEach(dagWrite.assertValidHash);
2835
- if (client.persistHash) {
2836
- dagWrite.assertValidHash(client.persistHash);
2837
- }
2838
- } else {
2839
- dagWrite.assertValidHash(client.headHash);
2840
- if (client.tempRefreshHash) {
2841
- dagWrite.assertValidHash(client.tempRefreshHash);
360
+ a = a;
361
+ b = b;
362
+ let aSize = 0;
363
+ for (const key in a) {
364
+ if (hasOwn(a, key)) {
365
+ if (!deepEqual(a[key], b[key])) {
366
+ return false;
2842
367
  }
368
+ aSize++;
2843
369
  }
2844
370
  }
2845
- return deepFreeze(Object.fromEntries(clients));
2846
- }
2847
- async function getClients(dagRead) {
2848
- const hash2 = await dagRead.getHead(CLIENTS_HEAD_NAME);
2849
- return getClientsAtHash(hash2, dagRead);
2850
- }
2851
- async function getClientsAtHash(hash2, dagRead) {
2852
- if (!hash2) {
2853
- return /* @__PURE__ */ new Map();
2854
- }
2855
- const chunk = await dagRead.getChunk(hash2);
2856
- return chunkDataToClientMap(chunk?.data);
2857
- }
2858
- var ClientStateNotFoundError = class extends Error {
2859
- name = "ClientStateNotFoundError";
2860
- id;
2861
- constructor(id) {
2862
- super(`Client state not found, id: ${id}`);
2863
- this.id = id;
2864
- }
2865
- };
2866
- async function assertHasClientState(id, dagRead) {
2867
- if (!await hasClientState(id, dagRead)) {
2868
- throw new ClientStateNotFoundError(id);
371
+ let bSize = 0;
372
+ for (const key in b) {
373
+ if (hasOwn(b, key)) {
374
+ bSize++;
375
+ }
2869
376
  }
377
+ return aSize === bSize;
2870
378
  }
2871
- async function hasClientState(id, dagRead) {
2872
- return !!await getClient(id, dagRead);
2873
- }
2874
- async function getClient(id, dagRead) {
2875
- const clients = await getClients(dagRead);
2876
- return clients.get(id);
2877
- }
2878
- async function mustGetClient(id, dagRead) {
2879
- const client = await getClient(id, dagRead);
2880
- if (!client) {
2881
- throw new ClientStateNotFoundError(id);
379
+ function assertJSONValue(v2) {
380
+ if (isProd) {
381
+ return;
2882
382
  }
2883
- return client;
2884
- }
2885
- function initClientV6(newClientID, lc, perdag, mutatorNames, indexes, formatVersion, enableClientGroupForking) {
2886
- return withWrite(perdag, async (dagWrite) => {
2887
- async function setClientsAndClientGroupAndCommit(basisHash, cookieJSON, valueHash2, indexRecords2) {
2888
- const newSnapshotData = newSnapshotCommitDataDD31(
2889
- basisHash,
2890
- {},
2891
- cookieJSON,
2892
- valueHash2,
2893
- indexRecords2
2894
- );
2895
- const chunk = dagWrite.createChunk(
2896
- newSnapshotData,
2897
- getRefs(newSnapshotData)
2898
- );
2899
- const newClientGroupID = makeClientID();
2900
- const newClient = {
2901
- heartbeatTimestampMs: Date.now(),
2902
- refreshHashes: [chunk.hash],
2903
- persistHash: null,
2904
- clientGroupID: newClientGroupID
2905
- };
2906
- const newClients = new Map(clients).set(newClientID, newClient);
2907
- const clientGroup = {
2908
- headHash: chunk.hash,
2909
- mutatorNames,
2910
- indexes,
2911
- mutationIDs: {},
2912
- lastServerAckdMutationIDs: {},
2913
- disabled: false
2914
- };
2915
- await Promise.all([
2916
- dagWrite.putChunk(chunk),
2917
- setClients(newClients, dagWrite),
2918
- setClientGroup(newClientGroupID, clientGroup, dagWrite)
2919
- ]);
2920
- return [newClient, chunk.hash, newClients, true];
2921
- }
2922
- const clients = await getClients(dagWrite);
2923
- const res = await findMatchingClient(dagWrite, mutatorNames, indexes);
2924
- if (res.type === FIND_MATCHING_CLIENT_TYPE_HEAD) {
2925
- const { clientGroupID, headHash } = res;
2926
- const newClient = {
2927
- clientGroupID,
2928
- refreshHashes: [headHash],
2929
- heartbeatTimestampMs: Date.now(),
2930
- persistHash: null
2931
- };
2932
- const newClients = new Map(clients).set(newClientID, newClient);
2933
- await setClients(newClients, dagWrite);
2934
- return [newClient, headHash, newClients, false];
2935
- }
2936
- if (!enableClientGroupForking || res.type === FIND_MATCHING_CLIENT_TYPE_NEW) {
2937
- const emptyBTreeChunk = dagWrite.createChunk(emptyDataNode, []);
2938
- await dagWrite.putChunk(emptyBTreeChunk);
2939
- const indexRecords2 = [];
2940
- for (const [name, indexDefinition] of Object.entries(indexes)) {
2941
- const chunkIndexDefinition = toChunkIndexDefinition(
2942
- name,
2943
- indexDefinition
2944
- );
2945
- indexRecords2.push({
2946
- definition: chunkIndexDefinition,
2947
- valueHash: emptyBTreeChunk.hash
2948
- });
383
+ switch (typeof v2) {
384
+ case "boolean":
385
+ case "number":
386
+ case "string":
387
+ return;
388
+ case "object":
389
+ if (v2 === null) {
390
+ return;
2949
391
  }
2950
- return setClientsAndClientGroupAndCommit(
2951
- null,
2952
- null,
2953
- emptyBTreeChunk.hash,
2954
- indexRecords2
2955
- );
2956
- }
2957
- assert(res.type === FIND_MATCHING_CLIENT_TYPE_FORK);
2958
- const { snapshot } = res;
2959
- const indexRecords = [];
2960
- const { valueHash, indexes: oldIndexes } = snapshot;
2961
- const map = new BTreeRead(dagWrite, formatVersion, valueHash);
2962
- for (const [name, indexDefinition] of Object.entries(indexes)) {
2963
- const { prefix = "", jsonPointer, allowEmpty = false } = indexDefinition;
2964
- const chunkIndexDefinition = {
2965
- name,
2966
- keyPrefix: prefix,
2967
- jsonPointer,
2968
- allowEmpty
2969
- };
2970
- const oldIndex = findMatchingOldIndex(oldIndexes, chunkIndexDefinition);
2971
- if (oldIndex) {
2972
- indexRecords.push({
2973
- definition: chunkIndexDefinition,
2974
- valueHash: oldIndex.valueHash
2975
- });
2976
- } else {
2977
- const indexBTree = await createIndexBTree(
2978
- lc,
2979
- dagWrite,
2980
- map,
2981
- prefix,
2982
- jsonPointer,
2983
- allowEmpty,
2984
- formatVersion
2985
- );
2986
- indexRecords.push({
2987
- definition: chunkIndexDefinition,
2988
- valueHash: await indexBTree.flush()
2989
- });
392
+ if (Array.isArray(v2)) {
393
+ return assertJSONArray(v2);
2990
394
  }
2991
- }
2992
- return setClientsAndClientGroupAndCommit(
2993
- snapshot.meta.basisHash,
2994
- snapshot.meta.cookieJSON,
2995
- snapshot.valueHash,
2996
- indexRecords
2997
- );
2998
- });
395
+ return assertObjectIsJSONObject(v2);
396
+ }
397
+ throwInvalidType(v2, "JSON value");
2999
398
  }
3000
- function findMatchingOldIndex(oldIndexes, chunkIndexDefinition) {
3001
- return oldIndexes.find(
3002
- (index) => chunkIndexDefinitionEqualIgnoreName(index.definition, chunkIndexDefinition)
3003
- );
399
+ function assertJSONObject(v2) {
400
+ assertObject(v2);
401
+ assertObjectIsJSONObject(v2);
3004
402
  }
3005
- var FIND_MATCHING_CLIENT_TYPE_NEW = 0;
3006
- var FIND_MATCHING_CLIENT_TYPE_FORK = 1;
3007
- var FIND_MATCHING_CLIENT_TYPE_HEAD = 2;
3008
- async function findMatchingClient(dagRead, mutatorNames, indexes) {
3009
- let newestCookie;
3010
- let bestSnapshot;
3011
- const mutatorNamesSet = new Set(mutatorNames);
3012
- const clientGroups = await getClientGroups(dagRead);
3013
- for (const [clientGroupID, clientGroup] of clientGroups) {
3014
- if (!clientGroup.disabled && mutatorNamesEqual(mutatorNamesSet, clientGroup.mutatorNames) && indexDefinitionsEqual(indexes, clientGroup.indexes)) {
3015
- return {
3016
- type: FIND_MATCHING_CLIENT_TYPE_HEAD,
3017
- clientGroupID,
3018
- headHash: clientGroup.headHash
3019
- };
3020
- }
3021
- const clientGroupSnapshotCommit = await baseSnapshotFromHash(
3022
- clientGroup.headHash,
3023
- dagRead
3024
- );
3025
- assertSnapshotCommitDD31(clientGroupSnapshotCommit);
3026
- const { cookieJSON } = clientGroupSnapshotCommit.meta;
3027
- if (newestCookie === void 0 || compareCookies(cookieJSON, newestCookie) > 0) {
3028
- newestCookie = cookieJSON;
3029
- bestSnapshot = clientGroupSnapshotCommit;
403
+ function assertObjectIsJSONObject(v2) {
404
+ for (const k in v2) {
405
+ if (hasOwn(v2, k)) {
406
+ const value = v2[k];
407
+ if (value !== void 0) {
408
+ assertJSONValue(value);
409
+ }
3030
410
  }
3031
411
  }
3032
- if (bestSnapshot) {
3033
- return {
3034
- type: FIND_MATCHING_CLIENT_TYPE_FORK,
3035
- snapshot: bestSnapshot
3036
- };
412
+ }
413
+ function assertJSONArray(v2) {
414
+ for (const item of v2) {
415
+ assertJSONValue(item);
3037
416
  }
3038
- return { type: FIND_MATCHING_CLIENT_TYPE_NEW };
3039
417
  }
3040
- function getRefsForClients(clients) {
3041
- const refs = /* @__PURE__ */ new Set();
3042
- for (const client of clients.values()) {
3043
- if (isClientV6(client)) {
3044
- for (const hash2 of client.refreshHashes) {
3045
- refs.add(hash2);
3046
- }
3047
- if (client.persistHash) {
3048
- refs.add(client.persistHash);
418
+ function isJSONValue(v2, path2) {
419
+ switch (typeof v2) {
420
+ case "boolean":
421
+ case "number":
422
+ case "string":
423
+ return true;
424
+ case "object":
425
+ if (v2 === null) {
426
+ return true;
3049
427
  }
3050
- } else {
3051
- refs.add(client.headHash);
3052
- if (client.tempRefreshHash) {
3053
- refs.add(client.tempRefreshHash);
428
+ if (Array.isArray(v2)) {
429
+ return isJSONArray(v2, path2);
3054
430
  }
3055
- }
431
+ return objectIsJSONObject(v2, path2);
3056
432
  }
3057
- return toRefs(refs);
433
+ return false;
3058
434
  }
3059
- async function getClientGroupForClient(clientID, read) {
3060
- const clientGroupID = await getClientGroupIDForClient(clientID, read);
3061
- if (!clientGroupID) {
3062
- return void 0;
435
+ function isJSONObject(v2, path2) {
436
+ if (typeof v2 !== "object" || v2 === null) {
437
+ return false;
3063
438
  }
3064
- return getClientGroup(clientGroupID, read);
3065
- }
3066
- async function getClientGroupIDForClient(clientID, read) {
3067
- const client = await getClient(clientID, read);
3068
- return client?.clientGroupID;
3069
- }
3070
- async function setClient(clientID, client, dagWrite) {
3071
- const clients = await getClients(dagWrite);
3072
- const newClients = new Map(clients).set(clientID, client);
3073
- return setClients(newClients, dagWrite);
3074
- }
3075
- async function setClients(clients, dagWrite) {
3076
- const chunkData = clientMapToChunkData(clients, dagWrite);
3077
- const chunk = dagWrite.createChunk(chunkData, getRefsForClients(clients));
3078
- await dagWrite.putChunk(chunk);
3079
- await dagWrite.setHead(CLIENTS_HEAD_NAME, chunk.hash);
3080
- return chunk.hash;
439
+ return objectIsJSONObject(v2, path2);
3081
440
  }
3082
-
3083
- // ../zero-protocol/src/ast.ts
3084
- import { compareUTF8 as compareUTF82 } from "compare-utf8";
3085
-
3086
- // ../shared/src/arrays.ts
3087
- function defined(arr) {
3088
- let i = arr.findIndex((x) => x === void 0);
3089
- if (i < 0) {
3090
- return arr;
3091
- }
3092
- const defined2 = arr.slice(0, i);
3093
- for (i++; i < arr.length; i++) {
3094
- const x = arr[i];
3095
- if (x !== void 0) {
3096
- defined2.push(x);
441
+ function objectIsJSONObject(v2, path2) {
442
+ for (const k in v2) {
443
+ if (hasOwn(v2, k)) {
444
+ path2.push(k);
445
+ const value = v2[k];
446
+ if (value !== void 0 && !isJSONValue(value, path2)) {
447
+ return false;
448
+ }
449
+ path2.pop();
3097
450
  }
3098
451
  }
3099
- return defined2;
452
+ return true;
3100
453
  }
3101
- function areEqual(arr1, arr2) {
3102
- return arr1.length === arr2.length && arr1.every((e, i) => e === arr2[i]);
454
+ function isJSONArray(v2, path2) {
455
+ for (let i = 0; i < v2.length; i++) {
456
+ path2.push(i);
457
+ if (!isJSONValue(v2[i], path2)) {
458
+ return false;
459
+ }
460
+ path2.pop();
461
+ }
462
+ return true;
3103
463
  }
3104
464
 
3105
465
  // ../shared/src/json-schema.ts
3106
- import * as valita from "@badrap/valita";
3107
466
  var path = [];
3108
467
  var jsonSchema = valita_exports.unknown().chain((v2) => {
3109
468
  if (isProd) {
@@ -3397,15 +756,15 @@ function cmpCondition(a, b) {
3397
756
  }
3398
757
  function compareValuePosition(a, b) {
3399
758
  if (a.type !== b.type) {
3400
- return compareUTF82(a.type, b.type);
759
+ return compareUTF8(a.type, b.type);
3401
760
  }
3402
761
  switch (a.type) {
3403
762
  case "literal":
3404
763
  assert(b.type === "literal");
3405
- return compareUTF82(String(a.value), String(b.value));
764
+ return compareUTF8(String(a.value), String(b.value));
3406
765
  case "column":
3407
766
  assert(b.type === "column");
3408
- return compareUTF82(a.name, b.name);
767
+ return compareUTF8(a.name, b.name);
3409
768
  case "static":
3410
769
  throw new Error(
3411
770
  "Static parameters should be resolved before normalization"
@@ -3413,7 +772,7 @@ function compareValuePosition(a, b) {
3413
772
  }
3414
773
  }
3415
774
  function cmpRelated(a, b) {
3416
- return compareUTF82(must(a.subquery.alias), must(b.subquery.alias));
775
+ return compareUTF8(must(a.subquery.alias), must(b.subquery.alias));
3417
776
  }
3418
777
  function flattened(cond) {
3419
778
  if (cond.type === "simple" || cond.type === "correlatedSubquery") {
@@ -3438,7 +797,7 @@ function flattened(cond) {
3438
797
  }
3439
798
  function compareUTF8MaybeNull(a, b) {
3440
799
  if (a !== null && b !== null) {
3441
- return compareUTF82(a, b);
800
+ return compareUTF8(a, b);
3442
801
  }
3443
802
  if (b !== null) {
3444
803
  return -1;
@@ -3449,109 +808,6 @@ function compareUTF8MaybeNull(a, b) {
3449
808
  return 0;
3450
809
  }
3451
810
 
3452
- // ../zero-protocol/src/inspect-down.ts
3453
- var inspectQueryRowSchema = valita_exports.object({
3454
- clientID: valita_exports.string(),
3455
- queryID: valita_exports.string(),
3456
- ast: astSchema,
3457
- got: valita_exports.boolean(),
3458
- deleted: valita_exports.boolean(),
3459
- ttl: valita_exports.number(),
3460
- inactivatedAt: valita_exports.number().nullable(),
3461
- rowCount: valita_exports.number()
3462
- });
3463
- var inspectQueriesDownSchema = valita_exports.object({
3464
- op: valita_exports.literal("queries"),
3465
- id: valita_exports.string(),
3466
- value: valita_exports.array(inspectQueryRowSchema)
3467
- });
3468
- var inspectDownBodySchema = valita_exports.union(inspectQueriesDownSchema);
3469
- var inspectDownMessageSchema = valita_exports.tuple([
3470
- valita_exports.literal("inspect"),
3471
- inspectDownBodySchema
3472
- ]);
3473
-
3474
- // ../shared/src/random-values.ts
3475
- function getNonCryptoRandomValues(array5) {
3476
- if (array5 === null) {
3477
- throw new TypeError("array cannot be null");
3478
- }
3479
- for (let i = 0; i < array5.length; i++) {
3480
- array5[i] = Math.floor(Math.random() * 256);
3481
- }
3482
- return array5;
3483
- }
3484
-
3485
- // ../zero-client/src/util/nanoid.ts
3486
- function nanoid(size = 21) {
3487
- const randomBytes = getNonCryptoRandomValues(new Uint8Array(size));
3488
- return randomBytes.reduce((id, byte) => {
3489
- byte &= 63;
3490
- if (byte < 36) {
3491
- id += byte.toString(36);
3492
- } else if (byte < 62) {
3493
- id += (byte - 26).toString(36).toUpperCase();
3494
- } else if (byte > 62) {
3495
- id += "-";
3496
- } else {
3497
- id += "_";
3498
- }
3499
- return id;
3500
- }, "");
3501
- }
3502
-
3503
- // ../shared/src/hash.ts
3504
- import { xxHash32 } from "js-xxhash";
3505
- var h64 = (s) => hash(s, 2);
3506
- var h128 = (s) => hash(s, 4);
3507
- function hash(str, words) {
3508
- let hash2 = 0n;
3509
- for (let i = 0; i < words; i++) {
3510
- hash2 = (hash2 << 32n) + BigInt(xxHash32(str, i));
3511
- }
3512
- return hash2;
3513
- }
3514
-
3515
- // ../zero-protocol/src/primary-key.ts
3516
- var primaryKeySchema = readonly(
3517
- valita_exports.tuple([valita_exports.string()]).concat(valita_exports.array(valita_exports.string()))
3518
- );
3519
- var primaryKeyValueSchema = valita_exports.union(
3520
- valita_exports.string(),
3521
- valita_exports.number(),
3522
- valita_exports.boolean()
3523
- );
3524
- var primaryKeyValueRecordSchema = readonlyRecord(
3525
- primaryKeyValueSchema
3526
- );
3527
-
3528
- // ../zero-client/src/client/keys.ts
3529
- var DESIRED_QUERIES_KEY_PREFIX = "d/";
3530
- var GOT_QUERIES_KEY_PREFIX = "g/";
3531
- var ENTITIES_KEY_PREFIX = "e/";
3532
- function toDesiredQueriesKey(clientID, hash2) {
3533
- return DESIRED_QUERIES_KEY_PREFIX + clientID + "/" + hash2;
3534
- }
3535
- function desiredQueriesPrefixForClient(clientID) {
3536
- return DESIRED_QUERIES_KEY_PREFIX + clientID + "/";
3537
- }
3538
- function toGotQueriesKey(hash2) {
3539
- return GOT_QUERIES_KEY_PREFIX + hash2;
3540
- }
3541
- function toPrimaryKeyString(tableName, primaryKey, value) {
3542
- if (primaryKey.length === 1) {
3543
- return ENTITIES_KEY_PREFIX + tableName + "/" + parse(value[primaryKey[0]], primaryKeyValueSchema);
3544
- }
3545
- const values = primaryKey.map((k) => parse(value[k], primaryKeyValueSchema));
3546
- const str = JSON.stringify(values);
3547
- const idSegment = h128(str);
3548
- return ENTITIES_KEY_PREFIX + tableName + "/" + idSegment;
3549
- }
3550
- function sourceNameFromKey(key) {
3551
- const slash = key.indexOf("/", ENTITIES_KEY_PREFIX.length);
3552
- return key.slice(ENTITIES_KEY_PREFIX.length, slash);
3553
- }
3554
-
3555
811
  // ../zero-schema/src/table-schema.ts
3556
812
  function isOneHop(r) {
3557
813
  return r.length === 1;
@@ -3838,6 +1094,77 @@ var Exists = class {
3838
1094
  }
3839
1095
  };
3840
1096
 
1097
+ // ../shared/src/iterables.ts
1098
+ function* joinIterables(...iters) {
1099
+ for (const iter of iters) {
1100
+ yield* iter;
1101
+ }
1102
+ }
1103
+ function* filterIter(iter, p) {
1104
+ let index = 0;
1105
+ for (const t of iter) {
1106
+ if (p(t, index++)) {
1107
+ yield t;
1108
+ }
1109
+ }
1110
+ }
1111
+ function* mapIter(iter, f) {
1112
+ let index = 0;
1113
+ for (const t of iter) {
1114
+ yield f(t, index++);
1115
+ }
1116
+ }
1117
+ var IterWrapper = class _IterWrapper {
1118
+ iter;
1119
+ constructor(iter) {
1120
+ this.iter = iter;
1121
+ }
1122
+ [Symbol.iterator]() {
1123
+ return this.iter[Symbol.iterator]();
1124
+ }
1125
+ map(f) {
1126
+ return new _IterWrapper(mapIter(this.iter, f));
1127
+ }
1128
+ filter(p) {
1129
+ return new _IterWrapper(filterIter(this.iter, p));
1130
+ }
1131
+ };
1132
+ function wrapIterable(iter) {
1133
+ return new IterWrapper(iter);
1134
+ }
1135
+ function* mergeIterables(iterables, comparator, distinct = false) {
1136
+ const iterators = iterables.map((i) => i[Symbol.iterator]());
1137
+ try {
1138
+ const current = iterators.map((i) => i.next());
1139
+ let lastYielded;
1140
+ while (current.some((c) => !c.done)) {
1141
+ const min = current.reduce(
1142
+ (acc, c, i) => {
1143
+ if (c.done) {
1144
+ return acc;
1145
+ }
1146
+ if (acc === void 0 || comparator(c.value, acc[0]) < 0) {
1147
+ return [c.value, i];
1148
+ }
1149
+ return acc;
1150
+ },
1151
+ void 0
1152
+ );
1153
+ assert(min !== void 0, "min is undefined");
1154
+ current[min[1]] = iterators[min[1]].next();
1155
+ if (lastYielded !== void 0 && distinct && comparator(lastYielded, min[0]) === 0) {
1156
+ continue;
1157
+ }
1158
+ lastYielded = min[0];
1159
+ yield min[0];
1160
+ }
1161
+ } finally {
1162
+ for (const it of iterators) {
1163
+ it.return?.();
1164
+ }
1165
+ }
1166
+ }
1167
+
3841
1168
  // ../zql/src/ivm/fan-in.ts
3842
1169
  var FanIn = class {
3843
1170
  #inputs;
@@ -5550,10 +2877,12 @@ var ArrayView = class {
5550
2877
  onDestroy;
5551
2878
  #dirty = false;
5552
2879
  #complete = false;
5553
- constructor(input, format = { singular: false, relationships: {} }, queryComplete = true) {
2880
+ #updateTTL;
2881
+ constructor(input, format, queryComplete, updateTTL) {
5554
2882
  this.#input = input;
5555
2883
  this.#schema = input.getSchema();
5556
2884
  this.#format = format;
2885
+ this.#updateTTL = updateTTL;
5557
2886
  this.#root = { "": format.singular ? void 0 : [] };
5558
2887
  input.setOutput(this);
5559
2888
  if (queryComplete === true) {
@@ -5615,6 +2944,9 @@ var ArrayView = class {
5615
2944
  this.#dirty = false;
5616
2945
  this.#fireListeners();
5617
2946
  }
2947
+ updateTTL(ttl) {
2948
+ this.#updateTTL(ttl);
2949
+ }
5618
2950
  };
5619
2951
 
5620
2952
  // ../zql/src/query/expression.ts
@@ -5757,8 +3089,8 @@ var negateOperatorMap = {
5757
3089
  function negateOperator(op) {
5758
3090
  return must(negateOperatorMap[op]);
5759
3091
  }
5760
- function filterUndefined(array5) {
5761
- return array5.filter((e) => e !== void 0);
3092
+ function filterUndefined(array3) {
3093
+ return array3.filter((e) => e !== void 0);
5762
3094
  }
5763
3095
  function filterTrue(conditions) {
5764
3096
  return conditions.filter((c) => !isAlwaysTrue(c));
@@ -5821,7 +3153,7 @@ function unwrap(c) {
5821
3153
  }
5822
3154
 
5823
3155
  // ../zql/src/query/query-impl.ts
5824
- var astForTestingSymbol = Symbol();
3156
+ var astSymbol = Symbol();
5825
3157
  function newQuery(delegate, schema, table) {
5826
3158
  return new QueryImpl(delegate, schema, table, { table }, defaultFormat);
5827
3159
  }
@@ -5850,8 +3182,7 @@ var AbstractQuery = class {
5850
3182
  this.#ast = ast;
5851
3183
  this.format = format;
5852
3184
  }
5853
- // Not part of Query or QueryInternal interface
5854
- get [astForTestingSymbol]() {
3185
+ get [astSymbol]() {
5855
3186
  return this.#ast;
5856
3187
  }
5857
3188
  hash() {
@@ -6242,6 +3573,9 @@ var QueryImpl = class extends AbstractQuery {
6242
3573
  queryCompleteResolver.resolve(true);
6243
3574
  }
6244
3575
  });
3576
+ const updateTTL = (newTTL) => {
3577
+ this.#delegate.updateServerQuery(ast, newTTL);
3578
+ };
6245
3579
  const input = buildPipeline(ast, this.#delegate);
6246
3580
  let removeCommitObserver;
6247
3581
  const onDestroy = () => {
@@ -6258,14 +3592,12 @@ var QueryImpl = class extends AbstractQuery {
6258
3592
  (cb) => {
6259
3593
  removeCommitObserver = this.#delegate.onTransactionCommit(cb);
6260
3594
  },
6261
- queryGot || queryCompleteResolver.promise
3595
+ queryGot || queryCompleteResolver.promise,
3596
+ updateTTL
6262
3597
  )
6263
3598
  );
6264
3599
  return view;
6265
3600
  }
6266
- updateTTL(ttl) {
6267
- this.#delegate.updateServerQuery(this._completeAst(), ttl);
6268
- }
6269
3601
  run() {
6270
3602
  const v2 = this.materialize();
6271
3603
  const ret = v2.data;
@@ -6311,8 +3643,13 @@ function addPrimaryKeysToAst(schema, ast) {
6311
3643
  orderBy: addPrimaryKeys(schema, ast.orderBy)
6312
3644
  };
6313
3645
  }
6314
- function arrayViewFactory(_query, input, format, onDestroy, onTransactionCommit, queryComplete) {
6315
- const v2 = new ArrayView(input, format, queryComplete);
3646
+ function arrayViewFactory(_query, input, format, onDestroy, onTransactionCommit, queryComplete, updateTTL) {
3647
+ const v2 = new ArrayView(
3648
+ input,
3649
+ format,
3650
+ queryComplete,
3651
+ updateTTL
3652
+ );
6316
3653
  v2.onDestroy = onDestroy;
6317
3654
  onTransactionCommit(() => {
6318
3655
  v2.flush();
@@ -6325,94 +3662,24 @@ function isCompoundKey(field) {
6325
3662
 
6326
3663
  export {
6327
3664
  isProd,
3665
+ hasOwn,
6328
3666
  deepEqual,
6329
3667
  assertJSONValue,
6330
3668
  assertJSONObject,
6331
- stringCompare,
6332
- compareCookies,
6333
- assertCookie,
6334
- deepFreeze,
6335
- deepFreezeAllowUndefined,
6336
3669
  parse,
3670
+ assert2 as assert,
6337
3671
  test,
3672
+ readonly,
6338
3673
  readonlyObject,
6339
3674
  readonlyArray,
3675
+ readonlyRecord,
6340
3676
  valita_exports,
6341
- emptyHash,
6342
- newRandomHash,
6343
- assertHash,
6344
- Chunk,
6345
- assertRefs,
6346
- createChunk,
6347
- ChunkNotFoundError,
6348
- mustGetChunk,
6349
- mustGetHeadHash,
6350
- DD31,
6351
- V6,
6352
- V7,
6353
- Latest,
6354
3677
  joinIterables,
6355
3678
  wrapIterable,
6356
- getSizeOfValue,
6357
- DEFAULT_HEAD_NAME,
6358
- commitIsLocalDD31,
6359
- localMutations,
6360
- localMutationsDD31,
6361
- localMutationsGreaterThan,
6362
- baseSnapshotFromHead,
6363
- baseSnapshotFromHash,
6364
- baseSnapshotFromCommit,
6365
- snapshotMetaParts,
6366
- compareCookiesForSnapshots,
6367
- commitFromHash,
6368
- commitFromHead,
6369
- assertLocalMetaDD31,
6370
- isLocalMetaDD31,
6371
- assertSnapshotMetaDD31,
6372
- assertSnapshotCommitDD31,
6373
- binarySearch,
6374
- BTreeRead,
6375
- encodeIndexScanKey,
6376
- decodeIndexKey,
6377
- readFromDefaultHead,
6378
- readFromHash,
6379
- asyncIterableToArray,
6380
- diff,
6381
- DiffsMap,
6382
- diff2,
6383
- diffCommits,
6384
- addDiffsForIndexes,
6385
- newWriteLocal,
6386
- newWriteSnapshotDD31,
6387
- getClientGroups,
6388
- setClientGroups,
6389
- setClientGroup,
6390
- getClientGroup,
6391
- clientGroupHasPendingMutations,
6392
- disableClientGroup,
6393
- withRead,
6394
- withWriteNoImplicitCommit,
6395
- withWrite,
6396
- using,
6397
3679
  jsonSchema,
6398
3680
  jsonObjectSchema,
6399
- clientGroupIDSchema,
6400
- clientIDSchema,
6401
- makeClientID,
6402
- assertClientV6,
6403
- getClients,
6404
- ClientStateNotFoundError,
6405
- assertHasClientState,
6406
- hasClientState,
6407
- getClient,
6408
- mustGetClient,
6409
- initClientV6,
6410
- getClientGroupForClient,
6411
- getClientGroupIDForClient,
6412
- setClient,
6413
- setClients,
6414
- getNonCryptoRandomValues,
6415
3681
  h64,
3682
+ h128,
6416
3683
  rowSchema,
6417
3684
  toStaticParam,
6418
3685
  astSchema,
@@ -6425,22 +3692,14 @@ export {
6425
3692
  transformFilters,
6426
3693
  assertOrderingIncludesPK,
6427
3694
  ExpressionBuilder,
3695
+ DEFAULT_TTL,
3696
+ parseTTL,
3697
+ compareTTL,
3698
+ normalizeTTL,
6428
3699
  newQuery,
6429
3700
  staticParam,
6430
3701
  SUBQ_PREFIX,
6431
3702
  defaultFormat,
6432
- AbstractQuery,
6433
- inspectQueriesDownSchema,
6434
- inspectDownMessageSchema,
6435
- primaryKeySchema,
6436
- primaryKeyValueRecordSchema,
6437
- nanoid,
6438
- GOT_QUERIES_KEY_PREFIX,
6439
- ENTITIES_KEY_PREFIX,
6440
- toDesiredQueriesKey,
6441
- desiredQueriesPrefixForClient,
6442
- toGotQueriesKey,
6443
- toPrimaryKeyString,
6444
- sourceNameFromKey
3703
+ AbstractQuery
6445
3704
  };
6446
- //# sourceMappingURL=chunk-JW7AJ755.js.map
3705
+ //# sourceMappingURL=chunk-GTRWLUIW.js.map