@rocicorp/zero 1.10.0-canary.21 → 1.10.0-canary.23

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 (334) hide show
  1. package/out/analyze-query/src/bin-analyze.js +1 -1
  2. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  3. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  4. package/out/replicache/src/dag/gc.js +2 -1
  5. package/out/replicache/src/dag/gc.js.map +1 -1
  6. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
  7. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
  8. package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
  9. package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
  10. package/out/replicache/src/dag/store-impl.d.ts +12 -2
  11. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  12. package/out/replicache/src/dag/store-impl.js +22 -8
  13. package/out/replicache/src/dag/store-impl.js.map +1 -1
  14. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  15. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  16. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  17. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +15 -5
  18. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +1 -1
  19. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +25 -25
  20. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  21. package/out/replicache/src/kv/idb-store.d.ts +9 -0
  22. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  23. package/out/replicache/src/kv/idb-store.js +14 -2
  24. package/out/replicache/src/kv/idb-store.js.map +1 -1
  25. package/out/replicache/src/kv/mem-store.d.ts +1 -0
  26. package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
  27. package/out/replicache/src/kv/mem-store.js +3 -0
  28. package/out/replicache/src/kv/mem-store.js.map +1 -1
  29. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  30. package/out/replicache/src/kv/op-sqlite/store.js +1 -1
  31. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  32. package/out/replicache/src/kv/sqlite-store.d.ts +2 -1
  33. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  34. package/out/replicache/src/kv/sqlite-store.js +6 -1
  35. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  36. package/out/replicache/src/kv/store.d.ts +6 -0
  37. package/out/replicache/src/kv/store.d.ts.map +1 -1
  38. package/out/replicache/src/persist/collect-idb-databases.d.ts +10 -5
  39. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  40. package/out/replicache/src/persist/collect-idb-databases.js +16 -9
  41. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  42. package/out/replicache/src/replicache-impl.d.ts +14 -3
  43. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  44. package/out/replicache/src/replicache-impl.js +104 -9
  45. package/out/replicache/src/replicache-impl.js.map +1 -1
  46. package/out/shared/src/arrays.js +1 -15
  47. package/out/shared/src/arrays.js.map +1 -1
  48. package/out/shared/src/hash.d.ts +1 -0
  49. package/out/shared/src/hash.d.ts.map +1 -1
  50. package/out/shared/src/hash.js +10 -28
  51. package/out/shared/src/hash.js.map +1 -1
  52. package/out/shared/src/iterables.d.ts +2 -0
  53. package/out/shared/src/iterables.d.ts.map +1 -1
  54. package/out/shared/src/iterables.js +18 -1
  55. package/out/shared/src/iterables.js.map +1 -1
  56. package/out/shared/src/json.d.ts.map +1 -1
  57. package/out/shared/src/json.js +2 -2
  58. package/out/shared/src/json.js.map +1 -1
  59. package/out/shared/src/ring-buffer.d.ts +8 -0
  60. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  61. package/out/shared/src/ring-buffer.js +22 -1
  62. package/out/shared/src/ring-buffer.js.map +1 -1
  63. package/out/shared/src/xxhash32.d.ts +36 -0
  64. package/out/shared/src/xxhash32.d.ts.map +1 -0
  65. package/out/shared/src/xxhash32.js +51 -0
  66. package/out/shared/src/xxhash32.js.map +1 -0
  67. package/out/z2s/src/compiler.js +1 -1
  68. package/out/zero/package.js +1 -1
  69. package/out/zero/package.js.map +1 -1
  70. package/out/zero-cache/src/auth/read-authorizer.js +1 -1
  71. package/out/zero-cache/src/config/zero-config.d.ts +8 -0
  72. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  73. package/out/zero-cache/src/config/zero-config.js +28 -1
  74. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  75. package/out/zero-cache/src/custom-queries/transform-query.js +1 -1
  76. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  77. package/out/zero-cache/src/server/change-streamer.js +11 -3
  78. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  79. package/out/zero-cache/src/server/inspector-delegate.d.ts +18 -2
  80. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  81. package/out/zero-cache/src/server/inspector-delegate.js +23 -9
  82. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  83. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  84. package/out/zero-cache/src/server/main.js +8 -1
  85. package/out/zero-cache/src/server/main.js.map +1 -1
  86. package/out/zero-cache/src/server/mutator.js +2 -0
  87. package/out/zero-cache/src/server/mutator.js.map +1 -1
  88. package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
  89. package/out/zero-cache/src/server/reaper.js +2 -0
  90. package/out/zero-cache/src/server/reaper.js.map +1 -1
  91. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  92. package/out/zero-cache/src/server/replicator.js +2 -0
  93. package/out/zero-cache/src/server/replicator.js.map +1 -1
  94. package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
  95. package/out/zero-cache/src/server/runner/zero-dispatcher.js +3 -0
  96. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  97. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  98. package/out/zero-cache/src/server/syncer.js +2 -0
  99. package/out/zero-cache/src/server/syncer.js.map +1 -1
  100. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  101. package/out/zero-cache/src/services/analyze.js +3 -2
  102. package/out/zero-cache/src/services/analyze.js.map +1 -1
  103. package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
  104. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +14 -1
  105. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  106. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
  107. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +15 -3
  108. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  109. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +1 -1
  110. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +3 -0
  111. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  112. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +3 -1
  113. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  114. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
  115. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  116. package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
  117. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  118. package/out/zero-cache/src/services/mutagen/pusher.js +3 -2
  119. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  120. package/out/zero-cache/src/services/profz.d.ts +7 -0
  121. package/out/zero-cache/src/services/profz.d.ts.map +1 -0
  122. package/out/zero-cache/src/services/profz.js +103 -0
  123. package/out/zero-cache/src/services/profz.js.map +1 -0
  124. package/out/zero-cache/src/services/run-ast.d.ts +12 -0
  125. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  126. package/out/zero-cache/src/services/run-ast.js +27 -15
  127. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  128. package/out/zero-cache/src/services/runner.d.ts.map +1 -1
  129. package/out/zero-cache/src/services/runner.js +1 -1
  130. package/out/zero-cache/src/services/runner.js.map +1 -1
  131. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +45 -0
  132. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  133. package/out/zero-cache/src/services/view-syncer/cvr.js +133 -1
  134. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  135. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
  136. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  137. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
  138. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  139. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +33 -0
  140. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +1 -0
  141. package/out/zero-cache/src/services/view-syncer/hydration-budget.js +62 -0
  142. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -0
  143. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
  144. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
  145. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
  146. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
  147. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
  148. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
  149. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +2 -2
  150. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  151. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +2 -1
  152. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  153. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +33 -18
  154. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  155. package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
  156. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  157. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +4 -1
  158. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  159. package/out/zero-cache/src/services/view-syncer/snapshotter.js +9 -3
  160. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  161. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +11 -1
  162. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  163. package/out/zero-cache/src/services/view-syncer/view-syncer.js +470 -90
  164. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  165. package/out/zero-cache/src/types/processes.d.ts +32 -0
  166. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  167. package/out/zero-cache/src/types/processes.js +43 -4
  168. package/out/zero-cache/src/types/processes.js.map +1 -1
  169. package/out/zero-cache/src/types/profiler.d.ts +12 -0
  170. package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
  171. package/out/zero-cache/src/types/profiler.js +46 -1
  172. package/out/zero-cache/src/types/profiler.js.map +1 -1
  173. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  174. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
  175. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  176. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  177. package/out/zero-cache/src/workers/syncer.js +10 -1
  178. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  179. package/out/zero-client/src/client/connection-manager.d.ts +20 -0
  180. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  181. package/out/zero-client/src/client/connection-manager.js +32 -14
  182. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  183. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  184. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  185. package/out/zero-client/src/client/connection-status-enum.js +3 -1
  186. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  187. package/out/zero-client/src/client/connection.d.ts +6 -0
  188. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  189. package/out/zero-client/src/client/connection.js +2 -1
  190. package/out/zero-client/src/client/connection.js.map +1 -1
  191. package/out/zero-client/src/client/context.d.ts +22 -12
  192. package/out/zero-client/src/client/context.d.ts.map +1 -1
  193. package/out/zero-client/src/client/context.js +92 -25
  194. package/out/zero-client/src/client/context.js.map +1 -1
  195. package/out/zero-client/src/client/custom.js +2 -2
  196. package/out/zero-client/src/client/custom.js.map +1 -1
  197. package/out/zero-client/src/client/error.js +1 -1
  198. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  199. package/out/zero-client/src/client/ivm-branch.js +20 -3
  200. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  201. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  202. package/out/zero-client/src/client/mutator-proxy.js +2 -1
  203. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  204. package/out/zero-client/src/client/options.d.ts +3 -0
  205. package/out/zero-client/src/client/options.d.ts.map +1 -1
  206. package/out/zero-client/src/client/options.js.map +1 -1
  207. package/out/zero-client/src/client/query-manager.d.ts +2 -0
  208. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  209. package/out/zero-client/src/client/query-manager.js +48 -9
  210. package/out/zero-client/src/client/query-manager.js.map +1 -1
  211. package/out/zero-client/src/client/version.js +1 -1
  212. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  213. package/out/zero-client/src/client/zero-rep.js +1 -1
  214. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  215. package/out/zero-client/src/client/zero.d.ts +18 -3
  216. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  217. package/out/zero-client/src/client/zero.js +61 -14
  218. package/out/zero-client/src/client/zero.js.map +1 -1
  219. package/out/zero-client/src/types/query-result.d.ts +2 -0
  220. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  221. package/out/zero-protocol/src/ast.d.ts +64 -1
  222. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  223. package/out/zero-protocol/src/ast.js +223 -51
  224. package/out/zero-protocol/src/ast.js.map +1 -1
  225. package/out/zero-protocol/src/error.d.ts +1 -1
  226. package/out/zero-protocol/src/query-hash-visitor.d.ts +81 -0
  227. package/out/zero-protocol/src/query-hash-visitor.d.ts.map +1 -0
  228. package/out/zero-protocol/src/query-hash-visitor.js +324 -0
  229. package/out/zero-protocol/src/query-hash-visitor.js.map +1 -0
  230. package/out/zero-protocol/src/query-hash.d.ts +7 -2
  231. package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
  232. package/out/zero-protocol/src/query-hash.js +12 -9
  233. package/out/zero-protocol/src/query-hash.js.map +1 -1
  234. package/out/zero-react/src/use-query.d.ts +5 -4
  235. package/out/zero-react/src/use-query.d.ts.map +1 -1
  236. package/out/zero-react/src/use-query.js +86 -9
  237. package/out/zero-react/src/use-query.js.map +1 -1
  238. package/out/zero-solid/src/solid-view.d.ts +17 -0
  239. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  240. package/out/zero-solid/src/solid-view.js +39 -1
  241. package/out/zero-solid/src/solid-view.js.map +1 -1
  242. package/out/zero-solid/src/use-query.js +5 -3
  243. package/out/zero-solid/src/use-query.js.map +1 -1
  244. package/out/zql/src/builder/debug-delegate.d.ts +6 -1
  245. package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
  246. package/out/zql/src/builder/debug-delegate.js +14 -2
  247. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  248. package/out/zql/src/ivm/array-view.d.ts +29 -0
  249. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  250. package/out/zql/src/ivm/array-view.js +58 -9
  251. package/out/zql/src/ivm/array-view.js.map +1 -1
  252. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  253. package/out/zql/src/ivm/cap.js +5 -3
  254. package/out/zql/src/ivm/cap.js.map +1 -1
  255. package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
  256. package/out/zql/src/ivm/deferred-input.js +3 -2
  257. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  258. package/out/zql/src/ivm/exists.d.ts +1 -1
  259. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  260. package/out/zql/src/ivm/exists.js +1 -1
  261. package/out/zql/src/ivm/exists.js.map +1 -1
  262. package/out/zql/src/ivm/fan-in.d.ts +2 -2
  263. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  264. package/out/zql/src/ivm/fan-in.js +6 -5
  265. package/out/zql/src/ivm/fan-in.js.map +1 -1
  266. package/out/zql/src/ivm/fan-out.d.ts +2 -2
  267. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  268. package/out/zql/src/ivm/fan-out.js.map +1 -1
  269. package/out/zql/src/ivm/filter-operators.d.ts +4 -4
  270. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  271. package/out/zql/src/ivm/filter-operators.js +10 -8
  272. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  273. package/out/zql/src/ivm/filter.d.ts +2 -2
  274. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  275. package/out/zql/src/ivm/filter.js +7 -4
  276. package/out/zql/src/ivm/filter.js.map +1 -1
  277. package/out/zql/src/ivm/flipped-join.js +2 -2
  278. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  279. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  280. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  281. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
  282. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  283. package/out/zql/src/ivm/memory-source.d.ts +15 -3
  284. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  285. package/out/zql/src/ivm/memory-source.js +35 -9
  286. package/out/zql/src/ivm/memory-source.js.map +1 -1
  287. package/out/zql/src/ivm/take.d.ts.map +1 -1
  288. package/out/zql/src/ivm/take.js +3 -4
  289. package/out/zql/src/ivm/take.js.map +1 -1
  290. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  291. package/out/zql/src/ivm/union-fan-in.js +9 -7
  292. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  293. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  294. package/out/zql/src/ivm/view-apply-change.js +3 -3
  295. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  296. package/out/zql/src/ivm/view.d.ts +15 -0
  297. package/out/zql/src/ivm/view.d.ts.map +1 -1
  298. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  299. package/out/zql/src/mutate/mutator-registry.js +2 -2
  300. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  301. package/out/zql/src/query/query-delegate-base.d.ts +4 -2
  302. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  303. package/out/zql/src/query/query-delegate-base.js +69 -36
  304. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  305. package/out/zql/src/query/query-delegate.d.ts +33 -6
  306. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  307. package/out/zql/src/query/query-impl.d.ts +25 -14
  308. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  309. package/out/zql/src/query/query-impl.js +414 -94
  310. package/out/zql/src/query/query-impl.js.map +1 -1
  311. package/out/zql/src/query/query-internals.d.ts +21 -11
  312. package/out/zql/src/query/query-internals.d.ts.map +1 -1
  313. package/out/zql/src/query/query-internals.js.map +1 -1
  314. package/out/zql/src/query/query-transitions.d.ts +171 -0
  315. package/out/zql/src/query/query-transitions.d.ts.map +1 -0
  316. package/out/zql/src/query/query-transitions.js +207 -0
  317. package/out/zql/src/query/query-transitions.js.map +1 -0
  318. package/out/zql/src/query/query.d.ts +11 -2
  319. package/out/zql/src/query/query.d.ts.map +1 -1
  320. package/out/zql/src/query/runnable-query-impl.d.ts +3 -2
  321. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  322. package/out/zql/src/query/runnable-query-impl.js +23 -2
  323. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  324. package/out/zql/src/query/typed-view.d.ts +1 -1
  325. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  326. package/out/zqlite/src/db.d.ts +9 -1
  327. package/out/zqlite/src/db.d.ts.map +1 -1
  328. package/out/zqlite/src/db.js +8 -2
  329. package/out/zqlite/src/db.js.map +1 -1
  330. package/out/zqlite/src/table-source.d.ts +1 -0
  331. package/out/zqlite/src/table-source.d.ts.map +1 -1
  332. package/out/zqlite/src/table-source.js +10 -5
  333. package/out/zqlite/src/table-source.js.map +1 -1
  334. package/package.json +1 -1
@@ -0,0 +1,81 @@
1
+ import type { Format } from '../../zero-types/src/format.ts';
2
+ /**
3
+ * Hashes a normalized AST by visiting it, rather than by rendering it to JSON
4
+ * and hashing the bytes. `hashOfAST` and `hashOfNameAndArgs` in
5
+ * `query-hash.ts` are both built on this, so these digests are the query IDs
6
+ * the client registers and the transformation hashes the server stores.
7
+ *
8
+ * The pipeline this replaced was
9
+ * `h64(JSON.stringify(normalizeAST(ast))).toString(36)`, which materialized
10
+ * the whole AST as a string, UTF-8 encoded it, and only then hashed it — three
11
+ * passes over the data, two of which existed purely to produce bytes to hash.
12
+ *
13
+ * A visitor can fold values into the hash state as it walks, so nothing is
14
+ * materialized at all. The primitives that make that pay off:
15
+ *
16
+ * - Two 32-bit accumulators held in module-level `let`s, so the "state" is
17
+ * plain numbers in registers rather than an object being threaded through
18
+ * the walk.
19
+ * - xxHash32's own round and final mix, shared with `shared/src/hash.ts` via
20
+ * `shared/src/xxhash32.ts`. Only the ingestion differs: that one feeds them
21
+ * UTF-8 bytes, this one feeds them words straight out of the structure.
22
+ * - Strings folded straight from `charCodeAt`, two UTF-16 units at a time, into
23
+ * one 32-bit word. No UTF-8 encoding, and half the loop iterations a
24
+ * byte-oriented hash would need over ASCII.
25
+ *
26
+ * These digests do not agree with xxHash32 over the old JSON encoding, and are
27
+ * not meant to: nothing recomputes a hash produced elsewhere and compares it,
28
+ * so the encoding is free to change as long as every writer moves together.
29
+ * What it does have to give is distinct words for structurally distinct
30
+ * queries — a 64-bit digest cannot promise that absolutely, but every field
31
+ * and node kind must at least reach the mixer, and no two of them may be
32
+ * written so as to be confusable. `query-hash-visitor.test.ts` holds that
33
+ * line with a corpus and a per-field mutation test.
34
+ *
35
+ * The walk is deliberately specialized to the AST shape rather than written as
36
+ * a generic JSON-value walk. That is not premature: a generic version was
37
+ * measured alongside this one and came out ~2.4x slower, no better than the
38
+ * `JSON.stringify` it was meant to replace, because `for...in` and the
39
+ * megamorphic property loads cost about what the native stringify costs. Only
40
+ * `visitValue` below stays generic, for the two places an AST holds arbitrary
41
+ * JSON: a literal's value and a bound's row.
42
+ */
43
+ import type { AST, System } from './ast.ts';
44
+ export declare function hashAST(ast: AST): string;
45
+ /**
46
+ * The identity of a custom query: its name and its arguments.
47
+ *
48
+ * Same walk, entered at a different node. `args` is arbitrary JSON, which is
49
+ * what `visitValue` already exists to handle. The leading tag keeps this hash
50
+ * space disjoint from `hashAST`'s -- both produce query IDs that live in the
51
+ * same namespace, so an AST must not be able to fold to the same words as some
52
+ * name and args.
53
+ */
54
+ export declare function hashNameAndArgs(name: string, args: readonly unknown[]): string;
55
+ /**
56
+ * The identity of a query as the client sees it: its AST, the shape it returns,
57
+ * the system it was built for, and -- for a custom query -- the name and
58
+ * arguments it was declared with.
59
+ *
60
+ * Everything past the AST is here because it is part of what makes two queries
61
+ * different while leaving no trace, or an incomplete one, in the AST itself:
62
+ *
63
+ * - **name and args**: `nameAndArgs` reuses the AST it is given and only
64
+ * attaches a `CustomQueryID`, so without these two different named queries
65
+ * over the same table would be indistinguishable.
66
+ * - **system**: a query stamps it onto every `related` entry and every `exists`
67
+ * correlation it builds, so it is already hashed via
68
+ * {@link visitCorrelatedSubquery} -- but a query with neither has nowhere to
69
+ * put it, and would otherwise hash the same whether it was built for the
70
+ * client or for permissions.
71
+ * - **currentJunction**: builder state, set on the sub-query handed to a
72
+ * two-hop relationship's callback, which makes `limit` and `orderBy` throw.
73
+ * It leaves no trace in the AST at all, so two queries that differ only in
74
+ * whether those methods work would otherwise be indistinguishable.
75
+ *
76
+ * The name and args are taken apart rather than as a `CustomQueryID` because
77
+ * that type lives in `zql`, which is above this package; `hashNameAndArgs`
78
+ * splits them the same way.
79
+ */
80
+ export declare function hashOfQueryInternals(ast: AST, format: Format, system: System, currentJunction: string | undefined, customQueryName: string | undefined, customQueryArgs: readonly unknown[] | undefined): string;
81
+ //# sourceMappingURL=query-hash-visitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-hash-visitor.d.ts","sourceRoot":"","sources":["../../../../zero-protocol/src/query-hash-visitor.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,KAAK,EACV,GAAG,EAIH,MAAM,EAEP,MAAM,UAAU,CAAC;AA8UlB,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAcxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,MAAM,CAaR;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,eAAe,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,GAC9C,MAAM,CA2BR"}
@@ -0,0 +1,324 @@
1
+ import { unreachable } from "../../shared/src/asserts.js";
2
+ import { PRIME32_1, PRIME32_5, avalanche32, round32 } from "../../shared/src/xxhash32.js";
3
+ import "../../shared/src/hash.js";
4
+ //#region ../zero-protocol/src/query-hash-visitor.ts
5
+ var h1 = 0;
6
+ var h2 = 0;
7
+ /**
8
+ * Fold one 32-bit word into both lanes.
9
+ *
10
+ * Both lanes run xxHash32's own round; only their starting values differ, so
11
+ * they diverge immediately and stay diverged. That is the same construction
12
+ * `h64` uses to widen xxHash32 past 32 bits, just fed words taken from a
13
+ * structure rather than bytes taken from a string.
14
+ */
15
+ function mix(w) {
16
+ h1 = round32(h1, w);
17
+ h2 = round32(h2, w);
18
+ }
19
+ /**
20
+ * Fold a string, two UTF-16 units per word.
21
+ *
22
+ * The leading length keeps `['ab','c']` and `['a','bc']` apart. STR_MARK is
23
+ * folded into that same word rather than mixed separately: it costs nothing,
24
+ * and since every other count written by this file is a small array length, a
25
+ * string can never fold like one.
26
+ */
27
+ function mixString(s) {
28
+ const n = s.length;
29
+ mix(n | STR_MARK);
30
+ let i = 0;
31
+ for (; i + 1 < n; i += 2) mix(s.charCodeAt(i) | s.charCodeAt(i + 1) << 16);
32
+ if (i < n) mix(s.charCodeAt(i));
33
+ }
34
+ var numView = /* @__PURE__ */ new DataView(/* @__PURE__ */ new ArrayBuffer(8));
35
+ /** Fold a number: one word for an int32, two for anything else. */
36
+ function mixNumber(n) {
37
+ if ((n | 0) === n) mix(n);
38
+ else {
39
+ numView.setFloat64(0, n, true);
40
+ mix(numView.getInt32(0, true));
41
+ mix(numView.getInt32(4, true));
42
+ }
43
+ }
44
+ var TAG_NULL = 4097;
45
+ var TAG_FALSE = 4098;
46
+ var TAG_TRUE = 4099;
47
+ var TAG_INT = 4100;
48
+ var TAG_FLOAT = 4101;
49
+ var TAG_ARR = 4103;
50
+ var TAG_OBJ = 4104;
51
+ var TAG_END = 4105;
52
+ var TAG_UNDEF = 4106;
53
+ var TAG_LITERAL = 8193;
54
+ var TAG_COLUMN = 8194;
55
+ var TAG_STATIC = 8195;
56
+ var TAG_SIMPLE = 8196;
57
+ var TAG_SUBQUERY = 8197;
58
+ var TAG_AND = 8198;
59
+ var TAG_OR = 8199;
60
+ var TAG_FORMAT = 8200;
61
+ var TAG_NAME_ARGS = 8201;
62
+ var TAG_SYSTEM_PERMISSIONS = 8202;
63
+ var TAG_SYSTEM_CLIENT = 8203;
64
+ var TAG_SYSTEM_TEST = 8204;
65
+ var TAG_JUNCTION = 8205;
66
+ var STR_MARK = 1073741824;
67
+ function reset() {
68
+ h1 = PRIME32_5;
69
+ h2 = PRIME32_1;
70
+ }
71
+ /** Collapse the two lanes into one 64-bit value, avalanching each first. */
72
+ function finalize() {
73
+ return avalanche32(h1).toString(36).padStart(7, "0") + avalanche32(h2).toString(36).padStart(7, "0");
74
+ }
75
+ function visitValue(v) {
76
+ switch (typeof v) {
77
+ case "string":
78
+ mixString(v);
79
+ return;
80
+ case "number":
81
+ if (!Number.isFinite(v)) {
82
+ mix(TAG_NULL);
83
+ return;
84
+ }
85
+ mix((v | 0) === v ? TAG_INT : TAG_FLOAT);
86
+ mixNumber(v);
87
+ return;
88
+ case "boolean":
89
+ mix(v ? TAG_TRUE : TAG_FALSE);
90
+ return;
91
+ case "object": {
92
+ if (v === null) {
93
+ mix(TAG_NULL);
94
+ return;
95
+ }
96
+ if (Array.isArray(v)) {
97
+ mix(TAG_ARR);
98
+ for (let i = 0; i < v.length; i++) {
99
+ const e = v[i];
100
+ visitValue(e === void 0 ? null : e);
101
+ }
102
+ mix(TAG_END);
103
+ return;
104
+ }
105
+ mix(TAG_OBJ);
106
+ const keys = Object.keys(v).sort();
107
+ for (const k of keys) {
108
+ const val = v[k];
109
+ if (val === void 0) continue;
110
+ mixString(k);
111
+ visitValue(val);
112
+ }
113
+ mix(TAG_END);
114
+ return;
115
+ }
116
+ default: return;
117
+ }
118
+ }
119
+ function visitOptionalString(s) {
120
+ if (s === void 0) mix(TAG_UNDEF);
121
+ else mixString(s);
122
+ }
123
+ function mixOptionalSystem(system) {
124
+ if (system === void 0) mix(TAG_UNDEF);
125
+ else mixSystem(system);
126
+ }
127
+ function mixSystem(system) {
128
+ switch (system) {
129
+ case "permissions":
130
+ mix(TAG_SYSTEM_PERMISSIONS);
131
+ break;
132
+ case "client":
133
+ mix(TAG_SYSTEM_CLIENT);
134
+ break;
135
+ case "test":
136
+ mix(TAG_SYSTEM_TEST);
137
+ break;
138
+ default: unreachable(system);
139
+ }
140
+ }
141
+ function visitCompoundKey(k) {
142
+ mix(k.length);
143
+ for (let i = 0; i < k.length; i++) mixString(k[i]);
144
+ }
145
+ function visitOrdering(o) {
146
+ if (o === void 0) {
147
+ mix(TAG_UNDEF);
148
+ return;
149
+ }
150
+ mix(o.length);
151
+ for (let i = 0; i < o.length; i++) {
152
+ const [field, dir] = o[i];
153
+ mixString(field);
154
+ mix(dir === "asc" ? TAG_TRUE : TAG_FALSE);
155
+ }
156
+ }
157
+ function visitValuePosition(v) {
158
+ switch (v.type) {
159
+ case "literal":
160
+ mix(TAG_LITERAL);
161
+ visitValue(v.value);
162
+ return;
163
+ case "column":
164
+ mix(TAG_COLUMN);
165
+ mixString(v.name);
166
+ return;
167
+ case "static":
168
+ mix(TAG_STATIC);
169
+ mixString(v.anchor);
170
+ if (typeof v.field === "string") mixString(v.field);
171
+ else visitCompoundKey(v.field);
172
+ return;
173
+ default: unreachable(v);
174
+ }
175
+ }
176
+ function visitCondition(c) {
177
+ switch (c.type) {
178
+ case "simple":
179
+ mix(TAG_SIMPLE);
180
+ mixString(c.op);
181
+ visitValuePosition(c.left);
182
+ visitValuePosition(c.right);
183
+ return;
184
+ case "correlatedSubquery":
185
+ mix(TAG_SUBQUERY);
186
+ mixString(c.op);
187
+ mix(c.flip === void 0 ? TAG_UNDEF : c.flip ? TAG_TRUE : TAG_FALSE);
188
+ mix(c.scalar === void 0 ? TAG_UNDEF : c.scalar ? TAG_TRUE : TAG_FALSE);
189
+ visitCorrelatedSubquery(c.related);
190
+ return;
191
+ default: {
192
+ c.type;
193
+ mix(c.type === "and" ? TAG_AND : TAG_OR);
194
+ const conds = c.conditions;
195
+ mix(conds.length);
196
+ for (let i = 0; i < conds.length; i++) visitCondition(conds[i]);
197
+ return;
198
+ }
199
+ }
200
+ }
201
+ function visitCorrelatedSubquery(csq) {
202
+ visitCompoundKey(csq.correlation.parentField);
203
+ visitCompoundKey(csq.correlation.childField);
204
+ mix(csq.hidden === void 0 ? TAG_UNDEF : csq.hidden ? TAG_TRUE : TAG_FALSE);
205
+ mixOptionalSystem(csq.system);
206
+ visitAST(csq.subquery);
207
+ }
208
+ function visitAST(ast) {
209
+ mix(TAG_OBJ);
210
+ visitOptionalString(ast.schema);
211
+ mixString(ast.table);
212
+ visitOptionalString(ast.alias);
213
+ if (ast.where === void 0) mix(TAG_UNDEF);
214
+ else visitCondition(ast.where);
215
+ const related = ast.related;
216
+ if (related === void 0) mix(TAG_UNDEF);
217
+ else {
218
+ mix(related.length);
219
+ for (let i = 0; i < related.length; i++) visitCorrelatedSubquery(related[i]);
220
+ }
221
+ const start = ast.start;
222
+ if (start === void 0) mix(TAG_UNDEF);
223
+ else {
224
+ mix(start.exclusive ? TAG_TRUE : TAG_FALSE);
225
+ visitValue(start.row);
226
+ }
227
+ if (ast.limit === void 0) mix(TAG_UNDEF);
228
+ else {
229
+ mix(TAG_INT);
230
+ mixNumber(ast.limit);
231
+ }
232
+ visitOrdering(ast.orderBy);
233
+ mix(TAG_END);
234
+ }
235
+ function hashAST(ast) {
236
+ const s1 = h1;
237
+ const s2 = h2;
238
+ try {
239
+ reset();
240
+ visitAST(ast);
241
+ return finalize();
242
+ } finally {
243
+ h1 = s1;
244
+ h2 = s2;
245
+ }
246
+ }
247
+ /**
248
+ * The identity of a custom query: its name and its arguments.
249
+ *
250
+ * Same walk, entered at a different node. `args` is arbitrary JSON, which is
251
+ * what `visitValue` already exists to handle. The leading tag keeps this hash
252
+ * space disjoint from `hashAST`'s -- both produce query IDs that live in the
253
+ * same namespace, so an AST must not be able to fold to the same words as some
254
+ * name and args.
255
+ */
256
+ function hashNameAndArgs(name, args) {
257
+ const s1 = h1;
258
+ const s2 = h2;
259
+ try {
260
+ reset();
261
+ mix(TAG_NAME_ARGS);
262
+ mixString(name);
263
+ visitValue(args);
264
+ return finalize();
265
+ } finally {
266
+ h1 = s1;
267
+ h2 = s2;
268
+ }
269
+ }
270
+ /**
271
+ * The identity of a query as the client sees it: its AST, the shape it returns,
272
+ * the system it was built for, and -- for a custom query -- the name and
273
+ * arguments it was declared with.
274
+ *
275
+ * Everything past the AST is here because it is part of what makes two queries
276
+ * different while leaving no trace, or an incomplete one, in the AST itself:
277
+ *
278
+ * - **name and args**: `nameAndArgs` reuses the AST it is given and only
279
+ * attaches a `CustomQueryID`, so without these two different named queries
280
+ * over the same table would be indistinguishable.
281
+ * - **system**: a query stamps it onto every `related` entry and every `exists`
282
+ * correlation it builds, so it is already hashed via
283
+ * {@link visitCorrelatedSubquery} -- but a query with neither has nowhere to
284
+ * put it, and would otherwise hash the same whether it was built for the
285
+ * client or for permissions.
286
+ * - **currentJunction**: builder state, set on the sub-query handed to a
287
+ * two-hop relationship's callback, which makes `limit` and `orderBy` throw.
288
+ * It leaves no trace in the AST at all, so two queries that differ only in
289
+ * whether those methods work would otherwise be indistinguishable.
290
+ *
291
+ * The name and args are taken apart rather than as a `CustomQueryID` because
292
+ * that type lives in `zql`, which is above this package; `hashNameAndArgs`
293
+ * splits them the same way.
294
+ */
295
+ function hashOfQueryInternals(ast, format, system, currentJunction, customQueryName, customQueryArgs) {
296
+ const s1 = h1;
297
+ const s2 = h2;
298
+ try {
299
+ reset();
300
+ visitAST(ast);
301
+ mix(TAG_FORMAT);
302
+ visitValue(format);
303
+ mixSystem(system);
304
+ if (currentJunction === void 0) mix(TAG_UNDEF);
305
+ else {
306
+ mix(TAG_JUNCTION);
307
+ mixString(currentJunction);
308
+ }
309
+ if (customQueryName === void 0) mix(TAG_UNDEF);
310
+ else {
311
+ mix(TAG_NAME_ARGS);
312
+ mixString(customQueryName);
313
+ visitValue(customQueryArgs);
314
+ }
315
+ return finalize();
316
+ } finally {
317
+ h1 = s1;
318
+ h2 = s2;
319
+ }
320
+ }
321
+ //#endregion
322
+ export { hashAST, hashNameAndArgs, hashOfQueryInternals };
323
+
324
+ //# sourceMappingURL=query-hash-visitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-hash-visitor.js","names":[],"sources":["../../../../zero-protocol/src/query-hash-visitor.ts"],"sourcesContent":["import {unreachable} from '../../shared/src/asserts.ts';\n// These live in shared/src/xxhash32.ts, imported via hash.ts's re-export\n// rather than directly: the direct zero-protocol -> shared/xxhash32.ts edge\n// makes tsc 7.0.2 mis-evaluate Query-type relations in other programs --\n// phantom TS2345s in zql's runnable-query-impl.ts under the packages/zero\n// declaration build, and zero-client silently losing the type error that\n// custom.test.ts pins with a ts-expect-error directive. Bisected cold-cache\n// to that one import statement; the hash.ts route checks clean everywhere.\n// Collapse to a direct import when TypeScript is upgraded past this.\nimport {\n avalanche32,\n PRIME32_1,\n PRIME32_5,\n round32,\n} from '../../shared/src/hash.ts';\nimport type {Format} from '../../zero-types/src/format.ts';\n\n/**\n * Hashes a normalized AST by visiting it, rather than by rendering it to JSON\n * and hashing the bytes. `hashOfAST` and `hashOfNameAndArgs` in\n * `query-hash.ts` are both built on this, so these digests are the query IDs\n * the client registers and the transformation hashes the server stores.\n *\n * The pipeline this replaced was\n * `h64(JSON.stringify(normalizeAST(ast))).toString(36)`, which materialized\n * the whole AST as a string, UTF-8 encoded it, and only then hashed it — three\n * passes over the data, two of which existed purely to produce bytes to hash.\n *\n * A visitor can fold values into the hash state as it walks, so nothing is\n * materialized at all. The primitives that make that pay off:\n *\n * - Two 32-bit accumulators held in module-level `let`s, so the \"state\" is\n * plain numbers in registers rather than an object being threaded through\n * the walk.\n * - xxHash32's own round and final mix, shared with `shared/src/hash.ts` via\n * `shared/src/xxhash32.ts`. Only the ingestion differs: that one feeds them\n * UTF-8 bytes, this one feeds them words straight out of the structure.\n * - Strings folded straight from `charCodeAt`, two UTF-16 units at a time, into\n * one 32-bit word. No UTF-8 encoding, and half the loop iterations a\n * byte-oriented hash would need over ASCII.\n *\n * These digests do not agree with xxHash32 over the old JSON encoding, and are\n * not meant to: nothing recomputes a hash produced elsewhere and compares it,\n * so the encoding is free to change as long as every writer moves together.\n * What it does have to give is distinct words for structurally distinct\n * queries — a 64-bit digest cannot promise that absolutely, but every field\n * and node kind must at least reach the mixer, and no two of them may be\n * written so as to be confusable. `query-hash-visitor.test.ts` holds that\n * line with a corpus and a per-field mutation test.\n *\n * The walk is deliberately specialized to the AST shape rather than written as\n * a generic JSON-value walk. That is not premature: a generic version was\n * measured alongside this one and came out ~2.4x slower, no better than the\n * `JSON.stringify` it was meant to replace, because `for...in` and the\n * megamorphic property loads cost about what the native stringify costs. Only\n * `visitValue` below stays generic, for the two places an AST holds arbitrary\n * JSON: a literal's value and a bound's row.\n */\nimport type {\n AST,\n Condition,\n CorrelatedSubquery,\n Ordering,\n System,\n ValuePosition,\n} from './ast.ts';\n\n// Two 32-bit lanes, combined into 64 bits at the end. Module-level so the walk\n// mutates registers rather than allocating or threading state through it.\nlet h1 = 0;\nlet h2 = 0;\n\n/**\n * Fold one 32-bit word into both lanes.\n *\n * Both lanes run xxHash32's own round; only their starting values differ, so\n * they diverge immediately and stay diverged. That is the same construction\n * `h64` uses to widen xxHash32 past 32 bits, just fed words taken from a\n * structure rather than bytes taken from a string.\n */\nfunction mix(w: number): void {\n h1 = round32(h1, w);\n h2 = round32(h2, w);\n}\n\n/**\n * Fold a string, two UTF-16 units per word.\n *\n * The leading length keeps `['ab','c']` and `['a','bc']` apart. STR_MARK is\n * folded into that same word rather than mixed separately: it costs nothing,\n * and since every other count written by this file is a small array length, a\n * string can never fold like one.\n */\nfunction mixString(s: string): void {\n const n = s.length;\n mix(n | STR_MARK);\n let i = 0;\n for (; i + 1 < n; i += 2) {\n mix(s.charCodeAt(i) | (s.charCodeAt(i + 1) << 16));\n }\n if (i < n) {\n mix(s.charCodeAt(i));\n }\n}\n\n// A DataView with an explicit byte order, not a Float64Array/Int32Array\n// aliasing pair: typed arrays read the buffer in host byte order, and these\n// digests are persisted, so a big-endian runtime would fold a float's words\n// swapped and disagree with every little-endian peer.\nconst numView = new DataView(new ArrayBuffer(8));\n\n/** Fold a number: one word for an int32, two for anything else. */\nfunction mixNumber(n: number): void {\n if ((n | 0) === n) {\n mix(n);\n } else {\n numView.setFloat64(0, n, true);\n mix(numView.getInt32(0, true));\n mix(numView.getInt32(4, true));\n }\n}\n\n// Structural tags. Distinct constants so that, say, a string \"1\" and the\n// number 1 cannot fold to the same state.\nconst TAG_NULL = 0x1001;\nconst TAG_FALSE = 0x1002;\nconst TAG_TRUE = 0x1003;\nconst TAG_INT = 0x1004;\nconst TAG_FLOAT = 0x1005;\nconst TAG_ARR = 0x1007;\nconst TAG_OBJ = 0x1008;\nconst TAG_END = 0x1009;\nconst TAG_UNDEF = 0x100a;\n\n// Discriminators for the AST's own unions, kept distinct from the value tags\n// above so a node kind can never fold like a value of some other type.\nconst TAG_LITERAL = 0x2001;\nconst TAG_COLUMN = 0x2002;\nconst TAG_STATIC = 0x2003;\nconst TAG_SIMPLE = 0x2004;\nconst TAG_SUBQUERY = 0x2005;\nconst TAG_AND = 0x2006;\nconst TAG_OR = 0x2007;\nconst TAG_FORMAT = 0x2008;\nconst TAG_NAME_ARGS = 0x2009;\n// `System` is a closed set of three, so it folds as one word rather than as a\n// string -- on an AST it appears once per correlated subquery, so this is on\n// the walk's hot path. The switch below is exhaustive, so adding a member is a\n// type error rather than a silent collision with an existing one.\nconst TAG_SYSTEM_PERMISSIONS = 0x200a;\nconst TAG_SYSTEM_CLIENT = 0x200b;\nconst TAG_SYSTEM_TEST = 0x200c;\nconst TAG_JUNCTION = 0x200d;\n\n// Set on a string's length word. High enough that no array length reaches it.\nconst STR_MARK = 0x40000000;\n\nfunction reset(): void {\n h1 = PRIME32_5;\n h2 = PRIME32_1;\n}\n\n/** Collapse the two lanes into one 64-bit value, avalanching each first. */\nfunction finalize(): string {\n return (\n avalanche32(h1).toString(36).padStart(7, '0') +\n avalanche32(h2).toString(36).padStart(7, '0')\n );\n}\n\n// ---------------------------------------------------------------------------\n// The generic part: arbitrary JSON, for literal values and bound rows.\n// ---------------------------------------------------------------------------\n\nfunction visitValue(v: unknown): void {\n switch (typeof v) {\n case 'string':\n mixString(v);\n return;\n case 'number':\n // NaN and Infinity are null by the time they reach the wire, because\n // that is what JSON.stringify writes for them. Two queries identical on\n // the wire must not get different IDs.\n if (!Number.isFinite(v)) {\n mix(TAG_NULL);\n return;\n }\n mix((v | 0) === v ? TAG_INT : TAG_FLOAT);\n mixNumber(v);\n return;\n case 'boolean':\n mix(v ? TAG_TRUE : TAG_FALSE);\n return;\n case 'object': {\n if (v === null) {\n mix(TAG_NULL);\n return;\n }\n if (Array.isArray(v)) {\n mix(TAG_ARR);\n for (let i = 0; i < v.length; i++) {\n // An `undefined` element is `null` by the time it reaches the wire,\n // because that is what JSON.stringify makes of it. Dropping it\n // instead would fold `[undefined]` onto `[]`.\n const e: unknown = v[i];\n visitValue(e === undefined ? null : e);\n }\n mix(TAG_END);\n return;\n }\n mix(TAG_OBJ);\n // Sorted, so the digest is a function of the object's contents and not\n // of its key order. Rows and custom-query args round-trip through\n // Postgres JSONB, which reorders keys; an order-sensitive digest made\n // reloaded query records look changed. (The AST's own fields don't need\n // this: visitAST reads them in a fixed order by name.)\n const keys = Object.keys(v).sort();\n for (const k of keys) {\n const val = (v as Record<string, unknown>)[k];\n if (val === undefined) {\n continue; // as JSON.stringify does\n }\n mixString(k);\n visitValue(val);\n }\n mix(TAG_END);\n return;\n }\n default:\n // `undefined` and functions as an object's value: dropped, as\n // JSON.stringify drops them. Array elements are handled above.\n return;\n }\n}\n\n// ---------------------------------------------------------------------------\n// The specialized part: the AST's own shape.\n// ---------------------------------------------------------------------------\n\nfunction visitOptionalString(s: string | undefined): void {\n if (s === undefined) {\n mix(TAG_UNDEF);\n } else {\n mixString(s);\n }\n}\n\nfunction mixOptionalSystem(system: System | undefined): void {\n if (system === undefined) {\n mix(TAG_UNDEF);\n } else {\n mixSystem(system);\n }\n}\n\nfunction mixSystem(system: System): void {\n switch (system) {\n case 'permissions':\n mix(TAG_SYSTEM_PERMISSIONS);\n break;\n case 'client':\n mix(TAG_SYSTEM_CLIENT);\n break;\n case 'test':\n mix(TAG_SYSTEM_TEST);\n break;\n default:\n unreachable(system);\n }\n}\n\nfunction visitCompoundKey(k: readonly string[]): void {\n mix(k.length);\n for (let i = 0; i < k.length; i++) {\n mixString(k[i]);\n }\n}\n\nfunction visitOrdering(o: Ordering | undefined): void {\n if (o === undefined) {\n mix(TAG_UNDEF);\n return;\n }\n mix(o.length);\n for (let i = 0; i < o.length; i++) {\n const [field, dir] = o[i];\n mixString(field);\n mix(dir === 'asc' ? TAG_TRUE : TAG_FALSE);\n }\n}\n\nfunction visitValuePosition(v: ValuePosition): void {\n switch (v.type) {\n case 'literal':\n mix(TAG_LITERAL);\n visitValue(v.value);\n return;\n case 'column':\n mix(TAG_COLUMN);\n mixString(v.name);\n return;\n case 'static': {\n mix(TAG_STATIC);\n mixString(v.anchor);\n if (typeof v.field === 'string') {\n mixString(v.field);\n } else {\n visitCompoundKey(v.field);\n }\n return;\n }\n default:\n unreachable(v);\n }\n}\n\nfunction visitCondition(c: Condition): void {\n switch (c.type) {\n case 'simple':\n mix(TAG_SIMPLE);\n mixString(c.op);\n visitValuePosition(c.left);\n visitValuePosition(c.right);\n return;\n case 'correlatedSubquery':\n mix(TAG_SUBQUERY);\n mixString(c.op);\n mix(c.flip === undefined ? TAG_UNDEF : c.flip ? TAG_TRUE : TAG_FALSE);\n mix(c.scalar === undefined ? TAG_UNDEF : c.scalar ? TAG_TRUE : TAG_FALSE);\n visitCorrelatedSubquery(c.related);\n return;\n default: {\n c.type satisfies 'and' | 'or';\n mix(c.type === 'and' ? TAG_AND : TAG_OR);\n const conds = c.conditions;\n mix(conds.length);\n for (let i = 0; i < conds.length; i++) {\n visitCondition(conds[i]);\n }\n return;\n }\n }\n}\n\nfunction visitCorrelatedSubquery(csq: CorrelatedSubquery): void {\n visitCompoundKey(csq.correlation.parentField);\n visitCompoundKey(csq.correlation.childField);\n mix(csq.hidden === undefined ? TAG_UNDEF : csq.hidden ? TAG_TRUE : TAG_FALSE);\n mixOptionalSystem(csq.system);\n visitAST(csq.subquery);\n}\n\nfunction visitAST(ast: AST): void {\n mix(TAG_OBJ);\n visitOptionalString(ast.schema);\n mixString(ast.table);\n visitOptionalString(ast.alias);\n\n if (ast.where === undefined) {\n mix(TAG_UNDEF);\n } else {\n visitCondition(ast.where);\n }\n\n const related = ast.related;\n if (related === undefined) {\n mix(TAG_UNDEF);\n } else {\n mix(related.length);\n for (let i = 0; i < related.length; i++) {\n visitCorrelatedSubquery(related[i]);\n }\n }\n\n const start = ast.start;\n if (start === undefined) {\n mix(TAG_UNDEF);\n } else {\n mix(start.exclusive ? TAG_TRUE : TAG_FALSE);\n visitValue(start.row);\n }\n\n if (ast.limit === undefined) {\n mix(TAG_UNDEF);\n } else {\n // Tagged, because this is the one optional field whose present and absent\n // forms would otherwise both write a single bare word: an untagged\n // `limit: 4106` is the same word as TAG_UNDEF. The other optionals are\n // safe -- a present string carries STR_MARK, a condition or bound leads\n // with its own kind tag, and `related`/`orderBy` write a count followed by\n // that many items, so their streams diverge straight after.\n mix(TAG_INT);\n mixNumber(ast.limit);\n }\n\n visitOrdering(ast.orderBy);\n mix(TAG_END);\n}\n\nexport function hashAST(ast: AST): string {\n // Save and restore the lanes: `visitValue` reads properties of arbitrary\n // runtime objects, and a getter is free to ask for another hash mid-walk.\n // Without this, the inner call's reset() would corrupt the outer digest.\n const s1 = h1;\n const s2 = h2;\n try {\n reset();\n visitAST(ast);\n return finalize();\n } finally {\n h1 = s1;\n h2 = s2;\n }\n}\n\n/**\n * The identity of a custom query: its name and its arguments.\n *\n * Same walk, entered at a different node. `args` is arbitrary JSON, which is\n * what `visitValue` already exists to handle. The leading tag keeps this hash\n * space disjoint from `hashAST`'s -- both produce query IDs that live in the\n * same namespace, so an AST must not be able to fold to the same words as some\n * name and args.\n */\nexport function hashNameAndArgs(\n name: string,\n args: readonly unknown[],\n): string {\n const s1 = h1;\n const s2 = h2;\n try {\n reset();\n mix(TAG_NAME_ARGS);\n mixString(name);\n visitValue(args);\n return finalize();\n } finally {\n h1 = s1;\n h2 = s2;\n }\n}\n\n/**\n * The identity of a query as the client sees it: its AST, the shape it returns,\n * the system it was built for, and -- for a custom query -- the name and\n * arguments it was declared with.\n *\n * Everything past the AST is here because it is part of what makes two queries\n * different while leaving no trace, or an incomplete one, in the AST itself:\n *\n * - **name and args**: `nameAndArgs` reuses the AST it is given and only\n * attaches a `CustomQueryID`, so without these two different named queries\n * over the same table would be indistinguishable.\n * - **system**: a query stamps it onto every `related` entry and every `exists`\n * correlation it builds, so it is already hashed via\n * {@link visitCorrelatedSubquery} -- but a query with neither has nowhere to\n * put it, and would otherwise hash the same whether it was built for the\n * client or for permissions.\n * - **currentJunction**: builder state, set on the sub-query handed to a\n * two-hop relationship's callback, which makes `limit` and `orderBy` throw.\n * It leaves no trace in the AST at all, so two queries that differ only in\n * whether those methods work would otherwise be indistinguishable.\n *\n * The name and args are taken apart rather than as a `CustomQueryID` because\n * that type lives in `zql`, which is above this package; `hashNameAndArgs`\n * splits them the same way.\n */\nexport function hashOfQueryInternals(\n ast: AST,\n format: Format,\n system: System,\n currentJunction: string | undefined,\n customQueryName: string | undefined,\n customQueryArgs: readonly unknown[] | undefined,\n): string {\n const s1 = h1;\n const s2 = h2;\n try {\n reset();\n visitAST(ast);\n mix(TAG_FORMAT);\n visitValue(format);\n mixSystem(system);\n if (currentJunction === undefined) {\n mix(TAG_UNDEF);\n } else {\n mix(TAG_JUNCTION);\n mixString(currentJunction);\n }\n if (customQueryName === undefined) {\n mix(TAG_UNDEF);\n } else {\n mix(TAG_NAME_ARGS);\n mixString(customQueryName);\n visitValue(customQueryArgs);\n }\n return finalize();\n } finally {\n h1 = s1;\n h2 = s2;\n }\n}\n"],"mappings":"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"}
@@ -1,4 +1,9 @@
1
- import { type AST } from './ast.ts';
1
+ import { type AST, type NormalizedAST } from './ast.ts';
2
2
  export declare function hashOfAST(ast: AST): string;
3
- export declare function hashOfNameAndArgs(name: string, args: readonly unknown[]): string;
3
+ /**
4
+ * The hash of an AST that is already normalized, e.g. the AST of a query
5
+ * whose builder kept it normalized as it built it.
6
+ */
7
+ export declare function hashOfNormalizedAST(ast: NormalizedAST): string;
8
+ export { hashNameAndArgs as hashOfNameAndArgs } from './query-hash-visitor.ts';
4
9
  //# sourceMappingURL=query-hash.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-hash.d.ts","sourceRoot":"","sources":["../../../../zero-protocol/src/query-hash.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,GAAG,EAAC,MAAM,UAAU,CAAC;AAIhD,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAS1C;AAED,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,MAAM,CAGR"}
1
+ {"version":3,"file":"query-hash.d.ts","sourceRoot":"","sources":["../../../../zero-protocol/src/query-hash.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,GAAG,EAAE,KAAK,aAAa,EAAC,MAAM,UAAU,CAAC;AAKpE,wBAAgB,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAE1C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAQ9D;AAED,OAAO,EAAC,eAAe,IAAI,iBAAiB,EAAC,MAAM,yBAAyB,CAAC"}
@@ -1,19 +1,22 @@
1
1
  import { normalizeAST } from "./ast.js";
2
- import { h64 } from "../../shared/src/hash.js";
2
+ import { hashAST } from "./query-hash-visitor.js";
3
3
  //#region ../zero-protocol/src/query-hash.ts
4
4
  var hashCache = /* @__PURE__ */ new WeakMap();
5
5
  function hashOfAST(ast) {
6
- const normalized = normalizeAST(ast);
7
- const cached = hashCache.get(normalized);
6
+ return hashOfNormalizedAST(normalizeAST(ast));
7
+ }
8
+ /**
9
+ * The hash of an AST that is already normalized, e.g. the AST of a query
10
+ * whose builder kept it normalized as it built it.
11
+ */
12
+ function hashOfNormalizedAST(ast) {
13
+ const cached = hashCache.get(ast);
8
14
  if (cached) return cached;
9
- const hash = h64(JSON.stringify(normalized)).toString(36);
10
- hashCache.set(normalized, hash);
15
+ const hash = hashAST(ast);
16
+ hashCache.set(ast, hash);
11
17
  return hash;
12
18
  }
13
- function hashOfNameAndArgs(name, args) {
14
- return h64(`${name}:${JSON.stringify(args)}`).toString(36);
15
- }
16
19
  //#endregion
17
- export { hashOfAST, hashOfNameAndArgs };
20
+ export { hashOfAST };
18
21
 
19
22
  //# sourceMappingURL=query-hash.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-hash.js","names":[],"sources":["../../../../zero-protocol/src/query-hash.ts"],"sourcesContent":["import {h64} from '../../shared/src/hash.ts';\nimport {normalizeAST, type AST} from './ast.ts';\n\nconst hashCache = new WeakMap<AST, string>();\n\nexport function hashOfAST(ast: AST): string {\n const normalized = normalizeAST(ast);\n const cached = hashCache.get(normalized);\n if (cached) {\n return cached;\n }\n const hash = h64(JSON.stringify(normalized)).toString(36);\n hashCache.set(normalized, hash);\n return hash;\n}\n\nexport function hashOfNameAndArgs(\n name: string,\n args: readonly unknown[],\n): string {\n const argsString = JSON.stringify(args);\n return h64(`${name}:${argsString}`).toString(36);\n}\n"],"mappings":";;;AAGA,IAAM,4BAAY,IAAI,QAAqB;AAE3C,SAAgB,UAAU,KAAkB;CAC1C,MAAM,aAAa,aAAa,GAAG;CACnC,MAAM,SAAS,UAAU,IAAI,UAAU;CACvC,IAAI,QACF,OAAO;CAET,MAAM,OAAO,IAAI,KAAK,UAAU,UAAU,CAAC,EAAE,SAAS,EAAE;CACxD,UAAU,IAAI,YAAY,IAAI;CAC9B,OAAO;AACT;AAEA,SAAgB,kBACd,MACA,MACQ;CAER,OAAO,IAAI,GAAG,KAAK,GADA,KAAK,UAAU,IACZ,GAAY,EAAE,SAAS,EAAE;AACjD"}
1
+ {"version":3,"file":"query-hash.js","names":[],"sources":["../../../../zero-protocol/src/query-hash.ts"],"sourcesContent":["import {normalizeAST, type AST, type NormalizedAST} from './ast.ts';\nimport {hashAST} from './query-hash-visitor.ts';\n\nconst hashCache = new WeakMap<AST, string>();\n\nexport function hashOfAST(ast: AST): string {\n return hashOfNormalizedAST(normalizeAST(ast));\n}\n\n/**\n * The hash of an AST that is already normalized, e.g. the AST of a query\n * whose builder kept it normalized as it built it.\n */\nexport function hashOfNormalizedAST(ast: NormalizedAST): string {\n const cached = hashCache.get(ast);\n if (cached) {\n return cached;\n }\n const hash = hashAST(ast);\n hashCache.set(ast, hash);\n return hash;\n}\n\nexport {hashNameAndArgs as hashOfNameAndArgs} from './query-hash-visitor.ts';\n"],"mappings":";;;AAGA,IAAM,4BAAY,IAAI,QAAqB;AAE3C,SAAgB,UAAU,KAAkB;CAC1C,OAAO,oBAAoB,aAAa,GAAG,CAAC;AAC9C;;;;;AAMA,SAAgB,oBAAoB,KAA4B;CAC9D,MAAM,SAAS,UAAU,IAAI,GAAG;CAChC,IAAI,QACF,OAAO;CAET,MAAM,OAAO,QAAQ,GAAG;CACxB,UAAU,IAAI,KAAK,IAAI;CACvB,OAAO;AACT"}
@@ -25,10 +25,11 @@ export type UseSuspenseQueryOptions = UseQueryOptions & {
25
25
  * Whether to suspend until:
26
26
  * - 'partial': the query has partial results (partial array or defined
27
27
  * value for singular results) which may be of result type 'unknown',
28
- * or the query result type is 'complete' (in which case results may be
29
- * empty). This is useful for suspending until there are partial
30
- * optimistic local results, or the query has completed loading from the
31
- * server.
28
+ * or the query result type is 'complete' or 'cached' (in which case
29
+ * results may be empty: a server-confirmed empty answer, from this
30
+ * connection or a previous one, is something to render). This is useful
31
+ * for suspending until there are partial optimistic local results, or
32
+ * the query has completed loading from the server.
32
33
  * - 'complete': the query result type is 'complete'.
33
34
  *
34
35
  * Default is 'partial'.
@@ -1 +1 @@
1
- {"version":3,"file":"use-query.d.ts","sourceRoot":"","sources":["../../../../zero-react/src/use-query.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-query.d.ts","sourceRoot":"","sources":["../../../../zero-react/src/use-query.tsx"],"names":[],"mappings":"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"}