@rocicorp/zero 0.6.2024112102 → 0.7.2024112700

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 (223) hide show
  1. package/out/advanced.js +1 -1
  2. package/out/{chunk-5UY46OAF.js → chunk-C7M3BJ3Z.js} +16 -8
  3. package/out/chunk-C7M3BJ3Z.js.map +7 -0
  4. package/out/{chunk-QB7G63C6.js → chunk-HDEKBM3G.js} +686 -660
  5. package/out/{chunk-QB7G63C6.js.map → chunk-HDEKBM3G.js.map} +4 -4
  6. package/out/shared/src/expand.js +2 -0
  7. package/out/shared/src/expand.js.map +1 -0
  8. package/out/shared/src/immutable.js +2 -0
  9. package/out/shared/src/immutable.js.map +1 -0
  10. package/out/{zero-cache/src/config/config.d.ts → shared/src/options.d.ts} +3 -5
  11. package/out/shared/src/options.d.ts.map +1 -0
  12. package/out/{zero-cache/src/config/config.js → shared/src/options.js} +26 -26
  13. package/out/shared/src/options.js.map +1 -0
  14. package/out/shared/src/sorted-entries.js +6 -0
  15. package/out/shared/src/sorted-entries.js.map +1 -0
  16. package/out/shared/src/writable.js +2 -0
  17. package/out/shared/src/writable.js.map +1 -0
  18. package/out/solid.js +2 -2
  19. package/out/zero/src/build-schema.d.ts +3 -0
  20. package/out/zero/src/build-schema.d.ts.map +1 -0
  21. package/out/zero/src/build-schema.js +3 -0
  22. package/out/zero/src/build-schema.js.map +1 -0
  23. package/out/zero-cache/src/auth/load-schema.d.ts +8 -0
  24. package/out/zero-cache/src/auth/load-schema.d.ts.map +1 -0
  25. package/out/zero-cache/src/auth/load-schema.js +34 -0
  26. package/out/zero-cache/src/auth/load-schema.js.map +1 -0
  27. package/out/zero-cache/src/auth/write-authorizer.d.ts +20 -0
  28. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -0
  29. package/out/zero-cache/src/auth/write-authorizer.js +320 -0
  30. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -0
  31. package/out/zero-cache/src/config/zero-config.d.ts +14 -4
  32. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  33. package/out/zero-cache/src/config/zero-config.js +27 -14
  34. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  35. package/out/zero-cache/src/server/main.js +7 -0
  36. package/out/zero-cache/src/server/main.js.map +1 -1
  37. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  38. package/out/zero-cache/src/server/replicator.js +4 -3
  39. package/out/zero-cache/src/server/replicator.js.map +1 -1
  40. package/out/zero-cache/src/server/runtime.d.ts +3 -0
  41. package/out/zero-cache/src/server/runtime.d.ts.map +1 -0
  42. package/out/zero-cache/src/server/runtime.js +19 -0
  43. package/out/zero-cache/src/server/runtime.js.map +1 -0
  44. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  45. package/out/zero-cache/src/server/syncer.js +7 -6
  46. package/out/zero-cache/src/server/syncer.js.map +1 -1
  47. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +1 -1
  48. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  49. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +6 -5
  50. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  51. package/out/zero-cache/src/services/mutagen/mutagen.js +19 -33
  52. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  53. package/out/zero-cache/src/services/replicator/replicator.d.ts +1 -1
  54. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  55. package/out/zero-cache/src/services/replicator/replicator.js +2 -2
  56. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  57. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +1 -1
  58. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  59. package/out/zero-cache/src/services/view-syncer/client-handler.js +11 -8
  60. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  61. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +17 -8
  62. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  63. package/out/zero-cache/src/services/view-syncer/cvr-store.js +357 -94
  64. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  65. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +6 -9
  66. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  67. package/out/zero-cache/src/services/view-syncer/cvr.js +36 -22
  68. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  69. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  70. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +2 -2
  71. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  72. package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +22 -0
  73. package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +1 -1
  74. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +33 -7
  75. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  76. package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +1 -1
  77. package/out/zero-cache/src/services/view-syncer/schema/init.js +44 -5
  78. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
  79. package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +1 -0
  80. package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
  81. package/out/zero-cache/src/services/view-syncer/schema/types.js +3 -0
  82. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  83. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  84. package/out/zero-cache/src/services/view-syncer/snapshotter.js +5 -0
  85. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  86. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -1
  87. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  88. package/out/zero-cache/src/services/view-syncer/view-syncer.js +69 -19
  89. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  90. package/out/zero-cache/src/types/row-key.d.ts +6 -0
  91. package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
  92. package/out/zero-cache/src/types/row-key.js +16 -1
  93. package/out/zero-cache/src/types/row-key.js.map +1 -1
  94. package/out/zero-cache/src/workers/connection.d.ts +1 -1
  95. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  96. package/out/zero-cache/src/workers/connection.js.map +1 -1
  97. package/out/zero-cache/src/workers/replicator.d.ts +3 -1
  98. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  99. package/out/zero-cache/src/workers/replicator.js +2 -0
  100. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  101. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  102. package/out/zero-cache/src/workers/syncer.js +8 -3
  103. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  104. package/out/zero-client/src/client/options.d.ts +37 -8
  105. package/out/zero-client/src/client/options.d.ts.map +1 -1
  106. package/out/zero-client/src/client/reload-error-handler.d.ts +16 -1
  107. package/out/zero-client/src/client/reload-error-handler.d.ts.map +1 -1
  108. package/out/zero-client/src/client/zero.d.ts +7 -55
  109. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  110. package/out/zero-client/src/mod.d.ts +1 -1
  111. package/out/zero-client/src/mod.d.ts.map +1 -1
  112. package/out/zero-protocol/src/ast-hash.js +14 -0
  113. package/out/zero-protocol/src/ast-hash.js.map +1 -0
  114. package/out/zero-protocol/src/down.d.ts +4 -4
  115. package/out/zero-protocol/src/poke.d.ts +16 -8
  116. package/out/zero-protocol/src/poke.d.ts.map +1 -1
  117. package/out/zero-protocol/src/poke.js +8 -2
  118. package/out/zero-protocol/src/poke.js.map +1 -1
  119. package/out/zero-schema/src/authorization.d.ts +12 -5
  120. package/out/zero-schema/src/authorization.d.ts.map +1 -1
  121. package/out/zero-schema/src/build-schema.d.ts +14 -0
  122. package/out/zero-schema/src/build-schema.d.ts.map +1 -0
  123. package/out/zero-schema/src/build-schema.js +55 -0
  124. package/out/zero-schema/src/build-schema.js.map +1 -0
  125. package/out/zero-schema/src/compiled-authorization.d.ts +213 -294
  126. package/out/zero-schema/src/compiled-authorization.d.ts.map +1 -1
  127. package/out/zero-schema/src/compiled-authorization.js +9 -4
  128. package/out/zero-schema/src/compiled-authorization.js.map +1 -1
  129. package/out/zero-schema/src/normalize-table-schema.d.ts +2 -11
  130. package/out/zero-schema/src/normalize-table-schema.d.ts.map +1 -1
  131. package/out/zero-schema/src/normalize-table-schema.js +108 -0
  132. package/out/zero-schema/src/normalize-table-schema.js.map +1 -0
  133. package/out/zero-schema/src/normalized-schema.js +31 -0
  134. package/out/zero-schema/src/normalized-schema.js.map +1 -0
  135. package/out/zero-schema/src/schema-config.d.ts +325 -0
  136. package/out/zero-schema/src/schema-config.d.ts.map +1 -0
  137. package/out/zero-schema/src/schema-config.js +41 -0
  138. package/out/zero-schema/src/schema-config.js.map +1 -0
  139. package/out/zero-schema/src/schema.js +4 -0
  140. package/out/zero-schema/src/schema.js.map +1 -0
  141. package/out/zero-schema/src/table-schema.d.ts +6 -15
  142. package/out/zero-schema/src/table-schema.d.ts.map +1 -1
  143. package/out/zero-schema/src/table-schema.js.map +1 -1
  144. package/out/zero.js +2 -2
  145. package/out/zql/src/builder/builder.d.ts +2 -2
  146. package/out/zql/src/builder/builder.d.ts.map +1 -1
  147. package/out/zql/src/builder/builder.js +19 -20
  148. package/out/zql/src/builder/builder.js.map +1 -1
  149. package/out/zql/src/builder/filter.d.ts +25 -2
  150. package/out/zql/src/builder/filter.d.ts.map +1 -1
  151. package/out/zql/src/builder/filter.js +91 -1
  152. package/out/zql/src/builder/filter.js.map +1 -1
  153. package/out/zql/src/ivm/array-view.js +70 -0
  154. package/out/zql/src/ivm/array-view.js.map +1 -0
  155. package/out/zql/src/ivm/change.d.ts +18 -6
  156. package/out/zql/src/ivm/change.d.ts.map +1 -1
  157. package/out/zql/src/ivm/change.js +1 -1
  158. package/out/zql/src/ivm/change.js.map +1 -1
  159. package/out/zql/src/ivm/constraint.d.ts +14 -0
  160. package/out/zql/src/ivm/constraint.d.ts.map +1 -0
  161. package/out/zql/src/ivm/constraint.js +60 -0
  162. package/out/zql/src/ivm/constraint.js.map +1 -0
  163. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  164. package/out/zql/src/ivm/exists.js +19 -2
  165. package/out/zql/src/ivm/exists.js.map +1 -1
  166. package/out/zql/src/ivm/join.d.ts +11 -5
  167. package/out/zql/src/ivm/join.d.ts.map +1 -1
  168. package/out/zql/src/ivm/join.js +49 -95
  169. package/out/zql/src/ivm/join.js.map +1 -1
  170. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  171. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +4 -13
  172. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  173. package/out/zql/src/ivm/memory-source.d.ts +5 -22
  174. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  175. package/out/zql/src/ivm/memory-source.js +58 -80
  176. package/out/zql/src/ivm/memory-source.js.map +1 -1
  177. package/out/zql/src/ivm/operator.d.ts +7 -10
  178. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  179. package/out/zql/src/ivm/operator.js +1 -1
  180. package/out/zql/src/ivm/operator.js.map +1 -1
  181. package/out/zql/src/ivm/take.d.ts +3 -1
  182. package/out/zql/src/ivm/take.d.ts.map +1 -1
  183. package/out/zql/src/ivm/take.js +95 -95
  184. package/out/zql/src/ivm/take.js.map +1 -1
  185. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  186. package/out/zql/src/ivm/view-apply-change.js +168 -0
  187. package/out/zql/src/ivm/view-apply-change.js.map +1 -0
  188. package/out/zql/src/ivm/view.js +2 -0
  189. package/out/zql/src/ivm/view.js.map +1 -0
  190. package/out/zql/src/query/auth-query.d.ts +3 -1
  191. package/out/zql/src/query/auth-query.d.ts.map +1 -1
  192. package/out/zql/src/query/auth-query.js +34 -0
  193. package/out/zql/src/query/auth-query.js.map +1 -0
  194. package/out/zql/src/query/dnf.js +57 -0
  195. package/out/zql/src/query/dnf.js.map +1 -0
  196. package/out/zql/src/query/expression.js +155 -0
  197. package/out/zql/src/query/expression.js.map +1 -0
  198. package/out/zql/src/query/query-impl.d.ts +4 -1
  199. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  200. package/out/zql/src/query/query-impl.js +359 -0
  201. package/out/zql/src/query/query-impl.js.map +1 -0
  202. package/out/zql/src/query/query-internal.js +2 -0
  203. package/out/zql/src/query/query-internal.js.map +1 -0
  204. package/out/zql/src/query/query.js +3 -0
  205. package/out/zql/src/query/query.js.map +1 -0
  206. package/out/zql/src/query/typed-view.js +2 -0
  207. package/out/zql/src/query/typed-view.js.map +1 -0
  208. package/out/zqlite/src/table-source.d.ts +2 -11
  209. package/out/zqlite/src/table-source.d.ts.map +1 -1
  210. package/out/zqlite/src/table-source.js +28 -80
  211. package/out/zqlite/src/table-source.js.map +1 -1
  212. package/package.json +5 -3
  213. package/out/chunk-5UY46OAF.js.map +0 -7
  214. package/out/zero-cache/src/auth/load-authorization.d.ts +0 -4
  215. package/out/zero-cache/src/auth/load-authorization.d.ts.map +0 -1
  216. package/out/zero-cache/src/auth/load-authorization.js +0 -20
  217. package/out/zero-cache/src/auth/load-authorization.js.map +0 -1
  218. package/out/zero-cache/src/config/config.d.ts.map +0 -1
  219. package/out/zero-cache/src/config/config.js.map +0 -1
  220. package/out/zero-cache/src/services/mutagen/write-authorizer.d.ts +0 -21
  221. package/out/zero-cache/src/services/mutagen/write-authorizer.d.ts.map +0 -1
  222. package/out/zero-cache/src/services/mutagen/write-authorizer.js +0 -168
  223. package/out/zero-cache/src/services/mutagen/write-authorizer.js.map +0 -1
@@ -14,7 +14,7 @@ import {
14
14
  must,
15
15
  throwInvalidType,
16
16
  unreachable
17
- } from "./chunk-5UY46OAF.js";
17
+ } from "./chunk-C7M3BJ3Z.js";
18
18
  import {
19
19
  __export,
20
20
  __reExport
@@ -9291,8 +9291,8 @@ function isJunctionRelationship(relationship) {
9291
9291
  }
9292
9292
 
9293
9293
  // ../shared/src/sorted-entries.ts
9294
- function sortedEntries(object16) {
9295
- return Object.entries(object16).sort((a, b) => stringCompare(a[0], b[0]));
9294
+ function sortedEntries(object17) {
9295
+ return Object.entries(object17).sort((a, b) => stringCompare(a[0], b[0]));
9296
9296
  }
9297
9297
 
9298
9298
  // ../zero-schema/src/normalize-table-schema.ts
@@ -9409,22 +9409,11 @@ function normalizeFieldRelationship(relationship, tableSchemaCache) {
9409
9409
  }
9410
9410
  function normalizeJunctionRelationship(relationship, tableSchemaCache) {
9411
9411
  return {
9412
- source: relationship.source,
9413
- junction: {
9414
- sourceField: relationship.junction.sourceField,
9415
- destField: relationship.junction.destField,
9416
- schema: normalizeLazyTableSchema(
9417
- relationship.junction.schema,
9418
- tableSchemaCache
9419
- )
9420
- },
9421
- dest: {
9422
- field: relationship.dest.field,
9423
- schema: normalizeLazyTableSchema(
9424
- relationship.dest.schema,
9425
- tableSchemaCache
9426
- )
9427
- }
9412
+ ...normalizeFieldRelationship(relationship, tableSchemaCache),
9413
+ junction: normalizeFieldRelationship(
9414
+ relationship.junction,
9415
+ tableSchemaCache
9416
+ )
9428
9417
  };
9429
9418
  }
9430
9419
  function normalizeLazyTableSchema(tableSchema, buildCache) {
@@ -9461,6 +9450,158 @@ function normalizeTables(tables) {
9461
9450
  return rv;
9462
9451
  }
9463
9452
 
9453
+ // ../zql/src/query/expression.ts
9454
+ var ExpressionBuilder = class {
9455
+ #exists;
9456
+ constructor(exists) {
9457
+ this.#exists = exists;
9458
+ this.exists = this.exists.bind(this);
9459
+ }
9460
+ get eb() {
9461
+ return this;
9462
+ }
9463
+ cmp(field, opOrValue, value) {
9464
+ return cmp(field, opOrValue, value);
9465
+ }
9466
+ cmpLit(left, op, right) {
9467
+ return {
9468
+ type: "simple",
9469
+ left: isParameter(left) ? left : { type: "literal", value: left },
9470
+ right: isParameter(right) ? right : { type: "literal", value: right },
9471
+ op
9472
+ };
9473
+ }
9474
+ and = and;
9475
+ or = or;
9476
+ not = not;
9477
+ exists(relationship, cb) {
9478
+ return this.#exists(relationship, cb);
9479
+ }
9480
+ };
9481
+ function and(...conditions) {
9482
+ const expressions = filterTrue(filterUndefined(conditions));
9483
+ if (expressions.length === 1) {
9484
+ return expressions[0];
9485
+ }
9486
+ if (expressions.some(isAlwaysFalse)) {
9487
+ return FALSE;
9488
+ }
9489
+ return { type: "and", conditions: expressions };
9490
+ }
9491
+ function or(...conditions) {
9492
+ const expressions = filterFalse(filterUndefined(conditions));
9493
+ if (expressions.length === 1) {
9494
+ return expressions[0];
9495
+ }
9496
+ if (expressions.some(isAlwaysTrue)) {
9497
+ return TRUE;
9498
+ }
9499
+ return { type: "or", conditions: expressions };
9500
+ }
9501
+ function not(expression) {
9502
+ switch (expression.type) {
9503
+ case "and":
9504
+ return {
9505
+ type: "or",
9506
+ conditions: expression.conditions.map(not)
9507
+ };
9508
+ case "or":
9509
+ return {
9510
+ type: "and",
9511
+ conditions: expression.conditions.map(not)
9512
+ };
9513
+ case "correlatedSubquery":
9514
+ return {
9515
+ type: "correlatedSubquery",
9516
+ related: expression.related,
9517
+ op: negateOperator(expression.op)
9518
+ };
9519
+ case "simple":
9520
+ return {
9521
+ type: "simple",
9522
+ op: negateOperator(expression.op),
9523
+ left: expression.left,
9524
+ right: expression.right
9525
+ };
9526
+ }
9527
+ }
9528
+ function cmp(field, opOrValue, value) {
9529
+ let op;
9530
+ if (value === void 0) {
9531
+ value = opOrValue;
9532
+ op = "=";
9533
+ } else {
9534
+ op = opOrValue;
9535
+ }
9536
+ return {
9537
+ type: "simple",
9538
+ left: { type: "column", name: field },
9539
+ right: isParameter(value) ? value : { type: "literal", value },
9540
+ op
9541
+ };
9542
+ }
9543
+ function isParameter(value) {
9544
+ return typeof value === "object" && value?.type === "static";
9545
+ }
9546
+ var TRUE = {
9547
+ type: "and",
9548
+ conditions: []
9549
+ };
9550
+ var FALSE = {
9551
+ type: "or",
9552
+ conditions: []
9553
+ };
9554
+ function isAlwaysTrue(condition) {
9555
+ return condition.type === "and" && condition.conditions.length === 0;
9556
+ }
9557
+ function isAlwaysFalse(condition) {
9558
+ return condition.type === "or" && condition.conditions.length === 0;
9559
+ }
9560
+ function flatten(type, conditions) {
9561
+ const flattened2 = [];
9562
+ for (const c of conditions) {
9563
+ if (c.type === type) {
9564
+ flattened2.push(...c.conditions);
9565
+ } else {
9566
+ flattened2.push(c);
9567
+ }
9568
+ }
9569
+ return flattened2;
9570
+ }
9571
+ var negateSimpleOperatorMap = {
9572
+ ["="]: "!=",
9573
+ ["!="]: "=",
9574
+ ["<"]: ">=",
9575
+ [">"]: "<=",
9576
+ [">="]: "<",
9577
+ ["<="]: ">",
9578
+ ["IN"]: "NOT IN",
9579
+ ["NOT IN"]: "IN",
9580
+ ["LIKE"]: "NOT LIKE",
9581
+ ["NOT LIKE"]: "LIKE",
9582
+ ["ILIKE"]: "NOT ILIKE",
9583
+ ["NOT ILIKE"]: "ILIKE",
9584
+ ["IS"]: "IS NOT",
9585
+ ["IS NOT"]: "IS"
9586
+ };
9587
+ var negateOperatorMap = {
9588
+ ...negateSimpleOperatorMap,
9589
+ ["EXISTS"]: "NOT EXISTS",
9590
+ ["NOT EXISTS"]: "EXISTS"
9591
+ };
9592
+ function negateOperator(op) {
9593
+ return must(negateOperatorMap[op]);
9594
+ }
9595
+ function filterUndefined(array9) {
9596
+ return array9.filter((e) => e !== void 0);
9597
+ }
9598
+ function filterTrue(conditions) {
9599
+ return conditions.filter((c) => !isAlwaysTrue(c));
9600
+ }
9601
+ function filterFalse(conditions) {
9602
+ return conditions.filter((c) => !isAlwaysFalse(c));
9603
+ }
9604
+
9464
9605
  // ../zql/src/query/query-impl.ts
9465
9606
  import { resolver as resolver7 } from "@rocicorp/resolver";
9466
9607
 
@@ -9753,7 +9894,7 @@ function hashOfAST(ast) {
9753
9894
  // ../zql/src/ivm/change.ts
9754
9895
  function rowForChange(change) {
9755
9896
  const { type } = change;
9756
- return type === "add" || type === "remove" ? change.node.row : change.row;
9897
+ return type === "child" ? change.row : change.node.row;
9757
9898
  }
9758
9899
 
9759
9900
  // ../zql/src/ivm/data.ts
@@ -9895,8 +10036,12 @@ var Exists = class {
9895
10036
  size = this.#fetchSize(change.row);
9896
10037
  }
9897
10038
  if (size === 1) {
10039
+ const type = this.#not ? "remove" : "add";
10040
+ if (type === "remove") {
10041
+ this.#output.push(change);
10042
+ }
9898
10043
  this.#output.push({
9899
- type: this.#not ? "remove" : "add",
10044
+ type,
9900
10045
  node: this.#fetchNodeForRow(change.row)
9901
10046
  });
9902
10047
  } else {
@@ -9914,8 +10059,12 @@ var Exists = class {
9914
10059
  size = this.#fetchSize(change.row);
9915
10060
  }
9916
10061
  if (size === 0) {
10062
+ const type = this.#not ? "add" : "remove";
10063
+ if (type === "remove") {
10064
+ this.#output.push(change);
10065
+ }
9917
10066
  this.#output.push({
9918
- type: this.#not ? "add" : "remove",
10067
+ type,
9919
10068
  node: this.#fetchNodeForRow(change.row)
9920
10069
  });
9921
10070
  } else {
@@ -10092,25 +10241,19 @@ var FanOut = class {
10092
10241
 
10093
10242
  // ../zql/src/ivm/maybe-split-and-push-edit-change.ts
10094
10243
  function maybeSplitAndPushEditChange(change, predicate, output) {
10095
- const oldWasPresent = predicate(change.oldRow);
10096
- const newIsPresent = predicate(change.row);
10244
+ const oldWasPresent = predicate(change.oldNode.row);
10245
+ const newIsPresent = predicate(change.node.row);
10097
10246
  if (oldWasPresent && newIsPresent) {
10098
10247
  output.push(change);
10099
10248
  } else if (oldWasPresent && !newIsPresent) {
10100
10249
  output.push({
10101
10250
  type: "remove",
10102
- node: {
10103
- row: change.oldRow,
10104
- relationships: {}
10105
- }
10251
+ node: change.oldNode
10106
10252
  });
10107
10253
  } else if (!oldWasPresent && newIsPresent) {
10108
10254
  output.push({
10109
10255
  type: "add",
10110
- node: {
10111
- row: change.row,
10112
- relationships: {}
10113
- }
10256
+ node: change.node
10114
10257
  });
10115
10258
  }
10116
10259
  }
@@ -10192,6 +10335,10 @@ var Join = class {
10192
10335
  hidden
10193
10336
  }) {
10194
10337
  assert(parent !== child, "Parent and child must be different operators");
10338
+ assert(
10339
+ parentKey.length === childKey.length,
10340
+ "The parentKey and childKey keys must have same length"
10341
+ );
10195
10342
  this.#parent = parent;
10196
10343
  this.#child = child;
10197
10344
  this.#storage = storage;
@@ -10270,68 +10417,33 @@ var Join = class {
10270
10417
  this.#output.push(change);
10271
10418
  break;
10272
10419
  case "edit": {
10273
- this.#output.push({
10274
- type: "edit",
10275
- row: change.row,
10276
- oldRow: change.oldRow
10277
- });
10278
- const oldKeyValue = normalizeUndefined(change.oldRow[this.#parentKey]);
10279
- const newKeyValue = normalizeUndefined(change.row[this.#parentKey]);
10280
- if (newKeyValue !== oldKeyValue) {
10281
- const childrenToRemoveStream = this.#child.cleanup({
10282
- constraint: {
10283
- key: this.#childKey,
10284
- value: oldKeyValue
10285
- }
10420
+ if (rowEqualsForCompoundKey(
10421
+ change.oldNode.row,
10422
+ change.node.row,
10423
+ this.#parentKey
10424
+ )) {
10425
+ this.#output.push({
10426
+ type: "edit",
10427
+ oldNode: this.#processParentNode(
10428
+ change.oldNode.row,
10429
+ change.oldNode.relationships,
10430
+ "cleanup"
10431
+ ),
10432
+ node: this.#processParentNode(
10433
+ change.node.row,
10434
+ change.node.relationships,
10435
+ "fetch"
10436
+ )
10286
10437
  });
10287
- for (const childNode of childrenToRemoveStream) {
10288
- this.#output.push({
10289
- type: "child",
10290
- // This is the new row since we already changed it in the edit above.
10291
- row: change.row,
10292
- child: {
10293
- relationshipName: this.#relationshipName,
10294
- change: {
10295
- type: "remove",
10296
- node: childNode
10297
- }
10298
- }
10299
- });
10300
- }
10301
- const childrenToAddStream = this.#child.fetch({
10302
- constraint: {
10303
- key: this.#childKey,
10304
- value: newKeyValue
10305
- }
10438
+ } else {
10439
+ this.#pushParent({
10440
+ type: "remove",
10441
+ node: change.oldNode
10442
+ });
10443
+ this.#pushParent({
10444
+ type: "add",
10445
+ node: change.node
10306
10446
  });
10307
- for (const childNode of childrenToAddStream) {
10308
- this.#output.push({
10309
- type: "child",
10310
- row: change.row,
10311
- child: {
10312
- relationshipName: this.#relationshipName,
10313
- change: {
10314
- type: "add",
10315
- node: childNode
10316
- }
10317
- }
10318
- });
10319
- }
10320
- }
10321
- const { primaryKey } = this.#parent.getSchema();
10322
- const oldStorageKey = makeStorageKey(
10323
- oldKeyValue,
10324
- primaryKey,
10325
- change.oldRow
10326
- );
10327
- const newStorageKey = makeStorageKey(
10328
- newKeyValue,
10329
- primaryKey,
10330
- change.row
10331
- );
10332
- if (oldStorageKey !== newStorageKey) {
10333
- this.#storage.del(oldStorageKey);
10334
- this.#storage.set(newStorageKey, true);
10335
10447
  }
10336
10448
  break;
10337
10449
  }
@@ -10343,10 +10455,9 @@ var Join = class {
10343
10455
  const pushChildChange = (childRow, change2) => {
10344
10456
  assert(this.#output, "Output not set");
10345
10457
  const parentNodes = this.#parent.fetch({
10346
- constraint: {
10347
- key: this.#parentKey,
10348
- value: childRow[this.#childKey]
10349
- }
10458
+ constraint: Object.fromEntries(
10459
+ this.#parentKey.map((key, i) => [key, childRow[this.#childKey[i]]])
10460
+ )
10350
10461
  });
10351
10462
  for (const parentNode of parentNodes) {
10352
10463
  const childChange = {
@@ -10369,34 +10480,18 @@ var Join = class {
10369
10480
  pushChildChange(change.row, change);
10370
10481
  break;
10371
10482
  case "edit": {
10372
- const childRow = change.row;
10373
- const oldChildRow = change.oldRow;
10374
- if (normalizeUndefined(oldChildRow[this.#childKey]) === normalizeUndefined(childRow[this.#childKey])) {
10483
+ const childRow = change.node.row;
10484
+ const oldChildRow = change.oldNode.row;
10485
+ if (rowEqualsForCompoundKey(oldChildRow, childRow, this.#childKey)) {
10375
10486
  pushChildChange(childRow, change);
10376
10487
  } else {
10377
- const { relationships } = must(
10378
- first(
10379
- this.#child.fetch({
10380
- constraint: {
10381
- key: this.#childKey,
10382
- value: oldChildRow[this.#childKey]
10383
- }
10384
- })
10385
- )
10386
- );
10387
10488
  pushChildChange(oldChildRow, {
10388
10489
  type: "remove",
10389
- node: {
10390
- row: oldChildRow,
10391
- relationships
10392
- }
10490
+ node: change.oldNode
10393
10491
  });
10394
10492
  pushChildChange(childRow, {
10395
10493
  type: "add",
10396
- node: {
10397
- row: childRow,
10398
- relationships
10399
- }
10494
+ node: change.node
10400
10495
  });
10401
10496
  }
10402
10497
  break;
@@ -10406,9 +10501,8 @@ var Join = class {
10406
10501
  }
10407
10502
  }
10408
10503
  #processParentNode(parentNodeRow, parentNodeRelations, mode) {
10409
- const parentKeyValue = normalizeUndefined(parentNodeRow[this.#parentKey]);
10410
10504
  const storageKey = makeStorageKey(
10411
- parentKeyValue,
10505
+ this.#parentKey,
10412
10506
  this.#parent.getSchema().primaryKey,
10413
10507
  parentNodeRow
10414
10508
  );
@@ -10416,17 +10510,19 @@ var Join = class {
10416
10510
  if (mode === "cleanup") {
10417
10511
  const [, second] = take(
10418
10512
  this.#storage.scan({
10419
- prefix: createPrimaryKeySetStorageKeyPrefix(parentKeyValue)
10513
+ prefix: makeStorageKeyPrefix(parentNodeRow, this.#parentKey)
10420
10514
  }),
10421
10515
  2
10422
10516
  );
10423
10517
  method = second ? "fetch" : "cleanup";
10424
10518
  }
10425
10519
  const childStream = this.#child[method]({
10426
- constraint: {
10427
- key: this.#childKey,
10428
- value: parentKeyValue
10429
- }
10520
+ constraint: Object.fromEntries(
10521
+ this.#childKey.map((key, i) => [
10522
+ key,
10523
+ parentNodeRow[this.#parentKey[i]]
10524
+ ])
10525
+ )
10430
10526
  });
10431
10527
  if (mode === "fetch") {
10432
10528
  this.#storage.set(storageKey, true);
@@ -10443,19 +10539,27 @@ var Join = class {
10443
10539
  };
10444
10540
  }
10445
10541
  };
10446
- function createPrimaryKeySetStorageKey(values) {
10542
+ function makeStorageKeyForValues(values) {
10447
10543
  const json = JSON.stringify(["pKeySet", ...values]);
10448
10544
  return json.substring(1, json.length - 1) + ",";
10449
10545
  }
10450
- function createPrimaryKeySetStorageKeyPrefix(value) {
10451
- return createPrimaryKeySetStorageKey([value]);
10546
+ function makeStorageKeyPrefix(row, key) {
10547
+ return makeStorageKeyForValues(key.map((k) => row[k]));
10452
10548
  }
10453
- function makeStorageKey(keyValue, primaryKey, row) {
10454
- const parentPrimaryKey = [keyValue];
10455
- for (const key of primaryKey) {
10456
- parentPrimaryKey.push(normalizeUndefined(row[key]));
10549
+ function makeStorageKey(key, primaryKey, row) {
10550
+ const values = key.map((k) => row[k]);
10551
+ for (const key2 of primaryKey) {
10552
+ values.push(row[key2]);
10457
10553
  }
10458
- return createPrimaryKeySetStorageKey(parentPrimaryKey);
10554
+ return makeStorageKeyForValues(values);
10555
+ }
10556
+ function rowEqualsForCompoundKey(a, b, key) {
10557
+ for (let i = 0; i < key.length; i++) {
10558
+ if (!valuesEqual(a[key[i]], b[key[i]])) {
10559
+ return false;
10560
+ }
10561
+ }
10562
+ return true;
10459
10563
  }
10460
10564
 
10461
10565
  // ../zql/src/ivm/skip.ts
@@ -10551,18 +10655,20 @@ var Take = class {
10551
10655
  #storage;
10552
10656
  #limit;
10553
10657
  #partitionKey;
10658
+ #partitionKeyComparator;
10554
10659
  #output = null;
10555
10660
  constructor(input, storage, limit, partitionKey) {
10556
- this.#input = input;
10557
- this.#storage = storage;
10558
- this.#limit = limit;
10559
- this.#partitionKey = partitionKey;
10560
10661
  assert(limit >= 0);
10561
10662
  assertOrderingIncludesPK(
10562
10663
  input.getSchema().sort,
10563
10664
  input.getSchema().primaryKey
10564
10665
  );
10565
10666
  input.setOutput(this);
10667
+ this.#input = input;
10668
+ this.#storage = storage;
10669
+ this.#limit = limit;
10670
+ this.#partitionKey = partitionKey;
10671
+ this.#partitionKeyComparator = partitionKey && makePartitionKeyComparator(partitionKey);
10566
10672
  }
10567
10673
  setOutput(output) {
10568
10674
  this.#output = output;
@@ -10571,9 +10677,8 @@ var Take = class {
10571
10677
  return this.#input.getSchema();
10572
10678
  }
10573
10679
  *fetch(req) {
10574
- if (this.#partitionKey === void 0 || req.constraint?.key === this.#partitionKey) {
10575
- const partitionValue = this.#partitionKey === void 0 ? void 0 : req.constraint?.value;
10576
- const takeStateKey = getTakeStateKey(partitionValue);
10680
+ if (!this.#partitionKey || req.constraint && constraintMatchesPartitionKey(req.constraint, this.#partitionKey)) {
10681
+ const takeStateKey = getTakeStateKey(this.#partitionKey, req.constraint);
10577
10682
  const takeState = this.#storage.get(takeStateKey);
10578
10683
  if (!takeState) {
10579
10684
  yield* this.#initialFetch(req);
@@ -10598,8 +10703,7 @@ var Take = class {
10598
10703
  if (this.getSchema().compareRows(inputNode.row, maxBound) > 0) {
10599
10704
  return;
10600
10705
  }
10601
- const partitionValue = inputNode.row[this.#partitionKey];
10602
- const takeStateKey = getTakeStateKey(partitionValue);
10706
+ const takeStateKey = getTakeStateKey(this.#partitionKey, inputNode.row);
10603
10707
  const takeState = this.#storage.get(takeStateKey);
10604
10708
  if (takeState?.bound !== void 0 && this.getSchema().compareRows(takeState.bound, inputNode.row) >= 0) {
10605
10709
  yield inputNode;
@@ -10609,13 +10713,13 @@ var Take = class {
10609
10713
  *#initialFetch(req) {
10610
10714
  assert(req.start === void 0);
10611
10715
  assert(
10612
- this.#partitionKey === void 0 || req.constraint !== void 0 && req.constraint.key === this.#partitionKey
10716
+ !this.#partitionKey || req.constraint && // TODO: Compound keys
10717
+ constraintMatchesPartitionKey(req.constraint, this.#partitionKey)
10613
10718
  );
10614
10719
  if (this.#limit === 0) {
10615
10720
  return;
10616
10721
  }
10617
- const partitionValue = this.#partitionKey === void 0 ? void 0 : req.constraint?.value;
10618
- const takeStateKey = getTakeStateKey(partitionValue);
10722
+ const takeStateKey = getTakeStateKey(this.#partitionKey, req.constraint);
10619
10723
  assert(this.#storage.get(takeStateKey) === void 0);
10620
10724
  let size = 0;
10621
10725
  let bound;
@@ -10646,14 +10750,17 @@ var Take = class {
10646
10750
  *cleanup(req) {
10647
10751
  assert(req.start === void 0);
10648
10752
  assert(
10649
- this.#partitionKey === void 0 || req.constraint !== void 0 && req.constraint.key === this.#partitionKey
10753
+ !this.#partitionKey || req.constraint && // TODO: Compound keys
10754
+ constraintMatchesPartitionKey(req.constraint, this.#partitionKey)
10650
10755
  );
10651
10756
  let takeState;
10652
10757
  if (this.#limit > 0) {
10653
- const partitionValue = this.#partitionKey === void 0 ? void 0 : req.constraint?.value;
10654
- const takeStateKey = getTakeStateKey(partitionValue);
10758
+ const takeStateKey = getTakeStateKey(this.#partitionKey, req.constraint);
10655
10759
  takeState = this.#storage.get(takeStateKey);
10656
- assert(takeState !== void 0);
10760
+ assert(
10761
+ takeState !== void 0,
10762
+ "takeStateKey was: " + takeStateKey + ", partitionKey was: " + this.#partitionKey + ", constraint was: " + JSON.stringify(req.constraint)
10763
+ );
10657
10764
  this.#storage.del(takeStateKey);
10658
10765
  }
10659
10766
  for (const inputNode of this.#input.cleanup(req)) {
@@ -10664,17 +10771,15 @@ var Take = class {
10664
10771
  }
10665
10772
  }
10666
10773
  #getStateAndConstraint(row) {
10667
- const partitionValue = this.#partitionKey === void 0 ? void 0 : row[this.#partitionKey];
10668
- const takeStateKey = getTakeStateKey(partitionValue);
10774
+ const takeStateKey = getTakeStateKey(this.#partitionKey, row);
10669
10775
  const takeState = this.#storage.get(takeStateKey);
10670
10776
  let maxBound;
10671
10777
  let constraint;
10672
10778
  if (takeState) {
10673
10779
  maxBound = this.#storage.get(MAX_BOUND_KEY);
10674
- constraint = this.#partitionKey ? {
10675
- key: this.#partitionKey,
10676
- value: partitionValue
10677
- } : void 0;
10780
+ constraint = this.#partitionKey && Object.fromEntries(
10781
+ this.#partitionKey.map((key) => [key, row[key]])
10782
+ );
10678
10783
  }
10679
10784
  return { takeState, takeStateKey, maxBound, constraint };
10680
10785
  }
@@ -10749,57 +10854,41 @@ var Take = class {
10749
10854
  if (compToBound > 0) {
10750
10855
  return;
10751
10856
  }
10752
- if (takeState.size === 1) {
10753
- this.#storage.set(takeStateKey, {
10754
- size: 0,
10755
- bound: void 0
10756
- });
10757
- this.#output.push(change);
10758
- return;
10759
- }
10760
- let beforeBoundNode;
10761
- let afterBoundNode;
10762
- if (compToBound === 0) {
10763
- [beforeBoundNode, afterBoundNode] = take(
10764
- this.#input.fetch({
10765
- start: {
10766
- row: takeState.bound,
10767
- basis: "before"
10768
- },
10769
- constraint
10770
- }),
10771
- 2
10772
- );
10773
- } else {
10774
- [beforeBoundNode, , afterBoundNode] = take(
10775
- this.#input.fetch({
10776
- start: {
10777
- row: takeState.bound,
10778
- basis: "before"
10779
- },
10780
- constraint
10781
- }),
10782
- 3
10783
- );
10857
+ let newBound;
10858
+ for (const node of this.#input.fetch({
10859
+ start: {
10860
+ row: takeState.bound,
10861
+ basis: "before"
10862
+ },
10863
+ constraint
10864
+ })) {
10865
+ const push2 = compareRows(node.row, takeState.bound) > 0;
10866
+ newBound = {
10867
+ node,
10868
+ push: push2
10869
+ };
10870
+ if (push2) {
10871
+ break;
10872
+ }
10784
10873
  }
10785
- if (afterBoundNode) {
10874
+ if (newBound?.push) {
10786
10875
  this.#setTakeState(
10787
10876
  takeStateKey,
10788
10877
  takeState.size,
10789
- afterBoundNode.row,
10878
+ newBound.node.row,
10790
10879
  maxBound
10791
10880
  );
10792
10881
  this.#output.push(change);
10793
10882
  this.#output.push({
10794
10883
  type: "add",
10795
- node: afterBoundNode
10884
+ node: newBound.node
10796
10885
  });
10797
10886
  return;
10798
10887
  }
10799
10888
  this.#setTakeState(
10800
10889
  takeStateKey,
10801
10890
  takeState.size - 1,
10802
- compToBound === 0 ? beforeBoundNode.row : takeState.bound,
10891
+ newBound?.node.row,
10803
10892
  maxBound
10804
10893
  );
10805
10894
  this.#output.push(change);
@@ -10811,33 +10900,32 @@ var Take = class {
10811
10900
  }
10812
10901
  #pushEditChange(change) {
10813
10902
  assert(this.#output, "Output not set");
10814
- if (this.#partitionKey !== void 0 && change.oldRow[this.#partitionKey] !== change.row[this.#partitionKey]) {
10903
+ if (this.#partitionKeyComparator && this.#partitionKeyComparator(change.oldNode.row, change.node.row) !== 0) {
10815
10904
  this.push({
10816
10905
  type: "remove",
10817
- node: {
10818
- row: change.oldRow,
10819
- relationships: {}
10820
- }
10906
+ node: change.oldNode
10821
10907
  });
10822
10908
  this.push({
10823
10909
  type: "add",
10824
- node: {
10825
- row: change.row,
10826
- relationships: {}
10827
- }
10910
+ node: change.node
10828
10911
  });
10829
10912
  return;
10830
10913
  }
10831
- const { takeState, takeStateKey, maxBound, constraint } = this.#getStateAndConstraint(change.oldRow);
10914
+ const { takeState, takeStateKey, maxBound, constraint } = this.#getStateAndConstraint(change.oldNode.row);
10832
10915
  if (!takeState) {
10833
10916
  return;
10834
10917
  }
10835
10918
  assert(takeState.bound, "Bound should be set");
10836
10919
  const { compareRows } = this.getSchema();
10837
- const oldCmp = compareRows(change.oldRow, takeState.bound);
10838
- const newCmp = compareRows(change.row, takeState.bound);
10920
+ const oldCmp = compareRows(change.oldNode.row, takeState.bound);
10921
+ const newCmp = compareRows(change.node.row, takeState.bound);
10839
10922
  const replaceBoundAndForwardChange = () => {
10840
- this.#setTakeState(takeStateKey, takeState.size, change.row, maxBound);
10923
+ this.#setTakeState(
10924
+ takeStateKey,
10925
+ takeState.size,
10926
+ change.node.row,
10927
+ maxBound
10928
+ );
10841
10929
  this.#output.push(change);
10842
10930
  };
10843
10931
  if (oldCmp === 0) {
@@ -10882,7 +10970,7 @@ var Take = class {
10882
10970
  })
10883
10971
  )
10884
10972
  );
10885
- if (compareRows(newBoundNode.row, change.row) === 0) {
10973
+ if (compareRows(newBoundNode.row, change.node.row) === 0) {
10886
10974
  replaceBoundAndForwardChange();
10887
10975
  return;
10888
10976
  }
@@ -10894,10 +10982,7 @@ var Take = class {
10894
10982
  );
10895
10983
  this.#output.push({
10896
10984
  type: "remove",
10897
- node: {
10898
- row: change.oldRow,
10899
- relationships: {}
10900
- }
10985
+ node: change.oldNode
10901
10986
  });
10902
10987
  this.#output.push({
10903
10988
  type: "add",
@@ -10933,10 +11018,7 @@ var Take = class {
10933
11018
  });
10934
11019
  this.#output.push({
10935
11020
  type: "add",
10936
- node: {
10937
- row: change.row,
10938
- relationships: {}
10939
- }
11021
+ node: change.node
10940
11022
  });
10941
11023
  return;
10942
11024
  }
@@ -10958,7 +11040,7 @@ var Take = class {
10958
11040
  })
10959
11041
  )
10960
11042
  );
10961
- if (compareRows(afterBoundNode.row, change.row) === 0) {
11043
+ if (compareRows(afterBoundNode.row, change.node.row) === 0) {
10962
11044
  replaceBoundAndForwardChange();
10963
11045
  return;
10964
11046
  }
@@ -10970,10 +11052,7 @@ var Take = class {
10970
11052
  );
10971
11053
  this.#output.push({
10972
11054
  type: "remove",
10973
- node: {
10974
- row: change.oldRow,
10975
- relationships: {}
10976
- }
11055
+ node: change.oldNode
10977
11056
  });
10978
11057
  this.#output.push({
10979
11058
  type: "add",
@@ -10996,8 +11075,33 @@ var Take = class {
10996
11075
  this.#input.destroy();
10997
11076
  }
10998
11077
  };
10999
- function getTakeStateKey(partitionValue) {
11000
- return JSON.stringify(["take", normalizeUndefined(partitionValue)]);
11078
+ function getTakeStateKey(partitionKey, rowOrConstraint) {
11079
+ const partitionValues = [];
11080
+ if (partitionKey && rowOrConstraint) {
11081
+ for (const key of partitionKey) {
11082
+ partitionValues.push(rowOrConstraint[key]);
11083
+ }
11084
+ }
11085
+ return JSON.stringify(["take", ...partitionValues]);
11086
+ }
11087
+ function constraintMatchesPartitionKey(constraint, partitionKey) {
11088
+ for (const key of partitionKey) {
11089
+ if (!hasOwn(constraint, key)) {
11090
+ return false;
11091
+ }
11092
+ }
11093
+ return true;
11094
+ }
11095
+ function makePartitionKeyComparator(partitionKey) {
11096
+ return (a, b) => {
11097
+ for (const key of partitionKey) {
11098
+ const cmp2 = compareValues(a[key], b[key]);
11099
+ if (cmp2 !== 0) {
11100
+ return cmp2;
11101
+ }
11102
+ }
11103
+ return 0;
11104
+ };
11001
11105
  }
11002
11106
 
11003
11107
  // ../zql/src/builder/like.ts
@@ -11050,6 +11154,24 @@ function patternToRegExp(source, flags = "") {
11050
11154
 
11051
11155
  // ../zql/src/builder/filter.ts
11052
11156
  function createPredicate(condition) {
11157
+ if (condition.type !== "simple") {
11158
+ const predicates = condition.conditions.map((c) => createPredicate(c));
11159
+ return condition.type === "and" ? (row) => {
11160
+ for (const predicate of predicates) {
11161
+ if (!predicate(row)) {
11162
+ return false;
11163
+ }
11164
+ }
11165
+ return true;
11166
+ } : (row) => {
11167
+ for (const predicate of predicates) {
11168
+ if (predicate(row)) {
11169
+ return true;
11170
+ }
11171
+ }
11172
+ return false;
11173
+ };
11174
+ }
11053
11175
  const { left } = condition;
11054
11176
  const { right } = condition;
11055
11177
  assert(
@@ -11115,11 +11237,11 @@ function createPredicateImpl(rhs, operator) {
11115
11237
  case "LIKE":
11116
11238
  return getLikePredicate(rhs, "");
11117
11239
  case "NOT LIKE":
11118
- return not(getLikePredicate(rhs, ""));
11240
+ return not2(getLikePredicate(rhs, ""));
11119
11241
  case "ILIKE":
11120
11242
  return getLikePredicate(rhs, "i");
11121
11243
  case "NOT ILIKE":
11122
- return not(getLikePredicate(rhs, "i"));
11244
+ return not2(getLikePredicate(rhs, "i"));
11123
11245
  case "IN": {
11124
11246
  assert(Array.isArray(rhs));
11125
11247
  const set = new Set(rhs);
@@ -11135,74 +11257,71 @@ function createPredicateImpl(rhs, operator) {
11135
11257
  throw new Error(`Unexpected operator: ${operator}`);
11136
11258
  }
11137
11259
  }
11138
- function not(f) {
11260
+ function not2(f) {
11139
11261
  return (lhs) => !f(lhs);
11140
11262
  }
11141
-
11142
- // ../zql/src/builder/builder.ts
11143
- function buildPipeline(ast, delegate, staticQueryParameters) {
11144
- return buildPipelineInternal(
11145
- bindStaticParameters(ast, staticQueryParameters),
11146
- delegate,
11147
- staticQueryParameters
11148
- );
11149
- }
11150
- function bindStaticParameters(ast, staticQueryParameters) {
11151
- const visit = (node) => {
11152
- if (node.where) {
11153
- return {
11154
- ...node,
11155
- where: bindCondition(node.where),
11156
- related: node.related?.map((sq) => ({
11157
- ...sq,
11158
- subquery: visit(sq.subquery)
11159
- }))
11160
- };
11161
- }
11162
- return node;
11163
- };
11164
- function bindCondition(condition) {
11165
- if (condition.type === "simple") {
11263
+ function transformFilters(filters) {
11264
+ if (!filters) {
11265
+ return { filters: void 0, conditionsRemoved: false };
11266
+ }
11267
+ switch (filters.type) {
11268
+ case "simple":
11269
+ return { filters, conditionsRemoved: false };
11270
+ case "correlatedSubquery":
11271
+ return { filters: void 0, conditionsRemoved: true };
11272
+ case "and": {
11273
+ const transformedConditions = [];
11274
+ for (const cond of filters.conditions) {
11275
+ assert(cond.type === "simple" || cond.type === "correlatedSubquery");
11276
+ if (cond.type === "simple") {
11277
+ transformedConditions.push(cond);
11278
+ }
11279
+ }
11280
+ const conditionsRemoved = transformedConditions.length !== filters.conditions.length;
11281
+ if (transformedConditions.length === 0) {
11282
+ return { filters: void 0, conditionsRemoved };
11283
+ }
11284
+ if (transformedConditions.length === 1) {
11285
+ return {
11286
+ filters: transformedConditions[0],
11287
+ conditionsRemoved
11288
+ };
11289
+ }
11166
11290
  return {
11167
- ...condition,
11168
- left: bindValue(condition.left),
11169
- right: bindValue(condition.right)
11291
+ filters: {
11292
+ type: "and",
11293
+ conditions: transformedConditions
11294
+ },
11295
+ conditionsRemoved
11170
11296
  };
11171
11297
  }
11172
- if (condition.type === "correlatedSubquery") {
11173
- return {
11174
- ...condition,
11175
- related: {
11176
- ...condition.related,
11177
- subquery: visit(condition.related.subquery)
11298
+ case "or": {
11299
+ const transformedConditions = [];
11300
+ let conditionsRemoved = false;
11301
+ for (const cond of filters.conditions) {
11302
+ assert(cond.type !== "or");
11303
+ const transformed = transformFilters(cond);
11304
+ if (transformed.filters === void 0) {
11305
+ return { filters: void 0, conditionsRemoved: true };
11178
11306
  }
11179
- };
11180
- }
11181
- return {
11182
- ...condition,
11183
- conditions: condition.conditions.map(bindCondition)
11184
- };
11185
- }
11186
- const bindValue = (value) => {
11187
- if (isParameter(value)) {
11188
- const anchor = must(
11189
- staticQueryParameters,
11190
- "Static query params do not exist"
11191
- )[value.anchor];
11192
- const resolvedValue = anchor?.[value.field] ?? null;
11307
+ conditionsRemoved = conditionsRemoved || transformed.conditionsRemoved;
11308
+ transformedConditions.push(transformed.filters);
11309
+ }
11193
11310
  return {
11194
- type: "literal",
11195
- value: resolvedValue
11311
+ filters: { type: "or", conditions: transformedConditions },
11312
+ conditionsRemoved
11196
11313
  };
11197
11314
  }
11198
- return value;
11199
- };
11200
- return visit(ast);
11315
+ default:
11316
+ unreachable(filters);
11317
+ }
11201
11318
  }
11202
- function isParameter(value) {
11203
- return value.type === "static";
11319
+
11320
+ // ../zql/src/builder/builder.ts
11321
+ function buildPipeline(ast, delegate) {
11322
+ return buildPipelineInternal(ast, delegate);
11204
11323
  }
11205
- function buildPipelineInternal(ast, delegate, staticQueryParameters, partitionKey) {
11324
+ function buildPipelineInternal(ast, delegate, partitionKey) {
11206
11325
  const source = delegate.getSource(ast.table);
11207
11326
  if (!source) {
11208
11327
  throw new Error(`Source not found: ${ast.table}`);
@@ -11215,17 +11334,22 @@ function buildPipelineInternal(ast, delegate, staticQueryParameters, partitionKe
11215
11334
  end = new Skip(end, ast.start);
11216
11335
  }
11217
11336
  for (const csq of gatherCorrelatedSubqueryQueriesFromCondition(ast.where)) {
11218
- end = applyCorrelatedSubQuery(csq, delegate, staticQueryParameters, end);
11337
+ end = applyCorrelatedSubQuery(csq, delegate, end);
11219
11338
  }
11220
11339
  if (ast.where) {
11221
11340
  end = applyWhere(end, ast.where, appliedFilters, delegate);
11222
11341
  }
11223
11342
  if (ast.limit) {
11224
- end = new Take(end, delegate.createStorage(), ast.limit, partitionKey);
11343
+ end = new Take(
11344
+ end,
11345
+ delegate.createStorage(),
11346
+ ast.limit,
11347
+ partitionKey === void 0 ? void 0 : [partitionKey]
11348
+ );
11225
11349
  }
11226
11350
  if (ast.related) {
11227
11351
  for (const csq of ast.related) {
11228
- end = applyCorrelatedSubQuery(csq, delegate, staticQueryParameters, end);
11352
+ end = applyCorrelatedSubQuery(csq, delegate, end);
11229
11353
  }
11230
11354
  }
11231
11355
  return end;
@@ -11262,20 +11386,20 @@ function applySimpleCondition(input, condition, appliedFilters) {
11262
11386
  createPredicate(condition)
11263
11387
  );
11264
11388
  }
11265
- function applyCorrelatedSubQuery(sq, delegate, staticQueryParameters, end) {
11389
+ function applyCorrelatedSubQuery(sq, delegate, end) {
11266
11390
  assert(sq.subquery.alias, "Subquery must have an alias");
11267
11391
  const child = buildPipelineInternal(
11268
11392
  sq.subquery,
11269
11393
  delegate,
11270
- staticQueryParameters,
11271
11394
  sq.correlation.childField
11272
11395
  );
11273
11396
  end = new Join({
11274
11397
  parent: end,
11275
11398
  child,
11276
11399
  storage: delegate.createStorage(),
11277
- parentKey: sq.correlation.parentField,
11278
- childKey: sq.correlation.childField,
11400
+ // TODO: Compound keys in the AST
11401
+ parentKey: [sq.correlation.parentField],
11402
+ childKey: [sq.correlation.childField],
11279
11403
  relationshipName: sq.subquery.alias,
11280
11404
  hidden: sq.hidden ?? false
11281
11405
  });
@@ -11412,196 +11536,44 @@ var ArrayView = class {
11412
11536
  addListener(listener) {
11413
11537
  assert(!this.#listeners.has(listener), "Listener already registered");
11414
11538
  this.#listeners.add(listener);
11415
- listener(this.data);
11416
- return () => {
11417
- this.#listeners.delete(listener);
11418
- };
11419
- }
11420
- #fireListeners() {
11421
- for (const listener of this.#listeners) {
11422
- listener(this.data);
11423
- }
11424
- }
11425
- destroy() {
11426
- this.onDestroy?.();
11427
- }
11428
- #hydrate() {
11429
- this.#dirty = true;
11430
- for (const node of this.#input.fetch({})) {
11431
- applyChange(
11432
- this.#root,
11433
- { type: "add", node },
11434
- this.#schema,
11435
- "",
11436
- this.#format
11437
- );
11438
- }
11439
- this.flush();
11440
- }
11441
- push(change) {
11442
- this.#dirty = true;
11443
- applyChange(this.#root, change, this.#schema, "", this.#format);
11444
- }
11445
- flush() {
11446
- if (!this.#dirty) {
11447
- return;
11448
- }
11449
- this.#dirty = false;
11450
- this.#fireListeners();
11451
- }
11452
- };
11453
-
11454
- // ../zql/src/query/expression.ts
11455
- var ExpressionBuilder = class {
11456
- #exists;
11457
- constructor(exists) {
11458
- this.#exists = exists;
11459
- this.exists = this.exists.bind(this);
11460
- }
11461
- get eb() {
11462
- return this;
11463
- }
11464
- cmp(field, opOrValue, value) {
11465
- return cmp(field, opOrValue, value);
11466
- }
11467
- cmpLit(left, op, right) {
11468
- return {
11469
- type: "simple",
11470
- left: isParameter2(left) ? left : { type: "literal", value: left },
11471
- right: isParameter2(right) ? right : { type: "literal", value: right },
11472
- op
11473
- };
11474
- }
11475
- and = and;
11476
- or = or;
11477
- not = not2;
11478
- exists(relationship, cb) {
11479
- return this.#exists(relationship, cb);
11480
- }
11481
- };
11482
- function and(...conditions) {
11483
- const expressions = filterTrue(filterUndefined(conditions));
11484
- if (expressions.length === 1) {
11485
- return expressions[0];
11486
- }
11487
- if (expressions.some(isAlwaysFalse)) {
11488
- return FALSE;
11539
+ listener(this.data);
11540
+ return () => {
11541
+ this.#listeners.delete(listener);
11542
+ };
11489
11543
  }
11490
- return { type: "and", conditions: expressions };
11491
- }
11492
- function or(...conditions) {
11493
- const expressions = filterFalse(filterUndefined(conditions));
11494
- if (expressions.length === 1) {
11495
- return expressions[0];
11544
+ #fireListeners() {
11545
+ for (const listener of this.#listeners) {
11546
+ listener(this.data);
11547
+ }
11496
11548
  }
11497
- if (expressions.some(isAlwaysTrue)) {
11498
- return TRUE;
11549
+ destroy() {
11550
+ this.onDestroy?.();
11499
11551
  }
11500
- return { type: "or", conditions: expressions };
11501
- }
11502
- function not2(expression) {
11503
- switch (expression.type) {
11504
- case "and":
11505
- return {
11506
- type: "or",
11507
- conditions: expression.conditions.map(not2)
11508
- };
11509
- case "or":
11510
- return {
11511
- type: "and",
11512
- conditions: expression.conditions.map(not2)
11513
- };
11514
- case "correlatedSubquery":
11515
- return {
11516
- type: "correlatedSubquery",
11517
- related: expression.related,
11518
- op: negateOperator(expression.op)
11519
- };
11520
- case "simple":
11521
- return {
11522
- type: "simple",
11523
- op: negateOperator(expression.op),
11524
- left: expression.left,
11525
- right: expression.right
11526
- };
11552
+ #hydrate() {
11553
+ this.#dirty = true;
11554
+ for (const node of this.#input.fetch({})) {
11555
+ applyChange(
11556
+ this.#root,
11557
+ { type: "add", node },
11558
+ this.#schema,
11559
+ "",
11560
+ this.#format
11561
+ );
11562
+ }
11563
+ this.flush();
11527
11564
  }
11528
- }
11529
- function cmp(field, opOrValue, value) {
11530
- let op;
11531
- if (value === void 0) {
11532
- value = opOrValue;
11533
- op = "=";
11534
- } else {
11535
- op = opOrValue;
11565
+ push(change) {
11566
+ this.#dirty = true;
11567
+ applyChange(this.#root, change, this.#schema, "", this.#format);
11536
11568
  }
11537
- return {
11538
- type: "simple",
11539
- left: { type: "column", name: field },
11540
- right: isParameter2(value) ? value : { type: "literal", value },
11541
- op
11542
- };
11543
- }
11544
- function isParameter2(value) {
11545
- return typeof value === "object" && value?.type === "static";
11546
- }
11547
- var TRUE = {
11548
- type: "and",
11549
- conditions: []
11550
- };
11551
- var FALSE = {
11552
- type: "or",
11553
- conditions: []
11554
- };
11555
- function isAlwaysTrue(condition) {
11556
- return condition.type === "and" && condition.conditions.length === 0;
11557
- }
11558
- function isAlwaysFalse(condition) {
11559
- return condition.type === "or" && condition.conditions.length === 0;
11560
- }
11561
- function flatten(type, conditions) {
11562
- const flattened2 = [];
11563
- for (const c of conditions) {
11564
- if (c.type === type) {
11565
- flattened2.push(...c.conditions);
11566
- } else {
11567
- flattened2.push(c);
11569
+ flush() {
11570
+ if (!this.#dirty) {
11571
+ return;
11568
11572
  }
11573
+ this.#dirty = false;
11574
+ this.#fireListeners();
11569
11575
  }
11570
- return flattened2;
11571
- }
11572
- var negateSimpleOperatorMap = {
11573
- ["="]: "!=",
11574
- ["!="]: "=",
11575
- ["<"]: ">=",
11576
- [">"]: "<=",
11577
- [">="]: "<",
11578
- ["<="]: ">",
11579
- ["IN"]: "NOT IN",
11580
- ["NOT IN"]: "IN",
11581
- ["LIKE"]: "NOT LIKE",
11582
- ["NOT LIKE"]: "LIKE",
11583
- ["ILIKE"]: "NOT ILIKE",
11584
- ["NOT ILIKE"]: "ILIKE",
11585
- ["IS"]: "IS NOT",
11586
- ["IS NOT"]: "IS"
11587
- };
11588
- var negateOperatorMap = {
11589
- ...negateSimpleOperatorMap,
11590
- ["EXISTS"]: "NOT EXISTS",
11591
- ["NOT EXISTS"]: "EXISTS"
11592
11576
  };
11593
- function negateOperator(op) {
11594
- return must(negateOperatorMap[op]);
11595
- }
11596
- function filterUndefined(array9) {
11597
- return array9.filter((e) => e !== void 0);
11598
- }
11599
- function filterTrue(conditions) {
11600
- return conditions.filter((c) => !isAlwaysTrue(c));
11601
- }
11602
- function filterFalse(conditions) {
11603
- return conditions.filter((c) => !isAlwaysFalse(c));
11604
- }
11605
11577
 
11606
11578
  // ../zql/src/query/dnf.ts
11607
11579
  function dnf(condition) {
@@ -11757,7 +11729,7 @@ var AbstractQuery = class {
11757
11729
  }
11758
11730
  if (isJunctionRelationship(junctionRelationship)) {
11759
11731
  const destSchema = junctionRelationship.dest.schema;
11760
- const junctionSchema = junctionRelationship.junction.schema;
11732
+ const junctionSchema = junctionRelationship.junction.dest.schema;
11761
11733
  const sq = cb(
11762
11734
  this._newQuery(
11763
11735
  destSchema,
@@ -11777,7 +11749,7 @@ var AbstractQuery = class {
11777
11749
  {
11778
11750
  correlation: {
11779
11751
  parentField: junctionRelationship.source,
11780
- childField: junctionRelationship.junction.sourceField,
11752
+ childField: junctionRelationship.junction.source,
11781
11753
  op: "="
11782
11754
  },
11783
11755
  subquery: {
@@ -11787,7 +11759,7 @@ var AbstractQuery = class {
11787
11759
  related: [
11788
11760
  {
11789
11761
  correlation: {
11790
- parentField: junctionRelationship.junction.destField,
11762
+ parentField: junctionRelationship.junction.dest.field,
11791
11763
  childField: junctionRelationship.dest.field,
11792
11764
  op: "="
11793
11765
  },
@@ -11813,7 +11785,7 @@ var AbstractQuery = class {
11813
11785
  where(fieldOrExpressionFactory, opOrValue, value) {
11814
11786
  let cond;
11815
11787
  if (typeof fieldOrExpressionFactory === "function") {
11816
- cond = fieldOrExpressionFactory(new ExpressionBuilder(this.#exists));
11788
+ cond = fieldOrExpressionFactory(new ExpressionBuilder(this._exists));
11817
11789
  } else {
11818
11790
  assert(opOrValue !== void 0, "Invalid condition");
11819
11791
  cond = cmp(fieldOrExpressionFactory, opOrValue, value);
@@ -11870,7 +11842,7 @@ var AbstractQuery = class {
11870
11842
  this.#format
11871
11843
  );
11872
11844
  }
11873
- #exists = (relationship, cb = (q) => q) => {
11845
+ _exists = (relationship, cb = (q) => q) => {
11874
11846
  const related = this.#schema.relationships[relationship];
11875
11847
  assert(related, "Invalid relationship");
11876
11848
  const fieldRelationship = related;
@@ -11902,7 +11874,7 @@ var AbstractQuery = class {
11902
11874
  }
11903
11875
  if (isJunctionRelationship(junctionRelationship)) {
11904
11876
  const destSchema = junctionRelationship.dest.schema;
11905
- const junctionSchema = junctionRelationship.junction.schema;
11877
+ const junctionSchema = junctionRelationship.junction.dest.schema;
11906
11878
  const queryToDest = cb(
11907
11879
  this._newQuery(
11908
11880
  destSchema,
@@ -11918,7 +11890,7 @@ var AbstractQuery = class {
11918
11890
  related: {
11919
11891
  correlation: {
11920
11892
  parentField: junctionRelationship.source,
11921
- childField: junctionRelationship.junction.sourceField,
11893
+ childField: junctionRelationship.junction.source,
11922
11894
  op: "="
11923
11895
  },
11924
11896
  subquery: {
@@ -11929,7 +11901,7 @@ var AbstractQuery = class {
11929
11901
  type: "correlatedSubquery",
11930
11902
  related: {
11931
11903
  correlation: {
11932
- parentField: junctionRelationship.junction.destField,
11904
+ parentField: junctionRelationship.junction.dest.field,
11933
11905
  childField: junctionRelationship.dest.field,
11934
11906
  op: "="
11935
11907
  },
@@ -11973,6 +11945,7 @@ var AbstractQuery = class {
11973
11945
  }
11974
11946
  };
11975
11947
  var astForTestingSymbol = Symbol();
11948
+ var completedAstSymbol = Symbol();
11976
11949
  var QueryImpl = class extends AbstractQuery {
11977
11950
  #delegate;
11978
11951
  #ast;
@@ -11985,13 +11958,16 @@ var QueryImpl = class extends AbstractQuery {
11985
11958
  get [astForTestingSymbol]() {
11986
11959
  return this.#ast;
11987
11960
  }
11961
+ get [completedAstSymbol]() {
11962
+ return this._completeAst();
11963
+ }
11988
11964
  _newQuery(schema, ast, format) {
11989
11965
  return newQueryWithDetails(this.#delegate, schema, ast, format);
11990
11966
  }
11991
11967
  materialize(factory) {
11992
11968
  const ast = this._completeAst();
11993
11969
  const removeServerQuery = this.#delegate.addServerQuery(ast);
11994
- const input = buildPipeline(ast, this.#delegate, void 0);
11970
+ const input = buildPipeline(ast, this.#delegate);
11995
11971
  let removeCommitObserver;
11996
11972
  const onDestroy = () => {
11997
11973
  input.destroy();
@@ -12060,6 +12036,9 @@ var AuthQuery = class _AuthQuery extends AbstractQuery {
12060
12036
  constructor(schema, ast = { table: schema.tableName }, format) {
12061
12037
  super(schema, ast, format);
12062
12038
  }
12039
+ expressionBuilder() {
12040
+ return new ExpressionBuilder(this._exists);
12041
+ }
12063
12042
  _newQuery(schema, ast, format) {
12064
12043
  return new _AuthQuery(schema, ast, format);
12065
12044
  }
@@ -12080,62 +12059,74 @@ var AuthQuery = class _AuthQuery extends AbstractQuery {
12080
12059
  // ../zero-schema/src/authorization.ts
12081
12060
  async function defineAuthorization(schema, definer) {
12082
12061
  const normalizedSchema = normalizeSchema(schema);
12083
- const queries = {};
12062
+ const expressionBuilders = {};
12084
12063
  for (const [name, tableSchema] of Object.entries(normalizedSchema.tables)) {
12085
- queries[name] = new AuthQuery(tableSchema);
12064
+ expressionBuilders[name] = new AuthQuery(tableSchema).expressionBuilder();
12086
12065
  }
12087
- const config = await definer(queries);
12088
- return compileAuthorization(config);
12066
+ const config = await definer();
12067
+ return compileAuthorization(config, expressionBuilders);
12089
12068
  }
12090
- function compileAuthorization(authz) {
12069
+ function compileAuthorization(authz, expressionBuilders) {
12091
12070
  if (!authz) {
12092
12071
  return void 0;
12093
12072
  }
12094
12073
  const ret = {};
12095
12074
  for (const [tableName, tableConfig] of Object.entries(authz)) {
12096
12075
  ret[tableName] = {
12097
- row: compileRowConfig(tableConfig.row),
12098
- cell: compileCellConfig(tableConfig.cell)
12076
+ row: compileRowConfig(tableConfig.row, expressionBuilders[tableName]),
12077
+ cell: compileCellConfig(tableConfig.cell, expressionBuilders[tableName])
12099
12078
  };
12100
12079
  }
12101
12080
  return ret;
12102
12081
  }
12103
- function compileRowConfig(rowRules) {
12082
+ function compileRowConfig(rowRules, expressionBuilder) {
12104
12083
  if (!rowRules) {
12105
12084
  return void 0;
12106
12085
  }
12107
12086
  return {
12108
- select: compileRules(rowRules.select),
12109
- insert: compileRules(rowRules.insert),
12110
- update: compileRules(rowRules.update),
12111
- delete: compileRules(rowRules.delete)
12087
+ select: compileRules(rowRules.select, expressionBuilder),
12088
+ insert: compileRules(rowRules.insert, expressionBuilder),
12089
+ update: {
12090
+ preMutation: compileRules(
12091
+ rowRules.update?.preMutation,
12092
+ expressionBuilder
12093
+ ),
12094
+ postProposedMutation: compileRules(
12095
+ rowRules.update?.postProposedMutation,
12096
+ expressionBuilder
12097
+ )
12098
+ },
12099
+ delete: compileRules(rowRules.delete, expressionBuilder)
12112
12100
  };
12113
12101
  }
12114
- function compileRules(rules) {
12102
+ function compileRules(rules, expressionBuilder) {
12115
12103
  if (!rules) {
12116
12104
  return void 0;
12117
12105
  }
12118
12106
  return rules.map(
12119
12107
  (rule) => [
12120
12108
  "allow",
12121
- rule(
12122
- authDataRef,
12123
- preMutationRowRef
12124
- ).ast
12109
+ rule(authDataRef, expressionBuilder)
12125
12110
  ]
12126
12111
  );
12127
12112
  }
12128
- function compileCellConfig(cellRules) {
12113
+ function compileCellConfig(cellRules, expressionBuilder) {
12129
12114
  if (!cellRules) {
12130
12115
  return void 0;
12131
12116
  }
12132
12117
  const ret = {};
12133
12118
  for (const [columnName, rules] of Object.entries(cellRules)) {
12134
12119
  ret[columnName] = {
12135
- select: compileRules(rules.select),
12136
- insert: compileRules(rules.insert),
12137
- update: compileRules(rules.update),
12138
- delete: compileRules(rules.delete)
12120
+ select: compileRules(rules.select, expressionBuilder),
12121
+ insert: compileRules(rules.insert, expressionBuilder),
12122
+ update: {
12123
+ preMutation: compileRules(rules.update?.preMutation, expressionBuilder),
12124
+ postProposedMutation: compileRules(
12125
+ rules.update?.postProposedMutation,
12126
+ expressionBuilder
12127
+ )
12128
+ },
12129
+ delete: compileRules(rules.delete, expressionBuilder)
12139
12130
  };
12140
12131
  }
12141
12132
  return ret;
@@ -12168,7 +12159,7 @@ function escapeLike(val) {
12168
12159
  }
12169
12160
 
12170
12161
  // ../zero-client/src/client/zero.ts
12171
- import { LogContext as LogContext3 } from "@rocicorp/logger";
12162
+ import { LogContext as LogContext4 } from "@rocicorp/logger";
12172
12163
  import { resolver as resolver8 } from "@rocicorp/resolver";
12173
12164
 
12174
12165
  // ../zero-protocol/src/queries-patch.ts
@@ -12312,10 +12303,14 @@ var pokeStartBodySchema = valita_exports.object({
12312
12303
  // able to send a base cookie with value `null` to match that state.
12313
12304
  baseCookie: nullableVersionSchema,
12314
12305
  cookie: versionSchema,
12306
+ /**
12307
+ * This field is always set if the poke contains a `rowsPatch`.
12308
+ * It may be absent for patches that only update clients and queries.
12309
+ */
12315
12310
  schemaVersions: valita_exports.object({
12316
12311
  minSupportedVersion: valita_exports.number(),
12317
12312
  maxSupportedVersion: valita_exports.number()
12318
- }),
12313
+ }).optional(),
12319
12314
  timestamp: valita_exports.number().optional()
12320
12315
  });
12321
12316
  var pokePartBodySchema = valita_exports.object({
@@ -14117,6 +14112,29 @@ var EmptyBTree = (() => {
14117
14112
  return t2;
14118
14113
  })();
14119
14114
 
14115
+ // ../zql/src/ivm/constraint.ts
14116
+ function constraintMatchesRow(constraint, row) {
14117
+ for (const [key, value] of Object.entries(constraint)) {
14118
+ if (!valuesEqual(row[key], value)) {
14119
+ return false;
14120
+ }
14121
+ }
14122
+ return true;
14123
+ }
14124
+ function constraintMatchesPrimaryKey(constraint, primary) {
14125
+ const constraintKeys = Object.keys(constraint);
14126
+ if (constraintKeys.length !== primary.length) {
14127
+ return false;
14128
+ }
14129
+ constraintKeys.sort(stringCompare);
14130
+ for (let i = 0; i < constraintKeys.length; i++) {
14131
+ if (constraintKeys[i][0] !== primary[i]) {
14132
+ return false;
14133
+ }
14134
+ }
14135
+ return true;
14136
+ }
14137
+
14120
14138
  // ../zql/src/ivm/lookahead-iterator.ts
14121
14139
  var LookaheadIterator = class {
14122
14140
  #iter;
@@ -14200,8 +14218,7 @@ var MemorySource = class {
14200
14218
  };
14201
14219
  }
14202
14220
  connect(sort, optionalFilters) {
14203
- const filteredOptionalFilters = filterOptionalFilters(optionalFilters);
14204
- const predicates = filteredOptionalFilters.filters.map((c) => createPredicate(c));
14221
+ const transformedFilters = transformFilters(optionalFilters);
14205
14222
  const input = {
14206
14223
  getSchema: () => schema,
14207
14224
  fetch: (req) => this.#fetch(req, connection),
@@ -14212,14 +14229,17 @@ var MemorySource = class {
14212
14229
  destroy: () => {
14213
14230
  this.#disconnect(input);
14214
14231
  },
14215
- appliedFilters: filteredOptionalFilters.allApplied
14232
+ appliedFilters: !transformedFilters.conditionsRemoved
14216
14233
  };
14217
14234
  const connection = {
14218
14235
  input,
14219
14236
  output: void 0,
14220
14237
  sort,
14221
14238
  compareRows: makeComparator(sort),
14222
- optionalFilters: predicates
14239
+ filters: transformedFilters.filters ? {
14240
+ condition: transformedFilters.filters,
14241
+ predicate: createPredicate(transformedFilters.filters)
14242
+ } : void 0
14223
14243
  };
14224
14244
  const schema = this.#getSchema(connection);
14225
14245
  assertOrderingIncludesPK(sort, this.#primaryKey);
@@ -14275,9 +14295,11 @@ var MemorySource = class {
14275
14295
  const { sort: requestedSort } = conn;
14276
14296
  const indexSort = [];
14277
14297
  if (req.constraint) {
14278
- indexSort.push([req.constraint.key, "asc"]);
14298
+ for (const key of Object.keys(req.constraint)) {
14299
+ indexSort.push([key, "asc"]);
14300
+ }
14279
14301
  }
14280
- if (this.#primaryKey.length > 1 || req.constraint?.key !== this.#primaryKey[0]) {
14302
+ if (this.#primaryKey.length > 1 || !req.constraint || !constraintMatchesPrimaryKey(req.constraint, this.#primaryKey)) {
14281
14303
  indexSort.push(...requestedSort);
14282
14304
  }
14283
14305
  const index = this.#getOrCreateIndex(indexSort, from);
@@ -14287,20 +14309,10 @@ var MemorySource = class {
14287
14309
  overlay = this.#overlay;
14288
14310
  }
14289
14311
  }
14290
- const matchesConstraint = (row) => {
14291
- if (!req.constraint) {
14292
- return true;
14293
- }
14294
- const { key, value } = req.constraint;
14295
- return valuesEqual(row[key], value);
14296
- };
14297
- const matchesFilters = (row) => conn.optionalFilters.every((f) => f(row));
14298
- const matchesConstraintAndFilters = (row) => matchesConstraint(row) && matchesFilters(row);
14299
- if (overlay) {
14300
- if (!matchesConstraintAndFilters(overlay.change.row)) {
14301
- overlay = void 0;
14302
- }
14303
- }
14312
+ const { constraint } = req;
14313
+ const matchesConstraint = constraint ? (row) => constraintMatchesRow(constraint, row) : (_) => true;
14314
+ const predicate = conn.filters?.predicate;
14315
+ const matchesConstraintAndFilters = predicate ? (row) => matchesConstraint(row) && predicate(row) : matchesConstraint;
14304
14316
  const nextLowerKey = (row) => {
14305
14317
  if (!row) {
14306
14318
  return void 0;
@@ -14325,9 +14337,7 @@ var MemorySource = class {
14325
14337
  let startAt = req.start?.row;
14326
14338
  if (startAt) {
14327
14339
  if (req.constraint) {
14328
- if (!matchesConstraint(startAt)) {
14329
- assert(false, "Start row must match constraint");
14330
- }
14340
+ assert(matchesConstraint(startAt), "Start row must match constraint");
14331
14341
  }
14332
14342
  if (req.start.basis === "before") {
14333
14343
  startAt = nextLowerKey(startAt);
@@ -14337,8 +14347,8 @@ var MemorySource = class {
14337
14347
  if (req.constraint) {
14338
14348
  scanStart = {};
14339
14349
  for (const [key, dir] of indexSort) {
14340
- if (key === req.constraint.key) {
14341
- scanStart[key] = req.constraint.value;
14350
+ if (hasOwn(req.constraint, key)) {
14351
+ scanStart[key] = req.constraint[key];
14342
14352
  } else {
14343
14353
  scanStart[key] = dir === "asc" ? minValue : maxValue;
14344
14354
  }
@@ -14353,13 +14363,14 @@ var MemorySource = class {
14353
14363
  data.keys(scanStart),
14354
14364
  req.constraint,
14355
14365
  overlay,
14356
- comparator
14366
+ comparator,
14367
+ conn.filters?.predicate
14357
14368
  );
14358
14369
  const withConstraint = generateWithConstraint(
14359
14370
  generateWithStart(withOverlay, req, comparator),
14360
14371
  req.constraint
14361
14372
  );
14362
- yield* conn.optionalFilters.length ? generateWithFilter(withConstraint, matchesFilters) : withConstraint;
14373
+ yield* conn.filters ? generateWithFilter(withConstraint, conn.filters.predicate) : withConstraint;
14363
14374
  }
14364
14375
  #cleanup(req, connection) {
14365
14376
  return this.#fetch(req, connection);
@@ -14386,7 +14397,17 @@ var MemorySource = class {
14386
14397
  default:
14387
14398
  unreachable(change);
14388
14399
  }
14389
- const outputChange = change.type === "edit" ? change : {
14400
+ const outputChange = change.type === "edit" ? {
14401
+ type: change.type,
14402
+ oldNode: {
14403
+ row: change.oldRow,
14404
+ relationships: {}
14405
+ },
14406
+ node: {
14407
+ row: change.row,
14408
+ relationships: {}
14409
+ }
14410
+ } : {
14390
14411
  type: change.type,
14391
14412
  node: {
14392
14413
  row: change.row,
@@ -14426,7 +14447,7 @@ var MemorySource = class {
14426
14447
  };
14427
14448
  function* generateWithConstraint(it, constraint) {
14428
14449
  for (const node of it) {
14429
- if (constraint && !valuesEqual(node.row[constraint.key], constraint.value)) {
14450
+ if (constraint && !constraintMatchesRow(constraint, node.row)) {
14430
14451
  break;
14431
14452
  }
14432
14453
  yield node;
@@ -14464,11 +14485,17 @@ function* generateWithStart(it, req, compare) {
14464
14485
  }
14465
14486
  }
14466
14487
  }
14467
- function* generateWithOverlay(startAt, rows, constraint, overlay, compare) {
14468
- const overlays = computeOverlays(startAt, constraint, overlay, compare);
14488
+ function* generateWithOverlay(startAt, rows, constraint, overlay, compare, filterPredicate) {
14489
+ const overlays = computeOverlays(
14490
+ startAt,
14491
+ constraint,
14492
+ overlay,
14493
+ compare,
14494
+ filterPredicate
14495
+ );
14469
14496
  yield* generateWithOverlayInner(rows, overlays, compare);
14470
14497
  }
14471
- function computeOverlays(startAt, constraint, overlay, compare) {
14498
+ function computeOverlays(startAt, constraint, overlay, compare, filterPredicate) {
14472
14499
  let overlays = {
14473
14500
  add: void 0,
14474
14501
  remove: void 0
@@ -14499,6 +14526,9 @@ function computeOverlays(startAt, constraint, overlay, compare) {
14499
14526
  if (constraint) {
14500
14527
  overlays = overlaysForConstraint(overlays, constraint);
14501
14528
  }
14529
+ if (filterPredicate) {
14530
+ overlays = overlaysForFilterPredicate(overlays, filterPredicate);
14531
+ }
14502
14532
  return overlays;
14503
14533
  }
14504
14534
  function overlaysForStartAt({ add, remove }, startAt, compare) {
@@ -14509,12 +14539,19 @@ function overlaysForStartAt({ add, remove }, startAt, compare) {
14509
14539
  };
14510
14540
  }
14511
14541
  function overlaysForConstraint({ add, remove }, constraint) {
14512
- const undefinedIfDoesntMatchConstraint = (row) => row === void 0 || !valuesEqual(row[constraint.key], constraint.value) ? void 0 : row;
14542
+ const undefinedIfDoesntMatchConstraint = (row) => row === void 0 || !constraintMatchesRow(constraint, row) ? void 0 : row;
14513
14543
  return {
14514
14544
  add: undefinedIfDoesntMatchConstraint(add),
14515
14545
  remove: undefinedIfDoesntMatchConstraint(remove)
14516
14546
  };
14517
14547
  }
14548
+ function overlaysForFilterPredicate({ add, remove }, filterPredicate) {
14549
+ const undefinedIfDoesntMatchFilter = (row) => row === void 0 || !filterPredicate(row) ? void 0 : row;
14550
+ return {
14551
+ add: undefinedIfDoesntMatchFilter(add),
14552
+ remove: undefinedIfDoesntMatchFilter(remove)
14553
+ };
14554
+ }
14518
14555
  function* generateWithOverlayInner(rowIterator, overlays, compare) {
14519
14556
  let addOverlayYielded = false;
14520
14557
  let removeOverlaySkipped = false;
@@ -14571,33 +14608,6 @@ function compareBounds(a, b) {
14571
14608
  }
14572
14609
  return compareValues(a, b);
14573
14610
  }
14574
- function filterOptionalFilters(optionalFilters) {
14575
- if (optionalFilters) {
14576
- if (optionalFilters.type === "or" && optionalFilters.conditions.length === 1) {
14577
- optionalFilters = optionalFilters.conditions[0];
14578
- }
14579
- if (optionalFilters.type === "and") {
14580
- const filters = optionalFilters.conditions.filter(
14581
- (c) => c.type === "simple"
14582
- );
14583
- return {
14584
- filters,
14585
- allApplied: filters.length === optionalFilters.conditions.length
14586
- };
14587
- }
14588
- if (optionalFilters.type === "simple") {
14589
- return {
14590
- filters: [optionalFilters],
14591
- allApplied: true
14592
- };
14593
- }
14594
- return { filters: [], allApplied: false };
14595
- }
14596
- return {
14597
- filters: [],
14598
- allApplied: true
14599
- };
14600
- }
14601
14611
 
14602
14612
  // ../zql/src/ivm/memory-storage.ts
14603
14613
  var MemoryStorage = class {
@@ -15236,7 +15246,7 @@ function makeMessage(message, context, logLevel) {
15236
15246
  }
15237
15247
 
15238
15248
  // ../zero-client/src/client/version.ts
15239
- var version2 = "0.6.2024112102+391068";
15249
+ var version2 = "0.7.2024112700+dfe437";
15240
15250
 
15241
15251
  // ../zero-client/src/client/log-options.ts
15242
15252
  var LevelFilterLogSink = class {
@@ -15522,6 +15532,9 @@ var State = class {
15522
15532
  }
15523
15533
  };
15524
15534
 
15535
+ // ../zero-client/src/client/protocol-version.ts
15536
+ var PROTOCOL_VERSION = 1;
15537
+
15525
15538
  // ../zero-client/src/client/query-manager.ts
15526
15539
  var QueryManager = class {
15527
15540
  #clientID;
@@ -15660,24 +15673,90 @@ var QueryManager = class {
15660
15673
  };
15661
15674
 
15662
15675
  // ../zero-client/src/client/reload-error-handler.ts
15676
+ import "@rocicorp/logger";
15663
15677
  var RELOAD_REASON_STORAGE_KEY = "_zeroReloadReason";
15678
+ var RELOAD_BACKOFF_STATE_KEY = "_zeroReloadBackoffState";
15679
+ var backoffStateSchema = valita_exports.object({
15680
+ lastReloadTime: valita_exports.number().default(0),
15681
+ nextIntervalMs: valita_exports.number().default(0)
15682
+ });
15683
+ var MIN_RELOAD_INTERVAL_MS = 500;
15684
+ var MAX_RELOAD_INTERVAL_MS = 6e4;
15685
+ var FALLBACK_RELOAD_INTERVAL_MS = 1e4;
15686
+ var reloadTimer = null;
15664
15687
  function reloadWithReason(lc, reload2, reason) {
15665
- if (typeof localStorage === "undefined") {
15666
- lc.error?.("Zero reloaded the page.", reason);
15667
- } else {
15668
- localStorage[RELOAD_REASON_STORAGE_KEY] = reason;
15688
+ if (reloadTimer) {
15689
+ lc.warn?.("reload timer already scheduled");
15690
+ return;
15669
15691
  }
15670
- reload2();
15692
+ const now = Date.now();
15693
+ const backoff = nextBackoff(lc, now);
15694
+ if (typeof sessionStorage !== "undefined") {
15695
+ sessionStorage.setItem(RELOAD_BACKOFF_STATE_KEY, JSON.stringify(backoff));
15696
+ sessionStorage.setItem(RELOAD_REASON_STORAGE_KEY, reason);
15697
+ }
15698
+ const delay = backoff.lastReloadTime - now;
15699
+ lc.error?.(
15700
+ reason,
15701
+ "\n",
15702
+ "reloading",
15703
+ delay > 0 ? `in ${delay / 1e3} seconds` : ""
15704
+ );
15705
+ reloadTimer = setTimeout(() => {
15706
+ reloadTimer = null;
15707
+ reload2();
15708
+ }, delay);
15671
15709
  }
15672
15710
  function reportReloadReason(lc) {
15673
- if (typeof localStorage === "undefined") {
15674
- return;
15711
+ if (typeof sessionStorage !== "undefined") {
15712
+ const reason = sessionStorage.getItem(RELOAD_REASON_STORAGE_KEY);
15713
+ if (reason) {
15714
+ sessionStorage.removeItem(RELOAD_REASON_STORAGE_KEY);
15715
+ lc.error?.("Zero reloaded the page.", reason);
15716
+ }
15717
+ }
15718
+ }
15719
+ function reloadScheduled() {
15720
+ return reloadTimer !== null;
15721
+ }
15722
+ function resetBackoff() {
15723
+ if (typeof sessionStorage !== "undefined") {
15724
+ sessionStorage.removeItem(RELOAD_BACKOFF_STATE_KEY);
15725
+ }
15726
+ }
15727
+ function nextBackoff(lc, now) {
15728
+ if (typeof sessionStorage === "undefined") {
15729
+ lc.warn?.(
15730
+ `sessionStorage not supported. backing off in ${FALLBACK_RELOAD_INTERVAL_MS / 1e3} seconds`
15731
+ );
15732
+ return {
15733
+ lastReloadTime: now + FALLBACK_RELOAD_INTERVAL_MS,
15734
+ nextIntervalMs: MIN_RELOAD_INTERVAL_MS
15735
+ };
15675
15736
  }
15676
- const reason = localStorage[RELOAD_REASON_STORAGE_KEY];
15677
- if (reason) {
15678
- delete localStorage[RELOAD_REASON_STORAGE_KEY];
15679
- lc.error?.("Zero reloaded the page.", reason);
15737
+ const val = sessionStorage.getItem(RELOAD_BACKOFF_STATE_KEY);
15738
+ if (!val) {
15739
+ return { lastReloadTime: now, nextIntervalMs: MIN_RELOAD_INTERVAL_MS };
15680
15740
  }
15741
+ let parsed;
15742
+ try {
15743
+ parsed = parse(JSON.parse(val), backoffStateSchema, "passthrough");
15744
+ } catch (e) {
15745
+ lc.warn?.("ignoring unparsable backoff state", val, e);
15746
+ return { lastReloadTime: now, nextIntervalMs: MIN_RELOAD_INTERVAL_MS };
15747
+ }
15748
+ const { lastReloadTime, nextIntervalMs } = parsed;
15749
+ if (now - lastReloadTime > MAX_RELOAD_INTERVAL_MS * 2) {
15750
+ return { lastReloadTime: now, nextIntervalMs: MIN_RELOAD_INTERVAL_MS };
15751
+ }
15752
+ if (now < lastReloadTime) {
15753
+ return parsed;
15754
+ }
15755
+ const nextReloadTime = Math.max(now, lastReloadTime + nextIntervalMs);
15756
+ return {
15757
+ lastReloadTime: nextReloadTime,
15758
+ nextIntervalMs: Math.min(nextIntervalMs * 2, MAX_RELOAD_INTERVAL_MS)
15759
+ };
15681
15760
  }
15682
15761
 
15683
15762
  // ../zero-client/src/client/server-error.ts
@@ -16028,9 +16107,6 @@ function rafFallback(callback) {
16028
16107
  setTimeout(callback, 0);
16029
16108
  }
16030
16109
 
16031
- // ../zero-client/src/client/protocol-version.ts
16032
- var PROTOCOL_VERSION = 1;
16033
-
16034
16110
  // ../zero-client/src/client/zero.ts
16035
16111
  var onSetConnectionStateSymbol = Symbol();
16036
16112
  var exposedToTestingSymbol = Symbol();
@@ -16097,14 +16173,9 @@ var Zero = class {
16097
16173
  #lastMutationIDSent = NULL_LAST_MUTATION_ID_SENT;
16098
16174
  #onPong = () => void 0;
16099
16175
  #online = false;
16100
- /**
16101
- * `onOnlineChange` is called when the Zero instance's online status
16102
- * changes.
16103
- */
16104
- onOnlineChange = null;
16105
- #onUpdateNeeded = null;
16106
- #onClientStateNotFound = null;
16107
- #jurisdiction;
16176
+ #onOnlineChange;
16177
+ #onUpdateNeeded;
16178
+ #onClientStateNotFound;
16108
16179
  // Last cookie used to initiate a connection
16109
16180
  #connectCookie = null;
16110
16181
  // Total number of sockets successfully connected by this client
@@ -16118,52 +16189,6 @@ var Zero = class {
16118
16189
  #abortPingTimeout = () => {
16119
16190
  };
16120
16191
  #zeroContext;
16121
- /**
16122
- * `onUpdateNeeded` is called when a code update is needed.
16123
- *
16124
- * A code update can be needed because:
16125
- * - the server no longer supports the protocol version of the current code,
16126
- * - a new Zero client has created a new client group, because its code
16127
- * has different mutators, indexes, schema version and/or format version
16128
- * from this Zero client. This is likely due to the new client having
16129
- * newer code. A code update is needed to be able to locally sync with this
16130
- * new Zero client (i.e. to sync while offline, the clients can can
16131
- * still sync with each other via the server).
16132
- *
16133
- * The default behavior is to reload the page (using `location.reload()`). Set
16134
- * this to `null` or provide your own function to prevent the page from
16135
- * reloading automatically. You may want to provide your own function to
16136
- * display a toast to inform the end user there is a new version of your app
16137
- * available and prompting them to refresh.
16138
- */
16139
- get onUpdateNeeded() {
16140
- return this.#onUpdateNeeded;
16141
- }
16142
- set onUpdateNeeded(callback) {
16143
- this.#onUpdateNeeded = callback;
16144
- this.#rep.onUpdateNeeded = callback && ((reason) => {
16145
- callback(convertOnUpdateNeededReason(reason));
16146
- });
16147
- }
16148
- /**
16149
- * `onClientStateNotFound` is called when this client will no longer be able
16150
- * to sync due to missing synchronization state. This can be because:
16151
- * - the local persistent synchronization state has been garbage collected.
16152
- * This can happen if the client has no pending mutations and has not been
16153
- * used for a while.
16154
- * - the zero-cache fails to find the synchronization state of this client.
16155
- *
16156
- * The default behavior is to reload the page (using `location.reload()`). Set
16157
- * this to `null` or provide your own function to prevent the page from
16158
- * reloading automatically.
16159
- */
16160
- get onClientStateNotFound() {
16161
- return this.#onClientStateNotFound;
16162
- }
16163
- set onClientStateNotFound(value) {
16164
- this.#onClientStateNotFound = value;
16165
- this.#rep.onClientStateNotFound = value;
16166
- }
16167
16192
  #connectResolver = resolver8();
16168
16193
  #pendingPullsByRequestID = /* @__PURE__ */ new Map();
16169
16194
  #lastMutationIDReceived = 0;
@@ -16214,7 +16239,8 @@ var Zero = class {
16214
16239
  const {
16215
16240
  userID,
16216
16241
  onOnlineChange,
16217
- jurisdiction,
16242
+ onUpdateNeeded,
16243
+ onClientStateNotFound,
16218
16244
  hiddenTabDisconnectDelay = DEFAULT_DISCONNECT_HIDDEN_DELAY_MS,
16219
16245
  kvStore = "idb",
16220
16246
  schema,
@@ -16229,15 +16255,12 @@ var Zero = class {
16229
16255
  false
16230
16256
  // Reenable analytics
16231
16257
  );
16232
- if (jurisdiction !== void 0 && jurisdiction !== "eu") {
16233
- throw new Error('ZeroOptions.jurisdiction must be "eu" if present.');
16234
- }
16235
16258
  if (hiddenTabDisconnectDelay < 0) {
16236
16259
  throw new Error(
16237
16260
  "ZeroOptions.hiddenTabDisconnectDelay must not be negative."
16238
16261
  );
16239
16262
  }
16240
- this.onOnlineChange = onOnlineChange;
16263
+ this.#onOnlineChange = onOnlineChange;
16241
16264
  this.#options = options;
16242
16265
  this.#logOptions = this.#createLogOptions({
16243
16266
  consoleLogLevel: options.logLevel ?? "error",
@@ -16267,36 +16290,41 @@ var Zero = class {
16267
16290
  kvStore
16268
16291
  };
16269
16292
  const replicacheImplOptions = {
16270
- enableClientGroupForking: false
16293
+ enableClientGroupForking: false,
16294
+ enableMutationRecovery: false
16271
16295
  };
16272
16296
  const rep = new ReplicacheImpl(replicacheOptions, replicacheImplOptions);
16273
16297
  this.#rep = rep;
16274
16298
  if (false) {
16275
16299
  internalReplicacheImplMap.set(this, rep);
16276
16300
  }
16277
- rep.getAuth = this.#getAuthToken;
16278
16301
  this.#server = server;
16279
16302
  this.userID = userID;
16280
- this.#jurisdiction = jurisdiction;
16281
- this.#lc = new LogContext3(
16303
+ this.#lc = new LogContext4(
16282
16304
  logOptions.logLevel,
16283
16305
  { clientID: rep.clientID },
16284
16306
  logOptions.logSink
16285
16307
  );
16286
- this.onUpdateNeeded = (reason, serverErrorMsg) => {
16308
+ const onUpdateNeededCallback = onUpdateNeeded ?? ((reason, serverErrorMsg) => {
16287
16309
  reloadWithReason(
16288
16310
  this.#lc,
16289
16311
  this.#reload,
16290
16312
  updateNeededReloadReason(reason, serverErrorMsg)
16291
16313
  );
16314
+ });
16315
+ this.#onUpdateNeeded = onUpdateNeededCallback;
16316
+ this.#rep.onUpdateNeeded = (reason) => {
16317
+ onUpdateNeededCallback(convertOnUpdateNeededReason(reason));
16292
16318
  };
16293
- this.onClientStateNotFound = (reason) => {
16319
+ const onClientStateNotFoundCallback = onClientStateNotFound ?? ((reason) => {
16294
16320
  reloadWithReason(
16295
16321
  this.#lc,
16296
16322
  this.#reload,
16297
16323
  reason ?? ON_CLIENT_STATE_NOT_FOUND_REASON_CLIENT
16298
16324
  );
16299
- };
16325
+ });
16326
+ this.#onClientStateNotFound = onClientStateNotFoundCallback;
16327
+ this.#rep.onClientStateNotFound = onClientStateNotFoundCallback;
16300
16328
  const { mutate, mutateBatch } = makeCRUDMutate(
16301
16329
  normalizedSchema,
16302
16330
  rep.mutate
@@ -16433,10 +16461,10 @@ var Zero = class {
16433
16461
  */
16434
16462
  mutateBatch;
16435
16463
  /**
16436
- * Whether this Zero instance has been closed. Once a Zero instance has
16437
- * been closed it no longer syncs and you can no longer read or write data out
16438
- * of it. After it has been closed it is pretty much useless and should not be
16439
- * used any more.
16464
+ * Whether this Zero instance has been closed.
16465
+ *
16466
+ * Once a Zero instance has been closed it no longer syncs, you can no
16467
+ * longer query or mutate data with it, and its query views stop updating.
16440
16468
  */
16441
16469
  get closed() {
16442
16470
  return this.#rep.closed;
@@ -16444,7 +16472,8 @@ var Zero = class {
16444
16472
  /**
16445
16473
  * Closes this Zero instance.
16446
16474
  *
16447
- * When closed all subscriptions end and no more read or writes are allowed.
16475
+ * Once a Zero instance has been closed it no longer syncs, you can no
16476
+ * longer query or mutate data with it, and its query views stop updating.
16448
16477
  */
16449
16478
  close() {
16450
16479
  const lc = this.#lc.withContext("close");
@@ -16681,7 +16710,6 @@ var Zero = class {
16681
16710
  this.#options.schema.version,
16682
16711
  this.userID,
16683
16712
  this.#rep.auth,
16684
- this.#jurisdiction,
16685
16713
  this.#lastMutationIDReceived,
16686
16714
  wsid,
16687
16715
  this.#options.logLevel === "debug",
@@ -16768,6 +16796,7 @@ var Zero = class {
16768
16796
  this.#pokeHandler.handleDisconnect();
16769
16797
  }
16770
16798
  async #handlePokeStart(_lc, pokeMessage) {
16799
+ resetBackoff();
16771
16800
  this.#abortPingTimeout();
16772
16801
  await this.#pokeHandler.handlePokeStart(pokeMessage[1]);
16773
16802
  }
@@ -16869,12 +16898,9 @@ var Zero = class {
16869
16898
  }
16870
16899
  };
16871
16900
  }
16872
- #getAuthToken = () => {
16873
- const { auth } = this.#options;
16874
- return typeof auth === "function" ? auth() : auth;
16875
- };
16876
- async #updateAuthToken(lc) {
16877
- const auth = await this.#getAuthToken();
16901
+ async #updateAuthToken(lc, error) {
16902
+ const { auth: authOption } = this.#options;
16903
+ const auth = await (typeof authOption === "function" ? authOption(error) : authOption);
16878
16904
  if (auth) {
16879
16905
  lc.debug?.("Got auth token");
16880
16906
  this.#rep.auth = auth;
@@ -16910,7 +16936,10 @@ var Zero = class {
16910
16936
  }
16911
16937
  await this.#visibilityWatcher.waitForVisible();
16912
16938
  if (needsReauth) {
16913
- await this.#updateAuthToken(lc);
16939
+ await this.#updateAuthToken(lc, "invalid-token");
16940
+ }
16941
+ if (reloadScheduled()) {
16942
+ break;
16914
16943
  }
16915
16944
  await this.#connect(lc);
16916
16945
  if (this.closed) {
@@ -17080,7 +17109,7 @@ var Zero = class {
17080
17109
  return;
17081
17110
  }
17082
17111
  this.#online = online;
17083
- this.onOnlineChange?.(online);
17112
+ this.#onOnlineChange?.(online);
17084
17113
  }
17085
17114
  /**
17086
17115
  * A rough heuristic for whether the client is currently online and
@@ -17138,7 +17167,7 @@ var Zero = class {
17138
17167
  return rv;
17139
17168
  }
17140
17169
  };
17141
- async function createSocket(rep, queryManager, socketOrigin, baseCookie, clientID, clientGroupID, schemaVersion, userID, auth, jurisdiction, lmid, wsid, debugPerf, lc, maxHeaderLength = 1024 * 8) {
17170
+ async function createSocket(rep, queryManager, socketOrigin, baseCookie, clientID, clientGroupID, schemaVersion, userID, auth, lmid, wsid, debugPerf, lc, maxHeaderLength = 1024 * 8) {
17142
17171
  const url = new URL(
17143
17172
  appendPath(socketOrigin, `/sync/v${PROTOCOL_VERSION}/connect`)
17144
17173
  );
@@ -17147,9 +17176,6 @@ async function createSocket(rep, queryManager, socketOrigin, baseCookie, clientI
17147
17176
  searchParams.set("clientGroupID", clientGroupID);
17148
17177
  searchParams.set("schemaVersion", schemaVersion.toString());
17149
17178
  searchParams.set("userID", userID);
17150
- if (jurisdiction !== void 0) {
17151
- searchParams.set("jurisdiction", jurisdiction);
17152
- }
17153
17179
  searchParams.set("baseCookie", baseCookie === null ? "" : String(baseCookie));
17154
17180
  searchParams.set("ts", String(performance.now()));
17155
17181
  searchParams.set("lmid", String(lmid));
@@ -17210,4 +17236,4 @@ export {
17210
17236
  escapeLike,
17211
17237
  Zero
17212
17238
  };
17213
- //# sourceMappingURL=chunk-QB7G63C6.js.map
17239
+ //# sourceMappingURL=chunk-HDEKBM3G.js.map