@rocicorp/zero 0.1.2024100802 → 0.2.2024101101

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 (132) hide show
  1. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  2. package/out/replicache/src/replicache-impl.d.ts +0 -1
  3. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  4. package/out/shared/src/browser-env.d.ts +4 -2
  5. package/out/shared/src/browser-env.d.ts.map +1 -1
  6. package/out/shared/src/h64-with-reverse.d.ts +6 -0
  7. package/out/shared/src/h64-with-reverse.d.ts.map +1 -0
  8. package/out/shared/src/h64-with-reverse.js +13 -0
  9. package/out/shared/src/h64-with-reverse.js.map +1 -0
  10. package/out/shared/src/reverse-string.d.ts +2 -0
  11. package/out/shared/src/reverse-string.d.ts.map +1 -0
  12. package/out/shared/src/reverse-string.js +8 -0
  13. package/out/shared/src/reverse-string.js.map +1 -0
  14. package/out/zero-cache/src/config/zero-config.d.ts +25 -0
  15. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  16. package/out/zero-cache/src/config/zero-config.js +10 -0
  17. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  18. package/out/zero-cache/src/db/statements.d.ts +1 -0
  19. package/out/zero-cache/src/db/statements.d.ts.map +1 -1
  20. package/out/zero-cache/src/db/statements.js +3 -0
  21. package/out/zero-cache/src/db/statements.js.map +1 -1
  22. package/out/zero-cache/src/server/change-streamer.js +1 -1
  23. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  24. package/out/zero-cache/src/server/life-cycle.d.ts +1 -1
  25. package/out/zero-cache/src/server/life-cycle.d.ts.map +1 -1
  26. package/out/zero-cache/src/server/life-cycle.js +20 -5
  27. package/out/zero-cache/src/server/life-cycle.js.map +1 -1
  28. package/out/zero-cache/src/server/logging.d.ts.map +1 -1
  29. package/out/zero-cache/src/server/logging.js +43 -4
  30. package/out/zero-cache/src/server/logging.js.map +1 -1
  31. package/out/zero-cache/src/server/replicator.js +1 -1
  32. package/out/zero-cache/src/server/replicator.js.map +1 -1
  33. package/out/zero-cache/src/server/syncer.js +1 -1
  34. package/out/zero-cache/src/server/syncer.js.map +1 -1
  35. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +1 -1
  36. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  37. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +6 -5
  38. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  39. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +2 -2
  40. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  41. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +1 -1
  42. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  43. package/out/zero-cache/src/services/change-streamer/pg/initial-sync.d.ts.map +1 -1
  44. package/out/zero-cache/src/services/change-streamer/pg/initial-sync.js +3 -3
  45. package/out/zero-cache/src/services/change-streamer/pg/initial-sync.js.map +1 -1
  46. package/out/zero-cache/src/services/change-streamer/pg/schema/lite.d.ts +2 -1
  47. package/out/zero-cache/src/services/change-streamer/pg/schema/lite.d.ts.map +1 -1
  48. package/out/zero-cache/src/services/change-streamer/pg/schema/lite.js +19 -67
  49. package/out/zero-cache/src/services/change-streamer/pg/schema/lite.js.map +1 -1
  50. package/out/zero-cache/src/services/dispatcher/dispatcher.d.ts.map +1 -1
  51. package/out/zero-cache/src/services/dispatcher/dispatcher.js +0 -4
  52. package/out/zero-cache/src/services/dispatcher/dispatcher.js.map +1 -1
  53. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  54. package/out/zero-cache/src/services/mutagen/mutagen.js +4 -4
  55. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  56. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +3 -3
  57. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  58. package/out/zero-cache/src/services/replicator/incremental-sync.js +57 -32
  59. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  60. package/out/zero-cache/src/services/replicator/replicator.js +1 -1
  61. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  62. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +4 -4
  63. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  64. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  65. package/out/zero-cache/src/services/running-state.js +3 -3
  66. package/out/zero-cache/src/services/running-state.js.map +1 -1
  67. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +5 -7
  68. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  69. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +9 -9
  70. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  71. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +9 -4
  72. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  73. package/out/zero-cache/src/services/view-syncer/snapshotter.js +24 -12
  74. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  75. package/out/zero-cache/src/types/lite.d.ts +30 -8
  76. package/out/zero-cache/src/types/lite.d.ts.map +1 -1
  77. package/out/zero-cache/src/types/lite.js +114 -15
  78. package/out/zero-cache/src/types/lite.js.map +1 -1
  79. package/out/zero-cache/src/types/pg.d.ts +21 -0
  80. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  81. package/out/zero-cache/src/types/pg.js +49 -6
  82. package/out/zero-cache/src/types/pg.js.map +1 -1
  83. package/out/zero-cache/src/types/row-key.d.ts +4 -1
  84. package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
  85. package/out/zero-cache/src/types/row-key.js +5 -14
  86. package/out/zero-cache/src/types/row-key.js.map +1 -1
  87. package/out/zero-cache/src/types/streams.d.ts +2 -2
  88. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  89. package/out/zero-cache/src/types/streams.js +36 -26
  90. package/out/zero-cache/src/types/streams.js.map +1 -1
  91. package/out/zero-client/src/client/crud.d.ts +20 -18
  92. package/out/zero-client/src/client/crud.d.ts.map +1 -1
  93. package/out/zero-client/src/client/keys.d.ts +2 -2
  94. package/out/zero-client/src/client/keys.d.ts.map +1 -1
  95. package/out/zero-client/src/client/make-id-from-primary-key.d.ts +5 -0
  96. package/out/zero-client/src/client/make-id-from-primary-key.d.ts.map +1 -0
  97. package/out/zero-client/src/client/zero-poke-handler.d.ts +4 -3
  98. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  99. package/out/zero-client/src/client/zero.d.ts +2 -2
  100. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  101. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  102. package/out/zero-protocol/src/ast.js +5 -8
  103. package/out/zero-protocol/src/ast.js.map +1 -1
  104. package/out/zero-protocol/src/down.d.ts +3 -3
  105. package/out/zero-protocol/src/entities-patch.d.ts +9 -9
  106. package/out/zero-protocol/src/entities-patch.d.ts.map +1 -1
  107. package/out/zero-protocol/src/entities-patch.js +5 -4
  108. package/out/zero-protocol/src/entities-patch.js.map +1 -1
  109. package/out/zero-protocol/src/poke.d.ts +6 -6
  110. package/out/zero-protocol/src/primary-key.d.ts +9 -0
  111. package/out/zero-protocol/src/primary-key.d.ts.map +1 -0
  112. package/out/zero-protocol/src/primary-key.js +7 -0
  113. package/out/zero-protocol/src/primary-key.js.map +1 -0
  114. package/out/zero-protocol/src/push.d.ts +28 -28
  115. package/out/zero-protocol/src/push.js +5 -5
  116. package/out/zero-protocol/src/push.js.map +1 -1
  117. package/out/zero-protocol/src/up.d.ts +4 -4
  118. package/out/zero.js +201 -105
  119. package/out/zero.js.map +4 -4
  120. package/out/zql/src/zql/ivm/schema.d.ts +1 -1
  121. package/out/zql/src/zql/ivm/schema.d.ts.map +1 -1
  122. package/out/zql/src/zql/ivm/schema.js.map +1 -1
  123. package/out/zqlite/src/db.js +1 -1
  124. package/out/zqlite/src/db.js.map +1 -1
  125. package/out/zqlite/src/table-source.d.ts.map +1 -1
  126. package/out/zqlite/src/table-source.js +35 -32
  127. package/out/zqlite/src/table-source.js.map +1 -1
  128. package/package.json +6 -2
  129. package/out/zero-protocol/src/entity.d.ts +0 -9
  130. package/out/zero-protocol/src/entity.d.ts.map +0 -1
  131. package/out/zero-protocol/src/entity.js +0 -8
  132. package/out/zero-protocol/src/entity.js.map +0 -1
package/out/zero.js CHANGED
@@ -609,6 +609,20 @@ var WriteImplBase = class {
609
609
  }
610
610
  };
611
611
 
612
+ // ../shared/src/browser-env.ts
613
+ function getBrowserGlobal(name) {
614
+ return globalThis[name];
615
+ }
616
+ function mustGetBrowserGlobal(name) {
617
+ const r = getBrowserGlobal(name);
618
+ if (r === void 0) {
619
+ throw new Error(
620
+ `Unsupported JavaScript environment: Could not find ${name}.`
621
+ );
622
+ }
623
+ return r;
624
+ }
625
+
612
626
  // ../replicache/src/kv/idb-store.ts
613
627
  var RELAXED = { durability: "relaxed" };
614
628
  var OBJECT_STORE = "chunks";
@@ -663,7 +677,7 @@ var IDBStore = class {
663
677
  return fn(reopened);
664
678
  } else if (e.name === "NotFoundError") {
665
679
  this.#idbDeleted = true;
666
- indexedDB.deleteDatabase(db.name);
680
+ mustGetBrowserGlobal("indexedDB").deleteDatabase(db.name);
667
681
  throw new IDBNotFoundError(
668
682
  `Replicache IndexedDB ${db.name} missing object store. Deleting db.`
669
683
  );
@@ -744,8 +758,9 @@ function objectStore(tx) {
744
758
  return tx.objectStore(OBJECT_STORE);
745
759
  }
746
760
  function openDatabase(name) {
761
+ const idb = mustGetBrowserGlobal("indexedDB");
747
762
  return new Promise((resolve, reject) => {
748
- const req = indexedDB.open(name);
763
+ const req = idb.open(name);
749
764
  req.onupgradeneeded = () => {
750
765
  req.result.createObjectStore(OBJECT_STORE);
751
766
  };
@@ -1571,14 +1586,6 @@ function dropIDBStore(name) {
1571
1586
  import { consoleLogSink as consoleLogSink2 } from "@rocicorp/logger";
1572
1587
  import { resolver as resolver6 } from "@rocicorp/resolver";
1573
1588
 
1574
- // ../shared/src/browser-env.ts
1575
- function getDocument() {
1576
- return typeof document !== "undefined" ? document : void 0;
1577
- }
1578
- function getLocation() {
1579
- return typeof location !== "undefined" ? location : void 0;
1580
- }
1581
-
1582
1589
  // ../shared/src/document-visible.ts
1583
1590
  import { resolver as resolver3 } from "@rocicorp/resolver";
1584
1591
  function getDocumentVisibilityWatcher(doc, hiddenIntervalMS, signal) {
@@ -7952,7 +7959,7 @@ var ReplicacheImpl = class {
7952
7959
  auth;
7953
7960
  /** The name of the Replicache database. Populated by {@link ReplicacheOptions#name}. */
7954
7961
  name;
7955
- subscriptions;
7962
+ #subscriptions;
7956
7963
  #mutationRecovery;
7957
7964
  /**
7958
7965
  * Client groups gets disabled when the server does not know about it.
@@ -8142,7 +8149,7 @@ var ReplicacheImpl = class {
8142
8149
  name,
8143
8150
  "replicache version": version
8144
8151
  });
8145
- this.subscriptions = new SubscriptionsManagerImpl(
8152
+ this.#subscriptions = new SubscriptionsManagerImpl(
8146
8153
  this.#queryInternal,
8147
8154
  this.#lc,
8148
8155
  this.#closeAbortController.signal
@@ -8163,7 +8170,7 @@ var ReplicacheImpl = class {
8163
8170
  const { minDelayMs = MIN_DELAY_MS, maxDelayMs = MAX_DELAY_MS } = requestOptions;
8164
8171
  this.#requestOptions = { maxDelayMs, minDelayMs };
8165
8172
  const visibilityWatcher = getDocumentVisibilityWatcher(
8166
- getDocument(),
8173
+ getBrowserGlobal("document"),
8167
8174
  0,
8168
8175
  this.#closeAbortController.signal
8169
8176
  );
@@ -8278,7 +8285,7 @@ var ReplicacheImpl = class {
8278
8285
  signal
8279
8286
  );
8280
8287
  void this.recoverMutations(clients);
8281
- getDocument()?.addEventListener(
8288
+ getBrowserGlobal("document")?.addEventListener(
8282
8289
  "visibilitychange",
8283
8290
  this.#onVisibilityChange
8284
8291
  );
@@ -8287,7 +8294,7 @@ var ReplicacheImpl = class {
8287
8294
  if (this.#closed) {
8288
8295
  return;
8289
8296
  }
8290
- if (getDocument()?.visibilityState !== "visible") {
8297
+ if (getBrowserGlobal("document")?.visibilityState !== "visible") {
8291
8298
  return;
8292
8299
  }
8293
8300
  await this.#checkForClientStateNotFoundAndCallHandler();
@@ -8359,7 +8366,7 @@ var ReplicacheImpl = class {
8359
8366
  const { promise, resolve } = resolver6();
8360
8367
  closingInstances.set(this.name, promise);
8361
8368
  this.#closeAbortController.abort();
8362
- getDocument()?.removeEventListener(
8369
+ getBrowserGlobal("document")?.removeEventListener(
8363
8370
  "visibilitychange",
8364
8371
  this.#onVisibilityChange
8365
8372
  );
@@ -8371,7 +8378,7 @@ var ReplicacheImpl = class {
8371
8378
  ];
8372
8379
  this.#pullConnectionLoop.close();
8373
8380
  this.#pushConnectionLoop.close();
8374
- this.subscriptions.clear();
8381
+ this.#subscriptions.clear();
8375
8382
  await Promise.all(closingPromises);
8376
8383
  closingInstances.delete(this.name);
8377
8384
  resolve();
@@ -8389,16 +8396,16 @@ var ReplicacheImpl = class {
8389
8396
  lc,
8390
8397
  syncHead,
8391
8398
  clientID,
8392
- this.subscriptions,
8399
+ this.#subscriptions,
8393
8400
  Latest
8394
8401
  );
8395
8402
  if (!replayMutations || replayMutations.length === 0) {
8396
- await this.subscriptions.fire(diffs);
8403
+ await this.#subscriptions.fire(diffs);
8397
8404
  void this.#schedulePersist();
8398
8405
  return;
8399
8406
  }
8400
8407
  for (const mutation of replayMutations) {
8401
- if (this.subscriptions.hasPendingSubscriptionRuns) {
8408
+ if (this.#subscriptions.hasPendingSubscriptionRuns) {
8402
8409
  await Promise.resolve();
8403
8410
  }
8404
8411
  const { meta } = mutation;
@@ -8759,7 +8766,7 @@ var ReplicacheImpl = class {
8759
8766
  this.perdag,
8760
8767
  clientID,
8761
8768
  this.#mutatorRegistry,
8762
- this.subscriptions,
8769
+ this.#subscriptions,
8763
8770
  () => this.closed,
8764
8771
  Latest
8765
8772
  );
@@ -8773,7 +8780,7 @@ var ReplicacheImpl = class {
8773
8780
  }
8774
8781
  }
8775
8782
  if (diffs !== void 0) {
8776
- await this.subscriptions.fire(diffs);
8783
+ await this.#subscriptions.fire(diffs);
8777
8784
  }
8778
8785
  }
8779
8786
  #fireOnClientStateNotFound() {
@@ -8883,12 +8890,12 @@ var ReplicacheImpl = class {
8883
8890
  options = { onData: options };
8884
8891
  }
8885
8892
  const { onData, onError, onDone, isEqual } = options;
8886
- return this.subscriptions.add(
8893
+ return this.#subscriptions.add(
8887
8894
  new SubscriptionImpl(body, onData, onError, onDone, isEqual)
8888
8895
  );
8889
8896
  }
8890
8897
  experimentalWatch(callback, options) {
8891
- return this.subscriptions.add(
8898
+ return this.#subscriptions.add(
8892
8899
  new WatchSubscription(callback, options)
8893
8900
  );
8894
8901
  }
@@ -8941,7 +8948,7 @@ var ReplicacheImpl = class {
8941
8948
  }
8942
8949
  async #mutate(name, mutatorImpl, args, timestamp) {
8943
8950
  const frozenArgs = deepFreeze(args ?? null);
8944
- if (this.subscriptions.hasPendingSubscriptionRuns) {
8951
+ if (this.#subscriptions.hasPendingSubscriptionRuns) {
8945
8952
  await Promise.resolve();
8946
8953
  }
8947
8954
  await this.#ready;
@@ -8972,11 +8979,11 @@ var ReplicacheImpl = class {
8972
8979
  const lastMutationID = await dbWrite.getMutationID();
8973
8980
  const diffs = await dbWrite.commitWithDiffs(
8974
8981
  DEFAULT_HEAD_NAME,
8975
- this.subscriptions
8982
+ this.#subscriptions
8976
8983
  );
8977
8984
  this.lastMutationID = lastMutationID;
8978
8985
  this.#pushConnectionLoop.send(false).catch(() => void 0);
8979
- await this.subscriptions.fire(diffs);
8986
+ await this.#subscriptions.fire(diffs);
8980
8987
  void this.#schedulePersist();
8981
8988
  return result;
8982
8989
  } catch (ex) {
@@ -10939,14 +10946,11 @@ import { LogContext as LogContext3 } from "@rocicorp/logger";
10939
10946
  import { resolver as resolver8 } from "@rocicorp/resolver";
10940
10947
 
10941
10948
  // ../zero-protocol/src/ast.ts
10942
- function readonly2(t2) {
10943
- return t2;
10944
- }
10945
10949
  var selectorSchema = valita_exports.string();
10946
- var orderingElementSchema = readonly2(
10950
+ var orderingElementSchema = readonly(
10947
10951
  valita_exports.tuple([selectorSchema, valita_exports.union(valita_exports.literal("asc"), valita_exports.literal("desc"))])
10948
10952
  );
10949
- var orderingSchema = readonly2(valita_exports.array(orderingElementSchema));
10953
+ var orderingSchema = readonlyArray(orderingElementSchema);
10950
10954
  var primitiveSchema = valita_exports.union(
10951
10955
  valita_exports.string(),
10952
10956
  valita_exports.number(),
@@ -10981,7 +10985,7 @@ var simpleConditionSchema = valita_exports.object({
10981
10985
  valita_exports.string(),
10982
10986
  valita_exports.number(),
10983
10987
  valita_exports.boolean(),
10984
- readonly2(valita_exports.array(valita_exports.union(valita_exports.string(), valita_exports.number(), valita_exports.boolean()))),
10988
+ readonlyArray(valita_exports.union(valita_exports.string(), valita_exports.number(), valita_exports.boolean())),
10985
10989
  valita_exports.object({
10986
10990
  type: valita_exports.literal("static"),
10987
10991
  anchor: valita_exports.union(valita_exports.literal("authData"), valita_exports.literal("preMutationRow")),
@@ -11005,8 +11009,8 @@ var astSchema = valita_exports.object({
11005
11009
  schema: valita_exports.string().optional(),
11006
11010
  table: valita_exports.string(),
11007
11011
  alias: valita_exports.string().optional(),
11008
- where: readonly2(valita_exports.array(conditionSchema)).optional(),
11009
- related: readonly2(valita_exports.array(correlatedSubquerySchema)).optional(),
11012
+ where: readonlyArray(conditionSchema).optional(),
11013
+ related: readonlyArray(correlatedSubquerySchema).optional(),
11010
11014
  limit: valita_exports.number().optional(),
11011
11015
  orderBy: orderingSchema.optional(),
11012
11016
  start: valita_exports.object({
@@ -11101,27 +11105,35 @@ var errorMessageSchema = valita_exports.tuple([
11101
11105
  var versionSchema = valita_exports.string();
11102
11106
  var nullableVersionSchema = valita_exports.union(versionSchema, valita_exports.null());
11103
11107
 
11104
- // ../zero-protocol/src/entity.ts
11105
- var entityIDSchema = valita_exports.record(valita_exports.string());
11108
+ // ../zero-protocol/src/primary-key.ts
11109
+ var primaryKeySchema = valita_exports.array(valita_exports.string()).assert((arr) => arr.length > 0);
11110
+ var primaryKeyValueSchema = valita_exports.union(
11111
+ valita_exports.string(),
11112
+ valita_exports.number(),
11113
+ valita_exports.boolean()
11114
+ );
11115
+ var primaryKeyValueRecordSchema = readonlyRecord(
11116
+ primaryKeyValueSchema
11117
+ );
11106
11118
 
11107
11119
  // ../zero-protocol/src/entities-patch.ts
11108
11120
  var putOpSchema3 = valita_exports.object({
11109
11121
  op: valita_exports.literal("put"),
11110
11122
  entityType: valita_exports.string(),
11111
- entityID: entityIDSchema,
11123
+ entityID: primaryKeyValueRecordSchema,
11112
11124
  value: jsonObjectSchema
11113
11125
  });
11114
11126
  var updateOpSchema = valita_exports.object({
11115
11127
  op: valita_exports.literal("update"),
11116
11128
  entityType: valita_exports.string(),
11117
- entityID: entityIDSchema,
11129
+ entityID: primaryKeyValueRecordSchema,
11118
11130
  merge: jsonObjectSchema.optional(),
11119
11131
  constrain: valita_exports.array(valita_exports.string()).optional()
11120
11132
  });
11121
11133
  var delOpSchema3 = valita_exports.object({
11122
11134
  op: valita_exports.literal("del"),
11123
11135
  entityType: valita_exports.string(),
11124
- entityID: entityIDSchema
11136
+ entityID: primaryKeyValueRecordSchema
11125
11137
  });
11126
11138
  var clearOpSchema3 = valita_exports.object({
11127
11139
  op: valita_exports.literal("clear")
@@ -11226,25 +11238,25 @@ var CRUD_MUTATION_NAME = "_zero_crud";
11226
11238
  var createOpSchema = valita_exports.object({
11227
11239
  op: valita_exports.literal("create"),
11228
11240
  entityType: valita_exports.string(),
11229
- id: entityIDSchema,
11241
+ id: primaryKeyValueRecordSchema,
11230
11242
  value: jsonObjectSchema
11231
11243
  });
11232
11244
  var setOpSchema = valita_exports.object({
11233
11245
  op: valita_exports.literal("set"),
11234
11246
  entityType: valita_exports.string(),
11235
- id: entityIDSchema,
11247
+ id: primaryKeyValueRecordSchema,
11236
11248
  value: jsonObjectSchema
11237
11249
  });
11238
11250
  var updateOpSchema2 = valita_exports.object({
11239
11251
  op: valita_exports.literal("update"),
11240
11252
  entityType: valita_exports.string(),
11241
- id: entityIDSchema,
11253
+ id: primaryKeyValueRecordSchema,
11242
11254
  partialValue: jsonObjectSchema
11243
11255
  });
11244
11256
  var deleteOpSchema = valita_exports.object({
11245
11257
  op: valita_exports.literal("delete"),
11246
11258
  entityType: valita_exports.string(),
11247
- id: entityIDSchema
11259
+ id: primaryKeyValueRecordSchema
11248
11260
  });
11249
11261
  var crudOpSchema = valita_exports.union(
11250
11262
  createOpSchema,
@@ -13428,6 +13440,27 @@ var MemoryStorage = class {
13428
13440
  }
13429
13441
  };
13430
13442
 
13443
+ // ../shared/src/reverse-string.ts
13444
+ function reverseString(str) {
13445
+ let reversed = "";
13446
+ for (let i = str.length - 1; i >= 0; i--) {
13447
+ reversed += str[i];
13448
+ }
13449
+ return reversed;
13450
+ }
13451
+
13452
+ // ../shared/src/xxhash.ts
13453
+ import xxhash from "xxhash-wasm";
13454
+ var { create64, h32, h64 } = await xxhash();
13455
+
13456
+ // ../shared/src/h64-with-reverse.ts
13457
+ function h64WithReverse(str) {
13458
+ const forward = h64(str);
13459
+ const backward = h64(reverseString(str));
13460
+ const full = (forward << 64n) + backward;
13461
+ return full.toString(36);
13462
+ }
13463
+
13431
13464
  // ../zero-client/src/client/keys.ts
13432
13465
  var CLIENTS_KEY_PREFIX = "c/";
13433
13466
  var DESIRED_QUERIES_KEY_PREFIX = "d/";
@@ -13445,11 +13478,23 @@ function desiredQueriesPrefixForClient(clientID) {
13445
13478
  function toGotQueriesKey(hash2) {
13446
13479
  return GOT_QUERIES_KEY_PREFIX + hash2;
13447
13480
  }
13448
- function toEntitiesKey(entityType, entityID) {
13449
- const idKeys = Object.keys(entityID);
13450
- assert(idKeys.length > 0);
13451
- const idSegment = idKeys.length === 1 ? entityID[idKeys[0]] : JSON.stringify(entityID, idKeys.sort());
13452
- return ENTITIES_KEY_PREFIX + entityType + "/" + idSegment;
13481
+ function maybeSort(arr) {
13482
+ for (let i = 1; i < arr.length; i++) {
13483
+ if (arr[i] < arr[i - 1]) {
13484
+ return [...arr].sort();
13485
+ }
13486
+ }
13487
+ return arr;
13488
+ }
13489
+ function toPrimaryKeyString(tableName, primaryKey, id) {
13490
+ if (primaryKey.length === 1) {
13491
+ return ENTITIES_KEY_PREFIX + tableName + "/" + id[primaryKey[0]];
13492
+ }
13493
+ const sorted = maybeSort(primaryKey);
13494
+ const arr = sorted.map((k) => id[k]);
13495
+ const str = JSON.stringify(arr);
13496
+ const idSegment = h64WithReverse(str);
13497
+ return ENTITIES_KEY_PREFIX + tableName + "/" + idSegment;
13453
13498
  }
13454
13499
 
13455
13500
  // ../zero-client/src/client/context.ts
@@ -13538,6 +13583,15 @@ var ZeroContext = class {
13538
13583
  }
13539
13584
  };
13540
13585
 
13586
+ // ../zero-client/src/client/make-id-from-primary-key.ts
13587
+ function makeIDFromPrimaryKey(primaryKey, value) {
13588
+ const id = {};
13589
+ for (const key of primaryKey) {
13590
+ id[key] = parse(value[key], primaryKeyValueSchema);
13591
+ }
13592
+ return id;
13593
+ }
13594
+
13541
13595
  // ../zero-client/src/client/crud.ts
13542
13596
  function makeCRUDMutate(schema, repMutate) {
13543
13597
  const { [CRUD_MUTATION_NAME]: zeroCRUD } = repMutate;
@@ -13551,7 +13605,7 @@ function makeCRUDMutate(schema, repMutate) {
13551
13605
  const ops = [];
13552
13606
  const m = {};
13553
13607
  for (const name of Object.keys(schema.tables)) {
13554
- m[name] = makeBatchCRUDMutate(name, ops);
13608
+ m[name] = makeBatchCRUDMutate(name, schema, ops);
13555
13609
  }
13556
13610
  const rv = await body(m);
13557
13611
  await zeroCRUD({ ops });
@@ -13565,118 +13619,147 @@ function makeCRUDMutate(schema, repMutate) {
13565
13619
  throw new Error(`Cannot call mutate.${entityType}.${op} inside a batch`);
13566
13620
  }
13567
13621
  };
13568
- for (const name of Object.keys(schema.tables)) {
13569
- mutate[name] = makeEntityCRUDMutate(name, zeroCRUD, assertNotInBatch);
13622
+ for (const [name, tableSchema] of Object.entries(schema.tables)) {
13623
+ mutate[name] = makeEntityCRUDMutate(
13624
+ name,
13625
+ tableSchema.primaryKey,
13626
+ zeroCRUD,
13627
+ assertNotInBatch
13628
+ );
13570
13629
  }
13571
13630
  return mutate;
13572
13631
  }
13573
- function makeEntityCRUDMutate(entityType, zeroCRUD, assertNotInBatch) {
13632
+ function makeEntityCRUDMutate(entityType, primaryKey, zeroCRUD, assertNotInBatch) {
13574
13633
  return {
13575
13634
  create: (value) => {
13576
13635
  assertNotInBatch(entityType, "create");
13577
- const { id } = value;
13578
13636
  const op = {
13579
13637
  op: "create",
13580
13638
  entityType,
13581
- // TODO: Current crud mutators expect id to always exist
13582
- id: { id },
13639
+ id: makeIDFromPrimaryKey(primaryKey, value),
13583
13640
  value
13584
13641
  };
13585
13642
  return zeroCRUD({ ops: [op] });
13586
13643
  },
13587
13644
  set: (value) => {
13588
13645
  assertNotInBatch(entityType, "set");
13589
- const { id } = value;
13590
- const op = { op: "set", entityType, id: { id }, value };
13646
+ const op = {
13647
+ op: "set",
13648
+ entityType,
13649
+ id: makeIDFromPrimaryKey(primaryKey, value),
13650
+ value
13651
+ };
13591
13652
  return zeroCRUD({ ops: [op] });
13592
13653
  },
13593
13654
  update: (value) => {
13594
13655
  assertNotInBatch(entityType, "update");
13595
- const { id } = value;
13596
13656
  const op = {
13597
13657
  op: "update",
13598
13658
  entityType,
13599
- id: { id },
13659
+ id: makeIDFromPrimaryKey(primaryKey, value),
13600
13660
  partialValue: value
13601
13661
  };
13602
13662
  return zeroCRUD({ ops: [op] });
13603
13663
  },
13604
13664
  delete: (id) => {
13605
13665
  assertNotInBatch(entityType, "delete");
13606
- const op = { op: "delete", entityType, id };
13666
+ const op = {
13667
+ op: "delete",
13668
+ entityType,
13669
+ id: makeIDFromPrimaryKey(primaryKey, id)
13670
+ };
13607
13671
  return zeroCRUD({ ops: [op] });
13608
13672
  }
13609
13673
  };
13610
13674
  }
13611
- function makeBatchCRUDMutate(entityType, ops) {
13675
+ function makeBatchCRUDMutate(tableName, schema, ops) {
13676
+ const { primaryKey } = schema.tables[tableName];
13612
13677
  return {
13613
13678
  create: (value) => {
13614
- const { id } = value;
13615
13679
  const op = {
13616
13680
  op: "create",
13617
- entityType,
13618
- id: { id },
13681
+ entityType: tableName,
13682
+ id: makeIDFromPrimaryKey(primaryKey, value),
13619
13683
  value
13620
13684
  };
13621
13685
  ops.push(op);
13622
13686
  return promiseVoid;
13623
13687
  },
13624
13688
  set: (value) => {
13625
- const { id } = value;
13626
- const op = { op: "set", entityType, id: { id }, value };
13689
+ const op = {
13690
+ op: "set",
13691
+ entityType: tableName,
13692
+ id: makeIDFromPrimaryKey(primaryKey, value),
13693
+ value
13694
+ };
13627
13695
  ops.push(op);
13628
13696
  return promiseVoid;
13629
13697
  },
13630
13698
  update: (value) => {
13631
- const { id } = value;
13632
13699
  const op = {
13633
13700
  op: "update",
13634
- entityType,
13635
- id: { id },
13701
+ entityType: tableName,
13702
+ id: makeIDFromPrimaryKey(primaryKey, value),
13636
13703
  partialValue: value
13637
13704
  };
13638
13705
  ops.push(op);
13639
13706
  return promiseVoid;
13640
13707
  },
13641
13708
  delete: (id) => {
13642
- const op = { op: "delete", entityType, id };
13709
+ const op = {
13710
+ op: "delete",
13711
+ entityType: tableName,
13712
+ id: makeIDFromPrimaryKey(primaryKey, id)
13713
+ };
13643
13714
  ops.push(op);
13644
13715
  return promiseVoid;
13645
13716
  }
13646
13717
  };
13647
13718
  }
13648
- function makeCRUDMutator(_schemas) {
13719
+ function makeCRUDMutator(schema) {
13649
13720
  return async function zeroCRUDMutator(tx, crudArg) {
13650
13721
  for (const op of crudArg.ops) {
13651
13722
  switch (op.op) {
13652
13723
  case "create":
13653
- await createImpl(tx, op);
13724
+ await createImpl(tx, op, schema);
13654
13725
  break;
13655
13726
  case "set":
13656
- await setImpl(tx, op);
13727
+ await setImpl(tx, op, schema);
13657
13728
  break;
13658
13729
  case "update":
13659
- await updateImpl(tx, op);
13730
+ await updateImpl(tx, op, schema);
13660
13731
  break;
13661
13732
  case "delete":
13662
- await deleteImpl(tx, op);
13733
+ await deleteImpl(tx, op, schema);
13663
13734
  break;
13664
13735
  }
13665
13736
  }
13666
13737
  };
13667
13738
  }
13668
- async function createImpl(tx, arg) {
13669
- const key = toEntitiesKey(arg.entityType, arg.id);
13739
+ async function createImpl(tx, arg, schema) {
13740
+ const key = toPrimaryKeyString(
13741
+ arg.entityType,
13742
+ schema.tables[arg.entityType].primaryKey,
13743
+ arg.id
13744
+ );
13670
13745
  if (!await tx.has(key)) {
13671
13746
  await tx.set(key, arg.value);
13672
13747
  }
13673
13748
  }
13674
- async function setImpl(tx, arg) {
13675
- const key = toEntitiesKey(arg.entityType, arg.id);
13749
+ async function setImpl(tx, arg, schema) {
13750
+ const key = toPrimaryKeyString(
13751
+ arg.entityType,
13752
+ schema.tables[arg.entityType].primaryKey,
13753
+ arg.id
13754
+ );
13676
13755
  await tx.set(key, arg.value);
13677
13756
  }
13678
- async function updateImpl(tx, arg) {
13679
- const key = toEntitiesKey(arg.entityType, arg.id);
13757
+ async function updateImpl(tx, arg, schema) {
13758
+ const key = toPrimaryKeyString(
13759
+ arg.entityType,
13760
+ schema.tables[arg.entityType].primaryKey,
13761
+ arg.id
13762
+ );
13680
13763
  const prev = await tx.get(key);
13681
13764
  if (prev === void 0) {
13682
13765
  return;
@@ -13685,8 +13768,12 @@ async function updateImpl(tx, arg) {
13685
13768
  const next = { ...prev, ...update };
13686
13769
  await tx.set(key, next);
13687
13770
  }
13688
- async function deleteImpl(tx, arg) {
13689
- const key = toEntitiesKey(arg.entityType, arg.id);
13771
+ async function deleteImpl(tx, arg, schema) {
13772
+ const key = toPrimaryKeyString(
13773
+ arg.entityType,
13774
+ schema.tables[arg.entityType].primaryKey,
13775
+ arg.id
13776
+ );
13690
13777
  await tx.del(key);
13691
13778
  }
13692
13779
 
@@ -14221,10 +14308,6 @@ var State = class {
14221
14308
  }
14222
14309
  };
14223
14310
 
14224
- // ../shared/src/xxhash.ts
14225
- import xxhash from "xxhash-wasm";
14226
- var { create64, h32, h64 } = await xxhash();
14227
-
14228
14311
  // ../zql/src/zql/ast/ast.ts
14229
14312
  import { compareUTF8 as compareUTF84 } from "compare-utf8";
14230
14313
  function normalizeAST(ast) {
@@ -14490,10 +14573,12 @@ var PokeHandler = class {
14490
14573
  // Serializes calls to this.#replicachePoke otherwise we can cause out of
14491
14574
  // order poke errors.
14492
14575
  #pokeLock = new Lock3();
14493
- constructor(replicachePoke, onPokeError, clientID, lc) {
14576
+ #schema;
14577
+ constructor(replicachePoke, onPokeError, clientID, schema, lc) {
14494
14578
  this.#replicachePoke = replicachePoke;
14495
14579
  this.#onPokeError = onPokeError;
14496
14580
  this.#clientID = clientID;
14581
+ this.#schema = schema;
14497
14582
  this.#lc = lc.withContext("PokeHandler");
14498
14583
  }
14499
14584
  handlePokeStart(pokeStart) {
@@ -14567,7 +14652,7 @@ var PokeHandler = class {
14567
14652
  lc.debug?.("got poke lock at", now);
14568
14653
  lc.debug?.("merging", this.#pokeBuffer.length);
14569
14654
  try {
14570
- const merged = mergePokes(this.#pokeBuffer);
14655
+ const merged = mergePokes(this.#pokeBuffer, this.#schema);
14571
14656
  this.#pokeBuffer.length = 0;
14572
14657
  if (merged === void 0) {
14573
14658
  lc.debug?.("frame is empty");
@@ -14596,7 +14681,7 @@ var PokeHandler = class {
14596
14681
  this.#pokeBuffer.length = 0;
14597
14682
  }
14598
14683
  };
14599
- function mergePokes(pokeBuffer) {
14684
+ function mergePokes(pokeBuffer, schema) {
14600
14685
  if (pokeBuffer.length === 0) {
14601
14686
  return void 0;
14602
14687
  }
@@ -14650,7 +14735,9 @@ function mergePokes(pokeBuffer) {
14650
14735
  }
14651
14736
  if (pokePart.entitiesPatch) {
14652
14737
  mergedPatch.push(
14653
- ...pokePart.entitiesPatch.map(entitiesPatchOpToReplicachePatchOp)
14738
+ ...pokePart.entitiesPatch.map(
14739
+ (p) => entitiesPatchOpToReplicachePatchOp(p, schema)
14740
+ )
14654
14741
  );
14655
14742
  }
14656
14743
  }
@@ -14700,25 +14787,37 @@ function queryPatchOpToReplicachePatchOp(op, toKey) {
14700
14787
  };
14701
14788
  }
14702
14789
  }
14703
- function entitiesPatchOpToReplicachePatchOp(op) {
14790
+ function entitiesPatchOpToReplicachePatchOp(op, schema) {
14704
14791
  switch (op.op) {
14705
14792
  case "clear":
14706
14793
  return op;
14707
14794
  case "del":
14708
14795
  return {
14709
14796
  op: "del",
14710
- key: toEntitiesKey(op.entityType, op.entityID)
14797
+ key: toPrimaryKeyString(
14798
+ op.entityType,
14799
+ schema.tables[op.entityType].primaryKey,
14800
+ op.entityID
14801
+ )
14711
14802
  };
14712
14803
  case "put":
14713
14804
  return {
14714
14805
  op: "put",
14715
- key: toEntitiesKey(op.entityType, op.entityID),
14806
+ key: toPrimaryKeyString(
14807
+ op.entityType,
14808
+ schema.tables[op.entityType].primaryKey,
14809
+ op.entityID
14810
+ ),
14716
14811
  value: op.value
14717
14812
  };
14718
14813
  case "update":
14719
14814
  return {
14720
14815
  op: "update",
14721
- key: toEntitiesKey(op.entityType, op.entityID),
14816
+ key: toPrimaryKeyString(
14817
+ op.entityType,
14818
+ schema.tables[op.entityType].primaryKey,
14819
+ op.entityID
14820
+ ),
14722
14821
  merge: op.merge,
14723
14822
  constrain: op.constrain
14724
14823
  };
@@ -14893,7 +14992,7 @@ var Zero = class {
14893
14992
  #metrics;
14894
14993
  // Store as field to allow test subclass to override. Web API doesn't allow
14895
14994
  // overwriting location fields for security reasons.
14896
- #reload = () => getLocation()?.reload();
14995
+ #reload = () => getBrowserGlobal("location")?.reload();
14897
14996
  /**
14898
14997
  * Constructs a new Zero client.
14899
14998
  */
@@ -14906,11 +15005,6 @@ var Zero = class {
14906
15005
  kvStore = "idb",
14907
15006
  schema
14908
15007
  } = options;
14909
- if (typeof WebSocket === "undefined") {
14910
- throw new Error(
14911
- "Cannot find WebSocket global. Are you running in Node? Zero is only currently supported in browsers."
14912
- );
14913
- }
14914
15008
  if (!userID) {
14915
15009
  throw new Error("ZeroOptions.userID must not be empty.");
14916
15010
  }
@@ -15007,7 +15101,7 @@ var Zero = class {
15007
15101
  reportReloadReason(this.#lc);
15008
15102
  this.#metrics = new MetricManager({
15009
15103
  reportIntervalMs: REPORT_INTERVAL_MS,
15010
- host: getLocation()?.host ?? "",
15104
+ host: getBrowserGlobal("location")?.host ?? "",
15011
15105
  source: "client",
15012
15106
  reporter: this.#enableAnalytics ? (allSeries) => this.#reportMetrics(allSeries) : () => Promise.resolve(),
15013
15107
  lc: this.#lc
@@ -15017,10 +15111,11 @@ var Zero = class {
15017
15111
  (poke) => this.#rep.poke(poke),
15018
15112
  () => this.#onPokeError(),
15019
15113
  rep.clientID,
15114
+ schema,
15020
15115
  this.#lc
15021
15116
  );
15022
15117
  this.#visibilityWatcher = getDocumentVisibilityWatcher(
15023
- getDocument(),
15118
+ getBrowserGlobal("document"),
15024
15119
  hiddenTabDisconnectDelay,
15025
15120
  this.#closeAbortController.signal
15026
15121
  );
@@ -15832,7 +15927,8 @@ function createSocket(socketOrigin, baseCookie, clientID, clientGroupID, schemaV
15832
15927
  searchParams.set("debugPerf", true.toString());
15833
15928
  }
15834
15929
  lc.info?.("Connecting to", url.toString());
15835
- return new WebSocket(
15930
+ const WS = mustGetBrowserGlobal("WebSocket");
15931
+ return new WS(
15836
15932
  // toString() required for RN URL polyfill.
15837
15933
  url.toString(),
15838
15934
  auth === "" || auth === void 0 ? void 0 : encodeURIComponent(auth)