@rocicorp/zero 1.11.0 → 1.11.2

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 (737) hide show
  1. package/out/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.154.0/helpers/esm}/usingCtx.js +2 -2
  2. package/out/analyze-query/src/analyze-cli.js +2 -1
  3. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  4. package/out/analyze-query/src/bin-analyze.js +5 -3
  5. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  6. package/out/analyze-query/src/bin-transform.js +3 -2
  7. package/out/analyze-query/src/bin-transform.js.map +1 -1
  8. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  9. package/out/ast-to-zql/src/bin.js +3 -2
  10. package/out/ast-to-zql/src/bin.js.map +1 -1
  11. package/out/ast-to-zql/src/format.js.map +1 -1
  12. package/out/datadog/src/datadog-log-sink.js +5 -4
  13. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  14. package/out/otel/src/log-options.js.map +1 -1
  15. package/out/replicache/src/btree/node.js +13 -11
  16. package/out/replicache/src/btree/node.js.map +1 -1
  17. package/out/replicache/src/btree/read.js +4 -2
  18. package/out/replicache/src/btree/read.js.map +1 -1
  19. package/out/replicache/src/btree/splice.js.map +1 -1
  20. package/out/replicache/src/btree/write.js +9 -5
  21. package/out/replicache/src/btree/write.js.map +1 -1
  22. package/out/replicache/src/config.js +1 -2
  23. package/out/replicache/src/connection-loop.js.map +1 -1
  24. package/out/replicache/src/dag/chunk.js +1 -1
  25. package/out/replicache/src/dag/gc.js.map +1 -1
  26. package/out/replicache/src/dag/lazy-store.js +8 -7
  27. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  28. package/out/replicache/src/dag/store-impl.js +1 -1
  29. package/out/replicache/src/dag/store-impl.js.map +1 -1
  30. package/out/replicache/src/dag/visitor.js.map +1 -1
  31. package/out/replicache/src/db/commit.js +5 -3
  32. package/out/replicache/src/db/commit.js.map +1 -1
  33. package/out/replicache/src/db/read.js +1 -1
  34. package/out/replicache/src/db/read.js.map +1 -1
  35. package/out/replicache/src/db/rebase.js.map +1 -1
  36. package/out/replicache/src/db/write.js +5 -2
  37. package/out/replicache/src/db/write.js.map +1 -1
  38. package/out/replicache/src/deleted-clients.js +3 -2
  39. package/out/replicache/src/deleted-clients.js.map +1 -1
  40. package/out/replicache/src/expo-sqlite.js +1 -2
  41. package/out/replicache/src/frozen-json.js +1 -1
  42. package/out/replicache/src/frozen-json.js.map +1 -1
  43. package/out/replicache/src/get-default-puller.js +1 -1
  44. package/out/replicache/src/hash.js +1 -1
  45. package/out/replicache/src/hash.js.map +1 -1
  46. package/out/replicache/src/impl.js +1 -2
  47. package/out/replicache/src/index-defs.js +5 -3
  48. package/out/replicache/src/index-defs.js.map +1 -1
  49. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  50. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  51. package/out/replicache/src/kv/idb-store.js +1 -1
  52. package/out/replicache/src/kv/idb-store.js.map +1 -1
  53. package/out/replicache/src/kv/mem-fallback-store.js +1 -1
  54. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -1
  55. package/out/replicache/src/kv/mem-store.js.map +1 -1
  56. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  57. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  58. package/out/replicache/src/kv/read-impl.js.map +1 -1
  59. package/out/replicache/src/kv/sqlite-store.js +1 -1
  60. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  61. package/out/replicache/src/kv/write-impl-base.js +4 -1
  62. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  63. package/out/replicache/src/kv/write-impl.js.map +1 -1
  64. package/out/replicache/src/log-options.js +2 -1
  65. package/out/replicache/src/log-options.js.map +1 -1
  66. package/out/replicache/src/make-idb-name.js +1 -1
  67. package/out/replicache/src/new-client-channel.js +9 -7
  68. package/out/replicache/src/new-client-channel.js.map +1 -1
  69. package/out/replicache/src/on-persist-channel.js +1 -1
  70. package/out/replicache/src/on-persist-channel.js.map +1 -1
  71. package/out/replicache/src/op-sqlite.js +1 -2
  72. package/out/replicache/src/pending-mutations.js +2 -1
  73. package/out/replicache/src/pending-mutations.js.map +1 -1
  74. package/out/replicache/src/persist/client-gc.js +2 -2
  75. package/out/replicache/src/persist/client-gc.js.map +1 -1
  76. package/out/replicache/src/persist/client-group-gc.js +2 -2
  77. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  78. package/out/replicache/src/persist/client-groups.js +1 -1
  79. package/out/replicache/src/persist/client-groups.js.map +1 -1
  80. package/out/replicache/src/persist/clients.js +1 -1
  81. package/out/replicache/src/persist/clients.js.map +1 -1
  82. package/out/replicache/src/persist/collect-idb-databases.js +5 -4
  83. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  84. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  85. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  86. package/out/replicache/src/persist/heartbeat.js +2 -2
  87. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  88. package/out/replicache/src/persist/idb-databases-store.js +1 -1
  89. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  90. package/out/replicache/src/persist/make-client-id.js +1 -1
  91. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  92. package/out/replicache/src/persist/persist.js +3 -2
  93. package/out/replicache/src/persist/persist.js.map +1 -1
  94. package/out/replicache/src/persist/refresh.js +8 -5
  95. package/out/replicache/src/persist/refresh.js.map +1 -1
  96. package/out/replicache/src/process-scheduler.js.map +1 -1
  97. package/out/replicache/src/replicache-impl.js +3 -3
  98. package/out/replicache/src/replicache-impl.js.map +1 -1
  99. package/out/replicache/src/scan-iterator.js.map +1 -1
  100. package/out/replicache/src/scan-options.js +7 -6
  101. package/out/replicache/src/scan-options.js.map +1 -1
  102. package/out/replicache/src/sqlite.js +1 -2
  103. package/out/replicache/src/subscriptions.js +1 -1
  104. package/out/replicache/src/subscriptions.js.map +1 -1
  105. package/out/replicache/src/sync/diff.js +3 -1
  106. package/out/replicache/src/sync/diff.js.map +1 -1
  107. package/out/replicache/src/sync/ids.js.map +1 -1
  108. package/out/replicache/src/sync/patch.js +2 -4
  109. package/out/replicache/src/sync/patch.js.map +1 -1
  110. package/out/replicache/src/sync/pull.js +3 -1
  111. package/out/replicache/src/sync/pull.js.map +1 -1
  112. package/out/replicache/src/sync/push.js.map +1 -1
  113. package/out/replicache/src/sync/request-id.js +1 -1
  114. package/out/replicache/src/sync/request-id.js.map +1 -1
  115. package/out/replicache/src/transactions.js +1 -1
  116. package/out/replicache/src/transactions.js.map +1 -1
  117. package/out/shared/src/arrays.js +4 -1
  118. package/out/shared/src/arrays.js.map +1 -1
  119. package/out/shared/src/asserts.js +1 -1
  120. package/out/shared/src/bigint-json.js.map +1 -1
  121. package/out/shared/src/broadcast-channel.js +1 -1
  122. package/out/shared/src/btree-set.js +11 -8
  123. package/out/shared/src/btree-set.js.map +1 -1
  124. package/out/shared/src/cache.js.map +1 -1
  125. package/out/shared/src/config.js +1 -1
  126. package/out/shared/src/custom-key-map.js.map +1 -1
  127. package/out/shared/src/custom-key-set.js.map +1 -1
  128. package/out/shared/src/deep-clone.js +1 -1
  129. package/out/shared/src/document-visible.js.map +1 -1
  130. package/out/shared/src/dotenv.js.map +1 -1
  131. package/out/shared/src/error.js +1 -1
  132. package/out/shared/src/error.js.map +1 -1
  133. package/out/shared/src/hash.js +2 -2
  134. package/out/shared/src/hash.js.map +1 -1
  135. package/out/shared/src/iterables.js.map +1 -1
  136. package/out/shared/src/json-schema.js.map +1 -1
  137. package/out/shared/src/json.js.map +1 -1
  138. package/out/shared/src/logging-test-utils.js +1 -1
  139. package/out/shared/src/logging.js +1 -1
  140. package/out/shared/src/logging.js.map +1 -1
  141. package/out/shared/src/navigator.js +1 -1
  142. package/out/shared/src/options.js +9 -12
  143. package/out/shared/src/options.js.map +1 -1
  144. package/out/shared/src/promise-race.js.map +1 -1
  145. package/out/shared/src/queue.js.map +1 -1
  146. package/out/shared/src/record-proxy.js.map +1 -1
  147. package/out/shared/src/ring-buffer.js.map +1 -1
  148. package/out/shared/src/size-of-value.js +7 -10
  149. package/out/shared/src/size-of-value.js.map +1 -1
  150. package/out/shared/src/sorted-entries.js.map +1 -1
  151. package/out/shared/src/tdigest-schema.js.map +1 -1
  152. package/out/shared/src/tdigest.js.map +1 -1
  153. package/out/shared/src/valita.js +1 -1
  154. package/out/shared/src/valita.js.map +1 -1
  155. package/out/z2s/src/compiler.js +2 -4
  156. package/out/z2s/src/compiler.js.map +1 -1
  157. package/out/z2s/src/sql.js +1 -1
  158. package/out/z2s/src/sql.js.map +1 -1
  159. package/out/zero/package.js +212 -189
  160. package/out/zero/package.js.map +1 -1
  161. package/out/zero/src/adapters/drizzle.js +1 -2
  162. package/out/zero/src/adapters/kysely.js +1 -2
  163. package/out/zero/src/adapters/pg.js +1 -2
  164. package/out/zero/src/adapters/postgresjs.js +1 -2
  165. package/out/zero/src/adapters/prisma.js +1 -2
  166. package/out/zero/src/analyze.js +1 -2
  167. package/out/zero/src/change-protocol/v0.js +1 -2
  168. package/out/zero/src/expo-sqlite.js +1 -2
  169. package/out/zero/src/op-sqlite.js +1 -2
  170. package/out/zero/src/react-native.js.map +1 -1
  171. package/out/zero/src/sqlite.js +1 -2
  172. package/out/zero/src/zero-cache-dev.js +10 -9
  173. package/out/zero/src/zero-cache-dev.js.map +1 -1
  174. package/out/zero/src/zero-out.js +2 -1
  175. package/out/zero/src/zero-out.js.map +1 -1
  176. package/out/zero-cache/src/auth/auth.js +1 -1
  177. package/out/zero-cache/src/auth/auth.js.map +1 -1
  178. package/out/zero-cache/src/auth/jwt.js +4 -1
  179. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  180. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  181. package/out/zero-cache/src/auth/read-authorizer.js +3 -2
  182. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  183. package/out/zero-cache/src/auth/write-authorizer.js +5 -16
  184. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  185. package/out/zero-cache/src/config/network.js +1 -1
  186. package/out/zero-cache/src/config/network.js.map +1 -1
  187. package/out/zero-cache/src/config/server-context.js.map +1 -1
  188. package/out/zero-cache/src/config/zero-config.js +2 -2
  189. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  190. package/out/zero-cache/src/custom/fetch.js +1 -1
  191. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  192. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  193. package/out/zero-cache/src/db/create.js.map +1 -1
  194. package/out/zero-cache/src/db/index-predicate.js.map +1 -1
  195. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  196. package/out/zero-cache/src/db/migration-lite.js +1 -1
  197. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  198. package/out/zero-cache/src/db/migration.js +5 -3
  199. package/out/zero-cache/src/db/migration.js.map +1 -1
  200. package/out/zero-cache/src/db/pg-copy-binary.js +4 -3
  201. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  202. package/out/zero-cache/src/db/pg-copy.js +0 -1
  203. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  204. package/out/zero-cache/src/db/pg-to-lite.js +1 -1
  205. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  206. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  207. package/out/zero-cache/src/db/specs.js +7 -5
  208. package/out/zero-cache/src/db/specs.js.map +1 -1
  209. package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
  210. package/out/zero-cache/src/db/transaction-pool.js +5 -3
  211. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  212. package/out/zero-cache/src/db/warmup.js.map +1 -1
  213. package/out/zero-cache/src/observability/events.js.map +1 -1
  214. package/out/zero-cache/src/observability/log-throttle.js.map +1 -1
  215. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  216. package/out/zero-cache/src/scripts/deploy-permissions.js +4 -2
  217. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  218. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  219. package/out/zero-cache/src/server/anonymous-otel-start.js +2 -1
  220. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  221. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  222. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  223. package/out/zero-cache/src/server/logging.js +1 -1
  224. package/out/zero-cache/src/server/logging.js.map +1 -1
  225. package/out/zero-cache/src/server/main.js.map +1 -1
  226. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  227. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  228. package/out/zero-cache/src/server/reaper.js +2 -2
  229. package/out/zero-cache/src/server/reaper.js.map +1 -1
  230. package/out/zero-cache/src/server/replicator.js.map +1 -1
  231. package/out/zero-cache/src/server/runner/run-worker.js +2 -1
  232. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  233. package/out/zero-cache/src/server/runner/runtime.js +2 -1
  234. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  235. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  236. package/out/zero-cache/src/server/shadow-syncer.js +1 -1
  237. package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
  238. package/out/zero-cache/src/server/slot-keeper.js.map +1 -1
  239. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -1
  240. package/out/zero-cache/src/server/syncer.js.map +1 -1
  241. package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
  242. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  243. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  244. package/out/zero-cache/src/services/analyze.js +1 -1
  245. package/out/zero-cache/src/services/analyze.js.map +1 -1
  246. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -1
  247. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  248. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  249. package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -1
  250. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  251. package/out/zero-cache/src/services/change-source/common/replica-schema.js +3 -3
  252. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  253. package/out/zero-cache/src/services/change-source/custom/change-source.js +1 -1
  254. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  255. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  256. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +3 -3
  257. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  258. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +1 -1
  259. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
  260. package/out/zero-cache/src/services/change-source/pg/change-source.js +4 -6
  261. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  262. package/out/zero-cache/src/services/change-source/pg/decommission.js +2 -1
  263. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  264. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +5 -3
  265. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  266. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  267. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  268. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +3 -2
  269. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  270. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  271. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +2 -2
  272. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -1
  273. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js +1 -1
  274. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js.map +1 -1
  275. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +3 -3
  276. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  277. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +1 -1
  278. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  279. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +13 -12
  280. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  281. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  282. package/out/zero-cache/src/services/change-source/pg/schema/published.js +1 -1
  283. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  284. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -1
  285. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +9 -6
  286. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  287. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -1
  288. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  289. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +1 -1
  290. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -1
  291. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  292. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  293. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  294. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  295. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  296. package/out/zero-cache/src/services/change-source/protocol/current.js +1 -1
  297. package/out/zero-cache/src/services/change-source/protocol/mod.js +1 -2
  298. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -1
  299. package/out/zero-cache/src/services/change-streamer/backfill-state.js +1 -1
  300. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -1
  301. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  302. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  303. package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
  304. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  305. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +2 -2
  306. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
  307. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -1
  308. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +4 -2
  309. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  310. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +21 -21
  311. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  312. package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
  313. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  314. package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
  315. package/out/zero-cache/src/services/change-streamer/forwarder.js +11 -10
  316. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  317. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +1 -1
  318. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -1
  319. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +3 -3
  320. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
  321. package/out/zero-cache/src/services/change-streamer/replica-poller.js +1 -1
  322. package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/restore-admission.js +12 -1
  324. package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/schema/init.js +1 -1
  326. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  328. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +1 -1
  330. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
  331. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  332. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +1 -1
  333. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
  334. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +1 -1
  335. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -1
  336. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -1
  337. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
  338. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +1 -1
  339. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
  340. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +1 -3
  341. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  342. package/out/zero-cache/src/services/change-streamer/storer.js +1 -1
  343. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  344. package/out/zero-cache/src/services/change-streamer/subscribe.js +1 -1
  345. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
  346. package/out/zero-cache/src/services/change-streamer/subscriber.js +2 -2
  347. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  348. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +0 -1
  349. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  350. package/out/zero-cache/src/services/heapz.js +2 -1
  351. package/out/zero-cache/src/services/heapz.js.map +1 -1
  352. package/out/zero-cache/src/services/http-service.js.map +1 -1
  353. package/out/zero-cache/src/services/life-cycle.js +1 -1
  354. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  355. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +4 -2
  356. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  357. package/out/zero-cache/src/services/litestream/commands.js +1 -1
  358. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  359. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +2 -2
  360. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  361. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  362. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  363. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -1
  364. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
  365. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  366. package/out/zero-cache/src/services/mutagen/pusher.js +3 -2
  367. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  368. package/out/zero-cache/src/services/plannerz.js +4 -3
  369. package/out/zero-cache/src/services/plannerz.js.map +1 -1
  370. package/out/zero-cache/src/services/profz.js +5 -3
  371. package/out/zero-cache/src/services/profz.js.map +1 -1
  372. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  373. package/out/zero-cache/src/services/replicator/change-log-db.js +3 -2
  374. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
  375. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +1 -1
  376. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  377. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  378. package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
  379. package/out/zero-cache/src/services/replicator/incremental-sync.js +1 -1
  380. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  381. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  382. package/out/zero-cache/src/services/replicator/replication-status.js +4 -3
  383. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  384. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  385. package/out/zero-cache/src/services/replicator/reporter/recorder.js +1 -1
  386. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  387. package/out/zero-cache/src/services/replicator/reporter/report-schema.js +1 -1
  388. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  389. package/out/zero-cache/src/services/replicator/schema/backfilling.js +1 -1
  390. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  391. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  392. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  393. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  394. package/out/zero-cache/src/services/replicator/schema/replication-state.js +10 -7
  395. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  396. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  397. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +1 -1
  398. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  399. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +1 -1
  400. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -1
  401. package/out/zero-cache/src/services/replicator/write-worker-client.js +1 -1
  402. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  403. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  404. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  405. package/out/zero-cache/src/services/runner.js.map +1 -1
  406. package/out/zero-cache/src/services/running-state.js.map +1 -1
  407. package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
  408. package/out/zero-cache/src/services/statz.js +2 -1
  409. package/out/zero-cache/src/services/statz.js.map +1 -1
  410. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +2 -2
  411. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  412. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -1
  413. package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -1
  414. package/out/zero-cache/src/services/view-syncer/client-handler.js +4 -2
  415. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  416. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  417. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  418. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -2
  419. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  420. package/out/zero-cache/src/services/view-syncer/cvr-store.js +9 -5
  421. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  422. package/out/zero-cache/src/services/view-syncer/cvr.js +3 -2
  423. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  424. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +1 -1
  425. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -1
  426. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  427. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -1
  428. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -1
  429. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +2 -2
  430. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -1
  431. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +5 -3
  432. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  433. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +6 -4
  434. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  435. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -1
  436. package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -1
  437. package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -1
  438. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  439. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -1
  440. package/out/zero-cache/src/services/view-syncer/query-stats.js +1 -1
  441. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
  442. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  443. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
  444. package/out/zero-cache/src/services/view-syncer/schema/types.js +1 -1
  445. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  446. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +7 -1
  447. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -1
  448. package/out/zero-cache/src/services/view-syncer/snapshotter.js +3 -2
  449. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  450. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  451. package/out/zero-cache/src/services/view-syncer/view-syncer.js +4 -6
  452. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  453. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  454. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  455. package/out/zero-cache/src/types/lite.js +1 -1
  456. package/out/zero-cache/src/types/lite.js.map +1 -1
  457. package/out/zero-cache/src/types/pg-data-type.js +1 -1
  458. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  459. package/out/zero-cache/src/types/pg.js +6 -4
  460. package/out/zero-cache/src/types/pg.js.map +1 -1
  461. package/out/zero-cache/src/types/poke-chunk.js +2 -2
  462. package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
  463. package/out/zero-cache/src/types/processes.js +1 -1
  464. package/out/zero-cache/src/types/processes.js.map +1 -1
  465. package/out/zero-cache/src/types/profiler.js.map +1 -1
  466. package/out/zero-cache/src/types/row-key.js.map +1 -1
  467. package/out/zero-cache/src/types/sql.js.map +1 -1
  468. package/out/zero-cache/src/types/streams.js +10 -9
  469. package/out/zero-cache/src/types/streams.js.map +1 -1
  470. package/out/zero-cache/src/types/strings.js.map +1 -1
  471. package/out/zero-cache/src/types/subscription.js.map +1 -1
  472. package/out/zero-cache/src/types/timeout.js +1 -1
  473. package/out/zero-cache/src/types/websocket-handoff.js +1 -1
  474. package/out/zero-cache/src/types/ws.js +1 -1
  475. package/out/zero-cache/src/workers/connection.js +2 -3
  476. package/out/zero-cache/src/workers/connection.js.map +1 -1
  477. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  478. package/out/zero-cache/src/workers/replicator.js +5 -4
  479. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  480. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  481. package/out/zero-cache/src/workers/syncer.js +2 -2
  482. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  483. package/out/zero-client/src/client/active-clients-manager.js +1 -1
  484. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  485. package/out/zero-client/src/client/bindings.js +11 -11
  486. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  487. package/out/zero-client/src/client/connection.js +1 -1
  488. package/out/zero-client/src/client/connection.js.map +1 -1
  489. package/out/zero-client/src/client/context.js.map +1 -1
  490. package/out/zero-client/src/client/crud-impl.js +1 -1
  491. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  492. package/out/zero-client/src/client/crud.js +1 -1
  493. package/out/zero-client/src/client/crud.js.map +1 -1
  494. package/out/zero-client/src/client/custom.js +1 -1
  495. package/out/zero-client/src/client/custom.js.map +1 -1
  496. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  497. package/out/zero-client/src/client/enable-analytics.js +1 -1
  498. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  499. package/out/zero-client/src/client/error.js.map +1 -1
  500. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  501. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  502. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +1 -1
  503. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  504. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  505. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  506. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  507. package/out/zero-client/src/client/ivm-branch.js +1 -3
  508. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  509. package/out/zero-client/src/client/keys.js +2 -1
  510. package/out/zero-client/src/client/keys.js.map +1 -1
  511. package/out/zero-client/src/client/log-options.js.map +1 -1
  512. package/out/zero-client/src/client/make-replicache-mutators.js +5 -3
  513. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  514. package/out/zero-client/src/client/metrics.js +3 -5
  515. package/out/zero-client/src/client/metrics.js.map +1 -1
  516. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  517. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  518. package/out/zero-client/src/client/options.js.map +1 -1
  519. package/out/zero-client/src/client/query-manager.js +2 -2
  520. package/out/zero-client/src/client/query-manager.js.map +1 -1
  521. package/out/zero-client/src/client/reload-error-handler.js +4 -3
  522. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  523. package/out/zero-client/src/client/version.js +1 -1
  524. package/out/zero-client/src/client/zero-poke-handler.js +1 -1
  525. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  526. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  527. package/out/zero-client/src/client/zero.js +19 -11
  528. package/out/zero-client/src/client/zero.js.map +1 -1
  529. package/out/zero-client/src/mod.js +23 -23
  530. package/out/zero-client/src/util/nanoid.js.map +1 -1
  531. package/out/zero-permissions/src/permissions.js +3 -2
  532. package/out/zero-permissions/src/permissions.js.map +1 -1
  533. package/out/zero-pg/src/mod.js +9 -9
  534. package/out/zero-protocol/src/analyze-query-result.js +1 -1
  535. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  536. package/out/zero-protocol/src/application-error.js.map +1 -1
  537. package/out/zero-protocol/src/ast.js +19 -9
  538. package/out/zero-protocol/src/ast.js.map +1 -1
  539. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  540. package/out/zero-protocol/src/client-schema.js +1 -1
  541. package/out/zero-protocol/src/client-schema.js.map +1 -1
  542. package/out/zero-protocol/src/close-connection.js +1 -1
  543. package/out/zero-protocol/src/close-connection.js.map +1 -1
  544. package/out/zero-protocol/src/connect.js +1 -1
  545. package/out/zero-protocol/src/connect.js.map +1 -1
  546. package/out/zero-protocol/src/custom-queries.js +1 -1
  547. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  548. package/out/zero-protocol/src/data.js +4 -2
  549. package/out/zero-protocol/src/data.js.map +1 -1
  550. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  551. package/out/zero-protocol/src/down.js.map +1 -1
  552. package/out/zero-protocol/src/error.js.map +1 -1
  553. package/out/zero-protocol/src/inspect-down.d.ts +81 -81
  554. package/out/zero-protocol/src/inspect-down.js +1 -1
  555. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  556. package/out/zero-protocol/src/inspect-up.js +1 -1
  557. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  558. package/out/zero-protocol/src/mutate-server.js +1 -1
  559. package/out/zero-protocol/src/mutate-server.js.map +1 -1
  560. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  561. package/out/zero-protocol/src/mutation.js +1 -1
  562. package/out/zero-protocol/src/mutation.js.map +1 -1
  563. package/out/zero-protocol/src/mutations-patch.js +1 -1
  564. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  565. package/out/zero-protocol/src/ping.js +1 -1
  566. package/out/zero-protocol/src/ping.js.map +1 -1
  567. package/out/zero-protocol/src/poke.js +1 -1
  568. package/out/zero-protocol/src/poke.js.map +1 -1
  569. package/out/zero-protocol/src/pong.js +1 -1
  570. package/out/zero-protocol/src/pong.js.map +1 -1
  571. package/out/zero-protocol/src/primary-key.js.map +1 -1
  572. package/out/zero-protocol/src/protocol-version.js +1 -0
  573. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  574. package/out/zero-protocol/src/pull.js +1 -1
  575. package/out/zero-protocol/src/pull.js.map +1 -1
  576. package/out/zero-protocol/src/push.js +1 -1
  577. package/out/zero-protocol/src/push.js.map +1 -1
  578. package/out/zero-protocol/src/queries-patch.js +1 -1
  579. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  580. package/out/zero-protocol/src/query-hash-visitor.js.map +1 -1
  581. package/out/zero-protocol/src/query-hash.js +2 -2
  582. package/out/zero-protocol/src/query-server.js +1 -1
  583. package/out/zero-protocol/src/query-server.js.map +1 -1
  584. package/out/zero-protocol/src/row-patch.js.map +1 -1
  585. package/out/zero-protocol/src/up.js.map +1 -1
  586. package/out/zero-protocol/src/update-auth.js.map +1 -1
  587. package/out/zero-protocol/src/version.js.map +1 -1
  588. package/out/zero-react/src/bindings.js +11 -11
  589. package/out/zero-react/src/mod.js +5 -5
  590. package/out/zero-react/src/use-query.js +1 -1
  591. package/out/zero-react/src/use-query.js.map +1 -1
  592. package/out/zero-react/src/zero-provider.d.ts +1 -1
  593. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  594. package/out/zero-react/src/zero-provider.js +2 -1
  595. package/out/zero-react/src/zero-provider.js.map +1 -1
  596. package/out/zero-react/src/zero.js +23 -23
  597. package/out/zero-schema/src/builder/schema-builder.js +3 -2
  598. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  599. package/out/zero-schema/src/builder/table-builder.js +1 -1
  600. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  601. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  602. package/out/zero-schema/src/name-mapper.js +7 -5
  603. package/out/zero-schema/src/name-mapper.js.map +1 -1
  604. package/out/zero-schema/src/schema-config.js +1 -1
  605. package/out/zero-schema/src/schema-config.js.map +1 -1
  606. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  607. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  608. package/out/zero-server/src/adapters/pg.js.map +1 -1
  609. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  610. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  611. package/out/zero-server/src/closable-db-transaction.js.map +1 -1
  612. package/out/zero-server/src/custom.js +1 -1
  613. package/out/zero-server/src/custom.js.map +1 -1
  614. package/out/zero-server/src/mod.js +8 -8
  615. package/out/zero-server/src/process-mutations.js.map +1 -1
  616. package/out/zero-server/src/push-processor.js.map +1 -1
  617. package/out/zero-server/src/queries/process-queries.js +2 -1
  618. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  619. package/out/zero-server/src/schema.js +7 -7
  620. package/out/zero-server/src/schema.js.map +1 -1
  621. package/out/zero-server/src/zql-database.js.map +1 -1
  622. package/out/zero-solid/src/bindings.js +11 -11
  623. package/out/zero-solid/src/mod.js +5 -5
  624. package/out/zero-solid/src/solid-view.js +1 -1
  625. package/out/zero-solid/src/solid-view.js.map +1 -1
  626. package/out/zero-solid/src/use-connection-state.js +2 -1
  627. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  628. package/out/zero-solid/src/use-query.js.map +1 -1
  629. package/out/zero-solid/src/use-zero-online.js +2 -1
  630. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  631. package/out/zero-solid/src/use-zero.js +3 -2
  632. package/out/zero-solid/src/use-zero.js.map +1 -1
  633. package/out/zero-solid/src/zero.js +23 -23
  634. package/out/zero-types/src/name-mapper.js.map +1 -1
  635. package/out/zql/src/builder/builder.js +15 -13
  636. package/out/zql/src/builder/builder.js.map +1 -1
  637. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -1
  638. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  639. package/out/zql/src/builder/like.js +0 -1
  640. package/out/zql/src/builder/like.js.map +1 -1
  641. package/out/zql/src/ivm/array-view.js.map +1 -1
  642. package/out/zql/src/ivm/cap.js.map +1 -1
  643. package/out/zql/src/ivm/constraint.js +1 -1
  644. package/out/zql/src/ivm/constraint.js.map +1 -1
  645. package/out/zql/src/ivm/data.js.map +1 -1
  646. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  647. package/out/zql/src/ivm/exists.js +20 -18
  648. package/out/zql/src/ivm/exists.js.map +1 -1
  649. package/out/zql/src/ivm/fan-in.js.map +1 -1
  650. package/out/zql/src/ivm/fan-out.js.map +1 -1
  651. package/out/zql/src/ivm/filter-operators.js +1 -1
  652. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  653. package/out/zql/src/ivm/filter-push.js.map +1 -1
  654. package/out/zql/src/ivm/filter.js.map +1 -1
  655. package/out/zql/src/ivm/flipped-join.js +1 -3
  656. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  657. package/out/zql/src/ivm/join-index-tap.js.map +1 -1
  658. package/out/zql/src/ivm/join-index.js.map +1 -1
  659. package/out/zql/src/ivm/join-utils.js +11 -13
  660. package/out/zql/src/ivm/join-utils.js.map +1 -1
  661. package/out/zql/src/ivm/join.js.map +1 -1
  662. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  663. package/out/zql/src/ivm/memory-source.js +26 -22
  664. package/out/zql/src/ivm/memory-source.js.map +1 -1
  665. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  666. package/out/zql/src/ivm/operator.js +2 -2
  667. package/out/zql/src/ivm/push-accumulated.js +0 -1
  668. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  669. package/out/zql/src/ivm/skip-yields.js.map +1 -1
  670. package/out/zql/src/ivm/skip.js.map +1 -1
  671. package/out/zql/src/ivm/take-gate.js.map +1 -1
  672. package/out/zql/src/ivm/take.js +1 -1
  673. package/out/zql/src/ivm/take.js.map +1 -1
  674. package/out/zql/src/ivm/union-fan-in.js +1 -1
  675. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  676. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  677. package/out/zql/src/ivm/view-apply-change.js +1 -1
  678. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  679. package/out/zql/src/mutate/crud.js +3 -2
  680. package/out/zql/src/mutate/crud.js.map +1 -1
  681. package/out/zql/src/planner/planner-builder.js +1 -1
  682. package/out/zql/src/planner/planner-builder.js.map +1 -1
  683. package/out/zql/src/planner/planner-connection.js.map +1 -1
  684. package/out/zql/src/planner/planner-debug.js.map +1 -1
  685. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  686. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  687. package/out/zql/src/planner/planner-filter.js.map +1 -1
  688. package/out/zql/src/planner/planner-graph.js +1 -5
  689. package/out/zql/src/planner/planner-graph.js.map +1 -1
  690. package/out/zql/src/planner/planner-join.js +1 -1
  691. package/out/zql/src/planner/planner-join.js.map +1 -1
  692. package/out/zql/src/planner/planner-source.js.map +1 -1
  693. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  694. package/out/zql/src/query/create-builder.js +2 -1
  695. package/out/zql/src/query/create-builder.js.map +1 -1
  696. package/out/zql/src/query/expression.js +1 -1
  697. package/out/zql/src/query/expression.js.map +1 -1
  698. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  699. package/out/zql/src/query/named.js +2 -1
  700. package/out/zql/src/query/named.js.map +1 -1
  701. package/out/zql/src/query/query-delegate-base.js +1 -1
  702. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  703. package/out/zql/src/query/query-impl.js +3 -2
  704. package/out/zql/src/query/query-impl.js.map +1 -1
  705. package/out/zql/src/query/query-registry.js +1 -1
  706. package/out/zql/src/query/query-registry.js.map +1 -1
  707. package/out/zql/src/query/query-transitions.js +1 -1
  708. package/out/zql/src/query/query-transitions.js.map +1 -1
  709. package/out/zql/src/query/runnable-query-impl.js +3 -2
  710. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  711. package/out/zql/src/query/static-query.js.map +1 -1
  712. package/out/zql/src/query/ttl.js +8 -8
  713. package/out/zql/src/query/ttl.js.map +1 -1
  714. package/out/zql/src/query/validate-input.js.map +1 -1
  715. package/out/zqlite/src/database-storage.js +2 -2
  716. package/out/zqlite/src/database-storage.js.map +1 -1
  717. package/out/zqlite/src/db.js +2 -2
  718. package/out/zqlite/src/db.js.map +1 -1
  719. package/out/zqlite/src/explain-queries.js.map +1 -1
  720. package/out/zqlite/src/index-usage.js.map +1 -1
  721. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  722. package/out/zqlite/src/internal/sql.js.map +1 -1
  723. package/out/zqlite/src/internal/statement-cache.js +1 -1
  724. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  725. package/out/zqlite/src/mod.js +5 -5
  726. package/out/zqlite/src/pending-delta.js.map +1 -1
  727. package/out/zqlite/src/query-builder.js +1 -1
  728. package/out/zqlite/src/query-builder.js.map +1 -1
  729. package/out/zqlite/src/query-delegate.js.map +1 -1
  730. package/out/zqlite/src/resolve-scalar-subqueries.js +2 -5
  731. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  732. package/out/zqlite/src/sqlite-cost-model.js +3 -2
  733. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  734. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  735. package/out/zqlite/src/table-source.js +1 -1
  736. package/out/zqlite/src/table-source.js.map +1 -1
  737. package/package.json +16 -14
@@ -1 +1 @@
1
- {"version":3,"file":"pong.js","names":[],"sources":["../../../../zero-protocol/src/pong.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\n\nexport const pongBodySchema = v.object({});\nexport const pongMessageSchema = v.tuple([v.literal('pong'), pongBodySchema]);\n\nexport type PongBody = v.Infer<typeof pongBodySchema>;\nexport type PongMessage = v.Infer<typeof pongMessageSchema>;\n"],"mappings":";;AAEA,IAAa,iBAAiB,eAAE,OAAO,CAAC,CAAC;AACzC,IAAa,oBAAoB,eAAE,MAAM,CAAC,eAAE,QAAQ,MAAM,GAAG,cAAc,CAAC"}
1
+ {"version":3,"file":"pong.js","names":["v"],"sources":["../../../../zero-protocol/src/pong.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\n\nexport const pongBodySchema = v.object({});\nexport const pongMessageSchema = v.tuple([v.literal('pong'), pongBodySchema]);\n\nexport type PongBody = v.Infer<typeof pongBodySchema>;\nexport type PongMessage = v.Infer<typeof pongMessageSchema>;\n"],"mappings":";;AAEA,IAAa,iBAAiBA,eAAE,OAAO,CAAC,CAAC;AACzC,IAAa,oBAAoBA,eAAE,MAAM,CAACA,eAAE,QAAQ,MAAM,GAAG,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"primary-key.js","names":[],"sources":["../../../../zero-protocol/src/primary-key.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\n\nexport const primaryKeySchema = v.readonly(\n // oxlint-disable-next-line e18e/prefer-spread-syntax\n v.tuple([v.string()]).concat(v.array(v.string())),\n);\n\nexport type PrimaryKey = v.Infer<typeof primaryKeySchema>;\n\nexport const primaryKeyValueSchema = v.union(\n v.string(),\n v.number(),\n v.boolean(),\n);\n\nexport type PrimaryKeyValue = v.Infer<typeof primaryKeyValueSchema>;\n\nexport const primaryKeyValueRecordSchema = v.readonlyRecord(\n primaryKeyValueSchema,\n);\n\nexport type PrimaryKeyValueRecord = v.Infer<typeof primaryKeyValueRecordSchema>;\n"],"mappings":";;AAEA,IAAa,mBAAmB,SAE9B,eAAE,MAAM,CAAC,eAAE,OAAO,CAAC,CAAC,EAAE,OAAO,eAAE,MAAM,eAAE,OAAO,CAAC,CAAC,CAClD;AAIA,IAAa,wBAAwB,eAAE,MACrC,eAAE,OAAO,GACT,eAAE,OAAO,GACT,eAAE,QAAQ,CACZ;AAIA,IAAa,8BAA8B,eACzC,qBACF"}
1
+ {"version":3,"file":"primary-key.js","names":["v.readonly","v","v.readonlyRecord"],"sources":["../../../../zero-protocol/src/primary-key.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\n\nexport const primaryKeySchema = v.readonly(\n // oxlint-disable-next-line e18e/prefer-spread-syntax\n v.tuple([v.string()]).concat(v.array(v.string())),\n);\n\nexport type PrimaryKey = v.Infer<typeof primaryKeySchema>;\n\nexport const primaryKeyValueSchema = v.union(\n v.string(),\n v.number(),\n v.boolean(),\n);\n\nexport type PrimaryKeyValue = v.Infer<typeof primaryKeyValueSchema>;\n\nexport const primaryKeyValueRecordSchema = v.readonlyRecord(\n primaryKeyValueSchema,\n);\n\nexport type PrimaryKeyValueRecord = v.Infer<typeof primaryKeyValueRecordSchema>;\n"],"mappings":";;AAEA,IAAa,mBAAmBA,SAE9BC,eAAE,MAAM,CAACA,eAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAOA,eAAE,MAAMA,eAAE,OAAO,CAAC,CAAC,CAClD;AAIA,IAAa,wBAAwBA,eAAE,MACrCA,eAAE,OAAO,GACTA,eAAE,OAAO,GACTA,eAAE,QAAQ,CACZ;AAIA,IAAa,8BAA8BC,eACzC,qBACF"}
@@ -1,4 +1,5 @@
1
1
  import { assert } from "../../shared/src/asserts.js";
2
+ //#region ../zero-protocol/src/protocol-version.ts
2
3
  assert(true, "MIN_SERVER_SUPPORTED_SYNC_PROTOCOL must be less than PROTOCOL_VERSION");
3
4
  //#endregion
4
5
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"protocol-version.js","names":[],"sources":["../../../../zero-protocol/src/protocol-version.ts"],"sourcesContent":["import {assert} from '../../shared/src/asserts.ts';\n\n/**\n * The current `PROTOCOL_VERSION` of the code.\n *\n * The `PROTOCOL_VERSION` encompasses both the wire-protocol of the `/sync/...`\n * connection between the browser and `zero-cache`, as well as the format of\n * the `AST` objects stored in the CVR. The client's local database has its\n * own version, `STORAGE_VERSION` in zero-client. A bump that changes what the\n * client stores (as version 23 did by adding mutation results) must bump that\n * too.\n *\n * A change in the `AST` schema (e.g. new functionality added) must be\n * accompanied by an increment of the `PROTOCOL_VERSION` and a new major\n * release. The server (`zero-cache`) must be deployed before clients start\n * running the new code.\n */\n// History:\n// -- Version 5 adds support for `pokeEnd.cookie`. (0.14)\n// -- Version 6 makes `pokeStart.cookie` optional. (0.16)\n// -- Version 7 introduces the initConnection.clientSchema field. (0.17)\n// -- Version 8 drops support for Version 5 (0.18).\n// -- Version 11 adds inspect queries. (0.18)\n// -- Version 12 adds 'timestamp' and 'date' types to the ClientSchema ValueType. (not shipped, reversed by version 14)\n// -- Version 14 removes 'timestamp' and 'date' types from the ClientSchema ValueType. (0.18)\n// -- Version 15 adds a `userPushParams` field to `initConnection` (0.19)\n// -- Version 16 adds a new error type (alreadyProcessed) to mutation responses (0.19)\n// -- Version 17 deprecates `AST` in downstream query puts. It was never used anyway. (0.21)\n// -- Version 18 adds `name` and `args` to the `queries-patch` protocol (0.21)\n// -- Version 19 adds `activeClients` to the `initConnection` protocol (0.22)\n// -- Version 20 changes inspector down message (0.22)\n// -- Version 21 removes `AST` in downstream query puts which was deprecated in Version 17, removes support for versions < 18 (0.22)\n// -- Version 22 adds an optional 'userQueryParams' field to `initConnection` (0.22)\n// -- Version 23 add `mutationResults` to poke (0.22)\n// -- Version 24 adds `ackMutationResults` to upstream (0.22).\n// -- version 25 modifies `mutationsResults` to include `del` patches (0.22)\n// -- version 26 adds inspect/metrics and adds metrics to inspect/query (0.23)\n// -- version 27 adds inspect/version (0.23)\n// -- version 28 adds more inspect/metrics (0.23)\n// -- version 29 adds error responses for custom queries (0.23)\n// -- version 30 adds an optional primaryKey to the ClientSchema (0.24)\n// -- version 31 adds admin password authentication to inspector RPC calls (0.24)\n// -- version 32 adds analyze-query to the inspector RPC calls (0.24)\n// -- version 33 adds `flip` to CorrelatedSubquery (0.25)\n// -- version 34 moves `flip` from CorrelatedSubquery to CorrelatedSubqueryCondition (0.25)\n// -- version 35 adds `readRows`, `readRowCountsByQuery` and `readRowCount` to analyze-query result (0.25)\n// -- version 36 changes inspector analyze-query and adds error response to RPC (0.25)\n// -- version 37 adds `elapsed` to AnalyzeQueryResult (0.25)\n// -- version 38 adds structured push/transform error responses (0.25)\n// -- version 39 removes per-transform error types and adds `message` to app error (0.25)\n// -- version 40 adds `dbRowScansByQuery` to AnalyzeQueryResult (0.25)\n// -- version 41 makes ClientSchema.primaryKey required (0.25)\n// -- version 42 adds planner events to AnalyzeQueryResult (0.25)\n// -- version 43 renames `plans` to `sqlitePlans`, `plannerEvents` to `joinPlans`, and `plannerDebug` option to `joinPlans` (0.25)\n// -- version 44 adds profileID to connection URL (0.25)\n// -- version 45 adds userPushHeaders and userQueryHeaders to initConnection (0.25)\n// -- version 46 adds scalarSubquery condition type to AST\n// -- version 47 adds optional auth token to push body\n// -- version 48 adds updateAuth\n// -- version 49 adds `scalar` to CorrelatedSubqueryCondition, removes scalarSubquery\n// -- version 50 adds OTEL headers to push and query messages\n// -- version 51 changes inspector metrics fields\n// -- version 52 replaces JSON pokePart messages with binary poke chunks for\n// clients using protocol version 52 or newer. Older clients retain pokePart.\n// -- version 53 adds 'filter' node type to AnalyzeQueryResult\nexport const PROTOCOL_VERSION = 53;\n\n/**\n * The minimum server-supported sync protocol version (i.e. the version\n * declared in the \"/sync/v{#}/connect\" URL).\n *\n * CloudZero can serve applications running old client releases indefinitely.\n * Consequently, this value must never be increased: `zero-cache` must continue\n * to support every sync protocol from this version through `PROTOCOL_VERSION`.\n * A wire change that an old client cannot ignore must branch on the client's\n * protocol version and retain the old behavior. Keep each compatibility fork\n * isolated at the boundary that owns the changed behavior and test both sides\n * of its version cutoff.\n *\n * Client connections from protocol versions before this historical floor are\n * closed with a `VersionNotSupported` error.\n */\nexport const MIN_SERVER_SUPPORTED_SYNC_PROTOCOL = 30;\n\nassert(\n MIN_SERVER_SUPPORTED_SYNC_PROTOCOL < PROTOCOL_VERSION,\n 'MIN_SERVER_SUPPORTED_SYNC_PROTOCOL must be less than PROTOCOL_VERSION',\n);\n"],"mappings":";AAoFA,OAAA,MAEE,uEACF"}
1
+ {"version":3,"file":"protocol-version.js","names":[],"sources":["../../../../zero-protocol/src/protocol-version.ts"],"sourcesContent":["import {assert} from '../../shared/src/asserts.ts';\n\n/**\n * The current `PROTOCOL_VERSION` of the code.\n *\n * The `PROTOCOL_VERSION` encompasses both the wire-protocol of the `/sync/...`\n * connection between the browser and `zero-cache`, as well as the format of\n * the `AST` objects stored in the CVR. The client's local database has its\n * own version, `STORAGE_VERSION` in zero-client. A bump that changes what the\n * client stores (as version 23 did by adding mutation results) must bump that\n * too.\n *\n * A change in the `AST` schema (e.g. new functionality added) must be\n * accompanied by an increment of the `PROTOCOL_VERSION` and a new major\n * release. The server (`zero-cache`) must be deployed before clients start\n * running the new code.\n */\n// History:\n// -- Version 5 adds support for `pokeEnd.cookie`. (0.14)\n// -- Version 6 makes `pokeStart.cookie` optional. (0.16)\n// -- Version 7 introduces the initConnection.clientSchema field. (0.17)\n// -- Version 8 drops support for Version 5 (0.18).\n// -- Version 11 adds inspect queries. (0.18)\n// -- Version 12 adds 'timestamp' and 'date' types to the ClientSchema ValueType. (not shipped, reversed by version 14)\n// -- Version 14 removes 'timestamp' and 'date' types from the ClientSchema ValueType. (0.18)\n// -- Version 15 adds a `userPushParams` field to `initConnection` (0.19)\n// -- Version 16 adds a new error type (alreadyProcessed) to mutation responses (0.19)\n// -- Version 17 deprecates `AST` in downstream query puts. It was never used anyway. (0.21)\n// -- Version 18 adds `name` and `args` to the `queries-patch` protocol (0.21)\n// -- Version 19 adds `activeClients` to the `initConnection` protocol (0.22)\n// -- Version 20 changes inspector down message (0.22)\n// -- Version 21 removes `AST` in downstream query puts which was deprecated in Version 17, removes support for versions < 18 (0.22)\n// -- Version 22 adds an optional 'userQueryParams' field to `initConnection` (0.22)\n// -- Version 23 add `mutationResults` to poke (0.22)\n// -- Version 24 adds `ackMutationResults` to upstream (0.22).\n// -- version 25 modifies `mutationsResults` to include `del` patches (0.22)\n// -- version 26 adds inspect/metrics and adds metrics to inspect/query (0.23)\n// -- version 27 adds inspect/version (0.23)\n// -- version 28 adds more inspect/metrics (0.23)\n// -- version 29 adds error responses for custom queries (0.23)\n// -- version 30 adds an optional primaryKey to the ClientSchema (0.24)\n// -- version 31 adds admin password authentication to inspector RPC calls (0.24)\n// -- version 32 adds analyze-query to the inspector RPC calls (0.24)\n// -- version 33 adds `flip` to CorrelatedSubquery (0.25)\n// -- version 34 moves `flip` from CorrelatedSubquery to CorrelatedSubqueryCondition (0.25)\n// -- version 35 adds `readRows`, `readRowCountsByQuery` and `readRowCount` to analyze-query result (0.25)\n// -- version 36 changes inspector analyze-query and adds error response to RPC (0.25)\n// -- version 37 adds `elapsed` to AnalyzeQueryResult (0.25)\n// -- version 38 adds structured push/transform error responses (0.25)\n// -- version 39 removes per-transform error types and adds `message` to app error (0.25)\n// -- version 40 adds `dbRowScansByQuery` to AnalyzeQueryResult (0.25)\n// -- version 41 makes ClientSchema.primaryKey required (0.25)\n// -- version 42 adds planner events to AnalyzeQueryResult (0.25)\n// -- version 43 renames `plans` to `sqlitePlans`, `plannerEvents` to `joinPlans`, and `plannerDebug` option to `joinPlans` (0.25)\n// -- version 44 adds profileID to connection URL (0.25)\n// -- version 45 adds userPushHeaders and userQueryHeaders to initConnection (0.25)\n// -- version 46 adds scalarSubquery condition type to AST\n// -- version 47 adds optional auth token to push body\n// -- version 48 adds updateAuth\n// -- version 49 adds `scalar` to CorrelatedSubqueryCondition, removes scalarSubquery\n// -- version 50 adds OTEL headers to push and query messages\n// -- version 51 changes inspector metrics fields\n// -- version 52 replaces JSON pokePart messages with binary poke chunks for\n// clients using protocol version 52 or newer. Older clients retain pokePart.\n// -- version 53 adds 'filter' node type to AnalyzeQueryResult\nexport const PROTOCOL_VERSION = 53;\n\n/**\n * The minimum server-supported sync protocol version (i.e. the version\n * declared in the \"/sync/v{#}/connect\" URL).\n *\n * CloudZero can serve applications running old client releases indefinitely.\n * Consequently, this value must never be increased: `zero-cache` must continue\n * to support every sync protocol from this version through `PROTOCOL_VERSION`.\n * A wire change that an old client cannot ignore must branch on the client's\n * protocol version and retain the old behavior. Keep each compatibility fork\n * isolated at the boundary that owns the changed behavior and test both sides\n * of its version cutoff.\n *\n * Client connections from protocol versions before this historical floor are\n * closed with a `VersionNotSupported` error.\n */\nexport const MIN_SERVER_SUPPORTED_SYNC_PROTOCOL = 30;\n\nassert(\n MIN_SERVER_SUPPORTED_SYNC_PROTOCOL < PROTOCOL_VERSION,\n 'MIN_SERVER_SUPPORTED_SYNC_PROTOCOL must be less than PROTOCOL_VERSION',\n);\n"],"mappings":";;AAoFA,OACE,MACA,uEACF"}
@@ -14,6 +14,6 @@ var pullResponseBodySchema = valita_exports.object({
14
14
  var pullRequestMessageSchema = valita_exports.tuple([valita_exports.literal("pull"), pullRequestBodySchema]);
15
15
  var pullResponseMessageSchema = valita_exports.tuple([valita_exports.literal("pull"), pullResponseBodySchema]);
16
16
  //#endregion
17
- export { pullRequestMessageSchema, pullResponseMessageSchema };
17
+ export { pullRequestBodySchema, pullRequestMessageSchema, pullResponseBodySchema, pullResponseMessageSchema };
18
18
 
19
19
  //# sourceMappingURL=pull.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pull.js","names":[],"sources":["../../../../zero-protocol/src/pull.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\nimport {nullableVersionSchema, versionSchema} from './version.ts';\n\nexport const pullRequestBodySchema = v.object({\n clientGroupID: v.string(),\n cookie: nullableVersionSchema,\n requestID: v.string(),\n});\n\nexport const pullResponseBodySchema = v.object({\n cookie: versionSchema,\n // Matches pullRequestBodySchema requestID that initiated this response\n requestID: v.string(),\n lastMutationIDChanges: v.record(v.number()),\n // Pull is currently only used for mutation recovery which does not use\n // the patch so we save work by not computing the patch.\n});\n\nexport const pullRequestMessageSchema = v.tuple([\n v.literal('pull'),\n pullRequestBodySchema,\n]);\n\nexport const pullResponseMessageSchema = v.tuple([\n v.literal('pull'),\n pullResponseBodySchema,\n]);\n\nexport type PullRequestBody = v.Infer<typeof pullRequestBodySchema>;\nexport type PullResponseBody = v.Infer<typeof pullResponseBodySchema>;\n\nexport type PullRequestMessage = v.Infer<typeof pullRequestMessageSchema>;\nexport type PullResponseMessage = v.Infer<typeof pullResponseMessageSchema>;\n"],"mappings":";;;AAGA,IAAa,wBAAwB,eAAE,OAAO;CAC5C,eAAe,eAAE,OAAO;CACxB,QAAQ;CACR,WAAW,eAAE,OAAO;AACtB,CAAC;AAED,IAAa,yBAAyB,eAAE,OAAO;CAC7C,QAAQ;CAER,WAAW,eAAE,OAAO;CACpB,uBAAuB,eAAE,OAAO,eAAE,OAAO,CAAC;AAG5C,CAAC;AAED,IAAa,2BAA2B,eAAE,MAAM,CAC9C,eAAE,QAAQ,MAAM,GAChB,qBACF,CAAC;AAED,IAAa,4BAA4B,eAAE,MAAM,CAC/C,eAAE,QAAQ,MAAM,GAChB,sBACF,CAAC"}
1
+ {"version":3,"file":"pull.js","names":["v"],"sources":["../../../../zero-protocol/src/pull.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\nimport {nullableVersionSchema, versionSchema} from './version.ts';\n\nexport const pullRequestBodySchema = v.object({\n clientGroupID: v.string(),\n cookie: nullableVersionSchema,\n requestID: v.string(),\n});\n\nexport const pullResponseBodySchema = v.object({\n cookie: versionSchema,\n // Matches pullRequestBodySchema requestID that initiated this response\n requestID: v.string(),\n lastMutationIDChanges: v.record(v.number()),\n // Pull is currently only used for mutation recovery which does not use\n // the patch so we save work by not computing the patch.\n});\n\nexport const pullRequestMessageSchema = v.tuple([\n v.literal('pull'),\n pullRequestBodySchema,\n]);\n\nexport const pullResponseMessageSchema = v.tuple([\n v.literal('pull'),\n pullResponseBodySchema,\n]);\n\nexport type PullRequestBody = v.Infer<typeof pullRequestBodySchema>;\nexport type PullResponseBody = v.Infer<typeof pullResponseBodySchema>;\n\nexport type PullRequestMessage = v.Infer<typeof pullRequestMessageSchema>;\nexport type PullResponseMessage = v.Infer<typeof pullResponseMessageSchema>;\n"],"mappings":";;;AAGA,IAAa,wBAAwBA,eAAE,OAAO;CAC5C,eAAeA,eAAE,OAAO;CACxB,QAAQ;CACR,WAAWA,eAAE,OAAO;AACtB,CAAC;AAED,IAAa,yBAAyBA,eAAE,OAAO;CAC7C,QAAQ;CAER,WAAWA,eAAE,OAAO;CACpB,uBAAuBA,eAAE,OAAOA,eAAE,OAAO,CAAC;AAG5C,CAAC;AAED,IAAa,2BAA2BA,eAAE,MAAM,CAC9CA,eAAE,QAAQ,MAAM,GAChB,qBACF,CAAC;AAED,IAAa,4BAA4BA,eAAE,MAAM,CAC/CA,eAAE,QAAQ,MAAM,GAChB,sBACF,CAAC"}
@@ -71,6 +71,6 @@ valita_exports.union(pushResponseBodySchema, pushFailedBodySchema);
71
71
  var pushResponseMessageSchema = valita_exports.tuple([valita_exports.literal("pushResponse"), pushResponseBodySchema]);
72
72
  var ackMutationResponsesMessageSchema = valita_exports.tuple([valita_exports.literal("ackMutationResponses"), mutationIDSchema]);
73
73
  //#endregion
74
- export { ackMutationResponsesMessageSchema, pushBodySchema, pushErrorSchema, pushMessageSchema, pushResponseMessageSchema };
74
+ export { ackMutationResponsesMessageSchema, pushBodySchema, pushErrorSchema, pushMessageSchema, pushResponseBodySchema, pushResponseMessageSchema };
75
75
 
76
76
  //# sourceMappingURL=push.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"push.js","names":[],"sources":["../../../../zero-protocol/src/push.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\nimport {pushFailedBodySchema} from './error.ts';\nimport {mutationIDSchema} from './mutation-id.ts';\nimport {mutationResponseSchema, mutationSchema} from './mutation.ts';\n\nexport const pushBodySchema = v.object({\n clientGroupID: v.string(),\n mutations: v.array(mutationSchema),\n pushVersion: v.number(),\n // For legacy (CRUD) mutations, the schema is tied to the client group /\n // sync connection. For custom mutations, schema versioning is delegated\n // to the custom protocol / api-server.\n schemaVersion: v.number().optional(),\n timestamp: v.number(),\n requestID: v.string(),\n /**\n * @deprecated auth is managed at client-group scope via connect/updateAuth\n * and should not be included in push messages.\n */\n auth: v.string().optional(),\n /** W3C traceparent header for distributed tracing. */\n traceparent: v.string().optional(),\n});\n\nexport const pushMessageSchema = v.tuple([v.literal('push'), pushBodySchema]);\n\nconst pushOkSchema = v.object({\n mutations: v.array(mutationResponseSchema),\n});\n\n/**\n * @deprecated push errors are now represented as ['error', { ... }] messages\n */\nconst unsupportedPushVersionSchema = v.object({\n /** @deprecated */\n error: v.literal('unsupportedPushVersion'),\n /** @deprecated */\n mutationIDs: v.array(mutationIDSchema).optional(),\n});\n/**\n * @deprecated push errors are now represented as ['error', { ... }] messages\n */\nconst unsupportedSchemaVersionSchema = v.object({\n /** @deprecated */\n error: v.literal('unsupportedSchemaVersion'),\n /** @deprecated */\n mutationIDs: v.array(mutationIDSchema).optional(),\n});\n/**\n * @deprecated push http errors are now represented as ['error', { ... }] messages\n */\nconst httpErrorSchema = v.object({\n /** @deprecated */\n error: v.literal('http'),\n /** @deprecated */\n status: v.number(),\n /** @deprecated */\n details: v.string(),\n /** @deprecated */\n mutationIDs: v.array(mutationIDSchema).optional(),\n});\n/**\n * @deprecated push zero errors are now represented as ['error', { ... }] messages\n */\nconst zeroPusherErrorSchema = v.object({\n /** @deprecated */\n error: v.literal('zeroPusher'),\n /** @deprecated */\n details: v.string(),\n /** @deprecated */\n mutationIDs: v.array(mutationIDSchema).optional(),\n});\n/**\n * @deprecated push errors are now represented as ['error', { ... }] messages\n */\nexport const pushErrorSchema = v.union(\n unsupportedPushVersionSchema,\n unsupportedSchemaVersionSchema,\n httpErrorSchema,\n zeroPusherErrorSchema,\n);\n\nexport const pushResponseBodySchema = v.union(pushOkSchema, pushErrorSchema);\n\nexport const pushResponseSchema = v.union(\n pushResponseBodySchema,\n pushFailedBodySchema,\n);\nexport const pushResponseMessageSchema = v.tuple([\n v.literal('pushResponse'),\n pushResponseBodySchema,\n]);\n\nexport const ackMutationResponsesMessageSchema = v.tuple([\n v.literal('ackMutationResponses'),\n mutationIDSchema,\n]);\n\nexport type PushBody = v.Infer<typeof pushBodySchema>;\nexport type PushMessage = v.Infer<typeof pushMessageSchema>;\nexport type PushResponseBody = v.Infer<typeof pushResponseBodySchema>;\nexport type PushResponse = v.Infer<typeof pushResponseSchema>;\nexport type PushResponseMessage = v.Infer<typeof pushResponseMessageSchema>;\nexport type MutationResponse = v.Infer<typeof mutationResponseSchema>;\n/**\n * @deprecated push errors are now represented as ['error', { ... }] messages\n */\nexport type PushError = v.Infer<typeof pushErrorSchema>;\nexport type PushOk = v.Infer<typeof pushOkSchema>;\nexport type AckMutationMessage = v.Infer<\n typeof ackMutationResponsesMessageSchema\n>;\n"],"mappings":";;;;;AAKA,IAAa,iBAAiB,eAAE,OAAO;CACrC,eAAe,eAAE,OAAO;CACxB,WAAW,eAAE,MAAM,cAAc;CACjC,aAAa,eAAE,OAAO;CAItB,eAAe,eAAE,OAAO,EAAE,SAAS;CACnC,WAAW,eAAE,OAAO;CACpB,WAAW,eAAE,OAAO;;;;;CAKpB,MAAM,eAAE,OAAO,EAAE,SAAS;;CAE1B,aAAa,eAAE,OAAO,EAAE,SAAS;AACnC,CAAC;AAED,IAAa,oBAAoB,eAAE,MAAM,CAAC,eAAE,QAAQ,MAAM,GAAG,cAAc,CAAC;AAE5E,IAAM,eAAe,eAAE,OAAO,EAC5B,WAAW,eAAE,MAAM,sBAAsB,EAC3C,CAAC;;;;AAKD,IAAM,+BAA+B,eAAE,OAAO;;CAE5C,OAAO,eAAE,QAAQ,wBAAwB;;CAEzC,aAAa,eAAE,MAAM,gBAAgB,EAAE,SAAS;AAClD,CAAC;;;;AAID,IAAM,iCAAiC,eAAE,OAAO;;CAE9C,OAAO,eAAE,QAAQ,0BAA0B;;CAE3C,aAAa,eAAE,MAAM,gBAAgB,EAAE,SAAS;AAClD,CAAC;;;;AAID,IAAM,kBAAkB,eAAE,OAAO;;CAE/B,OAAO,eAAE,QAAQ,MAAM;;CAEvB,QAAQ,eAAE,OAAO;;CAEjB,SAAS,eAAE,OAAO;;CAElB,aAAa,eAAE,MAAM,gBAAgB,EAAE,SAAS;AAClD,CAAC;;;;AAID,IAAM,wBAAwB,eAAE,OAAO;;CAErC,OAAO,eAAE,QAAQ,YAAY;;CAE7B,SAAS,eAAE,OAAO;;CAElB,aAAa,eAAE,MAAM,gBAAgB,EAAE,SAAS;AAClD,CAAC;;;;AAID,IAAa,kBAAkB,eAAE,MAC/B,8BACA,gCACA,iBACA,qBACF;AAEA,IAAa,yBAAyB,eAAE,MAAM,cAAc,eAAe;AAEzC,eAAE,MAClC,wBACA,oBACF;AACA,IAAa,4BAA4B,eAAE,MAAM,CAC/C,eAAE,QAAQ,cAAc,GACxB,sBACF,CAAC;AAED,IAAa,oCAAoC,eAAE,MAAM,CACvD,eAAE,QAAQ,sBAAsB,GAChC,gBACF,CAAC"}
1
+ {"version":3,"file":"push.js","names":["v"],"sources":["../../../../zero-protocol/src/push.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\nimport {pushFailedBodySchema} from './error.ts';\nimport {mutationIDSchema} from './mutation-id.ts';\nimport {mutationResponseSchema, mutationSchema} from './mutation.ts';\n\nexport const pushBodySchema = v.object({\n clientGroupID: v.string(),\n mutations: v.array(mutationSchema),\n pushVersion: v.number(),\n // For legacy (CRUD) mutations, the schema is tied to the client group /\n // sync connection. For custom mutations, schema versioning is delegated\n // to the custom protocol / api-server.\n schemaVersion: v.number().optional(),\n timestamp: v.number(),\n requestID: v.string(),\n /**\n * @deprecated auth is managed at client-group scope via connect/updateAuth\n * and should not be included in push messages.\n */\n auth: v.string().optional(),\n /** W3C traceparent header for distributed tracing. */\n traceparent: v.string().optional(),\n});\n\nexport const pushMessageSchema = v.tuple([v.literal('push'), pushBodySchema]);\n\nconst pushOkSchema = v.object({\n mutations: v.array(mutationResponseSchema),\n});\n\n/**\n * @deprecated push errors are now represented as ['error', { ... }] messages\n */\nconst unsupportedPushVersionSchema = v.object({\n /** @deprecated */\n error: v.literal('unsupportedPushVersion'),\n /** @deprecated */\n mutationIDs: v.array(mutationIDSchema).optional(),\n});\n/**\n * @deprecated push errors are now represented as ['error', { ... }] messages\n */\nconst unsupportedSchemaVersionSchema = v.object({\n /** @deprecated */\n error: v.literal('unsupportedSchemaVersion'),\n /** @deprecated */\n mutationIDs: v.array(mutationIDSchema).optional(),\n});\n/**\n * @deprecated push http errors are now represented as ['error', { ... }] messages\n */\nconst httpErrorSchema = v.object({\n /** @deprecated */\n error: v.literal('http'),\n /** @deprecated */\n status: v.number(),\n /** @deprecated */\n details: v.string(),\n /** @deprecated */\n mutationIDs: v.array(mutationIDSchema).optional(),\n});\n/**\n * @deprecated push zero errors are now represented as ['error', { ... }] messages\n */\nconst zeroPusherErrorSchema = v.object({\n /** @deprecated */\n error: v.literal('zeroPusher'),\n /** @deprecated */\n details: v.string(),\n /** @deprecated */\n mutationIDs: v.array(mutationIDSchema).optional(),\n});\n/**\n * @deprecated push errors are now represented as ['error', { ... }] messages\n */\nexport const pushErrorSchema = v.union(\n unsupportedPushVersionSchema,\n unsupportedSchemaVersionSchema,\n httpErrorSchema,\n zeroPusherErrorSchema,\n);\n\nexport const pushResponseBodySchema = v.union(pushOkSchema, pushErrorSchema);\n\nexport const pushResponseSchema = v.union(\n pushResponseBodySchema,\n pushFailedBodySchema,\n);\nexport const pushResponseMessageSchema = v.tuple([\n v.literal('pushResponse'),\n pushResponseBodySchema,\n]);\n\nexport const ackMutationResponsesMessageSchema = v.tuple([\n v.literal('ackMutationResponses'),\n mutationIDSchema,\n]);\n\nexport type PushBody = v.Infer<typeof pushBodySchema>;\nexport type PushMessage = v.Infer<typeof pushMessageSchema>;\nexport type PushResponseBody = v.Infer<typeof pushResponseBodySchema>;\nexport type PushResponse = v.Infer<typeof pushResponseSchema>;\nexport type PushResponseMessage = v.Infer<typeof pushResponseMessageSchema>;\nexport type MutationResponse = v.Infer<typeof mutationResponseSchema>;\n/**\n * @deprecated push errors are now represented as ['error', { ... }] messages\n */\nexport type PushError = v.Infer<typeof pushErrorSchema>;\nexport type PushOk = v.Infer<typeof pushOkSchema>;\nexport type AckMutationMessage = v.Infer<\n typeof ackMutationResponsesMessageSchema\n>;\n"],"mappings":";;;;;AAKA,IAAa,iBAAiBA,eAAE,OAAO;CACrC,eAAeA,eAAE,OAAO;CACxB,WAAWA,eAAE,MAAM,cAAc;CACjC,aAAaA,eAAE,OAAO;CAItB,eAAeA,eAAE,OAAO,CAAC,CAAC,SAAS;CACnC,WAAWA,eAAE,OAAO;CACpB,WAAWA,eAAE,OAAO;;;;;CAKpB,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;;CAE1B,aAAaA,eAAE,OAAO,CAAC,CAAC,SAAS;AACnC,CAAC;AAED,IAAa,oBAAoBA,eAAE,MAAM,CAACA,eAAE,QAAQ,MAAM,GAAG,cAAc,CAAC;AAE5E,IAAM,eAAeA,eAAE,OAAO,EAC5B,WAAWA,eAAE,MAAM,sBAAsB,EAC3C,CAAC;;;;AAKD,IAAM,+BAA+BA,eAAE,OAAO;;CAE5C,OAAOA,eAAE,QAAQ,wBAAwB;;CAEzC,aAAaA,eAAE,MAAM,gBAAgB,CAAC,CAAC,SAAS;AAClD,CAAC;;;;AAID,IAAM,iCAAiCA,eAAE,OAAO;;CAE9C,OAAOA,eAAE,QAAQ,0BAA0B;;CAE3C,aAAaA,eAAE,MAAM,gBAAgB,CAAC,CAAC,SAAS;AAClD,CAAC;;;;AAID,IAAM,kBAAkBA,eAAE,OAAO;;CAE/B,OAAOA,eAAE,QAAQ,MAAM;;CAEvB,QAAQA,eAAE,OAAO;;CAEjB,SAASA,eAAE,OAAO;;CAElB,aAAaA,eAAE,MAAM,gBAAgB,CAAC,CAAC,SAAS;AAClD,CAAC;;;;AAID,IAAM,wBAAwBA,eAAE,OAAO;;CAErC,OAAOA,eAAE,QAAQ,YAAY;;CAE7B,SAASA,eAAE,OAAO;;CAElB,aAAaA,eAAE,MAAM,gBAAgB,CAAC,CAAC,SAAS;AAClD,CAAC;;;;AAID,IAAa,kBAAkBA,eAAE,MAC/B,8BACA,gCACA,iBACA,qBACF;AAEA,IAAa,yBAAyBA,eAAE,MAAM,cAAc,eAAe;AAEzCA,eAAE,MAClC,wBACA,oBACF;AACA,IAAa,4BAA4BA,eAAE,MAAM,CAC/CA,eAAE,QAAQ,cAAc,GACxB,sBACF,CAAC;AAED,IAAa,oCAAoCA,eAAE,MAAM,CACvDA,eAAE,QAAQ,sBAAsB,GAChC,gBACF,CAAC"}
@@ -22,6 +22,6 @@ var upPatchOpSchema = valita_exports.union(upPutOpSchema, delOpSchema, clearOpSc
22
22
  var queriesPatchSchema = valita_exports.array(patchOpSchema);
23
23
  var upQueriesPatchSchema = valita_exports.array(upPatchOpSchema);
24
24
  //#endregion
25
- export { queriesPatchSchema, upQueriesPatchSchema };
25
+ export { putOpSchema, queriesPatchSchema, upPutOpSchema, upQueriesPatchSchema };
26
26
 
27
27
  //# sourceMappingURL=queries-patch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queries-patch.js","names":[],"sources":["../../../../zero-protocol/src/queries-patch.ts"],"sourcesContent":["import {jsonSchema} from '../../shared/src/json-schema.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {strictASTSchema} from './ast.ts';\n\nexport const putOpSchema = v.object({\n op: v.literal('put'),\n hash: v.string(),\n ttl: v.number().optional(),\n});\n\nexport const upPutOpSchema = putOpSchema.extend({\n // All fields are optional in this transitional period.\n // - ast is filled in for client queries\n // - name and args are filled in for custom queries\n ast: strictASTSchema.optional(),\n name: v.string().optional(),\n args: v.readonly(v.array(jsonSchema)).optional(),\n});\n\nconst delOpSchema = v.object({\n op: v.literal('del'),\n hash: v.string(),\n});\n\nconst clearOpSchema = v.object({\n op: v.literal('clear'),\n});\n\nconst patchOpSchema = v.union(putOpSchema, delOpSchema, clearOpSchema);\nconst upPatchOpSchema = v.union(upPutOpSchema, delOpSchema, clearOpSchema);\n\nexport const queriesPatchSchema = v.array(patchOpSchema);\nexport const upQueriesPatchSchema = v.array(upPatchOpSchema);\n\nexport type QueriesPutOp = v.Infer<typeof putOpSchema>;\nexport type QueriesDelOp = v.Infer<typeof delOpSchema>;\nexport type QueriesClearOp = v.Infer<typeof clearOpSchema>;\nexport type QueriesPatchOp = v.Infer<typeof patchOpSchema>;\nexport type UpQueriesPatchOp = v.Infer<typeof upPatchOpSchema>;\nexport type QueriesPatch = v.Infer<typeof queriesPatchSchema>;\nexport type UpQueriesPatch = v.Infer<typeof upQueriesPatchSchema>;\n"],"mappings":";;;;AAIA,IAAa,cAAc,eAAE,OAAO;CAClC,IAAI,eAAE,QAAQ,KAAK;CACnB,MAAM,eAAE,OAAO;CACf,KAAK,eAAE,OAAO,EAAE,SAAS;AAC3B,CAAC;AAED,IAAa,gBAAgB,YAAY,OAAO;CAI9C,KAAK,gBAAgB,SAAS;CAC9B,MAAM,eAAE,OAAO,EAAE,SAAS;CAC1B,MAAM,SAAW,eAAE,MAAM,UAAU,CAAC,EAAE,SAAS;AACjD,CAAC;AAED,IAAM,cAAc,eAAE,OAAO;CAC3B,IAAI,eAAE,QAAQ,KAAK;CACnB,MAAM,eAAE,OAAO;AACjB,CAAC;AAED,IAAM,gBAAgB,eAAE,OAAO,EAC7B,IAAI,eAAE,QAAQ,OAAO,EACvB,CAAC;AAED,IAAM,gBAAgB,eAAE,MAAM,aAAa,aAAa,aAAa;AACrE,IAAM,kBAAkB,eAAE,MAAM,eAAe,aAAa,aAAa;AAEzE,IAAa,qBAAqB,eAAE,MAAM,aAAa;AACvD,IAAa,uBAAuB,eAAE,MAAM,eAAe"}
1
+ {"version":3,"file":"queries-patch.js","names":["v","v.readonly"],"sources":["../../../../zero-protocol/src/queries-patch.ts"],"sourcesContent":["import {jsonSchema} from '../../shared/src/json-schema.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {strictASTSchema} from './ast.ts';\n\nexport const putOpSchema = v.object({\n op: v.literal('put'),\n hash: v.string(),\n ttl: v.number().optional(),\n});\n\nexport const upPutOpSchema = putOpSchema.extend({\n // All fields are optional in this transitional period.\n // - ast is filled in for client queries\n // - name and args are filled in for custom queries\n ast: strictASTSchema.optional(),\n name: v.string().optional(),\n args: v.readonly(v.array(jsonSchema)).optional(),\n});\n\nconst delOpSchema = v.object({\n op: v.literal('del'),\n hash: v.string(),\n});\n\nconst clearOpSchema = v.object({\n op: v.literal('clear'),\n});\n\nconst patchOpSchema = v.union(putOpSchema, delOpSchema, clearOpSchema);\nconst upPatchOpSchema = v.union(upPutOpSchema, delOpSchema, clearOpSchema);\n\nexport const queriesPatchSchema = v.array(patchOpSchema);\nexport const upQueriesPatchSchema = v.array(upPatchOpSchema);\n\nexport type QueriesPutOp = v.Infer<typeof putOpSchema>;\nexport type QueriesDelOp = v.Infer<typeof delOpSchema>;\nexport type QueriesClearOp = v.Infer<typeof clearOpSchema>;\nexport type QueriesPatchOp = v.Infer<typeof patchOpSchema>;\nexport type UpQueriesPatchOp = v.Infer<typeof upPatchOpSchema>;\nexport type QueriesPatch = v.Infer<typeof queriesPatchSchema>;\nexport type UpQueriesPatch = v.Infer<typeof upQueriesPatchSchema>;\n"],"mappings":";;;;AAIA,IAAa,cAAcA,eAAE,OAAO;CAClC,IAAIA,eAAE,QAAQ,KAAK;CACnB,MAAMA,eAAE,OAAO;CACf,KAAKA,eAAE,OAAO,CAAC,CAAC,SAAS;AAC3B,CAAC;AAED,IAAa,gBAAgB,YAAY,OAAO;CAI9C,KAAK,gBAAgB,SAAS;CAC9B,MAAMA,eAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,MAAMC,SAAWD,eAAE,MAAM,UAAU,CAAC,CAAC,CAAC,SAAS;AACjD,CAAC;AAED,IAAM,cAAcA,eAAE,OAAO;CAC3B,IAAIA,eAAE,QAAQ,KAAK;CACnB,MAAMA,eAAE,OAAO;AACjB,CAAC;AAED,IAAM,gBAAgBA,eAAE,OAAO,EAC7B,IAAIA,eAAE,QAAQ,OAAO,EACvB,CAAC;AAED,IAAM,gBAAgBA,eAAE,MAAM,aAAa,aAAa,aAAa;AACrE,IAAM,kBAAkBA,eAAE,MAAM,eAAe,aAAa,aAAa;AAEzE,IAAa,qBAAqBA,eAAE,MAAM,aAAa;AACvD,IAAa,uBAAuBA,eAAE,MAAM,eAAe"}
@@ -1 +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
+ {"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,6 +1,6 @@
1
1
  import { getOrInsertComputed } from "../../shared/src/map.js";
2
2
  import { normalizeAST } from "./ast.js";
3
- import { hashAST } from "./query-hash-visitor.js";
3
+ import { hashAST, hashNameAndArgs } from "./query-hash-visitor.js";
4
4
  //#region ../zero-protocol/src/query-hash.ts
5
5
  var hashCache = /* @__PURE__ */ new WeakMap();
6
6
  function hashOfAST(ast) {
@@ -14,6 +14,6 @@ function hashOfNormalizedAST(ast) {
14
14
  return getOrInsertComputed(hashCache, ast, hashAST);
15
15
  }
16
16
  //#endregion
17
- export { hashOfAST };
17
+ export { hashOfAST, hashNameAndArgs as hashOfNameAndArgs, hashOfNormalizedAST };
18
18
 
19
19
  //# sourceMappingURL=query-hash.js.map
@@ -11,6 +11,6 @@ var querySuccessSchema = valita_exports.object({
11
11
  });
12
12
  var queryResponseSchema = valita_exports.union(querySuccessSchema, transformFailedBodySchema, transformResponseMessageSchema);
13
13
  //#endregion
14
- export { queryResponseSchema };
14
+ export { queryResponseBodySchema, queryResponseSchema, queryResultSchema, querySuccessSchema };
15
15
 
16
16
  //# sourceMappingURL=query-server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-server.js","names":[],"sources":["../../../../zero-protocol/src/query-server.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\nimport {\n erroredQuerySchema,\n transformedQuerySchema,\n transformResponseMessageSchema,\n} from './custom-queries.ts';\nimport {transformFailedBodySchema} from './error.ts';\n\nexport const queryResultSchema = v.union(\n transformedQuerySchema,\n erroredQuerySchema,\n);\nexport type QueryResult = v.Infer<typeof queryResultSchema>;\n\nexport const queryResponseBodySchema = v.array(queryResultSchema);\nexport type QueryResponseBody = v.Infer<typeof queryResponseBodySchema>;\n\nexport const querySuccessSchema = v.object({\n kind: v.literal('QueryResponse'),\n userID: v.string().nullable().optional(),\n queries: queryResponseBodySchema,\n});\nexport type QuerySuccess = v.Infer<typeof querySuccessSchema>;\n\nexport const queryResponseSchema = v.union(\n querySuccessSchema,\n transformFailedBodySchema,\n // for backwards compatibility\n transformResponseMessageSchema,\n);\nexport type QueryResponse = v.Infer<typeof queryResponseSchema>;\n"],"mappings":";;;;AAQA,IAAa,oBAAoB,eAAE,MACjC,wBACA,kBACF;AAGA,IAAa,0BAA0B,eAAE,MAAM,iBAAiB;AAGhE,IAAa,qBAAqB,eAAE,OAAO;CACzC,MAAM,eAAE,QAAQ,eAAe;CAC/B,QAAQ,eAAE,OAAO,EAAE,SAAS,EAAE,SAAS;CACvC,SAAS;AACX,CAAC;AAGD,IAAa,sBAAsB,eAAE,MACnC,oBACA,2BAEA,8BACF"}
1
+ {"version":3,"file":"query-server.js","names":["v"],"sources":["../../../../zero-protocol/src/query-server.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\nimport {\n erroredQuerySchema,\n transformedQuerySchema,\n transformResponseMessageSchema,\n} from './custom-queries.ts';\nimport {transformFailedBodySchema} from './error.ts';\n\nexport const queryResultSchema = v.union(\n transformedQuerySchema,\n erroredQuerySchema,\n);\nexport type QueryResult = v.Infer<typeof queryResultSchema>;\n\nexport const queryResponseBodySchema = v.array(queryResultSchema);\nexport type QueryResponseBody = v.Infer<typeof queryResponseBodySchema>;\n\nexport const querySuccessSchema = v.object({\n kind: v.literal('QueryResponse'),\n userID: v.string().nullable().optional(),\n queries: queryResponseBodySchema,\n});\nexport type QuerySuccess = v.Infer<typeof querySuccessSchema>;\n\nexport const queryResponseSchema = v.union(\n querySuccessSchema,\n transformFailedBodySchema,\n // for backwards compatibility\n transformResponseMessageSchema,\n);\nexport type QueryResponse = v.Infer<typeof queryResponseSchema>;\n"],"mappings":";;;;AAQA,IAAa,oBAAoBA,eAAE,MACjC,wBACA,kBACF;AAGA,IAAa,0BAA0BA,eAAE,MAAM,iBAAiB;AAGhE,IAAa,qBAAqBA,eAAE,OAAO;CACzC,MAAMA,eAAE,QAAQ,eAAe;CAC/B,QAAQA,eAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS;CACvC,SAAS;AACX,CAAC;AAGD,IAAa,sBAAsBA,eAAE,MACnC,oBACA,2BAEA,8BACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"row-patch.js","names":[],"sources":["../../../../zero-protocol/src/row-patch.ts"],"sourcesContent":["import {jsonObjectSchema} from '../../shared/src/json-schema.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {rowSchema} from './data.ts';\nimport {primaryKeyValueRecordSchema} from './primary-key.ts';\n\nconst putOpSchema = v.object({\n op: v.literal('put'),\n tableName: v.string(),\n value: rowSchema,\n});\n\nconst updateOpSchema = v.object({\n op: v.literal('update'),\n tableName: v.string(),\n id: primaryKeyValueRecordSchema,\n merge: jsonObjectSchema.optional(),\n constrain: v.array(v.string()).optional(),\n});\n\nconst delOpSchema = v.object({\n op: v.literal('del'),\n tableName: v.string(),\n id: primaryKeyValueRecordSchema,\n});\n\nconst clearOpSchema = v.object({\n op: v.literal('clear'),\n});\n\nconst rowPatchOpSchema = v.union(\n putOpSchema,\n updateOpSchema,\n delOpSchema,\n clearOpSchema,\n);\n\nexport const rowsPatchSchema = v.array(rowPatchOpSchema);\nexport type RowPatchOp = v.Infer<typeof rowPatchOpSchema>;\n"],"mappings":";;;;;AAKA,IAAM,cAAc,eAAE,OAAO;CAC3B,IAAI,eAAE,QAAQ,KAAK;CACnB,WAAW,eAAE,OAAO;CACpB,OAAO;AACT,CAAC;AAED,IAAM,iBAAiB,eAAE,OAAO;CAC9B,IAAI,eAAE,QAAQ,QAAQ;CACtB,WAAW,eAAE,OAAO;CACpB,IAAI;CACJ,OAAO,iBAAiB,SAAS;CACjC,WAAW,eAAE,MAAM,eAAE,OAAO,CAAC,EAAE,SAAS;AAC1C,CAAC;AAED,IAAM,cAAc,eAAE,OAAO;CAC3B,IAAI,eAAE,QAAQ,KAAK;CACnB,WAAW,eAAE,OAAO;CACpB,IAAI;AACN,CAAC;AAED,IAAM,gBAAgB,eAAE,OAAO,EAC7B,IAAI,eAAE,QAAQ,OAAO,EACvB,CAAC;AAED,IAAM,mBAAmB,eAAE,MACzB,aACA,gBACA,aACA,aACF;AAEA,IAAa,kBAAkB,eAAE,MAAM,gBAAgB"}
1
+ {"version":3,"file":"row-patch.js","names":["v"],"sources":["../../../../zero-protocol/src/row-patch.ts"],"sourcesContent":["import {jsonObjectSchema} from '../../shared/src/json-schema.ts';\nimport * as v from '../../shared/src/valita.ts';\nimport {rowSchema} from './data.ts';\nimport {primaryKeyValueRecordSchema} from './primary-key.ts';\n\nconst putOpSchema = v.object({\n op: v.literal('put'),\n tableName: v.string(),\n value: rowSchema,\n});\n\nconst updateOpSchema = v.object({\n op: v.literal('update'),\n tableName: v.string(),\n id: primaryKeyValueRecordSchema,\n merge: jsonObjectSchema.optional(),\n constrain: v.array(v.string()).optional(),\n});\n\nconst delOpSchema = v.object({\n op: v.literal('del'),\n tableName: v.string(),\n id: primaryKeyValueRecordSchema,\n});\n\nconst clearOpSchema = v.object({\n op: v.literal('clear'),\n});\n\nconst rowPatchOpSchema = v.union(\n putOpSchema,\n updateOpSchema,\n delOpSchema,\n clearOpSchema,\n);\n\nexport const rowsPatchSchema = v.array(rowPatchOpSchema);\nexport type RowPatchOp = v.Infer<typeof rowPatchOpSchema>;\n"],"mappings":";;;;;AAKA,IAAM,cAAcA,eAAE,OAAO;CAC3B,IAAIA,eAAE,QAAQ,KAAK;CACnB,WAAWA,eAAE,OAAO;CACpB,OAAO;AACT,CAAC;AAED,IAAM,iBAAiBA,eAAE,OAAO;CAC9B,IAAIA,eAAE,QAAQ,QAAQ;CACtB,WAAWA,eAAE,OAAO;CACpB,IAAI;CACJ,OAAO,iBAAiB,SAAS;CACjC,WAAWA,eAAE,MAAMA,eAAE,OAAO,CAAC,CAAC,CAAC,SAAS;AAC1C,CAAC;AAED,IAAM,cAAcA,eAAE,OAAO;CAC3B,IAAIA,eAAE,QAAQ,KAAK;CACnB,WAAWA,eAAE,OAAO;CACpB,IAAI;AACN,CAAC;AAED,IAAM,gBAAgBA,eAAE,OAAO,EAC7B,IAAIA,eAAE,QAAQ,OAAO,EACvB,CAAC;AAED,IAAM,mBAAmBA,eAAE,MACzB,aACA,gBACA,aACA,aACF;AAEA,IAAa,kBAAkBA,eAAE,MAAM,gBAAgB"}
@@ -1 +1 @@
1
- {"version":3,"file":"up.js","names":[],"sources":["../../../../zero-protocol/src/up.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\nimport {changeDesiredQueriesMessageSchema} from './change-desired-queries.ts';\nimport {closeConnectionMessageSchema} from './close-connection.ts';\nimport {initConnectionMessageSchema} from './connect.ts';\nimport {deleteClientsMessageSchema} from './delete-clients.ts';\nimport {\n inspectUpMessageSchema,\n unparsedInspectUpMessageSchema,\n} from './inspect-up.ts';\nimport {pingMessageSchema} from './ping.ts';\nimport {pullRequestMessageSchema} from './pull.ts';\nimport {ackMutationResponsesMessageSchema, pushMessageSchema} from './push.ts';\nimport {updateAuthMessageSchema} from './update-auth.ts';\n\nexport const upstreamSchema = v.taggedTupleUnion(\n [\n initConnectionMessageSchema,\n pingMessageSchema,\n deleteClientsMessageSchema,\n changeDesiredQueriesMessageSchema,\n pullRequestMessageSchema,\n updateAuthMessageSchema,\n pushMessageSchema,\n closeConnectionMessageSchema,\n inspectUpMessageSchema,\n ackMutationResponsesMessageSchema,\n ],\n {open: true},\n);\n\nexport const upstreamSchemaWithUnparsedAnalyzeQuery = v.taggedTupleUnion(\n [\n initConnectionMessageSchema,\n pingMessageSchema,\n deleteClientsMessageSchema,\n changeDesiredQueriesMessageSchema,\n pullRequestMessageSchema,\n updateAuthMessageSchema,\n pushMessageSchema,\n closeConnectionMessageSchema,\n unparsedInspectUpMessageSchema,\n ackMutationResponsesMessageSchema,\n ],\n {open: true},\n);\n\n// The messages this build knows. Parsing can also return a v.UnrecognizedTuple\n// from a newer client; check with `isKnown`.\nexport type Upstream = Exclude<\n v.Infer<typeof upstreamSchema>,\n v.UnrecognizedTuple\n>;\nexport type UpstreamWithUnparsedAnalyzeQuery = Exclude<\n v.Infer<typeof upstreamSchemaWithUnparsedAnalyzeQuery>,\n v.UnrecognizedTuple\n>;\n"],"mappings":";;;;;;;;;;AAc8B,iBAC5B;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GACA,EAAC,MAAM,KAAI,CACb;AAEA,IAAa,yCAAyC,iBACpD;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GACA,EAAC,MAAM,KAAI,CACb"}
1
+ {"version":3,"file":"up.js","names":["v.taggedTupleUnion"],"sources":["../../../../zero-protocol/src/up.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\nimport {changeDesiredQueriesMessageSchema} from './change-desired-queries.ts';\nimport {closeConnectionMessageSchema} from './close-connection.ts';\nimport {initConnectionMessageSchema} from './connect.ts';\nimport {deleteClientsMessageSchema} from './delete-clients.ts';\nimport {\n inspectUpMessageSchema,\n unparsedInspectUpMessageSchema,\n} from './inspect-up.ts';\nimport {pingMessageSchema} from './ping.ts';\nimport {pullRequestMessageSchema} from './pull.ts';\nimport {ackMutationResponsesMessageSchema, pushMessageSchema} from './push.ts';\nimport {updateAuthMessageSchema} from './update-auth.ts';\n\nexport const upstreamSchema = v.taggedTupleUnion(\n [\n initConnectionMessageSchema,\n pingMessageSchema,\n deleteClientsMessageSchema,\n changeDesiredQueriesMessageSchema,\n pullRequestMessageSchema,\n updateAuthMessageSchema,\n pushMessageSchema,\n closeConnectionMessageSchema,\n inspectUpMessageSchema,\n ackMutationResponsesMessageSchema,\n ],\n {open: true},\n);\n\nexport const upstreamSchemaWithUnparsedAnalyzeQuery = v.taggedTupleUnion(\n [\n initConnectionMessageSchema,\n pingMessageSchema,\n deleteClientsMessageSchema,\n changeDesiredQueriesMessageSchema,\n pullRequestMessageSchema,\n updateAuthMessageSchema,\n pushMessageSchema,\n closeConnectionMessageSchema,\n unparsedInspectUpMessageSchema,\n ackMutationResponsesMessageSchema,\n ],\n {open: true},\n);\n\n// The messages this build knows. Parsing can also return a v.UnrecognizedTuple\n// from a newer client; check with `isKnown`.\nexport type Upstream = Exclude<\n v.Infer<typeof upstreamSchema>,\n v.UnrecognizedTuple\n>;\nexport type UpstreamWithUnparsedAnalyzeQuery = Exclude<\n v.Infer<typeof upstreamSchemaWithUnparsedAnalyzeQuery>,\n v.UnrecognizedTuple\n>;\n"],"mappings":";;;;;;;;;;AAc8BA,iBAC5B;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GACA,EAAC,MAAM,KAAI,CACb;AAEA,IAAa,yCAAyCA,iBACpD;CACE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,GACA,EAAC,MAAM,KAAI,CACb"}
@@ -1 +1 @@
1
- {"version":3,"file":"update-auth.js","names":[],"sources":["../../../../zero-protocol/src/update-auth.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\n\nconst updateAuthBodySchema = v.object({\n auth: v.string(),\n});\n\nexport const updateAuthMessageSchema = v.tuple([\n v.literal('updateAuth'),\n updateAuthBodySchema,\n]);\n\nexport type UpdateAuthBody = v.Infer<typeof updateAuthBodySchema>;\nexport type UpdateAuthMessage = v.Infer<typeof updateAuthMessageSchema>;\n"],"mappings":";;AAEA,IAAM,uBAAuB,eAAE,OAAO,EACpC,MAAM,eAAE,OAAO,EACjB,CAAC;AAED,IAAa,0BAA0B,eAAE,MAAM,CAC7C,eAAE,QAAQ,YAAY,GACtB,oBACF,CAAC"}
1
+ {"version":3,"file":"update-auth.js","names":["v"],"sources":["../../../../zero-protocol/src/update-auth.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\n\nconst updateAuthBodySchema = v.object({\n auth: v.string(),\n});\n\nexport const updateAuthMessageSchema = v.tuple([\n v.literal('updateAuth'),\n updateAuthBodySchema,\n]);\n\nexport type UpdateAuthBody = v.Infer<typeof updateAuthBodySchema>;\nexport type UpdateAuthMessage = v.Infer<typeof updateAuthMessageSchema>;\n"],"mappings":";;AAEA,IAAM,uBAAuBA,eAAE,OAAO,EACpC,MAAMA,eAAE,OAAO,EACjB,CAAC;AAED,IAAa,0BAA0BA,eAAE,MAAM,CAC7CA,eAAE,QAAQ,YAAY,GACtB,oBACF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","names":[],"sources":["../../../../zero-protocol/src/version.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\n\nexport const versionSchema = v.string();\nexport const nullableVersionSchema = v.union(versionSchema, v.null());\n\nexport type Version = v.Infer<typeof versionSchema>;\nexport type NullableVersion = v.Infer<typeof nullableVersionSchema>;\n"],"mappings":";;AAEA,IAAa,gBAAgB,eAAE,OAAO;AACtC,IAAa,wBAAwB,eAAE,MAAM,eAAe,eAAE,KAAK,CAAC"}
1
+ {"version":3,"file":"version.js","names":["v"],"sources":["../../../../zero-protocol/src/version.ts"],"sourcesContent":["import * as v from '../../shared/src/valita.ts';\n\nexport const versionSchema = v.string();\nexport const nullableVersionSchema = v.union(versionSchema, v.null());\n\nexport type Version = v.Infer<typeof versionSchema>;\nexport type NullableVersion = v.Infer<typeof nullableVersionSchema>;\n"],"mappings":";;AAEA,IAAa,gBAAgBA,eAAE,OAAO;AACtC,IAAa,wBAAwBA,eAAE,MAAM,eAAeA,eAAE,KAAK,CAAC"}
@@ -1,12 +1,12 @@
1
- import "../../shared/src/asserts.js";
2
- import "../../shared/src/must.js";
3
- import "../../zql/src/query/query-internals.js";
4
- import "../../zql/src/query/query-impl.js";
5
- import "../../zql/src/query/query-registry.js";
6
- import "../../zql/src/ivm/skip-yields.js";
7
- import "../../zql/src/ivm/stream.js";
8
- import "../../zql/src/ivm/view-apply-change.js";
9
- import "../../zql/src/query/ttl.js";
10
- import "../../shared/src/deep-clone.js";
1
+ import { assert, unreachable } from "../../shared/src/asserts.js";
2
+ import { must } from "../../shared/src/must.js";
3
+ import { asQueryInternals, queryInternalsTag } from "../../zql/src/query/query-internals.js";
4
+ import { newQuery } from "../../zql/src/query/query-impl.js";
5
+ import { addContextToQuery } from "../../zql/src/query/query-registry.js";
6
+ import { skipYields } from "../../zql/src/ivm/skip-yields.js";
7
+ import { consume } from "../../zql/src/ivm/stream.js";
8
+ import { applyChange, idSymbol, refCountSymbol } from "../../zql/src/ivm/view-apply-change.js";
9
+ import { DEFAULT_TTL_MS } from "../../zql/src/query/ttl.js";
10
+ import { deepClone } from "../../shared/src/deep-clone.js";
11
11
  import "../../zero-client/src/client/bindings.js";
12
- export {};
12
+ export { DEFAULT_TTL_MS, addContextToQuery, applyChange, asQueryInternals, assert, consume, deepClone, idSymbol, must, newQuery, queryInternalsTag, refCountSymbol, skipYields, unreachable };
@@ -1,5 +1,5 @@
1
- import "./zero-provider.js";
2
- import "./use-connection-state.js";
3
- import "./use-query.js";
4
- import "./use-zero-online.js";
5
- export {};
1
+ import { ZeroContext, ZeroProvider, createUseZero, useZero } from "./zero-provider.js";
2
+ import { useConnectionState } from "./use-connection-state.js";
3
+ import { useQuery, useSuspenseQuery } from "./use-query.js";
4
+ import { useZeroOnline } from "./use-zero-online.js";
5
+ export { ZeroContext, ZeroProvider, createUseZero, useConnectionState, useQuery, useSuspenseQuery, useZero, useZeroOnline };
@@ -379,6 +379,6 @@ var ViewWrapper = class {
379
379
  }
380
380
  };
381
381
  //#endregion
382
- export { useQuery, useSuspenseQuery };
382
+ export { ViewStore, useQuery, useSuspenseQuery };
383
383
 
384
384
  //# sourceMappingURL=use-query.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-query.js","names":["#views","#onDematerialized","#query","#reactInternals","#zero","#singular","#ttl","#snapshot","#materializeIfNeeded","#lastResultType","#lastData","#lastError","#retry","#complete","#completeResolver","#nonEmpty","#nonEmptyResolver","#view","#onData","#destroyTimer"],"sources":["../../../../zero-react/src/use-query.tsx"],"sourcesContent":["import {resolver} from '@rocicorp/resolver';\nimport React, {useRef, useSyncExternalStore} from 'react';\nimport {deepEqual} from '../../shared/src/json.ts';\nimport {TESTING} from '../../shared/src/testing.ts';\nimport {\n type Immutable,\n addContextToQuery,\n asQueryInternals,\n DEFAULT_TTL_MS,\n} from './bindings.ts';\nimport {useZero} from './zero-provider.tsx';\nimport type {\n AnyMutatorRegistry,\n BaseDefaultContext,\n BaseDefaultSchema,\n CustomMutatorDefs,\n DefaultContext,\n DefaultSchema,\n ErroredQuery,\n Falsy,\n HumanReadable,\n PullRow,\n Query,\n QueryErrorDetails,\n QueryOrQueryRequest,\n QueryResultDetails,\n ReadonlyJSONValue,\n ResultType,\n TTL,\n TypedView,\n Zero,\n} from './zero.ts';\n\ntype StableQueryCache = {\n zero: unknown;\n context: unknown;\n /** The last input, so an unchanged one is an identity compare and nothing else. */\n rawQuery: object;\n /** The `CustomQuery` a query request names; undefined for a plain query. */\n customQuery: unknown;\n args: ReadonlyJSONValue | undefined;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n q: Query<any, any, any>;\n};\n\n/**\n * Resolves a query request against the Zero context, reusing the previous\n * result while the request means the same thing.\n *\n * Interning already makes an unchanged *plain* query come back as the same\n * object, so this is aimed at the query-request form -- `queries.issue({id})`\n * -- where every render allocates a fresh request and `addContextToQuery`\n * re-runs the definition. That costs argument validation (a zod parse of\n * byte-identical args) plus a walk of the builder chain, neither of which\n * interning removes: it makes rebuilding the chain cheap and gives the same\n * object back, but only after the work has been done again.\n *\n * A request resolves to the previous query when it names the same\n * `CustomQuery`, the same context, and deep-equal args. Those are exactly the\n * inputs the definition is allowed to depend on: a named query is re-derived\n * on the server from its name and args, so it has to be a pure function of\n * them, or client and server would build different queries.\n *\n * The ref is written during render. That is safe here because it is a pure\n * cache: an entry is derived only from the inputs, so a StrictMode double\n * render or a discarded concurrent render leaves it valid either way.\n */\nfunction useStableQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema,\n TReturn,\n TContext extends BaseDefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n zero: Zero<TSchema, undefined, TContext>,\n): Query<TTable, TSchema, TReturn> | undefined {\n const cacheRef = useRef<StableQueryCache | undefined>(undefined);\n\n // Deliberately kept rather than cleared: a query toggled off and back on\n // reuses what it had.\n if (!query) {\n return undefined;\n }\n\n const cache = cacheRef.current;\n if (cache && cache.zero === zero) {\n if (cache.rawQuery === query) {\n return cache.q as Query<TTable, TSchema, TReturn>;\n }\n if (\n 'query' in query &&\n cache.customQuery === query.query &&\n cache.context === zero.context &&\n deepEqual(cache.args, query.args)\n ) {\n // Same meaning, new wrapper object: remember it so the next render is\n // the identity compare above.\n cache.rawQuery = query;\n return cache.q as Query<TTable, TSchema, TReturn>;\n }\n }\n\n const q = addContextToQuery(query, zero.context);\n const isRequest = 'query' in query;\n cacheRef.current = {\n zero: zero,\n context: zero.context,\n rawQuery: query,\n customQuery: isRequest ? query.query : undefined,\n args: isRequest ? query.args : undefined,\n q,\n };\n return q;\n}\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails & {},\n];\n\n/**\n * Result type for \"maybe queries\" - queries that may be falsy.\n * The data value can be undefined when the query is falsy/disabled.\n */\nexport type MaybeQueryResult<TReturn> = readonly [\n HumanReadable<TReturn> | undefined,\n QueryResultDetails & {},\n];\n\nexport type UseQueryOptions = {\n enabled?: boolean | undefined;\n /**\n * Time to live (TTL) in seconds. Controls how long query results are cached\n * after the query is removed. During this time, Zero continues to sync the query.\n * Default is 'never'.\n */\n ttl?: TTL | undefined;\n};\n\nexport type UseSuspenseQueryOptions = UseQueryOptions & {\n /**\n * Whether to suspend until:\n * - 'partial': the query has partial results (partial array or defined\n * value for singular results) which may be of result type 'unknown',\n * or the query result type is 'complete' or 'cached' (in which case\n * results may be empty: a server-confirmed empty answer, from this\n * connection or a previous one, is something to render). This is useful\n * for suspending until there are partial optimistic local results, or\n * the query has completed loading from the server.\n * - 'complete': the query result type is 'complete'.\n *\n * Default is 'partial'.\n */\n suspendUntil?: 'complete' | 'partial';\n};\n\nconst reactUse = (React as {use?: (p: Promise<unknown>) => void}).use;\nconst suspend: (p: Promise<unknown>) => void = reactUse\n ? reactUse\n : p => {\n throw p;\n };\n\n// Overload 1: Query\nexport function useQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query: QueryOrQueryRequest<\n TTable,\n TInput,\n TOutput,\n TSchema,\n TReturn,\n TContext\n >,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn>;\n\n// Overload 2: Maybe query\nexport function useQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n options?: UseQueryOptions | boolean,\n): MaybeQueryResult<TReturn>;\n\n// Implementation\nexport function useQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn> | MaybeQueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({enabled = true, ttl = DEFAULT_TTL_MS} = options);\n }\n\n const zero = useZero<TSchema, undefined, TContext>();\n\n // When query is falsy, use disabled subscriber/snapshot to maintain hook order\n const q = useStableQuery(query, zero);\n const view = q ? viewStore.getView(zero, q, enabled, ttl) : undefined;\n\n // https://react.dev/reference/react/useSyncExternalStore\n // Always call useSyncExternalStore to maintain consistent hook order\n return useSyncExternalStore(\n view?.subscribeReactInternals ?? disabledSubscriber,\n view?.getSnapshot ??\n (getDisabledSnapshot as () => MaybeQueryResult<TReturn>),\n view?.getSnapshot ??\n (getDisabledSnapshot as () => MaybeQueryResult<TReturn>),\n );\n}\n\n// Overload 1: Query\nexport function useSuspenseQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query: QueryOrQueryRequest<\n TTable,\n TInput,\n TOutput,\n TSchema,\n TReturn,\n TContext\n >,\n options?: UseSuspenseQueryOptions | boolean,\n): QueryResult<TReturn>;\n\n// Overload 2: Maybe query\nexport function useSuspenseQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n options?: UseSuspenseQueryOptions | boolean,\n): MaybeQueryResult<TReturn>;\n\n// Implementation\nexport function useSuspenseQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n options?: UseSuspenseQueryOptions | boolean,\n): QueryResult<TReturn> | MaybeQueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n let suspendUntil: 'complete' | 'partial' = 'partial';\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({\n enabled = true,\n ttl = DEFAULT_TTL_MS,\n suspendUntil = 'partial',\n } = options);\n }\n\n const zero = useZero<TSchema, undefined, TContext>();\n\n // When query is falsy, use disabled subscriber/snapshot to maintain hook order\n const q = useStableQuery(query, zero);\n const view = q ? viewStore.getView(zero, q, enabled, ttl) : undefined;\n\n // https://react.dev/reference/react/useSyncExternalStore\n // Always call useSyncExternalStore to maintain consistent hook order\n const snapshot = useSyncExternalStore(\n view?.subscribeReactInternals ?? disabledSubscriber,\n view?.getSnapshot ??\n (getDisabledSnapshot as () => MaybeQueryResult<TReturn>),\n view?.getSnapshot ??\n (getDisabledSnapshot as () => MaybeQueryResult<TReturn>),\n );\n\n if (view && enabled) {\n if (suspendUntil === 'complete' && !view.complete) {\n suspend(view.waitForComplete());\n }\n\n if (suspendUntil === 'partial' && !view.nonEmpty) {\n suspend(view.waitForNonEmpty());\n }\n }\n\n return snapshot;\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeCached = {type: 'cached'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\nconst resultTypeError = {type: 'error'} as const;\n\nconst disabledQuerySnapshot = [undefined, resultTypeUnknown] as const;\nconst getDisabledSnapshot = () => disabledQuerySnapshot;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularCached = [undefined, resultTypeCached] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotSingularErrorUnknown = [undefined, resultTypeError] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralCached = [emptyArray, resultTypeCached] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\nconst emptySnapshotErrorUnknown = [emptyArray, resultTypeError] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: ResultType,\n retryFn: () => void,\n error?: ErroredQuery,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n switch (resultType) {\n case 'error':\n if (error) {\n return [\n undefined,\n makeError(retryFn, error),\n ] as unknown as QueryResult<TReturn>;\n }\n return emptySnapshotSingularErrorUnknown as unknown as QueryResult<TReturn>;\n case 'complete':\n return emptySnapshotSingularComplete as unknown as QueryResult<TReturn>;\n case 'unknown':\n return emptySnapshotSingularUnknown as unknown as QueryResult<TReturn>;\n case 'cached':\n return emptySnapshotSingularCached as unknown as QueryResult<TReturn>;\n }\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n switch (resultType) {\n case 'error':\n if (error) {\n return [\n emptyArray,\n makeError(retryFn, error),\n ] as unknown as QueryResult<TReturn>;\n }\n return emptySnapshotErrorUnknown as unknown as QueryResult<TReturn>;\n case 'complete':\n return emptySnapshotPluralComplete as unknown as QueryResult<TReturn>;\n case 'unknown':\n return emptySnapshotPluralUnknown as unknown as QueryResult<TReturn>;\n case 'cached':\n return emptySnapshotPluralCached as unknown as QueryResult<TReturn>;\n }\n }\n\n switch (resultType) {\n case 'error':\n if (error) {\n return [data, makeError(retryFn, error)];\n }\n return [\n data,\n makeError(retryFn, {\n error: 'app',\n id: 'unknown',\n name: 'unknown',\n message: 'An unknown error occurred',\n }),\n ];\n case 'complete':\n return [data, resultTypeComplete];\n case 'unknown':\n return [data, resultTypeUnknown];\n case 'cached':\n return [data, resultTypeCached];\n }\n}\n\nfunction makeError(retry: () => void, error: ErroredQuery): QueryErrorDetails {\n const message = error.message ?? 'An unknown error occurred';\n return {\n type: 'error',\n retry,\n refetch: retry,\n error: {\n type: error.error,\n message,\n ...(error.details ? {details: error.details} : {}),\n },\n };\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyViewWrapper = ViewWrapper<any, any, any, any, any>;\n\nconst allViews = new WeakMap<\n ViewStore,\n Map<string, Map<string, AnyViewWrapper>>\n>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n let size = 0;\n for (const byHash of allViews.get(store)?.values() ?? []) {\n size += byHash.size;\n }\n return size;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n /**\n * Client id, then query hash.\n *\n * Nested rather than keyed by the two joined together, because this is\n * looked up on every render of every `useQuery`. Joining them builds a\n * string that V8 has to hash from scratch, where both halves on their own\n * are strings it has already hashed and cached -- `hash()` is memoized on an\n * interned query, so the same string comes back each render. Measured over a\n * rebuild-and-look-up of one chain, that is the difference between 202ns and\n * 123ns; the join cost more than rebuilding and hashing the whole query.\n */\n #views = new Map<string, Map<string, AnyViewWrapper>>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends BaseDefaultSchema,\n TReturn,\n MD extends CustomMutatorDefs | undefined,\n TContext extends BaseDefaultContext,\n >(\n zero: Zero<TSchema, MD, TContext>,\n q: Query<TTable, TSchema, TReturn>,\n enabled: boolean,\n ttl: TTL,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n updateTTL: (ttl: TTL) => void;\n waitForComplete: () => Promise<void>;\n waitForNonEmpty: () => Promise<void>;\n complete: boolean;\n nonEmpty: boolean;\n } {\n const qi = asQueryInternals(q);\n\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(qi.format.singular),\n subscribeReactInternals: disabledSubscriber,\n updateTTL: () => {},\n waitForComplete: () => Promise.resolve(),\n waitForNonEmpty: () => Promise.resolve(),\n complete: false,\n nonEmpty: false,\n };\n }\n\n const {clientID} = zero;\n const hash = qi.hash();\n let byHash = this.#views.get(clientID);\n let existing = byHash?.get(hash);\n if (!existing) {\n existing = new ViewWrapper(q, zero, ttl, view => {\n const views = this.#views.get(clientID);\n const currentView = views?.get(hash);\n if (currentView && currentView !== view) {\n // we replaced the view with a new one already.\n return;\n }\n views?.delete(hash);\n if (views?.size === 0) {\n // Nothing is left for this client, so drop its map rather than\n // keeping one per client id the page has ever seen.\n this.#views.delete(clientID);\n }\n });\n if (!byHash) {\n byHash = new Map();\n this.#views.set(clientID, byHash);\n }\n byHash.set(hash, existing);\n } else {\n existing.updateTTL(ttl);\n }\n return existing as ViewWrapper<TTable, TSchema, TReturn, MD, TContext>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends BaseDefaultSchema,\n TReturn,\n MD extends AnyMutatorRegistry | CustomMutatorDefs | undefined,\n TContext extends BaseDefaultContext,\n> {\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #query: Query<TTable, TSchema, TReturn>;\n #snapshot: QueryResult<TReturn>;\n readonly #reactInternals: Set<() => void> = new Set();\n #ttl: TTL;\n #complete = false;\n #completeResolver = resolver<void>();\n #nonEmpty = false;\n #nonEmptyResolver = resolver<void>();\n readonly #zero: Pick<Zero<TSchema, undefined, TContext>, 'materialize'>;\n readonly #singular: boolean;\n #destroyTimer: ReturnType<typeof setTimeout> | undefined;\n\n // Inputs of the previous #onData call. When a view flush delivers\n // reference-identical data with the same resultType and error, the previous\n // snapshot tuple is kept and React is not notified — building a fresh tuple\n // would defeat useSyncExternalStore's Object.is bailout and re-render every\n // subscriber with identical data. #lastResultType doubles as the \"has fired\n // before\" sentinel (data and error may both legitimately be undefined).\n #lastData: Immutable<HumanReadable<TReturn>> | undefined;\n #lastResultType: ResultType | undefined;\n #lastError: ErroredQuery | undefined;\n\n constructor(\n query: Query<TTable, TSchema, TReturn>,\n zero: Pick<Zero<TSchema, undefined, TContext>, 'materialize'>,\n ttl: TTL,\n onDematerialized: (\n view: ViewWrapper<TTable, TSchema, TReturn, MD, TContext>,\n ) => void,\n ) {\n this.#query = query;\n this.#zero = zero;\n this.#ttl = ttl;\n this.#onDematerialized = onDematerialized;\n const {singular} = asQueryInternals(query).format;\n this.#singular = singular;\n this.#snapshot = getDefaultSnapshot(singular);\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n error?: ErroredQuery,\n ) => {\n const wasCached = this.#snapshot[1].type === 'cached';\n const changed =\n this.#lastResultType === undefined ||\n this.#lastData !== snap ||\n this.#lastResultType !== resultType ||\n this.#lastError !== error;\n this.#lastData = snap;\n this.#lastResultType = resultType;\n this.#lastError = error;\n\n if (changed) {\n // applyChange now returns immutable data structures, so no deep clone needed.\n // Unchanged rows preserve their object identity for React.memo optimization.\n const data = snap as HumanReadable<TReturn>;\n this.#snapshot = getSnapshot(\n this.#singular,\n data,\n resultType,\n this.#retry,\n error,\n );\n }\n\n // The resolver bookkeeping runs even when unchanged: after a\n // destroy/re-materialize cycle the resolvers are fresh but the new view\n // may deliver the same data/resultType as before the destroy.\n if (resultType === 'complete' || resultType === 'error') {\n this.#complete = true;\n this.#completeResolver.resolve();\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n }\n\n const hasData = this.#singular\n ? this.#snapshot[0] !== undefined\n : (this.#snapshot[0] as unknown[]).length !== 0;\n // A 'cached' result is the server-confirmed answer from a previous\n // session, so even an empty one is something to render. It never\n // satisfies `complete`; only a confirmation on this connection does.\n if (resultType === 'cached' || hasData) {\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n } else if (wasCached && resultType === 'unknown') {\n // The cached claim was revoked (the got key was evicted before this\n // connection confirmed the query) and the view is empty: there is\n // nothing to render again until rows or a confirmation arrive.\n this.#nonEmpty = false;\n this.#nonEmptyResolver = resolver();\n }\n\n if (changed) {\n for (const internals of this.#reactInternals) {\n internals();\n }\n }\n };\n\n /**\n * Called by the user to force a retry of the query\n * in the case the query errored.\n */\n #retry = () => {\n this.#view?.destroy();\n this.#view = undefined;\n this.#materializeIfNeeded();\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n this.#view = this.#zero.materialize(this.#query, {\n ttl: this.#ttl,\n });\n this.#view.addListener(this.#onData);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n // Cancel any pending destroy timer from a previous unsubscribe.\n // Without this, rapid unsub/resub cycles accumulate stale timers\n // that can fire during a gap between unsubscribe and resubscribe,\n // destroying the view even though it was actively used.\n if (this.#destroyTimer !== undefined) {\n clearTimeout(this.#destroyTimer);\n this.#destroyTimer = undefined;\n }\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n this.#destroyTimer = setTimeout(() => {\n this.#destroyTimer = undefined;\n\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n\n this.#view.destroy();\n this.#view = undefined;\n this.#complete = false;\n this.#completeResolver = resolver();\n this.#nonEmpty = false;\n this.#nonEmptyResolver = resolver();\n this.#onDematerialized(this);\n }, 10);\n }\n };\n };\n\n updateTTL(ttl: TTL): void {\n // `getView` calls this on every render, and forwarding an unchanged TTL\n // reaches the query manager, which re-derives the query's id from its AST\n // to find the entry. Nothing downstream distinguishes a repeat, so skip\n // it. A change in how the same duration is spelled ('60s' vs 60000) is\n // still a change here and still propagates, as it did before.\n if (this.#ttl === ttl) {\n return;\n }\n this.#ttl = ttl;\n this.#view?.updateTTL(ttl);\n }\n\n get complete() {\n return this.#complete;\n }\n\n waitForComplete(): Promise<void> {\n return this.#completeResolver.promise;\n }\n\n get nonEmpty() {\n return this.#nonEmpty;\n }\n\n waitForNonEmpty(): Promise<void> {\n return this.#nonEmptyResolver.promise;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-query.js","names":[],"sources":["../../../../zero-react/src/use-query.tsx"],"sourcesContent":["import {resolver} from '@rocicorp/resolver';\nimport React, {useRef, useSyncExternalStore} from 'react';\nimport {deepEqual} from '../../shared/src/json.ts';\nimport {TESTING} from '../../shared/src/testing.ts';\nimport {\n type Immutable,\n addContextToQuery,\n asQueryInternals,\n DEFAULT_TTL_MS,\n} from './bindings.ts';\nimport {useZero} from './zero-provider.tsx';\nimport type {\n AnyMutatorRegistry,\n BaseDefaultContext,\n BaseDefaultSchema,\n CustomMutatorDefs,\n DefaultContext,\n DefaultSchema,\n ErroredQuery,\n Falsy,\n HumanReadable,\n PullRow,\n Query,\n QueryErrorDetails,\n QueryOrQueryRequest,\n QueryResultDetails,\n ReadonlyJSONValue,\n ResultType,\n TTL,\n TypedView,\n Zero,\n} from './zero.ts';\n\ntype StableQueryCache = {\n zero: unknown;\n context: unknown;\n /** The last input, so an unchanged one is an identity compare and nothing else. */\n rawQuery: object;\n /** The `CustomQuery` a query request names; undefined for a plain query. */\n customQuery: unknown;\n args: ReadonlyJSONValue | undefined;\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n q: Query<any, any, any>;\n};\n\n/**\n * Resolves a query request against the Zero context, reusing the previous\n * result while the request means the same thing.\n *\n * Interning already makes an unchanged *plain* query come back as the same\n * object, so this is aimed at the query-request form -- `queries.issue({id})`\n * -- where every render allocates a fresh request and `addContextToQuery`\n * re-runs the definition. That costs argument validation (a zod parse of\n * byte-identical args) plus a walk of the builder chain, neither of which\n * interning removes: it makes rebuilding the chain cheap and gives the same\n * object back, but only after the work has been done again.\n *\n * A request resolves to the previous query when it names the same\n * `CustomQuery`, the same context, and deep-equal args. Those are exactly the\n * inputs the definition is allowed to depend on: a named query is re-derived\n * on the server from its name and args, so it has to be a pure function of\n * them, or client and server would build different queries.\n *\n * The ref is written during render. That is safe here because it is a pure\n * cache: an entry is derived only from the inputs, so a StrictMode double\n * render or a discarded concurrent render leaves it valid either way.\n */\nfunction useStableQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema,\n TReturn,\n TContext extends BaseDefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n zero: Zero<TSchema, undefined, TContext>,\n): Query<TTable, TSchema, TReturn> | undefined {\n const cacheRef = useRef<StableQueryCache | undefined>(undefined);\n\n // Deliberately kept rather than cleared: a query toggled off and back on\n // reuses what it had.\n if (!query) {\n return undefined;\n }\n\n const cache = cacheRef.current;\n if (cache && cache.zero === zero) {\n if (cache.rawQuery === query) {\n return cache.q as Query<TTable, TSchema, TReturn>;\n }\n if (\n 'query' in query &&\n cache.customQuery === query.query &&\n cache.context === zero.context &&\n deepEqual(cache.args, query.args)\n ) {\n // Same meaning, new wrapper object: remember it so the next render is\n // the identity compare above.\n cache.rawQuery = query;\n return cache.q as Query<TTable, TSchema, TReturn>;\n }\n }\n\n const q = addContextToQuery(query, zero.context);\n const isRequest = 'query' in query;\n cacheRef.current = {\n zero: zero,\n context: zero.context,\n rawQuery: query,\n customQuery: isRequest ? query.query : undefined,\n args: isRequest ? query.args : undefined,\n q,\n };\n return q;\n}\n\nexport type QueryResult<TReturn> = readonly [\n HumanReadable<TReturn>,\n QueryResultDetails & {},\n];\n\n/**\n * Result type for \"maybe queries\" - queries that may be falsy.\n * The data value can be undefined when the query is falsy/disabled.\n */\nexport type MaybeQueryResult<TReturn> = readonly [\n HumanReadable<TReturn> | undefined,\n QueryResultDetails & {},\n];\n\nexport type UseQueryOptions = {\n enabled?: boolean | undefined;\n /**\n * Time to live (TTL) in seconds. Controls how long query results are cached\n * after the query is removed. During this time, Zero continues to sync the query.\n * Default is 'never'.\n */\n ttl?: TTL | undefined;\n};\n\nexport type UseSuspenseQueryOptions = UseQueryOptions & {\n /**\n * Whether to suspend until:\n * - 'partial': the query has partial results (partial array or defined\n * value for singular results) which may be of result type 'unknown',\n * or the query result type is 'complete' or 'cached' (in which case\n * results may be empty: a server-confirmed empty answer, from this\n * connection or a previous one, is something to render). This is useful\n * for suspending until there are partial optimistic local results, or\n * the query has completed loading from the server.\n * - 'complete': the query result type is 'complete'.\n *\n * Default is 'partial'.\n */\n suspendUntil?: 'complete' | 'partial';\n};\n\nconst reactUse = (React as {use?: (p: Promise<unknown>) => void}).use;\nconst suspend: (p: Promise<unknown>) => void = reactUse\n ? reactUse\n : p => {\n throw p;\n };\n\n// Overload 1: Query\nexport function useQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query: QueryOrQueryRequest<\n TTable,\n TInput,\n TOutput,\n TSchema,\n TReturn,\n TContext\n >,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn>;\n\n// Overload 2: Maybe query\nexport function useQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n options?: UseQueryOptions | boolean,\n): MaybeQueryResult<TReturn>;\n\n// Implementation\nexport function useQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n options?: UseQueryOptions | boolean,\n): QueryResult<TReturn> | MaybeQueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({enabled = true, ttl = DEFAULT_TTL_MS} = options);\n }\n\n const zero = useZero<TSchema, undefined, TContext>();\n\n // When query is falsy, use disabled subscriber/snapshot to maintain hook order\n const q = useStableQuery(query, zero);\n const view = q ? viewStore.getView(zero, q, enabled, ttl) : undefined;\n\n // https://react.dev/reference/react/useSyncExternalStore\n // Always call useSyncExternalStore to maintain consistent hook order\n return useSyncExternalStore(\n view?.subscribeReactInternals ?? disabledSubscriber,\n view?.getSnapshot ??\n (getDisabledSnapshot as () => MaybeQueryResult<TReturn>),\n view?.getSnapshot ??\n (getDisabledSnapshot as () => MaybeQueryResult<TReturn>),\n );\n}\n\n// Overload 1: Query\nexport function useSuspenseQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query: QueryOrQueryRequest<\n TTable,\n TInput,\n TOutput,\n TSchema,\n TReturn,\n TContext\n >,\n options?: UseSuspenseQueryOptions | boolean,\n): QueryResult<TReturn>;\n\n// Overload 2: Maybe query\nexport function useSuspenseQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n options?: UseSuspenseQueryOptions | boolean,\n): MaybeQueryResult<TReturn>;\n\n// Implementation\nexport function useSuspenseQuery<\n TTable extends keyof TSchema['tables'] & string,\n TInput extends ReadonlyJSONValue | undefined,\n TOutput extends ReadonlyJSONValue | undefined,\n TSchema extends BaseDefaultSchema = DefaultSchema,\n TReturn = PullRow<TTable, TSchema>,\n TContext extends BaseDefaultContext = DefaultContext,\n>(\n query:\n | QueryOrQueryRequest<TTable, TInput, TOutput, TSchema, TReturn, TContext>\n | Falsy,\n options?: UseSuspenseQueryOptions | boolean,\n): QueryResult<TReturn> | MaybeQueryResult<TReturn> {\n let enabled = true;\n let ttl: TTL = DEFAULT_TTL_MS;\n let suspendUntil: 'complete' | 'partial' = 'partial';\n if (typeof options === 'boolean') {\n enabled = options;\n } else if (options) {\n ({\n enabled = true,\n ttl = DEFAULT_TTL_MS,\n suspendUntil = 'partial',\n } = options);\n }\n\n const zero = useZero<TSchema, undefined, TContext>();\n\n // When query is falsy, use disabled subscriber/snapshot to maintain hook order\n const q = useStableQuery(query, zero);\n const view = q ? viewStore.getView(zero, q, enabled, ttl) : undefined;\n\n // https://react.dev/reference/react/useSyncExternalStore\n // Always call useSyncExternalStore to maintain consistent hook order\n const snapshot = useSyncExternalStore(\n view?.subscribeReactInternals ?? disabledSubscriber,\n view?.getSnapshot ??\n (getDisabledSnapshot as () => MaybeQueryResult<TReturn>),\n view?.getSnapshot ??\n (getDisabledSnapshot as () => MaybeQueryResult<TReturn>),\n );\n\n if (view && enabled) {\n if (suspendUntil === 'complete' && !view.complete) {\n suspend(view.waitForComplete());\n }\n\n if (suspendUntil === 'partial' && !view.nonEmpty) {\n suspend(view.waitForNonEmpty());\n }\n }\n\n return snapshot;\n}\n\nconst emptyArray: unknown[] = [];\nconst disabledSubscriber = () => () => {};\n\nconst resultTypeUnknown = {type: 'unknown'} as const;\nconst resultTypeCached = {type: 'cached'} as const;\nconst resultTypeComplete = {type: 'complete'} as const;\nconst resultTypeError = {type: 'error'} as const;\n\nconst disabledQuerySnapshot = [undefined, resultTypeUnknown] as const;\nconst getDisabledSnapshot = () => disabledQuerySnapshot;\n\nconst emptySnapshotSingularUnknown = [undefined, resultTypeUnknown] as const;\nconst emptySnapshotSingularCached = [undefined, resultTypeCached] as const;\nconst emptySnapshotSingularComplete = [undefined, resultTypeComplete] as const;\nconst emptySnapshotSingularErrorUnknown = [undefined, resultTypeError] as const;\nconst emptySnapshotPluralUnknown = [emptyArray, resultTypeUnknown] as const;\nconst emptySnapshotPluralCached = [emptyArray, resultTypeCached] as const;\nconst emptySnapshotPluralComplete = [emptyArray, resultTypeComplete] as const;\nconst emptySnapshotErrorUnknown = [emptyArray, resultTypeError] as const;\n\nfunction getDefaultSnapshot<TReturn>(singular: boolean): QueryResult<TReturn> {\n return (\n singular ? emptySnapshotSingularUnknown : emptySnapshotPluralUnknown\n ) as QueryResult<TReturn>;\n}\n\n/**\n * Returns a new snapshot or one of the empty predefined ones. Returning the\n * predefined ones is important to prevent unnecessary re-renders in React.\n */\nfunction getSnapshot<TReturn>(\n singular: boolean,\n data: HumanReadable<TReturn>,\n resultType: ResultType,\n retryFn: () => void,\n error?: ErroredQuery,\n): QueryResult<TReturn> {\n if (singular && data === undefined) {\n switch (resultType) {\n case 'error':\n if (error) {\n return [\n undefined,\n makeError(retryFn, error),\n ] as unknown as QueryResult<TReturn>;\n }\n return emptySnapshotSingularErrorUnknown as unknown as QueryResult<TReturn>;\n case 'complete':\n return emptySnapshotSingularComplete as unknown as QueryResult<TReturn>;\n case 'unknown':\n return emptySnapshotSingularUnknown as unknown as QueryResult<TReturn>;\n case 'cached':\n return emptySnapshotSingularCached as unknown as QueryResult<TReturn>;\n }\n }\n\n if (!singular && (data as unknown[]).length === 0) {\n switch (resultType) {\n case 'error':\n if (error) {\n return [\n emptyArray,\n makeError(retryFn, error),\n ] as unknown as QueryResult<TReturn>;\n }\n return emptySnapshotErrorUnknown as unknown as QueryResult<TReturn>;\n case 'complete':\n return emptySnapshotPluralComplete as unknown as QueryResult<TReturn>;\n case 'unknown':\n return emptySnapshotPluralUnknown as unknown as QueryResult<TReturn>;\n case 'cached':\n return emptySnapshotPluralCached as unknown as QueryResult<TReturn>;\n }\n }\n\n switch (resultType) {\n case 'error':\n if (error) {\n return [data, makeError(retryFn, error)];\n }\n return [\n data,\n makeError(retryFn, {\n error: 'app',\n id: 'unknown',\n name: 'unknown',\n message: 'An unknown error occurred',\n }),\n ];\n case 'complete':\n return [data, resultTypeComplete];\n case 'unknown':\n return [data, resultTypeUnknown];\n case 'cached':\n return [data, resultTypeCached];\n }\n}\n\nfunction makeError(retry: () => void, error: ErroredQuery): QueryErrorDetails {\n const message = error.message ?? 'An unknown error occurred';\n return {\n type: 'error',\n retry,\n refetch: retry,\n error: {\n type: error.error,\n message,\n ...(error.details ? {details: error.details} : {}),\n },\n };\n}\n\n// oxlint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyViewWrapper = ViewWrapper<any, any, any, any, any>;\n\nconst allViews = new WeakMap<\n ViewStore,\n Map<string, Map<string, AnyViewWrapper>>\n>();\n\nexport function getAllViewsSizeForTesting(store: ViewStore): number {\n if (TESTING) {\n let size = 0;\n for (const byHash of allViews.get(store)?.values() ?? []) {\n size += byHash.size;\n }\n return size;\n }\n return 0;\n}\n\n/**\n * A global store of all active views.\n *\n * React subscribes and unsubscribes to these views\n * via `useSyncExternalStore`.\n *\n * Managing views through `useEffect` or `useLayoutEffect` causes\n * inconsistencies because effects run after render.\n *\n * For example, if useQuery used use*Effect in the component below:\n * ```ts\n * function Foo({issueID}) {\n * const issue = useQuery(z.query.issue.where('id', issueID).one());\n * if (issue?.id !== undefined && issue.id !== issueID) {\n * console.log('MISMATCH!', issue.id, issueID);\n * }\n * }\n * ```\n *\n * `MISMATCH` will be printed whenever the `issueID` prop changes.\n *\n * This is because the component will render once with\n * the old state returned from `useQuery`. Then the effect inside\n * `useQuery` will run. The component will render again with the new\n * state. This inconsistent transition can cause unexpected results.\n *\n * Emulating `useEffect` via `useState` and `if` causes resource leaks.\n * That is:\n *\n * ```ts\n * function useQuery(q) {\n * const [oldHash, setOldHash] = useState();\n * if (hash(q) !== oldHash) {\n * // make new view\n * }\n *\n * useEffect(() => {\n * return () => view.destroy();\n * }, []);\n * }\n * ```\n *\n * I'm not sure why but in strict mode the cleanup function\n * fails to be called for the first instance of the view and only\n * cleans up later instances.\n *\n * Swapping `useState` to `useRef` has similar problems.\n */\nexport class ViewStore {\n /**\n * Client id, then query hash.\n *\n * Nested rather than keyed by the two joined together, because this is\n * looked up on every render of every `useQuery`. Joining them builds a\n * string that V8 has to hash from scratch, where both halves on their own\n * are strings it has already hashed and cached -- `hash()` is memoized on an\n * interned query, so the same string comes back each render. Measured over a\n * rebuild-and-look-up of one chain, that is the difference between 202ns and\n * 123ns; the join cost more than rebuilding and hashing the whole query.\n */\n #views = new Map<string, Map<string, AnyViewWrapper>>();\n\n constructor() {\n if (TESTING) {\n allViews.set(this, this.#views);\n }\n }\n\n getView<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends BaseDefaultSchema,\n TReturn,\n MD extends CustomMutatorDefs | undefined,\n TContext extends BaseDefaultContext,\n >(\n zero: Zero<TSchema, MD, TContext>,\n q: Query<TTable, TSchema, TReturn>,\n enabled: boolean,\n ttl: TTL,\n ): {\n getSnapshot: () => QueryResult<TReturn>;\n subscribeReactInternals: (internals: () => void) => () => void;\n updateTTL: (ttl: TTL) => void;\n waitForComplete: () => Promise<void>;\n waitForNonEmpty: () => Promise<void>;\n complete: boolean;\n nonEmpty: boolean;\n } {\n const qi = asQueryInternals(q);\n\n if (!enabled) {\n return {\n getSnapshot: () => getDefaultSnapshot(qi.format.singular),\n subscribeReactInternals: disabledSubscriber,\n updateTTL: () => {},\n waitForComplete: () => Promise.resolve(),\n waitForNonEmpty: () => Promise.resolve(),\n complete: false,\n nonEmpty: false,\n };\n }\n\n const {clientID} = zero;\n const hash = qi.hash();\n let byHash = this.#views.get(clientID);\n let existing = byHash?.get(hash);\n if (!existing) {\n existing = new ViewWrapper(q, zero, ttl, view => {\n const views = this.#views.get(clientID);\n const currentView = views?.get(hash);\n if (currentView && currentView !== view) {\n // we replaced the view with a new one already.\n return;\n }\n views?.delete(hash);\n if (views?.size === 0) {\n // Nothing is left for this client, so drop its map rather than\n // keeping one per client id the page has ever seen.\n this.#views.delete(clientID);\n }\n });\n if (!byHash) {\n byHash = new Map();\n this.#views.set(clientID, byHash);\n }\n byHash.set(hash, existing);\n } else {\n existing.updateTTL(ttl);\n }\n return existing as ViewWrapper<TTable, TSchema, TReturn, MD, TContext>;\n }\n}\n\nconst viewStore = new ViewStore();\n\n/**\n * This wraps and ref counts a view.\n *\n * The only signal we have from React as to whether or not it is\n * done with a view is when it calls `unsubscribe`.\n *\n * In non-strict-mode we can clean up the view as soon\n * as the listener count goes to 0.\n *\n * In strict-mode, the listener count will go to 0 then a\n * new listener for the same view is immediately added back.\n *\n * This is why the `onMaterialized` and `onDematerialized` callbacks exist --\n * they allow a view which React is still referencing to be added\n * back into the store when React re-subscribes to it.\n *\n * This wrapper also exists to deal with the various\n * `useSyncExternalStore` caveats that cause excessive\n * re-renders and materializations.\n *\n * See: https://react.dev/reference/react/useSyncExternalStore#caveats\n * Especially:\n * 1. The store snapshot returned by getSnapshot must be immutable. If the underlying store has mutable data, return a new immutable snapshot if the data has changed. Otherwise, return a cached last snapshot.\n * 2. If a different subscribe function is passed during a re-render, React will re-subscribe to the store using the newly passed subscribe function. You can prevent this by declaring subscribe outside the component.\n */\nclass ViewWrapper<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends BaseDefaultSchema,\n TReturn,\n MD extends AnyMutatorRegistry | CustomMutatorDefs | undefined,\n TContext extends BaseDefaultContext,\n> {\n #view: TypedView<HumanReadable<TReturn>> | undefined;\n readonly #onDematerialized;\n readonly #query: Query<TTable, TSchema, TReturn>;\n #snapshot: QueryResult<TReturn>;\n readonly #reactInternals: Set<() => void> = new Set();\n #ttl: TTL;\n #complete = false;\n #completeResolver = resolver<void>();\n #nonEmpty = false;\n #nonEmptyResolver = resolver<void>();\n readonly #zero: Pick<Zero<TSchema, undefined, TContext>, 'materialize'>;\n readonly #singular: boolean;\n #destroyTimer: ReturnType<typeof setTimeout> | undefined;\n\n // Inputs of the previous #onData call. When a view flush delivers\n // reference-identical data with the same resultType and error, the previous\n // snapshot tuple is kept and React is not notified — building a fresh tuple\n // would defeat useSyncExternalStore's Object.is bailout and re-render every\n // subscriber with identical data. #lastResultType doubles as the \"has fired\n // before\" sentinel (data and error may both legitimately be undefined).\n #lastData: Immutable<HumanReadable<TReturn>> | undefined;\n #lastResultType: ResultType | undefined;\n #lastError: ErroredQuery | undefined;\n\n constructor(\n query: Query<TTable, TSchema, TReturn>,\n zero: Pick<Zero<TSchema, undefined, TContext>, 'materialize'>,\n ttl: TTL,\n onDematerialized: (\n view: ViewWrapper<TTable, TSchema, TReturn, MD, TContext>,\n ) => void,\n ) {\n this.#query = query;\n this.#zero = zero;\n this.#ttl = ttl;\n this.#onDematerialized = onDematerialized;\n const {singular} = asQueryInternals(query).format;\n this.#singular = singular;\n this.#snapshot = getDefaultSnapshot(singular);\n this.#materializeIfNeeded();\n }\n\n #onData = (\n snap: Immutable<HumanReadable<TReturn>>,\n resultType: ResultType,\n error?: ErroredQuery,\n ) => {\n const wasCached = this.#snapshot[1].type === 'cached';\n const changed =\n this.#lastResultType === undefined ||\n this.#lastData !== snap ||\n this.#lastResultType !== resultType ||\n this.#lastError !== error;\n this.#lastData = snap;\n this.#lastResultType = resultType;\n this.#lastError = error;\n\n if (changed) {\n // applyChange now returns immutable data structures, so no deep clone needed.\n // Unchanged rows preserve their object identity for React.memo optimization.\n const data = snap as HumanReadable<TReturn>;\n this.#snapshot = getSnapshot(\n this.#singular,\n data,\n resultType,\n this.#retry,\n error,\n );\n }\n\n // The resolver bookkeeping runs even when unchanged: after a\n // destroy/re-materialize cycle the resolvers are fresh but the new view\n // may deliver the same data/resultType as before the destroy.\n if (resultType === 'complete' || resultType === 'error') {\n this.#complete = true;\n this.#completeResolver.resolve();\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n }\n\n const hasData = this.#singular\n ? this.#snapshot[0] !== undefined\n : (this.#snapshot[0] as unknown[]).length !== 0;\n // A 'cached' result is the server-confirmed answer from a previous\n // session, so even an empty one is something to render. It never\n // satisfies `complete`; only a confirmation on this connection does.\n if (resultType === 'cached' || hasData) {\n this.#nonEmpty = true;\n this.#nonEmptyResolver.resolve();\n } else if (wasCached && resultType === 'unknown') {\n // The cached claim was revoked (the got key was evicted before this\n // connection confirmed the query) and the view is empty: there is\n // nothing to render again until rows or a confirmation arrive.\n this.#nonEmpty = false;\n this.#nonEmptyResolver = resolver();\n }\n\n if (changed) {\n for (const internals of this.#reactInternals) {\n internals();\n }\n }\n };\n\n /**\n * Called by the user to force a retry of the query\n * in the case the query errored.\n */\n #retry = () => {\n this.#view?.destroy();\n this.#view = undefined;\n this.#materializeIfNeeded();\n };\n\n #materializeIfNeeded = () => {\n if (this.#view) {\n return;\n }\n this.#view = this.#zero.materialize(this.#query, {\n ttl: this.#ttl,\n });\n this.#view.addListener(this.#onData);\n };\n\n getSnapshot = () => this.#snapshot;\n\n subscribeReactInternals = (internals: () => void): (() => void) => {\n this.#reactInternals.add(internals);\n // Cancel any pending destroy timer from a previous unsubscribe.\n // Without this, rapid unsub/resub cycles accumulate stale timers\n // that can fire during a gap between unsubscribe and resubscribe,\n // destroying the view even though it was actively used.\n if (this.#destroyTimer !== undefined) {\n clearTimeout(this.#destroyTimer);\n this.#destroyTimer = undefined;\n }\n this.#materializeIfNeeded();\n return () => {\n this.#reactInternals.delete(internals);\n\n // only schedule a cleanup task if we have no listeners left\n if (this.#reactInternals.size === 0) {\n this.#destroyTimer = setTimeout(() => {\n this.#destroyTimer = undefined;\n\n // We already destroyed the view\n if (this.#view === undefined) {\n return;\n }\n\n // Someone re-registered a listener on this view before the timeout elapsed.\n // This happens often in strict-mode which forces a component\n // to mount, unmount, remount.\n if (this.#reactInternals.size > 0) {\n return;\n }\n\n this.#view.destroy();\n this.#view = undefined;\n this.#complete = false;\n this.#completeResolver = resolver();\n this.#nonEmpty = false;\n this.#nonEmptyResolver = resolver();\n this.#onDematerialized(this);\n }, 10);\n }\n };\n };\n\n updateTTL(ttl: TTL): void {\n // `getView` calls this on every render, and forwarding an unchanged TTL\n // reaches the query manager, which re-derives the query's id from its AST\n // to find the entry. Nothing downstream distinguishes a repeat, so skip\n // it. A change in how the same duration is spelled ('60s' vs 60000) is\n // still a change here and still propagates, as it did before.\n if (this.#ttl === ttl) {\n return;\n }\n this.#ttl = ttl;\n this.#view?.updateTTL(ttl);\n }\n\n get complete() {\n return this.#complete;\n }\n\n waitForComplete(): Promise<void> {\n return this.#completeResolver.promise;\n }\n\n get nonEmpty() {\n return this.#nonEmpty;\n }\n\n waitForNonEmpty(): Promise<void> {\n return this.#nonEmptyResolver.promise;\n }\n}\n"],"mappings":"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"}
@@ -26,5 +26,5 @@ export type ZeroProviderProps<S extends BaseDefaultSchema = DefaultSchema, MD ex
26
26
  init?: (zero: Zero<S, MD, Context>) => void;
27
27
  children: ReactNode;
28
28
  };
29
- export declare function ZeroProvider<S extends BaseDefaultSchema = DefaultSchema, MD extends CustomMutatorDefs | undefined = undefined, Context extends BaseDefaultContext = DefaultContext>({ children, init, ...props }: ZeroProviderProps<S, MD, Context>): import("react/jsx-runtime").JSX.Element | undefined;
29
+ export declare function ZeroProvider<S extends BaseDefaultSchema = DefaultSchema, MD extends CustomMutatorDefs | undefined = undefined, Context extends BaseDefaultContext = DefaultContext>({ children, init, ...props }: ZeroProviderProps<S, MD, Context>): import("react").JSX.Element | undefined;
30
30
  //# sourceMappingURL=zero-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"zero-provider.d.ts","sourceRoot":"","sources":["../../../../zero-react/src/zero-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EACL,IAAI,EACJ,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,WAAW,CAAC;AAGnB,eAAO,MAAM,WAAW,0DAEvB,CAAC;AAEF,wBAAgB,OAAO,CACrB,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAC3C,EAAE,SAAS,iBAAiB,GAAG,SAAS,GAAG,SAAS,EACpD,OAAO,SAAS,kBAAkB,GAAG,cAAc,KAChD,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAMxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAC3C,EAAE,SAAS,iBAAiB,GAAG,SAAS,GAAG,SAAS,EACpD,OAAO,SAAS,kBAAkB,GAAG,cAAc,gCAGpD;AAED,MAAM,MAAM,iBAAiB,CAC3B,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAC3C,EAAE,SAAS,iBAAiB,GAAG,SAAS,GAAG,SAAS,EACpD,OAAO,SAAS,kBAAkB,GAAG,cAAc,IACjD,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG;IAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;CAAC,CAAC,GAAG;IACjE;;;;;OAKG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,wBAAgB,YAAY,CAC1B,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAC3C,EAAE,SAAS,iBAAiB,GAAG,SAAS,GAAG,SAAS,EACpD,OAAO,SAAS,kBAAkB,GAAG,cAAc,EACnD,EAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,EAAC,EAAE,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,uDA4F9D"}
1
+ {"version":3,"file":"zero-provider.d.ts","sourceRoot":"","sources":["../../../../zero-react/src/zero-provider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EACL,IAAI,EACJ,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,WAAW,CAAC;AAGnB,eAAO,MAAM,WAAW,0DAEvB,CAAC;AAEF,wBAAgB,OAAO,CACrB,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAC3C,EAAE,SAAS,iBAAiB,GAAG,SAAS,GAAG,SAAS,EACpD,OAAO,SAAS,kBAAkB,GAAG,cAAc,KAChD,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAMxB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAC3C,EAAE,SAAS,iBAAiB,GAAG,SAAS,GAAG,SAAS,EACpD,OAAO,SAAS,kBAAkB,GAAG,cAAc,gCAGpD;AAED,MAAM,MAAM,iBAAiB,CAC3B,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAC3C,EAAE,SAAS,iBAAiB,GAAG,SAAS,GAAG,SAAS,EACpD,OAAO,SAAS,kBAAkB,GAAG,cAAc,IACjD,CAAC,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,GAAG;IAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;CAAC,CAAC,GAAG;IACjE;;;;;OAKG;IACH,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC5C,QAAQ,EAAE,SAAS,CAAC;CACrB,CAAC;AAEF,wBAAgB,YAAY,CAC1B,CAAC,SAAS,iBAAiB,GAAG,aAAa,EAC3C,EAAE,SAAS,iBAAiB,GAAG,SAAS,GAAG,SAAS,EACpD,OAAO,SAAS,kBAAkB,GAAG,cAAc,EACnD,EAAC,QAAQ,EAAE,IAAI,EAAE,GAAG,KAAK,EAAC,EAAE,iBAAiB,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,2CA4F9D"}
@@ -37,6 +37,7 @@ function ZeroProvider({ children, init, ...props }) {
37
37
  rotationPendingRef.current = true;
38
38
  setRotationGeneration((gen) => gen + 1);
39
39
  };
40
+ const keysWithoutAuth = useMemo(() => Object.entries(props).filter(([key]) => key !== "auth").sort(([a], [b]) => stringCompare(a, b)).map(([_, value]) => value), [props]);
40
41
  useEffect(() => {
41
42
  if (isExternalZero) {
42
43
  rotationPendingRef.current = false;
@@ -66,7 +67,7 @@ function ZeroProvider({ children, init, ...props }) {
66
67
  hasAuth,
67
68
  init,
68
69
  rotationGeneration,
69
- ...useMemo(() => Object.entries(props).filter(([key]) => key !== "auth").sort(([a], [b]) => stringCompare(a, b)).map(([_, value]) => value), [props])
70
+ ...keysWithoutAuth
70
71
  ]);
71
72
  useEffect(() => {
72
73
  if (!zero || isExternalZero) return;