@rocicorp/zero 0.25.0-canary.0 → 0.25.0-canary.1

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 (337) hide show
  1. package/out/{chunk-BJ2CGCME.js → chunk-55BOUNXO.js} +3 -3
  2. package/out/chunk-55BOUNXO.js.map +7 -0
  3. package/out/{chunk-MXPHMVU7.js → chunk-AIPM77UE.js} +2337 -548
  4. package/out/chunk-AIPM77UE.js.map +7 -0
  5. package/out/{chunk-4RB4OYLQ.js → chunk-TJFNGO7E.js} +3 -2
  6. package/out/{lazy-inspector-2SW772W4.js → lazy-inspector-OXIFYSSQ.js} +2 -2
  7. package/out/react.js +16 -4
  8. package/out/react.js.map +4 -4
  9. package/out/replicache/src/dag/lazy-store.d.ts +1 -1
  10. package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
  11. package/out/replicache/src/log-options.d.ts +1 -1
  12. package/out/replicache/src/log-options.d.ts.map +1 -1
  13. package/out/replicache/src/persist/collect-idb-databases.d.ts +3 -3
  14. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  15. package/out/replicache/src/replicache-options.d.ts +1 -1
  16. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  17. package/out/shared/src/options.d.ts +1 -1
  18. package/out/shared/src/options.d.ts.map +1 -1
  19. package/out/shared/src/promise-race.d.ts +17 -0
  20. package/out/shared/src/promise-race.d.ts.map +1 -0
  21. package/out/solid.js +19 -6
  22. package/out/solid.js.map +4 -4
  23. package/out/z2s/src/compiler.d.ts +1 -1
  24. package/out/z2s/src/compiler.d.ts.map +1 -1
  25. package/out/z2s/src/compiler.js +1 -1
  26. package/out/z2s/src/compiler.js.map +1 -1
  27. package/out/z2s/src/sql.d.ts.map +1 -1
  28. package/out/z2s/src/sql.js +1 -1
  29. package/out/z2s/src/sql.js.map +1 -1
  30. package/out/zero/package.json +4 -3
  31. package/out/zero-cache/src/config/zero-config.d.ts +12 -0
  32. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  33. package/out/zero-cache/src/config/zero-config.js +36 -0
  34. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  35. package/out/zero-cache/src/custom/fetch.d.ts +3 -1
  36. package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
  37. package/out/zero-cache/src/custom/fetch.js +101 -24
  38. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  39. package/out/zero-cache/src/custom-queries/transform-query.d.ts +2 -6
  40. package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
  41. package/out/zero-cache/src/custom-queries/transform-query.js +42 -41
  42. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  43. package/out/zero-cache/src/db/create.d.ts +4 -0
  44. package/out/zero-cache/src/db/create.d.ts.map +1 -1
  45. package/out/zero-cache/src/db/create.js +7 -9
  46. package/out/zero-cache/src/db/create.js.map +1 -1
  47. package/out/zero-cache/src/db/lite-tables.js +2 -2
  48. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  49. package/out/zero-cache/src/db/pg-to-lite.d.ts.map +1 -1
  50. package/out/zero-cache/src/db/pg-to-lite.js +7 -6
  51. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  52. package/out/zero-cache/src/db/specs.d.ts +12 -12
  53. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  54. package/out/zero-cache/src/server/change-streamer.js +1 -1
  55. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  56. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  57. package/out/zero-cache/src/server/inspector-delegate.js +5 -1
  58. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  59. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  60. package/out/zero-cache/src/server/syncer.js +1 -1
  61. package/out/zero-cache/src/server/syncer.js.map +1 -1
  62. package/out/zero-cache/src/services/change-source/pg/change-source.js +1 -0
  63. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  64. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.d.ts +1 -1
  65. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.d.ts.map +1 -1
  66. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js +1 -1
  67. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  68. package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +25 -25
  69. package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +10 -10
  70. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +5 -5
  71. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +16 -16
  72. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +24 -24
  73. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +2 -1
  74. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  75. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +18 -2
  76. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  77. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +8 -8
  78. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  79. package/out/zero-cache/src/services/mutagen/mutagen.js +9 -7
  80. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  81. package/out/zero-cache/src/services/mutagen/pusher.d.ts +4 -4
  82. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  83. package/out/zero-cache/src/services/mutagen/pusher.js +74 -56
  84. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  85. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +3 -1
  86. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  87. package/out/zero-cache/src/services/view-syncer/client-handler.js +10 -6
  88. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  89. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +1 -1
  90. package/out/zero-cache/src/services/view-syncer/client-schema.js +6 -3
  91. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  92. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +4 -4
  93. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  94. package/out/zero-cache/src/services/view-syncer/cvr-store.js +15 -6
  95. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  96. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  97. package/out/zero-cache/src/services/view-syncer/cvr.js +4 -2
  98. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  99. package/out/zero-cache/src/services/view-syncer/key-columns.d.ts.map +1 -1
  100. package/out/zero-cache/src/services/view-syncer/key-columns.js +4 -2
  101. package/out/zero-cache/src/services/view-syncer/key-columns.js.map +1 -1
  102. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -1
  103. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  104. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +19 -2
  105. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  106. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  107. package/out/zero-cache/src/services/view-syncer/view-syncer.js +67 -31
  108. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  109. package/out/zero-cache/src/types/error-with-level.d.ts +9 -0
  110. package/out/zero-cache/src/types/error-with-level.d.ts.map +1 -0
  111. package/out/zero-cache/src/types/error-with-level.js +24 -0
  112. package/out/zero-cache/src/types/error-with-level.js.map +1 -0
  113. package/out/zero-cache/src/types/lite.d.ts +15 -13
  114. package/out/zero-cache/src/types/lite.d.ts.map +1 -1
  115. package/out/zero-cache/src/types/lite.js +17 -5
  116. package/out/zero-cache/src/types/lite.js.map +1 -1
  117. package/out/zero-cache/src/types/pg-data-type.d.ts +73 -0
  118. package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -0
  119. package/out/zero-cache/src/types/pg-data-type.js +76 -0
  120. package/out/zero-cache/src/types/pg-data-type.js.map +1 -0
  121. package/out/zero-cache/src/types/pg.d.ts +1 -73
  122. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  123. package/out/zero-cache/src/types/pg.js +0 -77
  124. package/out/zero-cache/src/types/pg.js.map +1 -1
  125. package/out/zero-cache/src/types/processes.d.ts +1 -1
  126. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  127. package/out/zero-cache/src/types/processes.js.map +1 -1
  128. package/out/zero-cache/src/types/schema-versions.d.ts +7 -3
  129. package/out/zero-cache/src/types/schema-versions.d.ts.map +1 -1
  130. package/out/zero-cache/src/types/schema-versions.js +7 -5
  131. package/out/zero-cache/src/types/schema-versions.js.map +1 -1
  132. package/out/zero-cache/src/types/subscription.d.ts +1 -1
  133. package/out/zero-cache/src/types/subscription.js +1 -1
  134. package/out/zero-cache/src/types/websocket-handoff.d.ts +3 -3
  135. package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
  136. package/out/zero-cache/src/types/websocket-handoff.js +6 -4
  137. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  138. package/out/zero-cache/src/workers/connection.d.ts +6 -1
  139. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  140. package/out/zero-cache/src/workers/connection.js +26 -9
  141. package/out/zero-cache/src/workers/connection.js.map +1 -1
  142. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  143. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +7 -1
  144. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  145. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  146. package/out/zero-cache/src/workers/syncer.js +21 -1
  147. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  148. package/out/zero-client/src/client/client-error-kind-enum.d.ts +8 -0
  149. package/out/zero-client/src/client/client-error-kind-enum.d.ts.map +1 -1
  150. package/out/zero-client/src/client/connection-manager.d.ts +65 -13
  151. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  152. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  153. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  154. package/out/zero-client/src/client/connection.d.ts +45 -0
  155. package/out/zero-client/src/client/connection.d.ts.map +1 -0
  156. package/out/zero-client/src/client/error.d.ts +178 -23
  157. package/out/zero-client/src/client/error.d.ts.map +1 -1
  158. package/out/zero-client/src/client/ivm-branch.d.ts +2 -2
  159. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  160. package/out/zero-client/src/client/metrics.d.ts +9 -0
  161. package/out/zero-client/src/client/metrics.d.ts.map +1 -1
  162. package/out/zero-client/src/client/mutation-tracker.d.ts +5 -4
  163. package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
  164. package/out/zero-client/src/client/options.d.ts +6 -2
  165. package/out/zero-client/src/client/options.d.ts.map +1 -1
  166. package/out/zero-client/src/client/query-manager.d.ts +5 -4
  167. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  168. package/out/zero-client/src/client/zero-rep.d.ts +1 -1
  169. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  170. package/out/zero-client/src/client/zero.d.ts +27 -5
  171. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  172. package/out/zero-client/src/mod.d.ts +9 -1
  173. package/out/zero-client/src/mod.d.ts.map +1 -1
  174. package/out/zero-protocol/src/custom-queries.d.ts +75 -4
  175. package/out/zero-protocol/src/custom-queries.d.ts.map +1 -1
  176. package/out/zero-protocol/src/custom-queries.js +18 -1
  177. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  178. package/out/zero-protocol/src/down.d.ts +1 -1
  179. package/out/zero-protocol/src/error-kind-enum.d.ts +65 -0
  180. package/out/zero-protocol/src/error-kind-enum.d.ts.map +1 -1
  181. package/out/zero-protocol/src/error-kind-enum.js +2 -0
  182. package/out/zero-protocol/src/error-kind-enum.js.map +1 -1
  183. package/out/zero-protocol/src/error-origin-enum.d.ts +7 -0
  184. package/out/zero-protocol/src/error-origin-enum.d.ts.map +1 -0
  185. package/out/zero-protocol/src/error-origin-enum.js +4 -0
  186. package/out/zero-protocol/src/error-origin-enum.js.map +1 -0
  187. package/out/zero-protocol/src/error-origin.d.ts +5 -0
  188. package/out/zero-protocol/src/error-origin.d.ts.map +1 -0
  189. package/out/zero-protocol/src/error-origin.js +3 -0
  190. package/out/zero-protocol/src/error-origin.js.map +1 -0
  191. package/out/zero-protocol/src/error-reason-enum.d.ts +15 -0
  192. package/out/zero-protocol/src/error-reason-enum.d.ts.map +1 -0
  193. package/out/zero-protocol/src/error-reason-enum.js +8 -0
  194. package/out/zero-protocol/src/error-reason-enum.js.map +1 -0
  195. package/out/zero-protocol/src/error-reason.d.ts +5 -0
  196. package/out/zero-protocol/src/error-reason.d.ts.map +1 -0
  197. package/out/zero-protocol/src/error-reason.js +3 -0
  198. package/out/zero-protocol/src/error-reason.js.map +1 -0
  199. package/out/zero-protocol/src/error.d.ts +139 -1
  200. package/out/zero-protocol/src/error.d.ts.map +1 -1
  201. package/out/zero-protocol/src/error.js +64 -2
  202. package/out/zero-protocol/src/error.js.map +1 -1
  203. package/out/zero-protocol/src/mutation-id.d.ts +7 -0
  204. package/out/zero-protocol/src/mutation-id.d.ts.map +1 -0
  205. package/out/zero-protocol/src/mutation-id.js +6 -0
  206. package/out/zero-protocol/src/mutation-id.js.map +1 -0
  207. package/out/zero-protocol/src/mutations-patch.d.ts +3 -3
  208. package/out/zero-protocol/src/mutations-patch.d.ts.map +1 -1
  209. package/out/zero-protocol/src/mutations-patch.js +2 -1
  210. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  211. package/out/zero-protocol/src/protocol-version.d.ts +1 -1
  212. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  213. package/out/zero-protocol/src/protocol-version.js +2 -1
  214. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  215. package/out/zero-protocol/src/push.d.ts +138 -13
  216. package/out/zero-protocol/src/push.d.ts.map +1 -1
  217. package/out/zero-protocol/src/push.js +34 -13
  218. package/out/zero-protocol/src/push.js.map +1 -1
  219. package/out/zero-react/src/mod.d.ts +2 -1
  220. package/out/zero-react/src/mod.d.ts.map +1 -1
  221. package/out/zero-react/src/use-zero-connection-state.d.ts +9 -0
  222. package/out/zero-react/src/use-zero-connection-state.d.ts.map +1 -0
  223. package/out/zero-react/src/use-zero-online.d.ts +2 -0
  224. package/out/zero-react/src/use-zero-online.d.ts.map +1 -1
  225. package/out/zero-server/src/process-mutations.d.ts +3 -3
  226. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  227. package/out/zero-server/src/process-mutations.js.map +1 -1
  228. package/out/zero-server/src/schema.js +1 -1
  229. package/out/zero-server/src/schema.js.map +1 -1
  230. package/out/zero-server/src/zql-database.d.ts +1 -1
  231. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  232. package/out/zero-server/src/zql-database.js.map +1 -1
  233. package/out/zero-solid/src/mod.d.ts +3 -2
  234. package/out/zero-solid/src/mod.d.ts.map +1 -1
  235. package/out/zero-solid/src/use-zero-connection-state.d.ts +10 -0
  236. package/out/zero-solid/src/use-zero-connection-state.d.ts.map +1 -0
  237. package/out/zero-solid/src/use-zero-online.d.ts +1 -7
  238. package/out/zero-solid/src/use-zero-online.d.ts.map +1 -1
  239. package/out/zero.js +13 -3
  240. package/out/zql/src/builder/builder.d.ts +2 -1
  241. package/out/zql/src/builder/builder.d.ts.map +1 -1
  242. package/out/zql/src/builder/builder.js +5 -1
  243. package/out/zql/src/builder/builder.js.map +1 -1
  244. package/out/zql/src/ivm/data.d.ts +1 -1
  245. package/out/zql/src/ivm/data.d.ts.map +1 -1
  246. package/out/zql/src/ivm/data.js.map +1 -1
  247. package/out/zql/src/ivm/filter-push.d.ts +1 -1
  248. package/out/zql/src/ivm/filter-push.d.ts.map +1 -1
  249. package/out/zql/src/ivm/filter-push.js.map +1 -1
  250. package/out/zql/src/ivm/memory-source.d.ts +2 -2
  251. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  252. package/out/zql/src/ivm/memory-source.js.map +1 -1
  253. package/out/zql/src/ivm/source.d.ts +1 -1
  254. package/out/zql/src/ivm/source.d.ts.map +1 -1
  255. package/out/zql/src/ivm/take.d.ts +1 -1
  256. package/out/zql/src/ivm/take.d.ts.map +1 -1
  257. package/out/zql/src/ivm/take.js.map +1 -1
  258. package/out/zql/src/planner/planner-builder.d.ts +14 -0
  259. package/out/zql/src/planner/planner-builder.d.ts.map +1 -0
  260. package/out/zql/src/planner/planner-builder.js +180 -0
  261. package/out/zql/src/planner/planner-builder.js.map +1 -0
  262. package/out/zql/src/planner/planner-connection.d.ts +119 -0
  263. package/out/zql/src/planner/planner-connection.d.ts.map +1 -0
  264. package/out/zql/src/planner/planner-connection.js +301 -0
  265. package/out/zql/src/planner/planner-connection.js.map +1 -0
  266. package/out/zql/src/planner/planner-constraint.d.ts +14 -0
  267. package/out/zql/src/planner/planner-constraint.d.ts.map +1 -0
  268. package/out/zql/src/planner/planner-constraint.js +12 -0
  269. package/out/zql/src/planner/planner-constraint.js.map +1 -0
  270. package/out/zql/src/planner/planner-debug.d.ts +118 -0
  271. package/out/zql/src/planner/planner-debug.d.ts.map +1 -0
  272. package/out/zql/src/planner/planner-debug.js +125 -0
  273. package/out/zql/src/planner/planner-debug.js.map +1 -0
  274. package/out/zql/src/planner/planner-fan-in.d.ts +37 -0
  275. package/out/zql/src/planner/planner-fan-in.d.ts.map +1 -0
  276. package/out/zql/src/planner/planner-fan-in.js +149 -0
  277. package/out/zql/src/planner/planner-fan-in.js.map +1 -0
  278. package/out/zql/src/planner/planner-fan-out.d.ts +21 -0
  279. package/out/zql/src/planner/planner-fan-out.d.ts.map +1 -0
  280. package/out/zql/src/planner/planner-fan-out.js +45 -0
  281. package/out/zql/src/planner/planner-fan-out.js.map +1 -0
  282. package/out/zql/src/planner/planner-graph.d.ts +103 -0
  283. package/out/zql/src/planner/planner-graph.d.ts.map +1 -0
  284. package/out/zql/src/planner/planner-graph.js +411 -0
  285. package/out/zql/src/planner/planner-graph.js.map +1 -0
  286. package/out/zql/src/planner/planner-join.d.ts +81 -0
  287. package/out/zql/src/planner/planner-join.d.ts.map +1 -0
  288. package/out/zql/src/planner/planner-join.js +246 -0
  289. package/out/zql/src/planner/planner-join.js.map +1 -0
  290. package/out/zql/src/planner/planner-node.d.ts +21 -0
  291. package/out/zql/src/planner/planner-node.d.ts.map +1 -0
  292. package/out/zql/src/planner/planner-node.js +2 -0
  293. package/out/zql/src/planner/planner-node.js.map +1 -0
  294. package/out/zql/src/planner/planner-source.d.ts +11 -0
  295. package/out/zql/src/planner/planner-source.d.ts.map +1 -0
  296. package/out/zql/src/planner/planner-source.js +13 -0
  297. package/out/zql/src/planner/planner-source.js.map +1 -0
  298. package/out/zql/src/planner/planner-terminus.d.ts +16 -0
  299. package/out/zql/src/planner/planner-terminus.d.ts.map +1 -0
  300. package/out/zql/src/planner/planner-terminus.js +28 -0
  301. package/out/zql/src/planner/planner-terminus.js.map +1 -0
  302. package/out/zql/src/query/expression.d.ts +2 -2
  303. package/out/zql/src/query/expression.d.ts.map +1 -1
  304. package/out/zql/src/query/expression.js.map +1 -1
  305. package/out/zql/src/query/query-delegate.d.ts +3 -3
  306. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  307. package/out/zql/src/query/query-impl.d.ts +8 -8
  308. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  309. package/out/zql/src/query/query-impl.js.map +1 -1
  310. package/out/zql/src/query/query.d.ts +3 -3
  311. package/out/zql/src/query/query.d.ts.map +1 -1
  312. package/out/zql/src/query/static-query.d.ts +1 -1
  313. package/out/zql/src/query/static-query.d.ts.map +1 -1
  314. package/out/zql/src/query/static-query.js.map +1 -1
  315. package/out/zql/src/query/typed-view.d.ts +1 -1
  316. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  317. package/out/zqlite/src/query-delegate.d.ts +1 -1
  318. package/out/zqlite/src/query-delegate.d.ts.map +1 -1
  319. package/out/zqlite/src/query-delegate.js.map +1 -1
  320. package/out/zqlite/src/sqlite-cost-model.d.ts +17 -0
  321. package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -0
  322. package/out/zqlite/src/sqlite-cost-model.js +134 -0
  323. package/out/zqlite/src/sqlite-cost-model.js.map +1 -0
  324. package/out/zqlite/src/table-source.d.ts +1 -1
  325. package/out/zqlite/src/table-source.d.ts.map +1 -1
  326. package/out/zqlite/src/table-source.js.map +1 -1
  327. package/package.json +4 -3
  328. package/out/chunk-BJ2CGCME.js.map +0 -7
  329. package/out/chunk-MXPHMVU7.js.map +0 -7
  330. package/out/zero-cache/src/types/error-for-client.d.ts +0 -23
  331. package/out/zero-cache/src/types/error-for-client.d.ts.map +0 -1
  332. package/out/zero-cache/src/types/error-for-client.js +0 -28
  333. package/out/zero-cache/src/types/error-for-client.js.map +0 -1
  334. package/out/zero-client/src/client/ping-result-enum.d.ts +0 -5
  335. package/out/zero-client/src/client/ping-result-enum.d.ts.map +0 -1
  336. /package/out/{chunk-4RB4OYLQ.js.map → chunk-TJFNGO7E.js.map} +0 -0
  337. /package/out/{lazy-inspector-2SW772W4.js.map → lazy-inspector-OXIFYSSQ.js.map} +0 -0
@@ -96,6 +96,7 @@ import {
96
96
  normalizeAST,
97
97
  once,
98
98
  parse,
99
+ planIdSymbol,
99
100
  primaryKeySchema,
100
101
  primaryKeyValueRecordSchema,
101
102
  readFromDefaultHead,
@@ -123,7 +124,7 @@ import {
123
124
  withWrite,
124
125
  withWriteNoImplicitCommit,
125
126
  wrapIterable
126
- } from "./chunk-4RB4OYLQ.js";
127
+ } from "./chunk-TJFNGO7E.js";
127
128
  import {
128
129
  assert,
129
130
  assertArray,
@@ -1511,6 +1512,223 @@ function rejectIfClosed(tx) {
1511
1512
  return tx.closed ? Promise.reject(new TransactionClosedError()) : void 0;
1512
1513
  }
1513
1514
 
1515
+ // ../zero-protocol/src/error-kind-enum.ts
1516
+ var error_kind_enum_exports = {};
1517
+ __export(error_kind_enum_exports, {
1518
+ AuthInvalidated: () => AuthInvalidated,
1519
+ ClientNotFound: () => ClientNotFound,
1520
+ Internal: () => Internal,
1521
+ InvalidConnectionRequest: () => InvalidConnectionRequest,
1522
+ InvalidConnectionRequestBaseCookie: () => InvalidConnectionRequestBaseCookie,
1523
+ InvalidConnectionRequestClientDeleted: () => InvalidConnectionRequestClientDeleted,
1524
+ InvalidConnectionRequestLastMutationID: () => InvalidConnectionRequestLastMutationID,
1525
+ InvalidMessage: () => InvalidMessage,
1526
+ InvalidPush: () => InvalidPush,
1527
+ MutationFailed: () => MutationFailed,
1528
+ MutationRateLimited: () => MutationRateLimited,
1529
+ PushFailed: () => PushFailed,
1530
+ Rebalance: () => Rebalance,
1531
+ Rehome: () => Rehome,
1532
+ SchemaVersionNotSupported: () => SchemaVersionNotSupported,
1533
+ ServerOverloaded: () => ServerOverloaded,
1534
+ TransformFailed: () => TransformFailed,
1535
+ Unauthorized: () => Unauthorized,
1536
+ VersionNotSupported: () => VersionNotSupported
1537
+ });
1538
+ var AuthInvalidated = "AuthInvalidated";
1539
+ var ClientNotFound = "ClientNotFound";
1540
+ var InvalidConnectionRequest = "InvalidConnectionRequest";
1541
+ var InvalidConnectionRequestBaseCookie = "InvalidConnectionRequestBaseCookie";
1542
+ var InvalidConnectionRequestLastMutationID = "InvalidConnectionRequestLastMutationID";
1543
+ var InvalidConnectionRequestClientDeleted = "InvalidConnectionRequestClientDeleted";
1544
+ var InvalidMessage = "InvalidMessage";
1545
+ var InvalidPush = "InvalidPush";
1546
+ var PushFailed = "PushFailed";
1547
+ var MutationFailed = "MutationFailed";
1548
+ var MutationRateLimited = "MutationRateLimited";
1549
+ var Rebalance = "Rebalance";
1550
+ var Rehome = "Rehome";
1551
+ var TransformFailed = "TransformFailed";
1552
+ var Unauthorized = "Unauthorized";
1553
+ var VersionNotSupported = "VersionNotSupported";
1554
+ var SchemaVersionNotSupported = "SchemaVersionNotSupported";
1555
+ var ServerOverloaded = "ServerOverloaded";
1556
+ var Internal = "Internal";
1557
+
1558
+ // ../zero-protocol/src/error-origin-enum.ts
1559
+ var error_origin_enum_exports = {};
1560
+ __export(error_origin_enum_exports, {
1561
+ Client: () => Client,
1562
+ Server: () => Server,
1563
+ ZeroCache: () => ZeroCache
1564
+ });
1565
+ var Client = "client";
1566
+ var Server = "server";
1567
+ var ZeroCache = "zeroCache";
1568
+
1569
+ // ../zero-protocol/src/error-reason-enum.ts
1570
+ var error_reason_enum_exports = {};
1571
+ __export(error_reason_enum_exports, {
1572
+ Database: () => Database,
1573
+ HTTP: () => HTTP,
1574
+ Internal: () => Internal2,
1575
+ OutOfOrderMutation: () => OutOfOrderMutation,
1576
+ Parse: () => Parse,
1577
+ Timeout: () => Timeout,
1578
+ UnsupportedPushVersion: () => UnsupportedPushVersion
1579
+ });
1580
+ var Database = "database";
1581
+ var Parse = "parse";
1582
+ var OutOfOrderMutation = "oooMutation";
1583
+ var UnsupportedPushVersion = "unsupportedPushVersion";
1584
+ var Internal2 = "internal";
1585
+ var HTTP = "http";
1586
+ var Timeout = "timeout";
1587
+
1588
+ // ../zero-protocol/src/mutation-id.ts
1589
+ var mutationIDSchema = valita_exports.object({
1590
+ id: valita_exports.number(),
1591
+ clientID: valita_exports.string()
1592
+ });
1593
+
1594
+ // ../zero-protocol/src/error.ts
1595
+ var basicErrorKindSchema = literalUnion(
1596
+ error_kind_enum_exports.AuthInvalidated,
1597
+ error_kind_enum_exports.ClientNotFound,
1598
+ error_kind_enum_exports.InvalidConnectionRequest,
1599
+ error_kind_enum_exports.InvalidConnectionRequestBaseCookie,
1600
+ error_kind_enum_exports.InvalidConnectionRequestLastMutationID,
1601
+ error_kind_enum_exports.InvalidConnectionRequestClientDeleted,
1602
+ error_kind_enum_exports.InvalidMessage,
1603
+ error_kind_enum_exports.InvalidPush,
1604
+ error_kind_enum_exports.MutationRateLimited,
1605
+ error_kind_enum_exports.MutationFailed,
1606
+ error_kind_enum_exports.Unauthorized,
1607
+ error_kind_enum_exports.VersionNotSupported,
1608
+ error_kind_enum_exports.SchemaVersionNotSupported,
1609
+ error_kind_enum_exports.Internal
1610
+ );
1611
+ var basicErrorBodySchema = valita_exports.object({
1612
+ kind: basicErrorKindSchema,
1613
+ message: valita_exports.string(),
1614
+ // this is optional for backwards compatibility
1615
+ origin: literalUnion(error_origin_enum_exports.Server, error_origin_enum_exports.ZeroCache).optional()
1616
+ });
1617
+ var backoffErrorKindSchema = literalUnion(
1618
+ error_kind_enum_exports.Rebalance,
1619
+ error_kind_enum_exports.Rehome,
1620
+ error_kind_enum_exports.ServerOverloaded
1621
+ );
1622
+ var backoffBodySchema = valita_exports.object({
1623
+ kind: backoffErrorKindSchema,
1624
+ message: valita_exports.string(),
1625
+ minBackoffMs: valita_exports.number().optional(),
1626
+ maxBackoffMs: valita_exports.number().optional(),
1627
+ // Query parameters to send in the next reconnect. In the event of
1628
+ // a conflict, these will be overridden by the parameters used by
1629
+ // the client; it is the responsibility of the server to avoid
1630
+ // parameter name conflicts.
1631
+ //
1632
+ // The parameters will only be added to the immediately following
1633
+ // reconnect, and not after that.
1634
+ reconnectParams: valita_exports.record(valita_exports.string()).optional(),
1635
+ origin: valita_exports.literal(error_origin_enum_exports.ZeroCache).optional()
1636
+ });
1637
+ var pushFailedErrorKindSchema = valita_exports.literal(error_kind_enum_exports.PushFailed);
1638
+ var transformFailedErrorKindSchema = valita_exports.literal(error_kind_enum_exports.TransformFailed);
1639
+ var errorKindSchema = valita_exports.union(
1640
+ basicErrorKindSchema,
1641
+ backoffErrorKindSchema,
1642
+ pushFailedErrorKindSchema,
1643
+ transformFailedErrorKindSchema
1644
+ );
1645
+ var pushFailedBaseSchema = valita_exports.object({
1646
+ kind: pushFailedErrorKindSchema,
1647
+ details: jsonSchema.optional(),
1648
+ mutationIDs: valita_exports.array(mutationIDSchema),
1649
+ message: valita_exports.string()
1650
+ });
1651
+ var pushFailedBodySchema = valita_exports.union(
1652
+ pushFailedBaseSchema.extend({
1653
+ origin: valita_exports.literal(error_origin_enum_exports.Server),
1654
+ reason: literalUnion(
1655
+ error_reason_enum_exports.Database,
1656
+ error_reason_enum_exports.Parse,
1657
+ error_reason_enum_exports.OutOfOrderMutation,
1658
+ error_reason_enum_exports.UnsupportedPushVersion,
1659
+ error_reason_enum_exports.Internal
1660
+ )
1661
+ }),
1662
+ pushFailedBaseSchema.extend({
1663
+ origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
1664
+ reason: valita_exports.literal(error_reason_enum_exports.HTTP),
1665
+ status: valita_exports.number(),
1666
+ bodyPreview: valita_exports.string().optional()
1667
+ }),
1668
+ pushFailedBaseSchema.extend({
1669
+ origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
1670
+ reason: literalUnion(
1671
+ error_reason_enum_exports.Timeout,
1672
+ error_reason_enum_exports.Parse,
1673
+ error_reason_enum_exports.Internal
1674
+ )
1675
+ })
1676
+ );
1677
+ var transformFailedBaseSchema = valita_exports.object({
1678
+ kind: transformFailedErrorKindSchema,
1679
+ details: jsonSchema.optional(),
1680
+ queryIDs: valita_exports.array(valita_exports.string()),
1681
+ message: valita_exports.string()
1682
+ });
1683
+ var transformFailedBodySchema = valita_exports.union(
1684
+ transformFailedBaseSchema.extend({
1685
+ origin: valita_exports.literal(error_origin_enum_exports.Server),
1686
+ reason: literalUnion(
1687
+ error_reason_enum_exports.Database,
1688
+ error_reason_enum_exports.Parse,
1689
+ error_reason_enum_exports.Internal
1690
+ )
1691
+ }),
1692
+ transformFailedBaseSchema.extend({
1693
+ origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
1694
+ reason: valita_exports.literal(error_reason_enum_exports.HTTP),
1695
+ status: valita_exports.number(),
1696
+ bodyPreview: valita_exports.string().optional()
1697
+ }),
1698
+ transformFailedBaseSchema.extend({
1699
+ origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
1700
+ reason: literalUnion(
1701
+ error_reason_enum_exports.Timeout,
1702
+ error_reason_enum_exports.Parse,
1703
+ error_reason_enum_exports.Internal
1704
+ )
1705
+ })
1706
+ );
1707
+ var errorBodySchema = valita_exports.union(
1708
+ basicErrorBodySchema,
1709
+ backoffBodySchema,
1710
+ pushFailedBodySchema,
1711
+ transformFailedBodySchema
1712
+ );
1713
+ var errorMessageSchema = valita_exports.tuple([
1714
+ valita_exports.literal("error"),
1715
+ errorBodySchema
1716
+ ]);
1717
+ var ProtocolError = class extends Error {
1718
+ errorBody;
1719
+ constructor(errorBody, options) {
1720
+ super(errorBody.message, options);
1721
+ this.name = "ProtocolError";
1722
+ this.errorBody = errorBody;
1723
+ }
1724
+ get kind() {
1725
+ return this.errorBody.kind;
1726
+ }
1727
+ };
1728
+ function isProtocolError(error) {
1729
+ return error instanceof ProtocolError;
1730
+ }
1731
+
1514
1732
  // ../zero-protocol/src/custom-queries.ts
1515
1733
  var transformRequestBodySchema = valita_exports.array(
1516
1734
  valita_exports.object({
@@ -1531,16 +1749,25 @@ var appQueryErrorSchema = valita_exports.object({
1531
1749
  details: jsonSchema
1532
1750
  });
1533
1751
  var zeroErrorSchema = valita_exports.object({
1752
+ /** @deprecated */
1534
1753
  error: valita_exports.literal("zero"),
1754
+ /** @deprecated */
1535
1755
  id: valita_exports.string(),
1756
+ /** @deprecated */
1536
1757
  name: valita_exports.string(),
1758
+ /** @deprecated */
1537
1759
  details: jsonSchema
1538
1760
  });
1539
1761
  var httpQueryErrorSchema = valita_exports.object({
1762
+ /** @deprecated */
1540
1763
  error: valita_exports.literal("http"),
1764
+ /** @deprecated */
1541
1765
  id: valita_exports.string(),
1766
+ /** @deprecated */
1542
1767
  name: valita_exports.string(),
1768
+ /** @deprecated */
1543
1769
  status: valita_exports.number(),
1770
+ /** @deprecated */
1544
1771
  details: jsonSchema
1545
1772
  });
1546
1773
  var erroredQuerySchema = valita_exports.union(
@@ -1559,49 +1786,18 @@ var transformErrorMessageSchema = valita_exports.tuple([
1559
1786
  valita_exports.literal("transformError"),
1560
1787
  valita_exports.array(erroredQuerySchema)
1561
1788
  ]);
1562
- var transformResponseMessageSchema = valita_exports.tuple([
1789
+ var transformFailedMessageSchema = valita_exports.tuple([
1790
+ valita_exports.literal("transformFailed"),
1791
+ transformFailedBodySchema
1792
+ ]);
1793
+ var transformOkMessageSchema = valita_exports.tuple([
1563
1794
  valita_exports.literal("transformed"),
1564
1795
  transformResponseBodySchema
1565
1796
  ]);
1566
-
1567
- // ../zero-protocol/src/error-kind-enum.ts
1568
- var error_kind_enum_exports = {};
1569
- __export(error_kind_enum_exports, {
1570
- AuthInvalidated: () => AuthInvalidated,
1571
- ClientNotFound: () => ClientNotFound,
1572
- Internal: () => Internal,
1573
- InvalidConnectionRequest: () => InvalidConnectionRequest,
1574
- InvalidConnectionRequestBaseCookie: () => InvalidConnectionRequestBaseCookie,
1575
- InvalidConnectionRequestClientDeleted: () => InvalidConnectionRequestClientDeleted,
1576
- InvalidConnectionRequestLastMutationID: () => InvalidConnectionRequestLastMutationID,
1577
- InvalidMessage: () => InvalidMessage,
1578
- InvalidPush: () => InvalidPush,
1579
- MutationFailed: () => MutationFailed,
1580
- MutationRateLimited: () => MutationRateLimited,
1581
- Rebalance: () => Rebalance,
1582
- Rehome: () => Rehome,
1583
- SchemaVersionNotSupported: () => SchemaVersionNotSupported,
1584
- ServerOverloaded: () => ServerOverloaded,
1585
- Unauthorized: () => Unauthorized,
1586
- VersionNotSupported: () => VersionNotSupported
1587
- });
1588
- var AuthInvalidated = "AuthInvalidated";
1589
- var ClientNotFound = "ClientNotFound";
1590
- var InvalidConnectionRequest = "InvalidConnectionRequest";
1591
- var InvalidConnectionRequestBaseCookie = "InvalidConnectionRequestBaseCookie";
1592
- var InvalidConnectionRequestLastMutationID = "InvalidConnectionRequestLastMutationID";
1593
- var InvalidConnectionRequestClientDeleted = "InvalidConnectionRequestClientDeleted";
1594
- var InvalidMessage = "InvalidMessage";
1595
- var InvalidPush = "InvalidPush";
1596
- var MutationFailed = "MutationFailed";
1597
- var MutationRateLimited = "MutationRateLimited";
1598
- var Rebalance = "Rebalance";
1599
- var Rehome = "Rehome";
1600
- var Unauthorized = "Unauthorized";
1601
- var VersionNotSupported = "VersionNotSupported";
1602
- var SchemaVersionNotSupported = "SchemaVersionNotSupported";
1603
- var ServerOverloaded = "ServerOverloaded";
1604
- var Internal = "Internal";
1797
+ var transformResponseMessageSchema = valita_exports.union(
1798
+ transformOkMessageSchema,
1799
+ transformFailedMessageSchema
1800
+ );
1605
1801
 
1606
1802
  // ../zero-schema/src/builder/table-builder.ts
1607
1803
  function table(name) {
@@ -1611,14 +1807,14 @@ function table(name) {
1611
1807
  primaryKey: []
1612
1808
  });
1613
1809
  }
1614
- function string2() {
1810
+ function string4() {
1615
1811
  return new ColumnBuilder({
1616
1812
  type: "string",
1617
1813
  optional: false,
1618
1814
  customType: null
1619
1815
  });
1620
1816
  }
1621
- function number2() {
1817
+ function number4() {
1622
1818
  return new ColumnBuilder({
1623
1819
  type: "number",
1624
1820
  optional: false,
@@ -2172,6 +2368,170 @@ function makeID(row, schema) {
2172
2368
  return JSON.stringify(schema.primaryKey.map((k) => row[k]));
2173
2369
  }
2174
2370
 
2371
+ // ../zero-client/src/client/client-error-kind-enum.ts
2372
+ var client_error_kind_enum_exports = {};
2373
+ __export(client_error_kind_enum_exports, {
2374
+ AbruptClose: () => AbruptClose,
2375
+ CleanClose: () => CleanClose,
2376
+ ClientClosed: () => ClientClosed,
2377
+ ConnectTimeout: () => ConnectTimeout,
2378
+ DisconnectTimeout: () => DisconnectTimeout,
2379
+ Hidden: () => Hidden,
2380
+ Internal: () => Internal3,
2381
+ InvalidMessage: () => InvalidMessage2,
2382
+ NoSocketOrigin: () => NoSocketOrigin,
2383
+ PingTimeout: () => PingTimeout,
2384
+ PullTimeout: () => PullTimeout,
2385
+ UnexpectedBaseCookie: () => UnexpectedBaseCookie,
2386
+ UserDisconnect: () => UserDisconnect
2387
+ });
2388
+ var AbruptClose = "AbruptClose";
2389
+ var CleanClose = "CleanClose";
2390
+ var ClientClosed = "ClientClosed";
2391
+ var ConnectTimeout = "ConnectTimeout";
2392
+ var DisconnectTimeout = "DisconnectTimeout";
2393
+ var UnexpectedBaseCookie = "UnexpectedBaseCookie";
2394
+ var PingTimeout = "PingTimeout";
2395
+ var PullTimeout = "PullTimeout";
2396
+ var Hidden = "Hidden";
2397
+ var NoSocketOrigin = "NoSocketOrigin";
2398
+ var InvalidMessage2 = "InvalidMessage";
2399
+ var UserDisconnect = "UserDisconnect";
2400
+ var Internal3 = "Internal";
2401
+
2402
+ // ../zero-client/src/client/connection-status-enum.ts
2403
+ var connection_status_enum_exports = {};
2404
+ __export(connection_status_enum_exports, {
2405
+ Closed: () => Closed,
2406
+ Connected: () => Connected,
2407
+ Connecting: () => Connecting,
2408
+ Disconnected: () => Disconnected,
2409
+ Error: () => Error2
2410
+ });
2411
+ var Disconnected = "disconnected";
2412
+ var Connecting = "connecting";
2413
+ var Connected = "connected";
2414
+ var Error2 = "error";
2415
+ var Closed = "closed";
2416
+
2417
+ // ../zero-client/src/client/error.ts
2418
+ var ClientError = class extends Error {
2419
+ errorBody;
2420
+ constructor(errorBody, options) {
2421
+ super(errorBody.message, options);
2422
+ this.name = "ClientError";
2423
+ this.errorBody = { ...errorBody, origin: error_origin_enum_exports.Client };
2424
+ }
2425
+ get kind() {
2426
+ return this.errorBody.kind;
2427
+ }
2428
+ };
2429
+ function isServerError(ex) {
2430
+ return isProtocolError(ex) && (ex.errorBody.origin === error_origin_enum_exports.Server || ex.errorBody.origin === error_origin_enum_exports.ZeroCache);
2431
+ }
2432
+ function isAuthError(ex) {
2433
+ if (isServerError(ex)) {
2434
+ if (isAuthErrorKind(ex.errorBody.kind)) {
2435
+ return true;
2436
+ }
2437
+ if ((ex.errorBody.kind === error_kind_enum_exports.PushFailed || ex.errorBody.kind === error_kind_enum_exports.TransformFailed) && ex.errorBody.reason === error_reason_enum_exports.HTTP && (ex.errorBody.status === 401 || ex.errorBody.status === 403)) {
2438
+ return true;
2439
+ }
2440
+ }
2441
+ return false;
2442
+ }
2443
+ function isAuthErrorKind(kind) {
2444
+ return kind === error_kind_enum_exports.AuthInvalidated || kind === error_kind_enum_exports.Unauthorized;
2445
+ }
2446
+ function getBackoffParams(error) {
2447
+ if (isServerError(error)) {
2448
+ switch (error.errorBody.kind) {
2449
+ case error_kind_enum_exports.Rebalance:
2450
+ case error_kind_enum_exports.Rehome:
2451
+ case error_kind_enum_exports.ServerOverloaded:
2452
+ return error.errorBody;
2453
+ }
2454
+ }
2455
+ return void 0;
2456
+ }
2457
+ function isClientError(ex) {
2458
+ return ex instanceof ClientError && ex.errorBody.origin === error_origin_enum_exports.Client;
2459
+ }
2460
+ var NO_STATUS_TRANSITION = "NO_STATUS_TRANSITION";
2461
+ function getErrorConnectionTransition(ex) {
2462
+ if (isClientError(ex)) {
2463
+ switch (ex.kind) {
2464
+ // Connecting errors that should continue in the current state
2465
+ case client_error_kind_enum_exports.AbruptClose:
2466
+ case client_error_kind_enum_exports.CleanClose:
2467
+ case client_error_kind_enum_exports.ConnectTimeout:
2468
+ case client_error_kind_enum_exports.PingTimeout:
2469
+ case client_error_kind_enum_exports.PullTimeout:
2470
+ case client_error_kind_enum_exports.Hidden:
2471
+ case client_error_kind_enum_exports.NoSocketOrigin:
2472
+ return { status: NO_STATUS_TRANSITION, reason: ex };
2473
+ // Fatal errors that should transition to error state
2474
+ case client_error_kind_enum_exports.UnexpectedBaseCookie:
2475
+ case client_error_kind_enum_exports.Internal:
2476
+ case client_error_kind_enum_exports.InvalidMessage:
2477
+ case client_error_kind_enum_exports.UserDisconnect:
2478
+ return { status: connection_status_enum_exports.Error, reason: ex };
2479
+ // Disconnected error (this should already result in a disconnected state)
2480
+ case client_error_kind_enum_exports.DisconnectTimeout:
2481
+ return { status: connection_status_enum_exports.Disconnected, reason: ex };
2482
+ // Closed error (this should already result in a closed state)
2483
+ case client_error_kind_enum_exports.ClientClosed:
2484
+ return { status: connection_status_enum_exports.Closed, reason: ex };
2485
+ default:
2486
+ unreachable(ex.kind);
2487
+ }
2488
+ }
2489
+ if (isAuthError(ex)) {
2490
+ return { status: NO_STATUS_TRANSITION, reason: ex };
2491
+ }
2492
+ if (isServerError(ex)) {
2493
+ switch (ex.kind) {
2494
+ // Errors that should transition to error state
2495
+ case error_kind_enum_exports.ClientNotFound:
2496
+ case error_kind_enum_exports.InvalidConnectionRequest:
2497
+ case error_kind_enum_exports.InvalidConnectionRequestBaseCookie:
2498
+ case error_kind_enum_exports.InvalidConnectionRequestLastMutationID:
2499
+ case error_kind_enum_exports.InvalidConnectionRequestClientDeleted:
2500
+ case error_kind_enum_exports.InvalidMessage:
2501
+ case error_kind_enum_exports.InvalidPush:
2502
+ case error_kind_enum_exports.VersionNotSupported:
2503
+ case error_kind_enum_exports.SchemaVersionNotSupported:
2504
+ case error_kind_enum_exports.Internal:
2505
+ case error_kind_enum_exports.PushFailed:
2506
+ case error_kind_enum_exports.TransformFailed:
2507
+ return { status: connection_status_enum_exports.Error, reason: ex };
2508
+ // Errors that should continue with backoff/retry
2509
+ case error_kind_enum_exports.Rebalance:
2510
+ case error_kind_enum_exports.Rehome:
2511
+ case error_kind_enum_exports.ServerOverloaded:
2512
+ return { status: NO_STATUS_TRANSITION, reason: ex };
2513
+ // Auth errors will eventually transition to needs-auth state
2514
+ // For now, treat them as non-fatal so we can retry
2515
+ case error_kind_enum_exports.AuthInvalidated:
2516
+ case error_kind_enum_exports.Unauthorized:
2517
+ return { status: NO_STATUS_TRANSITION, reason: ex };
2518
+ // Mutation-specific errors don't affect connection state
2519
+ case error_kind_enum_exports.MutationRateLimited:
2520
+ case error_kind_enum_exports.MutationFailed:
2521
+ return { status: NO_STATUS_TRANSITION, reason: ex };
2522
+ default:
2523
+ unreachable(ex.kind);
2524
+ }
2525
+ }
2526
+ return {
2527
+ status: connection_status_enum_exports.Error,
2528
+ reason: new ClientError({
2529
+ kind: client_error_kind_enum_exports.Internal,
2530
+ message: "Unexpected internal error: " + (ex instanceof Error ? ex.message : typeof ex === "string" ? ex : String(ex ?? "Unknown error"))
2531
+ })
2532
+ };
2533
+ }
2534
+
2175
2535
  // ../zero-client/src/client/update-needed-reason-type-enum.ts
2176
2536
  var update_needed_reason_type_enum_exports = {};
2177
2537
  __export(update_needed_reason_type_enum_exports, {
@@ -6283,6 +6643,24 @@ function validateOptions(options) {
6283
6643
  }
6284
6644
  }
6285
6645
 
6646
+ // ../shared/src/promise-race.ts
6647
+ var NO_PROMISES_MESSAGE = "No promises to race";
6648
+ var wrapPromise = (key, promise) => Promise.resolve(promise).then((result) => ({
6649
+ key,
6650
+ status: "fulfilled",
6651
+ result
6652
+ }));
6653
+ async function promiseRace(promises) {
6654
+ const keys = Object.keys(promises);
6655
+ if (keys.length === 0) {
6656
+ throw new Error(NO_PROMISES_MESSAGE);
6657
+ }
6658
+ const wrapped = keys.map(
6659
+ (key) => wrapPromise(key, promises[key])
6660
+ );
6661
+ return await Promise.race(wrapped);
6662
+ }
6663
+
6286
6664
  // ../shared/src/sentinels.ts
6287
6665
  function emptyFunction() {
6288
6666
  }
@@ -6292,38 +6670,6 @@ function identity(x) {
6292
6670
  return x;
6293
6671
  }
6294
6672
 
6295
- // ../shared/src/subscribable.ts
6296
- var Subscribable = class {
6297
- _listeners = /* @__PURE__ */ new Set();
6298
- /**
6299
- * Subscribe to the subscribable.
6300
- *
6301
- * @param listener - The listener to subscribe to.
6302
- * @returns A function to unsubscribe from the subscribable.
6303
- */
6304
- subscribe = (listener) => {
6305
- this._listeners.add(listener);
6306
- return () => {
6307
- this._listeners.delete(listener);
6308
- };
6309
- };
6310
- /**
6311
- * Notify all listeners.
6312
- *
6313
- * @param update - The update to notify listeners with.
6314
- */
6315
- notify = (update) => {
6316
- this._listeners.forEach((listener) => listener(update));
6317
- };
6318
- hasListeners = () => this._listeners.size > 0;
6319
- /**
6320
- * Unsubscribe all listeners.
6321
- */
6322
- cleanup = () => {
6323
- this._listeners.clear();
6324
- };
6325
- };
6326
-
6327
6673
  // ../zero-protocol/src/delete-clients.ts
6328
6674
  var deleteClientsBodySchema = valita_exports.union(
6329
6675
  readonlyObject({
@@ -6401,56 +6747,6 @@ function encodeSecProtocols(initConnectionMessage, authToken) {
6401
6747
  return encodeURIComponent(btoa(s));
6402
6748
  }
6403
6749
 
6404
- // ../zero-protocol/src/error.ts
6405
- var basicErrorKindSchema = literalUnion(
6406
- error_kind_enum_exports.AuthInvalidated,
6407
- error_kind_enum_exports.ClientNotFound,
6408
- error_kind_enum_exports.InvalidConnectionRequest,
6409
- error_kind_enum_exports.InvalidConnectionRequestBaseCookie,
6410
- error_kind_enum_exports.InvalidConnectionRequestLastMutationID,
6411
- error_kind_enum_exports.InvalidConnectionRequestClientDeleted,
6412
- error_kind_enum_exports.InvalidMessage,
6413
- error_kind_enum_exports.InvalidPush,
6414
- error_kind_enum_exports.MutationRateLimited,
6415
- error_kind_enum_exports.MutationFailed,
6416
- error_kind_enum_exports.Unauthorized,
6417
- error_kind_enum_exports.VersionNotSupported,
6418
- error_kind_enum_exports.SchemaVersionNotSupported,
6419
- error_kind_enum_exports.Internal
6420
- );
6421
- var basicErrorBodySchema = valita_exports.object({
6422
- kind: basicErrorKindSchema,
6423
- message: valita_exports.string()
6424
- });
6425
- var backoffErrorKindSchema = literalUnion(
6426
- error_kind_enum_exports.Rebalance,
6427
- error_kind_enum_exports.Rehome,
6428
- error_kind_enum_exports.ServerOverloaded
6429
- );
6430
- var backoffBodySchema = valita_exports.object({
6431
- kind: backoffErrorKindSchema,
6432
- message: valita_exports.string(),
6433
- minBackoffMs: valita_exports.number().optional(),
6434
- maxBackoffMs: valita_exports.number().optional(),
6435
- // Query parameters to send in the next reconnect. In the event of
6436
- // a conflict, these will be overridden by the parameters used by
6437
- // the client; it is the responsibility of the server to avoid
6438
- // parameter name conflicts.
6439
- //
6440
- // The parameters will only be added to the immediately following
6441
- // reconnect, and not after that.
6442
- reconnectParams: valita_exports.record(valita_exports.string()).optional()
6443
- });
6444
- var errorKindSchema = valita_exports.union(
6445
- basicErrorKindSchema,
6446
- backoffErrorKindSchema
6447
- );
6448
- var errorBodySchema = valita_exports.union(basicErrorBodySchema, backoffBodySchema);
6449
- var errorMessageSchema = valita_exports.tuple([
6450
- valita_exports.literal("error"),
6451
- errorBodySchema
6452
- ]);
6453
-
6454
6750
  // ../zero-protocol/src/mutation-type-enum.ts
6455
6751
  var CRUD = "crud";
6456
6752
  var Custom = "custom";
@@ -6522,17 +6818,17 @@ var pushBodySchema = valita_exports.object({
6522
6818
  requestID: valita_exports.string()
6523
6819
  });
6524
6820
  var pushMessageSchema = valita_exports.tuple([valita_exports.literal("push"), pushBodySchema]);
6525
- var mutationIDSchema = valita_exports.object({
6526
- id: valita_exports.number(),
6527
- clientID: valita_exports.string()
6528
- });
6529
6821
  var appErrorSchema = valita_exports.object({
6530
6822
  error: valita_exports.literal("app"),
6531
6823
  // The user can return any additional data here
6532
6824
  details: jsonSchema.optional()
6533
6825
  });
6534
6826
  var zeroErrorSchema2 = valita_exports.object({
6535
- error: literalUnion("oooMutation", "alreadyProcessed"),
6827
+ error: valita_exports.union(
6828
+ /** @deprecated push oooMutation errors are now represented as ['error', { ... }] messages */
6829
+ valita_exports.literal("oooMutation"),
6830
+ valita_exports.literal("alreadyProcessed")
6831
+ ),
6536
6832
  details: jsonSchema.optional()
6537
6833
  });
6538
6834
  var mutationOkSchema = valita_exports.object({
@@ -6552,28 +6848,33 @@ var pushOkSchema = valita_exports.object({
6552
6848
  mutations: valita_exports.array(mutationResponseSchema)
6553
6849
  });
6554
6850
  var unsupportedPushVersionSchema = valita_exports.object({
6851
+ /** @deprecated */
6555
6852
  error: valita_exports.literal("unsupportedPushVersion"),
6556
- // optional for backwards compatibility
6557
- // This field is included so the client knows which mutations
6558
- // were not processed by the server.
6853
+ /** @deprecated */
6559
6854
  mutationIDs: valita_exports.array(mutationIDSchema).optional()
6560
6855
  });
6561
6856
  var unsupportedSchemaVersionSchema = valita_exports.object({
6857
+ /** @deprecated */
6562
6858
  error: valita_exports.literal("unsupportedSchemaVersion"),
6563
- // optional for backwards compatibility
6564
- // This field is included so the client knows which mutations
6565
- // were not processed by the server.
6859
+ /** @deprecated */
6566
6860
  mutationIDs: valita_exports.array(mutationIDSchema).optional()
6567
6861
  });
6568
6862
  var httpErrorSchema = valita_exports.object({
6863
+ /** @deprecated */
6569
6864
  error: valita_exports.literal("http"),
6865
+ /** @deprecated */
6570
6866
  status: valita_exports.number(),
6867
+ /** @deprecated */
6571
6868
  details: valita_exports.string(),
6869
+ /** @deprecated */
6572
6870
  mutationIDs: valita_exports.array(mutationIDSchema).optional()
6573
6871
  });
6574
6872
  var zeroPusherErrorSchema = valita_exports.object({
6873
+ /** @deprecated */
6575
6874
  error: valita_exports.literal("zeroPusher"),
6875
+ /** @deprecated */
6576
6876
  details: valita_exports.string(),
6877
+ /** @deprecated */
6577
6878
  mutationIDs: valita_exports.array(mutationIDSchema).optional()
6578
6879
  });
6579
6880
  var pushErrorSchema = valita_exports.union(
@@ -6582,10 +6883,14 @@ var pushErrorSchema = valita_exports.union(
6582
6883
  httpErrorSchema,
6583
6884
  zeroPusherErrorSchema
6584
6885
  );
6585
- var pushResponseSchema = valita_exports.union(pushOkSchema, pushErrorSchema);
6886
+ var pushResponseBodySchema = valita_exports.union(pushOkSchema, pushErrorSchema);
6887
+ var pushResponseSchema = valita_exports.union(
6888
+ pushResponseBodySchema,
6889
+ pushFailedBodySchema
6890
+ );
6586
6891
  var pushResponseMessageSchema = valita_exports.tuple([
6587
6892
  valita_exports.literal("pushResponse"),
6588
- pushResponseSchema
6893
+ pushResponseBodySchema
6589
6894
  ]);
6590
6895
  var ackMutationResponsesMessageSchema = valita_exports.tuple([
6591
6896
  valita_exports.literal("ackMutationResponses"),
@@ -6750,7 +7055,7 @@ var downstreamSchema = valita_exports.union(
6750
7055
  );
6751
7056
 
6752
7057
  // ../zero-protocol/src/protocol-version.ts
6753
- var PROTOCOL_VERSION = 37;
7058
+ var PROTOCOL_VERSION = 38;
6754
7059
  var MIN_SERVER_SUPPORTED_SYNC_PROTOCOL = 18;
6755
7060
  assert(MIN_SERVER_SUPPORTED_SYNC_PROTOCOL < PROTOCOL_VERSION);
6756
7061
 
@@ -9302,176 +9607,1426 @@ var UnionFanOut = class {
9302
9607
  }
9303
9608
  };
9304
9609
 
9305
- // ../zql/src/query/expression.ts
9306
- var ExpressionBuilder = class {
9307
- #exists;
9308
- constructor(exists) {
9309
- this.#exists = exists;
9310
- this.exists = this.exists.bind(this);
9610
+ // ../zql/src/planner/planner-fan-in.ts
9611
+ var PlannerFanIn = class {
9612
+ kind = "fan-in";
9613
+ #type;
9614
+ #output;
9615
+ #inputs;
9616
+ constructor(inputs) {
9617
+ this.#type = "FI";
9618
+ this.#inputs = inputs;
9311
9619
  }
9312
- get eb() {
9313
- return this;
9620
+ get type() {
9621
+ return this.#type;
9314
9622
  }
9315
- cmp(field, opOrValue, value) {
9316
- return cmp(field, opOrValue, value);
9623
+ closestJoinOrSource() {
9624
+ return "join";
9317
9625
  }
9318
- cmpLit(left, op, right) {
9319
- return {
9320
- type: "simple",
9321
- left: isParameterReference(left) ? left[toStaticParam]() : { type: "literal", value: left },
9322
- right: isParameterReference(right) ? right[toStaticParam]() : { type: "literal", value: right },
9323
- op
9324
- };
9626
+ setOutput(node) {
9627
+ this.#output = node;
9325
9628
  }
9326
- and = and;
9327
- or = or;
9328
- not = not;
9329
- exists = (relationship, cb, options) => this.#exists(relationship, cb, options);
9330
- };
9331
- function and(...conditions) {
9332
- const expressions = filterTrue(filterUndefined(conditions));
9333
- if (expressions.length === 1) {
9334
- return expressions[0];
9629
+ get output() {
9630
+ assert(this.#output !== void 0, "Output not set");
9631
+ return this.#output;
9335
9632
  }
9336
- if (expressions.some(isAlwaysFalse)) {
9337
- return FALSE;
9633
+ reset() {
9634
+ this.#type = "FI";
9338
9635
  }
9339
- return { type: "and", conditions: expressions };
9340
- }
9341
- function or(...conditions) {
9342
- const expressions = filterFalse(filterUndefined(conditions));
9343
- if (expressions.length === 1) {
9344
- return expressions[0];
9636
+ convertToUFI() {
9637
+ this.#type = "UFI";
9345
9638
  }
9346
- if (expressions.some(isAlwaysTrue)) {
9347
- return TRUE;
9639
+ /**
9640
+ * Propagate unlimiting when a parent join is flipped.
9641
+ * Fan-in propagates to all of its inputs.
9642
+ */
9643
+ propagateUnlimitFromFlippedJoin() {
9644
+ for (const input of this.#inputs) {
9645
+ if ("propagateUnlimitFromFlippedJoin" in input && typeof input.propagateUnlimitFromFlippedJoin === "function") {
9646
+ input.propagateUnlimitFromFlippedJoin();
9647
+ }
9648
+ }
9348
9649
  }
9349
- return { type: "or", conditions: expressions };
9350
- }
9351
- function not(expression) {
9352
- switch (expression.type) {
9353
- case "and":
9354
- return {
9355
- type: "or",
9356
- conditions: expression.conditions.map(not)
9357
- };
9358
- case "or":
9359
- return {
9360
- type: "and",
9361
- conditions: expression.conditions.map(not)
9362
- };
9363
- case "correlatedSubquery":
9364
- return {
9365
- type: "correlatedSubquery",
9366
- related: expression.related,
9367
- op: negateOperator(expression.op)
9368
- };
9369
- case "simple":
9370
- return {
9371
- type: "simple",
9372
- op: negateOperator(expression.op),
9373
- left: expression.left,
9374
- right: expression.right
9375
- };
9650
+ estimateCost(branchPattern) {
9651
+ let totalCost = {
9652
+ rows: 0,
9653
+ runningCost: 0,
9654
+ startupCost: 0,
9655
+ selectivity: 0,
9656
+ limit: void 0
9657
+ };
9658
+ branchPattern = branchPattern ?? [];
9659
+ if (this.#type === "FI") {
9660
+ const updatedPattern = [0, ...branchPattern];
9661
+ let maxrows = 0;
9662
+ let maxRunningCost = 0;
9663
+ let maxStartupCost = 0;
9664
+ let noMatchProb = 1;
9665
+ for (const input of this.#inputs) {
9666
+ const cost = input.estimateCost(updatedPattern);
9667
+ if (cost.rows > maxrows) {
9668
+ maxrows = cost.rows;
9669
+ }
9670
+ if (cost.runningCost > maxRunningCost) {
9671
+ maxRunningCost = cost.runningCost;
9672
+ }
9673
+ if (cost.startupCost > maxStartupCost) {
9674
+ maxStartupCost = cost.startupCost;
9675
+ }
9676
+ noMatchProb *= 1 - cost.selectivity;
9677
+ assert(
9678
+ totalCost.limit === void 0 || cost.limit === totalCost.limit,
9679
+ "All FanIn inputs should have the same limit"
9680
+ );
9681
+ totalCost.limit = cost.limit;
9682
+ }
9683
+ totalCost.rows = maxrows;
9684
+ totalCost.runningCost = maxRunningCost;
9685
+ totalCost.startupCost = maxStartupCost;
9686
+ totalCost.selectivity = 1 - noMatchProb;
9687
+ } else {
9688
+ let i = 0;
9689
+ let noMatchProb = 1;
9690
+ for (const input of this.#inputs) {
9691
+ const updatedPattern = [i, ...branchPattern];
9692
+ const cost = input.estimateCost(updatedPattern);
9693
+ totalCost.rows += cost.rows;
9694
+ totalCost.runningCost += cost.runningCost;
9695
+ totalCost.startupCost += cost.startupCost;
9696
+ noMatchProb *= 1 - cost.selectivity;
9697
+ assert(
9698
+ totalCost.limit === void 0 || cost.limit === totalCost.limit,
9699
+ "All FanIn inputs should have the same limit"
9700
+ );
9701
+ totalCost.limit = cost.limit;
9702
+ i++;
9703
+ }
9704
+ totalCost.selectivity = 1 - noMatchProb;
9705
+ }
9706
+ return totalCost;
9376
9707
  }
9377
- }
9378
- function cmp(field, opOrValue, value) {
9379
- let op;
9380
- if (value === void 0) {
9381
- value = opOrValue;
9382
- op = "=";
9383
- } else {
9384
- op = opOrValue;
9708
+ propagateConstraints(branchPattern, constraint, from) {
9709
+ if (this.#type === "FI") {
9710
+ const updatedPattern = [0, ...branchPattern];
9711
+ for (const input of this.#inputs) {
9712
+ input.propagateConstraints(updatedPattern, constraint, from);
9713
+ }
9714
+ return;
9715
+ }
9716
+ let i = 0;
9717
+ for (const input of this.#inputs) {
9718
+ input.propagateConstraints([i, ...branchPattern], constraint, from);
9719
+ i++;
9720
+ }
9385
9721
  }
9386
- return {
9387
- type: "simple",
9388
- left: { type: "column", name: field },
9389
- right: isParameterReference(value) ? value[toStaticParam]() : { type: "literal", value },
9390
- op
9391
- };
9392
- }
9393
- function isParameterReference(value) {
9394
- return value !== null && typeof value === "object" && value[toStaticParam];
9395
- }
9396
- var TRUE = {
9397
- type: "and",
9398
- conditions: []
9399
- };
9400
- var FALSE = {
9401
- type: "or",
9402
- conditions: []
9403
9722
  };
9404
- function isAlwaysTrue(condition) {
9405
- return condition.type === "and" && condition.conditions.length === 0;
9406
- }
9407
- function isAlwaysFalse(condition) {
9408
- return condition.type === "or" && condition.conditions.length === 0;
9409
- }
9410
- function simplifyCondition(c) {
9411
- if (c.type === "simple" || c.type === "correlatedSubquery") {
9412
- return c;
9723
+
9724
+ // ../zql/src/planner/planner-fan-out.ts
9725
+ var PlannerFanOut = class {
9726
+ kind = "fan-out";
9727
+ #type;
9728
+ #outputs = [];
9729
+ #input;
9730
+ constructor(input) {
9731
+ this.#type = "FO";
9732
+ this.#input = input;
9413
9733
  }
9414
- if (c.conditions.length === 1) {
9415
- return simplifyCondition(c.conditions[0]);
9734
+ get type() {
9735
+ return this.#type;
9416
9736
  }
9417
- const conditions = flatten(c.type, c.conditions.map(simplifyCondition));
9418
- if (c.type === "and" && conditions.some(isAlwaysFalse)) {
9419
- return FALSE;
9737
+ addOutput(node) {
9738
+ this.#outputs.push(node);
9420
9739
  }
9421
- if (c.type === "or" && conditions.some(isAlwaysTrue)) {
9422
- return TRUE;
9740
+ get outputs() {
9741
+ return this.#outputs;
9423
9742
  }
9424
- return {
9425
- type: c.type,
9426
- conditions
9427
- };
9428
- }
9429
- function flatten(type, conditions) {
9430
- const flattened = [];
9431
- for (const c of conditions) {
9432
- if (c.type === type) {
9433
- flattened.push(...c.conditions);
9434
- } else {
9435
- flattened.push(c);
9743
+ closestJoinOrSource() {
9744
+ return this.#input.closestJoinOrSource();
9745
+ }
9746
+ propagateConstraints(branchPattern, constraint, _from) {
9747
+ this.#input.propagateConstraints(branchPattern, constraint, this);
9748
+ }
9749
+ estimateCost(branchPattern) {
9750
+ return this.#input.estimateCost(branchPattern);
9751
+ }
9752
+ convertToUFO() {
9753
+ this.#type = "UFO";
9754
+ }
9755
+ reset() {
9756
+ this.#type = "FO";
9757
+ }
9758
+ /**
9759
+ * Propagate unlimiting when a parent join is flipped.
9760
+ * Fan-out propagates to its input.
9761
+ */
9762
+ propagateUnlimitFromFlippedJoin() {
9763
+ if ("propagateUnlimitFromFlippedJoin" in this.#input && typeof this.#input.propagateUnlimitFromFlippedJoin === "function") {
9764
+ this.#input.propagateUnlimitFromFlippedJoin();
9436
9765
  }
9437
9766
  }
9438
- return flattened;
9439
- }
9440
- var negateSimpleOperatorMap = {
9441
- ["="]: "!=",
9442
- ["!="]: "=",
9443
- ["<"]: ">=",
9444
- [">"]: "<=",
9445
- [">="]: "<",
9446
- ["<="]: ">",
9447
- ["IN"]: "NOT IN",
9448
- ["NOT IN"]: "IN",
9449
- ["LIKE"]: "NOT LIKE",
9450
- ["NOT LIKE"]: "LIKE",
9451
- ["ILIKE"]: "NOT ILIKE",
9452
- ["NOT ILIKE"]: "ILIKE",
9453
- ["IS"]: "IS NOT",
9454
- ["IS NOT"]: "IS"
9455
9767
  };
9456
- var negateOperatorMap = {
9457
- ...negateSimpleOperatorMap,
9458
- ["EXISTS"]: "NOT EXISTS",
9459
- ["NOT EXISTS"]: "EXISTS"
9460
- };
9461
- function negateOperator(op) {
9462
- return must(negateOperatorMap[op]);
9463
- }
9464
- function filterUndefined(array9) {
9465
- return array9.filter((e) => e !== void 0);
9466
- }
9467
- function filterTrue(conditions) {
9468
- return conditions.filter((c) => !isAlwaysTrue(c));
9469
- }
9470
- function filterFalse(conditions) {
9471
- return conditions.filter((c) => !isAlwaysFalse(c));
9768
+
9769
+ // ../zql/src/planner/planner-constraint.ts
9770
+ function mergeConstraints(a, b) {
9771
+ if (!a) return b;
9772
+ if (!b) return a;
9773
+ return { ...a, ...b };
9472
9774
  }
9473
9775
 
9474
- // ../zql/src/builder/like.ts
9776
+ // ../zql/src/planner/planner-connection.ts
9777
+ var PlannerConnection = class {
9778
+ kind = "connection";
9779
+ // ========================================================================
9780
+ // IMMUTABLE STRUCTURE (set during construction, never changes)
9781
+ // ========================================================================
9782
+ #sort;
9783
+ #filters;
9784
+ #model;
9785
+ table;
9786
+ name;
9787
+ // Human-readable name for debugging (defaults to table name)
9788
+ #baseConstraints;
9789
+ // Constraints from parent correlation
9790
+ #baseLimit;
9791
+ // Original limit from query structure (never modified)
9792
+ selectivity;
9793
+ // Fraction of rows passing filters (1.0 = no filtering)
9794
+ #output;
9795
+ // Set once during graph construction
9796
+ // ========================================================================
9797
+ // MUTABLE PLANNING STATE (changes during plan search)
9798
+ // ========================================================================
9799
+ /**
9800
+ * Current limit during planning. Can be cleared (set to undefined) when a
9801
+ * parent join is flipped, indicating this connection is now in an outer loop
9802
+ * and should not be limited by EXISTS semantics.
9803
+ */
9804
+ limit;
9805
+ /**
9806
+ * Constraints accumulated from parent joins during planning.
9807
+ * Key is a path through the graph (e.g., "0,1" for branch pattern [0,1]).
9808
+ *
9809
+ * Undefined constraints are possible when a FO converts to UFO and only
9810
+ * a single join in the UFO is flipped - other branches report undefined.
9811
+ */
9812
+ #constraints;
9813
+ /**
9814
+ * Cached total cost (sum of all branches) to avoid redundant calculations.
9815
+ * Invalidated when constraints change.
9816
+ */
9817
+ #cachedTotalCost = void 0;
9818
+ /**
9819
+ * Cached per-constraint costs to avoid redundant cost model calls.
9820
+ * Maps constraint key (branch pattern string) to computed cost.
9821
+ * Invalidated when constraints change.
9822
+ */
9823
+ #cachedConstraintCosts = /* @__PURE__ */ new Map();
9824
+ #costDirty = true;
9825
+ constructor(table2, model, sort, filters, baseConstraints, limit, name) {
9826
+ this.table = table2;
9827
+ this.name = name ?? table2;
9828
+ this.#sort = sort;
9829
+ this.#filters = filters;
9830
+ this.#model = model;
9831
+ this.#baseConstraints = baseConstraints;
9832
+ this.#baseLimit = limit;
9833
+ this.limit = limit;
9834
+ this.#constraints = /* @__PURE__ */ new Map();
9835
+ if (limit !== void 0 && filters) {
9836
+ const costWithFilters = model(table2, sort, filters, void 0);
9837
+ const costWithoutFilters = model(table2, sort, void 0, void 0);
9838
+ this.selectivity = costWithoutFilters.rows > 0 ? costWithFilters.rows / costWithoutFilters.rows : 1;
9839
+ } else {
9840
+ this.selectivity = 1;
9841
+ }
9842
+ }
9843
+ setOutput(node) {
9844
+ this.#output = node;
9845
+ }
9846
+ get output() {
9847
+ assert(this.#output !== void 0, "Output not set");
9848
+ return this.#output;
9849
+ }
9850
+ closestJoinOrSource() {
9851
+ return "connection";
9852
+ }
9853
+ /**
9854
+ * Constraints are uniquely identified by their path through the
9855
+ * graph.
9856
+ *
9857
+ * FO represents all sub-joins as a single path.
9858
+ * UFO represents each sub-join as a separate path.
9859
+ * The first branch in a UFO will match the path of FO so no re-set needs to happen
9860
+ * when swapping from FO to UFO.
9861
+ *
9862
+ * FO swaps to UFO when a join inside FO-FI gets flipped.
9863
+ *
9864
+ * The max of the last element of the paths is the number of
9865
+ * root branches.
9866
+ */
9867
+ propagateConstraints(path, c) {
9868
+ const key = path.join(",");
9869
+ this.#constraints.set(key, c);
9870
+ this.#cachedTotalCost = void 0;
9871
+ this.#cachedConstraintCosts.clear();
9872
+ this.#costDirty = true;
9873
+ }
9874
+ estimateCost(branchPattern) {
9875
+ if (branchPattern === void 0) {
9876
+ if (!this.#costDirty && this.#cachedTotalCost !== void 0) {
9877
+ return this.#cachedTotalCost;
9878
+ }
9879
+ let totalRows = 0;
9880
+ let maxStartupCost = 0;
9881
+ if (this.#constraints.size === 0) {
9882
+ const key2 = "";
9883
+ let cost2 = this.#cachedConstraintCosts.get(key2);
9884
+ if (cost2 === void 0) {
9885
+ const { startupCost: startupCost2, rows: rows2 } = this.#model(
9886
+ this.table,
9887
+ this.#sort,
9888
+ this.#filters,
9889
+ this.#baseConstraints
9890
+ );
9891
+ cost2 = {
9892
+ rows: rows2,
9893
+ runningCost: rows2,
9894
+ startupCost: startupCost2,
9895
+ selectivity: this.selectivity,
9896
+ limit: this.limit
9897
+ };
9898
+ this.#cachedConstraintCosts.set(key2, cost2);
9899
+ }
9900
+ totalRows = cost2.rows;
9901
+ maxStartupCost = cost2.startupCost;
9902
+ } else {
9903
+ for (const [key2, constraint2] of this.#constraints.entries()) {
9904
+ let cost2 = this.#cachedConstraintCosts.get(key2);
9905
+ if (cost2 === void 0) {
9906
+ const mergedConstraint2 = mergeConstraints(
9907
+ this.#baseConstraints,
9908
+ constraint2
9909
+ );
9910
+ const { startupCost: startupCost2, rows: rows2 } = this.#model(
9911
+ this.table,
9912
+ this.#sort,
9913
+ this.#filters,
9914
+ mergedConstraint2
9915
+ );
9916
+ cost2 = {
9917
+ rows: rows2,
9918
+ runningCost: rows2,
9919
+ startupCost: startupCost2,
9920
+ selectivity: this.selectivity,
9921
+ limit: this.limit
9922
+ };
9923
+ this.#cachedConstraintCosts.set(key2, cost2);
9924
+ }
9925
+ totalRows += cost2.rows;
9926
+ maxStartupCost = Math.max(maxStartupCost, cost2.startupCost);
9927
+ }
9928
+ }
9929
+ const ret = {
9930
+ rows: totalRows,
9931
+ runningCost: totalRows,
9932
+ startupCost: maxStartupCost,
9933
+ selectivity: this.selectivity,
9934
+ limit: this.limit
9935
+ };
9936
+ this.#cachedTotalCost = ret;
9937
+ this.#costDirty = false;
9938
+ return ret;
9939
+ }
9940
+ const key = branchPattern.join(",");
9941
+ let cost = this.#cachedConstraintCosts.get(key);
9942
+ if (cost !== void 0) {
9943
+ return cost;
9944
+ }
9945
+ const constraint = this.#constraints.get(key);
9946
+ const mergedConstraint = mergeConstraints(
9947
+ this.#baseConstraints,
9948
+ constraint
9949
+ );
9950
+ const { startupCost, rows } = this.#model(
9951
+ this.table,
9952
+ this.#sort,
9953
+ this.#filters,
9954
+ mergedConstraint
9955
+ );
9956
+ cost = {
9957
+ rows,
9958
+ runningCost: rows,
9959
+ startupCost,
9960
+ selectivity: this.selectivity,
9961
+ limit: this.limit
9962
+ };
9963
+ this.#cachedConstraintCosts.set(key, cost);
9964
+ return cost;
9965
+ }
9966
+ /**
9967
+ * Remove the limit from this connection.
9968
+ * Called when a parent join is flipped, making this connection part of an
9969
+ * outer loop that should produce all rows rather than stopping at the limit.
9970
+ */
9971
+ unlimit() {
9972
+ if (this.limit !== void 0) {
9973
+ this.limit = void 0;
9974
+ }
9975
+ }
9976
+ /**
9977
+ * Propagate unlimiting when a parent join is flipped.
9978
+ * For connections, we simply remove the limit.
9979
+ */
9980
+ propagateUnlimitFromFlippedJoin() {
9981
+ this.unlimit();
9982
+ }
9983
+ reset() {
9984
+ this.#constraints.clear();
9985
+ this.limit = this.#baseLimit;
9986
+ this.#cachedTotalCost = void 0;
9987
+ this.#cachedConstraintCosts.clear();
9988
+ this.#costDirty = true;
9989
+ }
9990
+ /**
9991
+ * Capture constraint state for snapshotting.
9992
+ * Used by PlannerGraph to save/restore planning state.
9993
+ */
9994
+ captureConstraints() {
9995
+ return new Map(this.#constraints);
9996
+ }
9997
+ /**
9998
+ * Restore constraint state from a snapshot.
9999
+ * Used by PlannerGraph to restore planning state.
10000
+ */
10001
+ restoreConstraints(constraints) {
10002
+ this.#constraints.clear();
10003
+ for (const [key, value] of constraints) {
10004
+ this.#constraints.set(key, value);
10005
+ }
10006
+ this.#cachedTotalCost = void 0;
10007
+ this.#cachedConstraintCosts.clear();
10008
+ this.#costDirty = true;
10009
+ }
10010
+ /**
10011
+ * Get current constraints for debugging.
10012
+ * Returns a copy of the constraints map.
10013
+ */
10014
+ getConstraintsForDebug() {
10015
+ return new Map(this.#constraints);
10016
+ }
10017
+ /**
10018
+ * Get estimated cost for each constraint branch.
10019
+ * Returns a map of constraint key to cost estimate.
10020
+ * Forces cost calculation if not already cached.
10021
+ */
10022
+ getConstraintCostsForDebug() {
10023
+ this.estimateCost(void 0);
10024
+ return new Map(this.#cachedConstraintCosts);
10025
+ }
10026
+ };
10027
+
10028
+ // ../zql/src/planner/planner-source.ts
10029
+ var PlannerSource = class {
10030
+ name;
10031
+ #model;
10032
+ constructor(name, model) {
10033
+ this.name = name;
10034
+ this.#model = model;
10035
+ }
10036
+ connect(sort, filters, baseConstraints, limit) {
10037
+ return new PlannerConnection(
10038
+ this.name,
10039
+ this.#model,
10040
+ sort,
10041
+ filters,
10042
+ baseConstraints,
10043
+ limit
10044
+ );
10045
+ }
10046
+ };
10047
+
10048
+ // ../zql/src/planner/planner-graph.ts
10049
+ var MAX_FLIPPABLE_JOINS = 13;
10050
+ var PlannerGraph = class {
10051
+ // Sources indexed by table name
10052
+ #sources = /* @__PURE__ */ new Map();
10053
+ // The final output node where constraint propagation starts
10054
+ #terminus = void 0;
10055
+ // Collections of nodes with mutable planning state
10056
+ joins = [];
10057
+ fanOuts = [];
10058
+ fanIns = [];
10059
+ connections = [];
10060
+ /**
10061
+ * Reset all planning state back to initial values for another planning pass.
10062
+ * Resets only mutable planning state - graph structure is unchanged.
10063
+ *
10064
+ * This allows replanning the same query graph with different strategies.
10065
+ */
10066
+ resetPlanningState() {
10067
+ for (const j of this.joins) j.reset();
10068
+ for (const fo of this.fanOuts) fo.reset();
10069
+ for (const fi of this.fanIns) fi.reset();
10070
+ for (const c of this.connections) c.reset();
10071
+ }
10072
+ /**
10073
+ * Create and register a source (table) in the graph.
10074
+ */
10075
+ addSource(name, model) {
10076
+ assert(
10077
+ !this.#sources.has(name),
10078
+ `Source ${name} already exists in the graph`
10079
+ );
10080
+ const source = new PlannerSource(name, model);
10081
+ this.#sources.set(name, source);
10082
+ return source;
10083
+ }
10084
+ /**
10085
+ * Get a source by table name.
10086
+ */
10087
+ getSource(name) {
10088
+ const source = this.#sources.get(name);
10089
+ assert(source !== void 0, `Source ${name} not found in the graph`);
10090
+ return source;
10091
+ }
10092
+ /**
10093
+ * Check if a source exists by table name.
10094
+ */
10095
+ hasSource(name) {
10096
+ return this.#sources.has(name);
10097
+ }
10098
+ /**
10099
+ * Set the terminus (final output) node of the graph.
10100
+ * Constraint propagation starts from this node.
10101
+ */
10102
+ setTerminus(terminus) {
10103
+ this.#terminus = terminus;
10104
+ }
10105
+ /**
10106
+ * Initiate constraint propagation from the terminus node.
10107
+ * This sends constraints up through the graph to update
10108
+ * connection cost estimates.
10109
+ */
10110
+ propagateConstraints() {
10111
+ assert(
10112
+ this.#terminus !== void 0,
10113
+ "Cannot propagate constraints without a terminus node"
10114
+ );
10115
+ this.#terminus.propagateConstraints();
10116
+ }
10117
+ /**
10118
+ * Calculate total cost of the current plan.
10119
+ * Total cost includes both startup cost (one-time, e.g., sorting) and running cost.
10120
+ */
10121
+ getTotalCost() {
10122
+ const estimate = must(this.#terminus).estimateCost();
10123
+ return estimate.startupCost + estimate.runningCost;
10124
+ }
10125
+ /**
10126
+ * Capture a lightweight snapshot of the current planning state.
10127
+ * Used for backtracking during multi-start greedy search.
10128
+ *
10129
+ * Captures mutable state including pinned flags, join types, and
10130
+ * constraint maps to avoid needing repropagation on restore.
10131
+ *
10132
+ * @returns A snapshot that can be restored via restorePlanningSnapshot()
10133
+ */
10134
+ capturePlanningSnapshot() {
10135
+ return {
10136
+ connections: this.connections.map((c) => ({
10137
+ limit: c.limit
10138
+ })),
10139
+ joins: this.joins.map((j) => ({ type: j.type })),
10140
+ fanOuts: this.fanOuts.map((fo) => ({ type: fo.type })),
10141
+ fanIns: this.fanIns.map((fi) => ({ type: fi.type })),
10142
+ connectionConstraints: this.connections.map((c) => c.captureConstraints())
10143
+ };
10144
+ }
10145
+ /**
10146
+ * Restore planning state from a previously captured snapshot.
10147
+ * Used for backtracking when a planning attempt fails.
10148
+ *
10149
+ * Restores pinned flags, join types, and constraint maps, eliminating
10150
+ * the need for repropagation.
10151
+ *
10152
+ * @param state - Snapshot created by capturePlanningSnapshot()
10153
+ */
10154
+ restorePlanningSnapshot(state) {
10155
+ this.#validateSnapshotShape(state);
10156
+ this.#restoreConnections(state);
10157
+ this.#restoreJoins(state);
10158
+ this.#restoreFanNodes(state);
10159
+ }
10160
+ /**
10161
+ * Collect cost estimates from all nodes in the graph for debugging.
10162
+ */
10163
+ #collectNodeCosts() {
10164
+ const costs = [];
10165
+ for (const c of this.connections) {
10166
+ costs.push({
10167
+ node: c.name,
10168
+ nodeType: "connection",
10169
+ costEstimate: c.estimateCost(void 0)
10170
+ });
10171
+ }
10172
+ for (const j of this.joins) {
10173
+ costs.push({
10174
+ node: j.getName(),
10175
+ nodeType: "join",
10176
+ costEstimate: j.estimateCost(void 0)
10177
+ });
10178
+ }
10179
+ for (const fo of this.fanOuts) {
10180
+ costs.push({
10181
+ node: "FO",
10182
+ nodeType: "fan-out",
10183
+ costEstimate: fo.estimateCost(void 0)
10184
+ });
10185
+ }
10186
+ for (const fi of this.fanIns) {
10187
+ costs.push({
10188
+ node: "FI",
10189
+ nodeType: "fan-in",
10190
+ costEstimate: fi.estimateCost(void 0)
10191
+ });
10192
+ }
10193
+ return costs;
10194
+ }
10195
+ /**
10196
+ * Validate that snapshot shape matches current graph structure.
10197
+ */
10198
+ #validateSnapshotShape(state) {
10199
+ assert(
10200
+ this.connections.length === state.connections.length,
10201
+ "Plan state mismatch: connections"
10202
+ );
10203
+ assert(
10204
+ this.joins.length === state.joins.length,
10205
+ "Plan state mismatch: joins"
10206
+ );
10207
+ assert(
10208
+ this.fanOuts.length === state.fanOuts.length,
10209
+ "Plan state mismatch: fanOuts"
10210
+ );
10211
+ assert(
10212
+ this.fanIns.length === state.fanIns.length,
10213
+ "Plan state mismatch: fanIns"
10214
+ );
10215
+ assert(
10216
+ this.connections.length === state.connectionConstraints.length,
10217
+ "Plan state mismatch: connectionConstraints"
10218
+ );
10219
+ }
10220
+ /**
10221
+ * Restore connection pinned flags, limits, and constraint maps.
10222
+ */
10223
+ #restoreConnections(state) {
10224
+ for (let i = 0; i < this.connections.length; i++) {
10225
+ this.connections[i].limit = state.connections[i].limit;
10226
+ this.connections[i].restoreConstraints(state.connectionConstraints[i]);
10227
+ }
10228
+ }
10229
+ /**
10230
+ * Restore join types and pinned flags.
10231
+ */
10232
+ #restoreJoins(state) {
10233
+ for (let i = 0; i < this.joins.length; i++) {
10234
+ const join = this.joins[i];
10235
+ const targetState = state.joins[i];
10236
+ join.reset();
10237
+ if (targetState.type === "flipped") {
10238
+ join.flip();
10239
+ }
10240
+ }
10241
+ }
10242
+ /**
10243
+ * Restore FanOut and FanIn types.
10244
+ */
10245
+ #restoreFanNodes(state) {
10246
+ for (let i = 0; i < this.fanOuts.length; i++) {
10247
+ const fo = this.fanOuts[i];
10248
+ const targetType = state.fanOuts[i].type;
10249
+ if (targetType === "UFO" && fo.type === "FO") {
10250
+ fo.convertToUFO();
10251
+ }
10252
+ }
10253
+ for (let i = 0; i < this.fanIns.length; i++) {
10254
+ const fi = this.fanIns[i];
10255
+ const targetType = state.fanIns[i].type;
10256
+ if (targetType === "UFI" && fi.type === "FI") {
10257
+ fi.convertToUFI();
10258
+ }
10259
+ }
10260
+ }
10261
+ /**
10262
+ * Main planning algorithm using exhaustive join flip enumeration.
10263
+ *
10264
+ * Enumerates all possible flip patterns for flippable joins (2^n for n flippable joins).
10265
+ * Each pattern represents a different query execution plan. We evaluate the cost of each
10266
+ * plan and select the one with the lowest cost.
10267
+ *
10268
+ * Connections are used only for cost estimation - the flip patterns determine the plan.
10269
+ * FanOut/FanIn states (FO/UFO and FI/UFI) are automatically derived from join flip states.
10270
+ *
10271
+ * @param planDebugger - Optional debugger to receive structured events during planning
10272
+ */
10273
+ plan(planDebugger) {
10274
+ const flippableJoins = this.joins.filter((j) => j.isFlippable());
10275
+ if (flippableJoins.length > MAX_FLIPPABLE_JOINS) {
10276
+ throw new Error(
10277
+ `Query has ${flippableJoins.length} EXISTS checks in a single RELATED call (or in the top level query), which would require ${2 ** flippableJoins.length} plan evaluations. This may be very slow. Consider simplifying the query or increasing MAX_FLIPPABLE_JOINS (currently set to ${MAX_FLIPPABLE_JOINS}).`
10278
+ );
10279
+ }
10280
+ const fofiCache = buildFOFICache(this);
10281
+ const numPatterns = 2 ** flippableJoins.length;
10282
+ let bestCost = Infinity;
10283
+ let bestPlan = void 0;
10284
+ let bestAttemptNumber = -1;
10285
+ for (let pattern = 0; pattern < numPatterns; pattern++) {
10286
+ this.resetPlanningState();
10287
+ if (planDebugger) {
10288
+ planDebugger.log({
10289
+ type: "attempt-start",
10290
+ attemptNumber: pattern,
10291
+ totalAttempts: numPatterns
10292
+ });
10293
+ }
10294
+ try {
10295
+ for (let i = 0; i < flippableJoins.length; i++) {
10296
+ if (pattern & 1 << i) {
10297
+ flippableJoins[i].flip();
10298
+ }
10299
+ }
10300
+ checkAndConvertFOFI(fofiCache);
10301
+ propagateUnlimitForFlippedJoins(this);
10302
+ this.propagateConstraints();
10303
+ if (planDebugger) {
10304
+ planDebugger.log({
10305
+ type: "constraints-propagated",
10306
+ attemptNumber: pattern,
10307
+ connectionConstraints: this.connections.map((c) => ({
10308
+ connection: c.name,
10309
+ constraints: c.getConstraintsForDebug(),
10310
+ constraintCosts: c.getConstraintCostsForDebug()
10311
+ }))
10312
+ });
10313
+ }
10314
+ const totalCost = this.getTotalCost();
10315
+ if (planDebugger) {
10316
+ planDebugger.log({
10317
+ type: "plan-complete",
10318
+ attemptNumber: pattern,
10319
+ totalCost,
10320
+ nodeCosts: this.#collectNodeCosts(),
10321
+ joinStates: this.joins.map((j) => {
10322
+ const info = j.getDebugInfo();
10323
+ return {
10324
+ join: info.name,
10325
+ type: info.type
10326
+ };
10327
+ })
10328
+ });
10329
+ }
10330
+ if (totalCost < bestCost) {
10331
+ bestCost = totalCost;
10332
+ bestPlan = this.capturePlanningSnapshot();
10333
+ bestAttemptNumber = pattern;
10334
+ }
10335
+ } catch (e) {
10336
+ if (planDebugger) {
10337
+ planDebugger.log({
10338
+ type: "plan-failed",
10339
+ attemptNumber: pattern,
10340
+ reason: `Flip pattern ${pattern.toString(2)} failed: ${e instanceof Error ? e.message : String(e)}`
10341
+ });
10342
+ }
10343
+ continue;
10344
+ }
10345
+ }
10346
+ if (bestPlan) {
10347
+ this.restorePlanningSnapshot(bestPlan);
10348
+ this.propagateConstraints();
10349
+ if (planDebugger) {
10350
+ planDebugger.log({
10351
+ type: "best-plan-selected",
10352
+ bestAttemptNumber,
10353
+ totalCost: bestCost,
10354
+ joinStates: this.joins.map((j) => ({
10355
+ join: j.getName(),
10356
+ type: j.type
10357
+ }))
10358
+ });
10359
+ }
10360
+ } else {
10361
+ throw new Error(
10362
+ "No valid query plan found. This should not happen - check query structure."
10363
+ );
10364
+ }
10365
+ }
10366
+ };
10367
+ function buildFOFICache(graph) {
10368
+ const cache = /* @__PURE__ */ new Map();
10369
+ for (const fo of graph.fanOuts) {
10370
+ const info = findFIAndJoins(fo);
10371
+ cache.set(fo, info);
10372
+ }
10373
+ return cache;
10374
+ }
10375
+ function checkAndConvertFOFI(fofiCache) {
10376
+ for (const [fo, info] of fofiCache) {
10377
+ const hasFlippedJoin = info.joinsBetween.some((j) => j.type === "flipped");
10378
+ if (info.fi && hasFlippedJoin) {
10379
+ fo.convertToUFO();
10380
+ info.fi.convertToUFI();
10381
+ }
10382
+ }
10383
+ }
10384
+ function findFIAndJoins(fo) {
10385
+ const joinsBetween = [];
10386
+ let fi = void 0;
10387
+ const queue = [...fo.outputs];
10388
+ const visited = /* @__PURE__ */ new Set();
10389
+ while (queue.length > 0) {
10390
+ const node = must(queue.shift());
10391
+ if (visited.has(node)) continue;
10392
+ visited.add(node);
10393
+ switch (node.kind) {
10394
+ case "join":
10395
+ joinsBetween.push(node);
10396
+ queue.push(node.output);
10397
+ break;
10398
+ case "fan-out":
10399
+ queue.push(...node.outputs);
10400
+ break;
10401
+ case "fan-in":
10402
+ fi = node;
10403
+ break;
10404
+ case "connection":
10405
+ break;
10406
+ case "terminus":
10407
+ break;
10408
+ }
10409
+ }
10410
+ return { fi, joinsBetween };
10411
+ }
10412
+ function propagateUnlimitForFlippedJoins(graph) {
10413
+ for (const join of graph.joins) {
10414
+ if (join.type === "flipped") {
10415
+ join.propagateUnlimit();
10416
+ }
10417
+ }
10418
+ }
10419
+
10420
+ // ../zql/src/planner/planner-join.ts
10421
+ var SEMI_JOIN_OVERHEAD_MULTIPLIER = 1.5;
10422
+ var PlannerJoin = class {
10423
+ kind = "join";
10424
+ #parent;
10425
+ #child;
10426
+ #parentConstraint;
10427
+ #childConstraint;
10428
+ #flippable;
10429
+ planId;
10430
+ #output;
10431
+ // Set once during graph construction
10432
+ // Reset between planning attempts
10433
+ #type;
10434
+ constructor(parent, child, parentConstraint, childConstraint, flippable, planId) {
10435
+ this.#type = "semi";
10436
+ this.#parent = parent;
10437
+ this.#child = child;
10438
+ this.#childConstraint = childConstraint;
10439
+ this.#parentConstraint = parentConstraint;
10440
+ this.#flippable = flippable;
10441
+ this.planId = planId;
10442
+ }
10443
+ setOutput(node) {
10444
+ this.#output = node;
10445
+ }
10446
+ get output() {
10447
+ assert(this.#output !== void 0, "Output not set");
10448
+ return this.#output;
10449
+ }
10450
+ closestJoinOrSource() {
10451
+ return "join";
10452
+ }
10453
+ flipIfNeeded(input) {
10454
+ if (input === this.#child) {
10455
+ this.flip();
10456
+ } else {
10457
+ assert(
10458
+ input === this.#parent,
10459
+ "Can only flip a join from one of its inputs"
10460
+ );
10461
+ }
10462
+ }
10463
+ flip() {
10464
+ assert(this.#type === "semi", "Can only flip a semi-join");
10465
+ if (!this.#flippable) {
10466
+ throw new UnflippableJoinError(
10467
+ "Cannot flip a non-flippable join (e.g., NOT EXISTS)"
10468
+ );
10469
+ }
10470
+ this.#type = "flipped";
10471
+ }
10472
+ get type() {
10473
+ return this.#type;
10474
+ }
10475
+ isFlippable() {
10476
+ return this.#flippable;
10477
+ }
10478
+ /**
10479
+ * Propagate unlimiting through the child subgraph when this join is flipped.
10480
+ * When a join is flipped, the child becomes the outer loop and should produce
10481
+ * all rows rather than stopping at an EXISTS limit.
10482
+ *
10483
+ * Propagation rules:
10484
+ * - Connection: call unlimit()
10485
+ * - Semi-join: continue to parent (outer loop)
10486
+ * - Flipped join: stop (already unlimited when it was flipped)
10487
+ * - Fan-out/Fan-in: propagate to all inputs
10488
+ */
10489
+ propagateUnlimit() {
10490
+ assert(this.#type === "flipped", "Can only unlimit a flipped join");
10491
+ propagateUnlimitToNode(this.#child);
10492
+ }
10493
+ /**
10494
+ * Called when a parent join is flipped and this join is part of its child subgraph.
10495
+ * - Semi-join: continue propagation to parent (the outer loop)
10496
+ * - Flipped join: stop propagation (already unlimited when it was flipped)
10497
+ */
10498
+ propagateUnlimitFromFlippedJoin() {
10499
+ if (this.#type === "semi") {
10500
+ propagateUnlimitToNode(this.#parent);
10501
+ }
10502
+ }
10503
+ propagateConstraints(branchPattern, constraint) {
10504
+ if (this.#type === "semi") {
10505
+ this.#child.propagateConstraints(
10506
+ branchPattern,
10507
+ this.#childConstraint,
10508
+ this
10509
+ );
10510
+ this.#parent.propagateConstraints(branchPattern, constraint, this);
10511
+ } else if (this.#type === "flipped") {
10512
+ this.#child.propagateConstraints(branchPattern, void 0, this);
10513
+ this.#parent.propagateConstraints(
10514
+ branchPattern,
10515
+ mergeConstraints(constraint, this.#parentConstraint),
10516
+ this
10517
+ );
10518
+ }
10519
+ }
10520
+ reset() {
10521
+ this.#type = "semi";
10522
+ }
10523
+ estimateCost(branchPattern) {
10524
+ const parentCost = this.#parent.estimateCost(branchPattern);
10525
+ const childCost = this.#child.estimateCost(branchPattern);
10526
+ let scanEst = parentCost.rows;
10527
+ if (this.#type === "semi" && parentCost.limit !== void 0) {
10528
+ if (childCost.selectivity !== 0) {
10529
+ scanEst = Math.min(scanEst, parentCost.limit / childCost.selectivity);
10530
+ }
10531
+ }
10532
+ if (this.#parent.closestJoinOrSource() === "join") {
10533
+ const pipelineCost = this.#type === "flipped" ? childCost.startupCost + childCost.runningCost * (parentCost.startupCost + parentCost.runningCost) : parentCost.runningCost + SEMI_JOIN_OVERHEAD_MULTIPLIER * scanEst * (childCost.startupCost + childCost.runningCost);
10534
+ return {
10535
+ rows: parentCost.rows,
10536
+ runningCost: pipelineCost,
10537
+ startupCost: parentCost.startupCost,
10538
+ selectivity: parentCost.selectivity,
10539
+ limit: parentCost.limit
10540
+ };
10541
+ }
10542
+ const nestedLoopCost = this.#type === "flipped" ? childCost.runningCost * (parentCost.startupCost + parentCost.runningCost) : SEMI_JOIN_OVERHEAD_MULTIPLIER * scanEst * (childCost.startupCost + childCost.runningCost);
10543
+ return {
10544
+ rows: parentCost.rows,
10545
+ runningCost: nestedLoopCost,
10546
+ startupCost: parentCost.startupCost,
10547
+ selectivity: parentCost.selectivity,
10548
+ limit: parentCost.limit
10549
+ };
10550
+ }
10551
+ /**
10552
+ * Get a human-readable name for this join for debugging.
10553
+ * Format: "parentName ⋈ childName"
10554
+ */
10555
+ getName() {
10556
+ const parentName = getNodeName(this.#parent);
10557
+ const childName = getNodeName(this.#child);
10558
+ return `${parentName} \u22C8 ${childName}`;
10559
+ }
10560
+ /**
10561
+ * Get debug information about this join's state.
10562
+ */
10563
+ getDebugInfo() {
10564
+ return {
10565
+ name: this.getName(),
10566
+ type: this.#type,
10567
+ planId: this.planId
10568
+ };
10569
+ }
10570
+ };
10571
+ var UnflippableJoinError = class extends Error {
10572
+ constructor(message) {
10573
+ super(message);
10574
+ this.name = "UnflippableJoinError";
10575
+ }
10576
+ };
10577
+ function getNodeName(node) {
10578
+ switch (node.kind) {
10579
+ case "connection":
10580
+ return node.name;
10581
+ case "join":
10582
+ return node.getName();
10583
+ case "fan-out":
10584
+ return "FO";
10585
+ case "fan-in":
10586
+ return "FI";
10587
+ case "terminus":
10588
+ return "terminus";
10589
+ }
10590
+ }
10591
+ function propagateUnlimitToNode(node) {
10592
+ if ("propagateUnlimitFromFlippedJoin" in node && typeof node.propagateUnlimitFromFlippedJoin === "function") {
10593
+ node.propagateUnlimitFromFlippedJoin();
10594
+ }
10595
+ }
10596
+
10597
+ // ../zql/src/planner/planner-terminus.ts
10598
+ var PlannerTerminus = class {
10599
+ kind = "terminus";
10600
+ #input;
10601
+ constructor(input) {
10602
+ this.#input = input;
10603
+ }
10604
+ get pinned() {
10605
+ return true;
10606
+ }
10607
+ closestJoinOrSource() {
10608
+ return this.#input.closestJoinOrSource();
10609
+ }
10610
+ propagateConstraints() {
10611
+ this.#input.propagateConstraints([], void 0, this);
10612
+ }
10613
+ estimateCost() {
10614
+ return this.#input.estimateCost([]);
10615
+ }
10616
+ /**
10617
+ * Propagate unlimiting when a parent join is flipped.
10618
+ * Terminus doesn't participate in unlimiting.
10619
+ */
10620
+ propagateUnlimitFromFlippedJoin() {
10621
+ }
10622
+ };
10623
+
10624
+ // ../zql/src/planner/planner-builder.ts
10625
+ function wireOutput(from, to) {
10626
+ switch (from.kind) {
10627
+ case "connection":
10628
+ case "join":
10629
+ case "fan-in":
10630
+ from.setOutput(to);
10631
+ break;
10632
+ case "fan-out":
10633
+ from.addOutput(to);
10634
+ break;
10635
+ case "terminus":
10636
+ assert(false, "Terminus nodes cannot have outputs");
10637
+ }
10638
+ }
10639
+ function buildPlanGraph(ast, model, baseConstraints) {
10640
+ const graph = new PlannerGraph();
10641
+ let nextPlanId = 0;
10642
+ const source = graph.addSource(ast.table, model);
10643
+ const connection = source.connect(
10644
+ ast.orderBy ?? [],
10645
+ ast.where,
10646
+ baseConstraints,
10647
+ ast.limit
10648
+ );
10649
+ graph.connections.push(connection);
10650
+ let end = connection;
10651
+ if (ast.where) {
10652
+ end = processCondition(
10653
+ ast.where,
10654
+ end,
10655
+ graph,
10656
+ model,
10657
+ ast.table,
10658
+ () => nextPlanId++
10659
+ );
10660
+ }
10661
+ const terminus = new PlannerTerminus(end);
10662
+ wireOutput(end, terminus);
10663
+ graph.setTerminus(terminus);
10664
+ const subPlans = {};
10665
+ if (ast.related) {
10666
+ for (const csq of ast.related) {
10667
+ const alias = must(
10668
+ csq.subquery.alias,
10669
+ "Related subquery must have alias"
10670
+ );
10671
+ const childConstraints = extractConstraint(
10672
+ csq.correlation.childField,
10673
+ csq.subquery.table
10674
+ );
10675
+ subPlans[alias] = buildPlanGraph(csq.subquery, model, childConstraints);
10676
+ }
10677
+ }
10678
+ return { plan: graph, subPlans };
10679
+ }
10680
+ function processCondition(condition, input, graph, model, parentTable, getPlanId) {
10681
+ switch (condition.type) {
10682
+ case "simple":
10683
+ return input;
10684
+ case "and":
10685
+ return processAnd(condition, input, graph, model, parentTable, getPlanId);
10686
+ case "or":
10687
+ return processOr(condition, input, graph, model, parentTable, getPlanId);
10688
+ case "correlatedSubquery":
10689
+ return processCorrelatedSubquery(
10690
+ condition,
10691
+ input,
10692
+ graph,
10693
+ model,
10694
+ parentTable,
10695
+ getPlanId
10696
+ );
10697
+ }
10698
+ }
10699
+ function processAnd(condition, input, graph, model, parentTable, getPlanId) {
10700
+ let end = input;
10701
+ for (const subCondition of condition.conditions) {
10702
+ end = processCondition(
10703
+ subCondition,
10704
+ end,
10705
+ graph,
10706
+ model,
10707
+ parentTable,
10708
+ getPlanId
10709
+ );
10710
+ }
10711
+ return end;
10712
+ }
10713
+ function processOr(condition, input, graph, model, parentTable, getPlanId) {
10714
+ const subqueryConditions = condition.conditions.filter(
10715
+ (c) => c.type === "correlatedSubquery" || hasCorrelatedSubquery(c)
10716
+ );
10717
+ if (subqueryConditions.length === 0) {
10718
+ return input;
10719
+ }
10720
+ const fanOut = new PlannerFanOut(input);
10721
+ graph.fanOuts.push(fanOut);
10722
+ wireOutput(input, fanOut);
10723
+ const branches = [];
10724
+ for (const subCondition of subqueryConditions) {
10725
+ const branch = processCondition(
10726
+ subCondition,
10727
+ fanOut,
10728
+ graph,
10729
+ model,
10730
+ parentTable,
10731
+ getPlanId
10732
+ );
10733
+ branches.push(branch);
10734
+ fanOut.addOutput(branch);
10735
+ }
10736
+ const fanIn = new PlannerFanIn(branches);
10737
+ graph.fanIns.push(fanIn);
10738
+ for (const branch of branches) {
10739
+ wireOutput(branch, fanIn);
10740
+ }
10741
+ return fanIn;
10742
+ }
10743
+ function processCorrelatedSubquery(condition, input, graph, model, parentTable, getPlanId) {
10744
+ const { related } = condition;
10745
+ const childTable = related.subquery.table;
10746
+ const childSource = graph.hasSource(childTable) ? graph.getSource(childTable) : graph.addSource(childTable, model);
10747
+ const childConnection = childSource.connect(
10748
+ related.subquery.orderBy ?? [],
10749
+ related.subquery.where,
10750
+ void 0,
10751
+ // no base constraints for EXISTS/NOT EXISTS
10752
+ condition.op === "EXISTS" ? 1 : void 0
10753
+ );
10754
+ graph.connections.push(childConnection);
10755
+ let childEnd = childConnection;
10756
+ if (related.subquery.where) {
10757
+ childEnd = processCondition(
10758
+ related.subquery.where,
10759
+ childEnd,
10760
+ graph,
10761
+ model,
10762
+ childTable,
10763
+ getPlanId
10764
+ );
10765
+ }
10766
+ const parentConstraint = extractConstraint(
10767
+ related.correlation.parentField,
10768
+ parentTable
10769
+ );
10770
+ const childConstraint = extractConstraint(
10771
+ related.correlation.childField,
10772
+ childTable
10773
+ );
10774
+ const planId = getPlanId();
10775
+ condition[planIdSymbol] = planId;
10776
+ const join = new PlannerJoin(
10777
+ input,
10778
+ childEnd,
10779
+ parentConstraint,
10780
+ childConstraint,
10781
+ condition.op !== "NOT EXISTS",
10782
+ planId
10783
+ );
10784
+ graph.joins.push(join);
10785
+ wireOutput(input, join);
10786
+ wireOutput(childEnd, join);
10787
+ return join;
10788
+ }
10789
+ function hasCorrelatedSubquery(condition) {
10790
+ if (condition.type === "correlatedSubquery") {
10791
+ return true;
10792
+ }
10793
+ if (condition.type === "and" || condition.type === "or") {
10794
+ return condition.conditions.some(hasCorrelatedSubquery);
10795
+ }
10796
+ return false;
10797
+ }
10798
+ function extractConstraint(fields, _tableName) {
10799
+ return Object.fromEntries(fields.map((field) => [field, void 0]));
10800
+ }
10801
+ function planRecursively(plans, planDebugger) {
10802
+ for (const subPlan of Object.values(plans.subPlans)) {
10803
+ planRecursively(subPlan, planDebugger);
10804
+ }
10805
+ plans.plan.plan(planDebugger);
10806
+ }
10807
+ function planQuery(ast, model, planDebugger) {
10808
+ const plans = buildPlanGraph(ast, model);
10809
+ planRecursively(plans, planDebugger);
10810
+ return applyPlansToAST(ast, plans);
10811
+ }
10812
+ function applyToCondition(condition, flippedIds) {
10813
+ if (condition.type === "simple") {
10814
+ return condition;
10815
+ }
10816
+ if (condition.type === "correlatedSubquery") {
10817
+ const planId = condition[planIdSymbol];
10818
+ const shouldFlip = planId !== void 0 && flippedIds.has(planId);
10819
+ return {
10820
+ ...condition,
10821
+ flip: shouldFlip ? true : condition.flip,
10822
+ related: {
10823
+ ...condition.related,
10824
+ subquery: {
10825
+ ...condition.related.subquery,
10826
+ where: condition.related.subquery.where ? applyToCondition(condition.related.subquery.where, flippedIds) : void 0
10827
+ }
10828
+ }
10829
+ };
10830
+ }
10831
+ return {
10832
+ ...condition,
10833
+ conditions: condition.conditions.map((c) => applyToCondition(c, flippedIds))
10834
+ };
10835
+ }
10836
+ function applyPlansToAST(ast, plans) {
10837
+ const flippedIds = /* @__PURE__ */ new Set();
10838
+ for (const join of plans.plan.joins) {
10839
+ if (join.type === "flipped" && join.planId !== void 0) {
10840
+ flippedIds.add(join.planId);
10841
+ }
10842
+ }
10843
+ return {
10844
+ ...ast,
10845
+ where: ast.where ? applyToCondition(ast.where, flippedIds) : void 0,
10846
+ related: ast.related?.map((csq) => {
10847
+ const alias = must(
10848
+ csq.subquery.alias,
10849
+ "Related subquery must have alias"
10850
+ );
10851
+ const subPlan = plans.subPlans[alias];
10852
+ return {
10853
+ ...csq,
10854
+ subquery: subPlan ? applyPlansToAST(csq.subquery, subPlan) : csq.subquery
10855
+ };
10856
+ })
10857
+ };
10858
+ }
10859
+
10860
+ // ../zql/src/query/expression.ts
10861
+ var ExpressionBuilder = class {
10862
+ #exists;
10863
+ constructor(exists) {
10864
+ this.#exists = exists;
10865
+ this.exists = this.exists.bind(this);
10866
+ }
10867
+ get eb() {
10868
+ return this;
10869
+ }
10870
+ cmp(field, opOrValue, value) {
10871
+ return cmp(field, opOrValue, value);
10872
+ }
10873
+ cmpLit(left, op, right) {
10874
+ return {
10875
+ type: "simple",
10876
+ left: isParameterReference(left) ? left[toStaticParam]() : { type: "literal", value: left },
10877
+ right: isParameterReference(right) ? right[toStaticParam]() : { type: "literal", value: right },
10878
+ op
10879
+ };
10880
+ }
10881
+ and = and;
10882
+ or = or;
10883
+ not = not;
10884
+ exists = (relationship, cb, options) => this.#exists(relationship, cb, options);
10885
+ };
10886
+ function and(...conditions) {
10887
+ const expressions = filterTrue(filterUndefined(conditions));
10888
+ if (expressions.length === 1) {
10889
+ return expressions[0];
10890
+ }
10891
+ if (expressions.some(isAlwaysFalse)) {
10892
+ return FALSE;
10893
+ }
10894
+ return { type: "and", conditions: expressions };
10895
+ }
10896
+ function or(...conditions) {
10897
+ const expressions = filterFalse(filterUndefined(conditions));
10898
+ if (expressions.length === 1) {
10899
+ return expressions[0];
10900
+ }
10901
+ if (expressions.some(isAlwaysTrue)) {
10902
+ return TRUE;
10903
+ }
10904
+ return { type: "or", conditions: expressions };
10905
+ }
10906
+ function not(expression) {
10907
+ switch (expression.type) {
10908
+ case "and":
10909
+ return {
10910
+ type: "or",
10911
+ conditions: expression.conditions.map(not)
10912
+ };
10913
+ case "or":
10914
+ return {
10915
+ type: "and",
10916
+ conditions: expression.conditions.map(not)
10917
+ };
10918
+ case "correlatedSubquery":
10919
+ return {
10920
+ type: "correlatedSubquery",
10921
+ related: expression.related,
10922
+ op: negateOperator(expression.op)
10923
+ };
10924
+ case "simple":
10925
+ return {
10926
+ type: "simple",
10927
+ op: negateOperator(expression.op),
10928
+ left: expression.left,
10929
+ right: expression.right
10930
+ };
10931
+ }
10932
+ }
10933
+ function cmp(field, opOrValue, value) {
10934
+ let op;
10935
+ if (value === void 0) {
10936
+ value = opOrValue;
10937
+ op = "=";
10938
+ } else {
10939
+ op = opOrValue;
10940
+ }
10941
+ return {
10942
+ type: "simple",
10943
+ left: { type: "column", name: field },
10944
+ right: isParameterReference(value) ? value[toStaticParam]() : { type: "literal", value },
10945
+ op
10946
+ };
10947
+ }
10948
+ function isParameterReference(value) {
10949
+ return value !== null && typeof value === "object" && value[toStaticParam];
10950
+ }
10951
+ var TRUE = {
10952
+ type: "and",
10953
+ conditions: []
10954
+ };
10955
+ var FALSE = {
10956
+ type: "or",
10957
+ conditions: []
10958
+ };
10959
+ function isAlwaysTrue(condition) {
10960
+ return condition.type === "and" && condition.conditions.length === 0;
10961
+ }
10962
+ function isAlwaysFalse(condition) {
10963
+ return condition.type === "or" && condition.conditions.length === 0;
10964
+ }
10965
+ function simplifyCondition(c) {
10966
+ if (c.type === "simple" || c.type === "correlatedSubquery") {
10967
+ return c;
10968
+ }
10969
+ if (c.conditions.length === 1) {
10970
+ return simplifyCondition(c.conditions[0]);
10971
+ }
10972
+ const conditions = flatten(c.type, c.conditions.map(simplifyCondition));
10973
+ if (c.type === "and" && conditions.some(isAlwaysFalse)) {
10974
+ return FALSE;
10975
+ }
10976
+ if (c.type === "or" && conditions.some(isAlwaysTrue)) {
10977
+ return TRUE;
10978
+ }
10979
+ return {
10980
+ type: c.type,
10981
+ conditions
10982
+ };
10983
+ }
10984
+ function flatten(type, conditions) {
10985
+ const flattened = [];
10986
+ for (const c of conditions) {
10987
+ if (c.type === type) {
10988
+ flattened.push(...c.conditions);
10989
+ } else {
10990
+ flattened.push(c);
10991
+ }
10992
+ }
10993
+ return flattened;
10994
+ }
10995
+ var negateSimpleOperatorMap = {
10996
+ ["="]: "!=",
10997
+ ["!="]: "=",
10998
+ ["<"]: ">=",
10999
+ [">"]: "<=",
11000
+ [">="]: "<",
11001
+ ["<="]: ">",
11002
+ ["IN"]: "NOT IN",
11003
+ ["NOT IN"]: "IN",
11004
+ ["LIKE"]: "NOT LIKE",
11005
+ ["NOT LIKE"]: "LIKE",
11006
+ ["ILIKE"]: "NOT ILIKE",
11007
+ ["NOT ILIKE"]: "ILIKE",
11008
+ ["IS"]: "IS NOT",
11009
+ ["IS NOT"]: "IS"
11010
+ };
11011
+ var negateOperatorMap = {
11012
+ ...negateSimpleOperatorMap,
11013
+ ["EXISTS"]: "NOT EXISTS",
11014
+ ["NOT EXISTS"]: "EXISTS"
11015
+ };
11016
+ function negateOperator(op) {
11017
+ return must(negateOperatorMap[op]);
11018
+ }
11019
+ function filterUndefined(array10) {
11020
+ return array10.filter((e) => e !== void 0);
11021
+ }
11022
+ function filterTrue(conditions) {
11023
+ return conditions.filter((c) => !isAlwaysTrue(c));
11024
+ }
11025
+ function filterFalse(conditions) {
11026
+ return conditions.filter((c) => !isAlwaysFalse(c));
11027
+ }
11028
+
11029
+ // ../zql/src/builder/like.ts
9475
11030
  function getLikePredicate(pattern, flags) {
9476
11031
  const op = getLikeOp(String(pattern), flags);
9477
11032
  return (lhs) => {
@@ -9666,8 +11221,11 @@ function transformFilters(filters) {
9666
11221
  }
9667
11222
 
9668
11223
  // ../zql/src/builder/builder.ts
9669
- function buildPipeline(ast, delegate, queryID) {
11224
+ function buildPipeline(ast, delegate, queryID, costModel) {
9670
11225
  ast = delegate.mapAst ? delegate.mapAst(ast) : ast;
11226
+ if (costModel) {
11227
+ ast = planQuery(ast, costModel);
11228
+ }
9671
11229
  return buildPipelineInternal(ast, delegate, queryID, "");
9672
11230
  }
9673
11231
  var EXISTS_LIMIT = 3;
@@ -11094,25 +12652,47 @@ var MockClientLockManager = class {
11094
12652
  }
11095
12653
  };
11096
12654
 
11097
- // ../zero-client/src/client/connection-manager.ts
11098
- import { resolver as resolver9 } from "@rocicorp/resolver";
11099
-
11100
- // ../zero-client/src/client/connection-status-enum.ts
11101
- var connection_status_enum_exports = {};
11102
- __export(connection_status_enum_exports, {
11103
- Closed: () => Closed,
11104
- Connected: () => Connected,
11105
- Connecting: () => Connecting,
11106
- Disconnected: () => Disconnected
11107
- });
11108
- var Disconnected = "disconnected";
11109
- var Connecting = "connecting";
11110
- var Connected = "connected";
11111
- var Closed = "closed";
11112
-
12655
+ // ../zero-client/src/client/connection-manager.ts
12656
+ import { resolver as resolver9 } from "@rocicorp/resolver";
12657
+
12658
+ // ../shared/src/subscribable.ts
12659
+ var Subscribable = class {
12660
+ _listeners = /* @__PURE__ */ new Set();
12661
+ /**
12662
+ * Subscribe to the subscribable.
12663
+ *
12664
+ * @param listener - The listener to subscribe to.
12665
+ * @returns A function to unsubscribe from the subscribable.
12666
+ */
12667
+ subscribe = (listener) => {
12668
+ this._listeners.add(listener);
12669
+ return () => {
12670
+ this._listeners.delete(listener);
12671
+ };
12672
+ };
12673
+ /**
12674
+ * Notify all listeners.
12675
+ *
12676
+ * @param update - The update to notify listeners with.
12677
+ */
12678
+ notify = (update) => {
12679
+ this._listeners.forEach((listener) => listener(update));
12680
+ };
12681
+ hasListeners = () => this._listeners.size > 0;
12682
+ /**
12683
+ * Unsubscribe all listeners.
12684
+ */
12685
+ cleanup = () => {
12686
+ this._listeners.clear();
12687
+ };
12688
+ };
12689
+
11113
12690
  // ../zero-client/src/client/connection-manager.ts
11114
12691
  var DEFAULT_TIMEOUT_CHECK_INTERVAL_MS = 1e3;
11115
- var ConnectionManager = class extends Subscribable {
12692
+ var TERMINAL_STATES = [
12693
+ connection_status_enum_exports.Error
12694
+ ];
12695
+ var ConnectionManager = class _ConnectionManager extends Subscribable {
11116
12696
  #state;
11117
12697
  /**
11118
12698
  * The timestamp when we first started trying to connect.
@@ -11160,14 +12740,34 @@ var ConnectionManager = class extends Subscribable {
11160
12740
  is(status) {
11161
12741
  return this.#state.name === status;
11162
12742
  }
12743
+ /**
12744
+ * Returns true if the current state is a terminal state
12745
+ * that can be recovered from by calling connect().
12746
+ */
12747
+ isInTerminalState() {
12748
+ return _ConnectionManager.isTerminalState(this.#state);
12749
+ }
12750
+ /**
12751
+ * Returns true if the given status is a terminal state
12752
+ * that can be recovered from by calling connect().
12753
+ */
12754
+ static isTerminalState(state) {
12755
+ return TERMINAL_STATES.includes(
12756
+ state.name
12757
+ );
12758
+ }
11163
12759
  /**
11164
12760
  * Returns true if the run loop should continue.
11165
- * The run loop continues in disconnected, connecting, and connected states.
12761
+ * The run loop continues in disconnected, connecting, connected, and error states.
11166
12762
  * It stops in closed state.
11167
12763
  */
11168
12764
  shouldContinueRunLoop() {
11169
12765
  return this.#state.name !== connection_status_enum_exports.Closed;
11170
12766
  }
12767
+ /**
12768
+ * Waits for the next state change.
12769
+ * @returns A promise that resolves when the next state change occurs.
12770
+ */
11171
12771
  waitForStateChange() {
11172
12772
  return this.#nextStatePromise();
11173
12773
  }
@@ -11259,29 +12859,55 @@ var ConnectionManager = class extends Subscribable {
11259
12859
  return { nextStatePromise };
11260
12860
  }
11261
12861
  /**
11262
- * Transition to closed state.
11263
- * This is terminal - no further transitions are allowed.
12862
+ * Transition to error state.
12863
+ * This pauses the run loop until connect() is called.
12864
+ * Resets the 5-minute retry window and attempt counter.
11264
12865
  *
11265
12866
  * @returns An object containing a promise that resolves on the next state change.
11266
12867
  */
11267
- closed() {
12868
+ error(reason) {
11268
12869
  if (this.#state.name === connection_status_enum_exports.Closed) {
11269
12870
  return { nextStatePromise: this.#nextStatePromise() };
11270
12871
  }
12872
+ if (this.#state.name === connection_status_enum_exports.Error) {
12873
+ return { nextStatePromise: this.#nextStatePromise() };
12874
+ }
11271
12875
  this.#connectingStartedAt = void 0;
11272
12876
  this.#maybeStopTimeoutInterval();
11273
12877
  this.#state = {
11274
- name: connection_status_enum_exports.Closed
12878
+ name: connection_status_enum_exports.Error,
12879
+ reason
11275
12880
  };
11276
12881
  const nextStatePromise = this.#publishStateAndGetPromise();
11277
12882
  return { nextStatePromise };
11278
12883
  }
12884
+ /**
12885
+ * Transition to closed state.
12886
+ * This is terminal - no further transitions are allowed.
12887
+ */
12888
+ closed() {
12889
+ if (this.#state.name === connection_status_enum_exports.Closed) {
12890
+ return;
12891
+ }
12892
+ this.#connectingStartedAt = void 0;
12893
+ this.#maybeStopTimeoutInterval();
12894
+ this.#state = {
12895
+ name: connection_status_enum_exports.Closed,
12896
+ reason: new ClientError({
12897
+ kind: client_error_kind_enum_exports.ClientClosed,
12898
+ message: "Zero was explicitly closed by calling zero.close()"
12899
+ })
12900
+ };
12901
+ this.#publishState();
12902
+ this.cleanup();
12903
+ return;
12904
+ }
11279
12905
  cleanup = () => {
11280
12906
  this._listeners.clear();
11281
12907
  this.#resolveNextStateWaiters();
11282
12908
  };
11283
12909
  #resolveNextStateWaiters() {
11284
- this.#stateChangeResolver.resolve();
12910
+ this.#stateChangeResolver.resolve(this.#state);
11285
12911
  this.#stateChangeResolver = resolver9();
11286
12912
  }
11287
12913
  #publishState() {
@@ -11305,7 +12931,12 @@ var ConnectionManager = class extends Subscribable {
11305
12931
  }
11306
12932
  const now = Date.now();
11307
12933
  if (now >= this.#state.disconnectAt) {
11308
- this.disconnected();
12934
+ this.disconnected(
12935
+ new ClientError({
12936
+ kind: client_error_kind_enum_exports.DisconnectTimeout,
12937
+ message: `Zero was unable to connect for ${Math.floor(this.#disconnectTimeoutMs / 1e3)} seconds and was disconnected`
12938
+ })
12939
+ );
11309
12940
  return true;
11310
12941
  }
11311
12942
  return false;
@@ -11326,6 +12957,56 @@ var ConnectionManager = class extends Subscribable {
11326
12957
  this.#timeoutInterval = void 0;
11327
12958
  }
11328
12959
  };
12960
+ var throwIfConnectionError = (state) => {
12961
+ if (ConnectionManager.isTerminalState(state) || state.name === connection_status_enum_exports.Closed || (state.name === connection_status_enum_exports.Connecting || state.name === connection_status_enum_exports.Disconnected) && state.reason) {
12962
+ if (isClientError(state.reason) && (state.reason.kind === client_error_kind_enum_exports.ConnectTimeout || state.reason.kind === client_error_kind_enum_exports.AbruptClose || state.reason.kind === client_error_kind_enum_exports.CleanClose)) {
12963
+ return;
12964
+ }
12965
+ throw state.reason;
12966
+ }
12967
+ };
12968
+
12969
+ // ../zero-client/src/client/connection.ts
12970
+ var ConnectionImpl = class {
12971
+ #connectionManager;
12972
+ #lc;
12973
+ #source;
12974
+ constructor(connectionManager, lc) {
12975
+ this.#connectionManager = connectionManager;
12976
+ this.#lc = lc;
12977
+ this.#source = new ConnectionSource(connectionManager);
12978
+ }
12979
+ get state() {
12980
+ return this.#source;
12981
+ }
12982
+ async connect() {
12983
+ const lc = this.#lc.withContext("connect");
12984
+ if (!this.#connectionManager.isInTerminalState()) {
12985
+ lc.debug?.(
12986
+ "connect() called but not in a terminal state. Current state:",
12987
+ this.#connectionManager.state.name
12988
+ );
12989
+ return;
12990
+ }
12991
+ lc.info?.(
12992
+ `Resuming connection from state: ${this.#connectionManager.state.name}`
12993
+ );
12994
+ const { nextStatePromise } = this.#connectionManager.connecting();
12995
+ await nextStatePromise;
12996
+ }
12997
+ };
12998
+ var ConnectionSource = class {
12999
+ #connectionManager;
13000
+ constructor(connectionManager) {
13001
+ this.#connectionManager = connectionManager;
13002
+ }
13003
+ get current() {
13004
+ return this.#connectionManager.state;
13005
+ }
13006
+ get subscribe() {
13007
+ return this.#connectionManager.subscribe;
13008
+ }
13009
+ };
11329
13010
 
11330
13011
  // ../zql/src/ivm/memory-storage.ts
11331
13012
  import { compareUTF8 as compareUTF83 } from "compare-utf8";
@@ -13267,7 +14948,7 @@ function makeMessage(message, context, logLevel) {
13267
14948
  }
13268
14949
 
13269
14950
  // ../zero-client/src/client/version.ts
13270
- var version2 = "0.25.0-canary.0";
14951
+ var version2 = "0.25.0-canary.1";
13271
14952
 
13272
14953
  // ../zero-client/src/client/log-options.ts
13273
14954
  var LevelFilterLogSink = class {
@@ -13323,74 +15004,6 @@ function createLogOptions(options, createDatadogLogSink = (options2) => new Data
13323
15004
  };
13324
15005
  }
13325
15006
 
13326
- // ../zero-client/src/client/client-error-kind-enum.ts
13327
- var client_error_kind_enum_exports = {};
13328
- __export(client_error_kind_enum_exports, {
13329
- AbruptClose: () => AbruptClose,
13330
- CleanClose: () => CleanClose,
13331
- ClientClosed: () => ClientClosed,
13332
- ConnectTimeout: () => ConnectTimeout,
13333
- DisconnectTimeout: () => DisconnectTimeout,
13334
- Hidden: () => Hidden,
13335
- NoSocketOrigin: () => NoSocketOrigin,
13336
- PingTimeout: () => PingTimeout,
13337
- UnexpectedBaseCookie: () => UnexpectedBaseCookie
13338
- });
13339
- var AbruptClose = "AbruptClose";
13340
- var CleanClose = "CleanClose";
13341
- var ClientClosed = "ClientClosed";
13342
- var ConnectTimeout = "ConnectTimeout";
13343
- var DisconnectTimeout = "DisconnectTimeout";
13344
- var UnexpectedBaseCookie = "UnexpectedBaseCookie";
13345
- var PingTimeout = "PingTimeout";
13346
- var Hidden = "Hidden";
13347
- var NoSocketOrigin = "NoSocketOrigin";
13348
-
13349
- // ../zero-client/src/client/error.ts
13350
- var BaseError = class extends Error {
13351
- errorBody;
13352
- constructor(errorBody, options) {
13353
- super(errorBody.kind + ": " + errorBody.message, options);
13354
- this.errorBody = errorBody;
13355
- }
13356
- get kind() {
13357
- return this.errorBody.kind;
13358
- }
13359
- };
13360
- var ServerError = class extends BaseError {
13361
- get name() {
13362
- return "ServerError";
13363
- }
13364
- };
13365
- var ClientError = class extends BaseError {
13366
- get name() {
13367
- return "ClientError";
13368
- }
13369
- };
13370
- function isServerError(ex) {
13371
- return ex instanceof ServerError;
13372
- }
13373
- function isAuthError(ex) {
13374
- return isServerError(ex) && isAuthErrorKind(ex.kind);
13375
- }
13376
- function isAuthErrorKind(kind) {
13377
- return kind === error_kind_enum_exports.AuthInvalidated || kind === error_kind_enum_exports.Unauthorized;
13378
- }
13379
- function isBackoffError(ex) {
13380
- if (isServerError(ex)) {
13381
- switch (ex.errorBody.kind) {
13382
- case error_kind_enum_exports.Rebalance:
13383
- case error_kind_enum_exports.Rehome:
13384
- case error_kind_enum_exports.ServerOverloaded:
13385
- return ex.errorBody;
13386
- }
13387
- }
13388
- return void 0;
13389
- }
13390
- function isClientError(ex) {
13391
- return ex instanceof ClientError;
13392
- }
13393
-
13394
15007
  // ../zero-client/src/client/metric-name-enum.ts
13395
15008
  var metric_name_enum_exports = {};
13396
15009
  __export(metric_name_enum_exports, {
@@ -13417,6 +15030,21 @@ function getLastConnectErrorValue(reason) {
13417
15030
  function camelToSnake(kind) {
13418
15031
  return kind.split(/\.?(?=[A-Z])/).join("_").toLowerCase();
13419
15032
  }
15033
+ function shouldReportConnectError(reason) {
15034
+ if (!isClientError(reason)) {
15035
+ return true;
15036
+ }
15037
+ switch (reason.kind) {
15038
+ case client_error_kind_enum_exports.Hidden:
15039
+ case client_error_kind_enum_exports.ClientClosed:
15040
+ case client_error_kind_enum_exports.UserDisconnect:
15041
+ case client_error_kind_enum_exports.CleanClose:
15042
+ case client_error_kind_enum_exports.AbruptClose:
15043
+ return false;
15044
+ default:
15045
+ return true;
15046
+ }
15047
+ }
13420
15048
  var MetricManager = class {
13421
15049
  #reportIntervalMs;
13422
15050
  #host;
@@ -13647,10 +15275,11 @@ var MutationTracker = class {
13647
15275
  #allMutationsAppliedListeners;
13648
15276
  #lc;
13649
15277
  #ackMutations;
15278
+ #onFatalError;
13650
15279
  #clientID;
13651
15280
  #largestOutstandingMutationID;
13652
15281
  #currentMutationID;
13653
- constructor(lc, ackMutations) {
15282
+ constructor(lc, ackMutations, onFatalError) {
13654
15283
  this.#lc = lc.withContext("MutationTracker");
13655
15284
  this.#outstandingMutations = /* @__PURE__ */ new Map();
13656
15285
  this.#ephemeralIDsByMutationID = /* @__PURE__ */ new Map();
@@ -13658,6 +15287,7 @@ var MutationTracker = class {
13658
15287
  this.#largestOutstandingMutationID = 0;
13659
15288
  this.#currentMutationID = 0;
13660
15289
  this.#ackMutations = ackMutations;
15290
+ this.#onFatalError = onFatalError;
13661
15291
  }
13662
15292
  setClientIDAndWatch(clientID, experimentalWatch) {
13663
15293
  assert(this.#clientID === void 0, "clientID already set");
@@ -13745,10 +15375,53 @@ var MutationTracker = class {
13745
15375
  "Received an error response when pushing mutations",
13746
15376
  response
13747
15377
  );
15378
+ const fatalError = this.#fatalErrorFromPushError(response);
15379
+ if (fatalError) {
15380
+ this.#onFatalError(fatalError);
15381
+ }
13748
15382
  } else {
13749
15383
  this.#processPushOk(response);
13750
15384
  }
13751
15385
  }
15386
+ #fatalErrorFromPushError(error) {
15387
+ switch (error.error) {
15388
+ case "unsupportedPushVersion":
15389
+ return new ProtocolError({
15390
+ kind: error_kind_enum_exports.PushFailed,
15391
+ origin: error_origin_enum_exports.ZeroCache,
15392
+ reason: error_reason_enum_exports.Internal,
15393
+ message: `Unsupported push version`,
15394
+ mutationIDs: []
15395
+ });
15396
+ case "unsupportedSchemaVersion":
15397
+ return new ProtocolError({
15398
+ kind: error_kind_enum_exports.PushFailed,
15399
+ origin: error_origin_enum_exports.ZeroCache,
15400
+ reason: error_reason_enum_exports.Internal,
15401
+ message: `Unsupported schema version`,
15402
+ mutationIDs: []
15403
+ });
15404
+ case "http":
15405
+ return new ProtocolError({
15406
+ kind: error_kind_enum_exports.PushFailed,
15407
+ origin: error_origin_enum_exports.ZeroCache,
15408
+ reason: error_reason_enum_exports.HTTP,
15409
+ status: error.status,
15410
+ message: `Fetch from API server returned non-OK status ${error.status}: ${error.details ?? "unknown"}`,
15411
+ mutationIDs: []
15412
+ });
15413
+ case "zeroPusher":
15414
+ return new ProtocolError({
15415
+ kind: error_kind_enum_exports.PushFailed,
15416
+ origin: error_origin_enum_exports.ZeroCache,
15417
+ reason: error_reason_enum_exports.Internal,
15418
+ message: `ZeroPusher error: ${error.details ?? "unknown"}`,
15419
+ mutationIDs: []
15420
+ });
15421
+ default:
15422
+ unreachable(error);
15423
+ }
15424
+ }
13752
15425
  /**
13753
15426
  * DEPRECATED: to be removed when we switch to fully driving
13754
15427
  * mutation resolution via poke.
@@ -13842,6 +15515,17 @@ var MutationTracker = class {
13842
15515
  const entry = this.#outstandingMutations.get(ephemeralID);
13843
15516
  assert(entry && entry.mutationID === mid);
13844
15517
  this.#settleMutation(ephemeralID, entry, "reject", error);
15518
+ if (error.error === "oooMutation") {
15519
+ this.#onFatalError(
15520
+ new ProtocolError({
15521
+ kind: error_kind_enum_exports.InvalidPush,
15522
+ origin: error_origin_enum_exports.Server,
15523
+ reason: error_reason_enum_exports.Internal,
15524
+ message: "Server reported an out-of-order mutation",
15525
+ details: error.details
15526
+ })
15527
+ );
15528
+ }
13845
15529
  }
13846
15530
  #processMutationOk(clientID, mid, result) {
13847
15531
  assert(
@@ -13891,16 +15575,13 @@ var MutationTracker = class {
13891
15575
  }
13892
15576
  };
13893
15577
 
13894
- // ../zero-client/src/client/ping-result-enum.ts
13895
- var TimedOut = 0;
13896
- var Success = 1;
13897
-
13898
15578
  // ../zero-client/src/client/query-manager.ts
13899
15579
  var QueryManager = class {
13900
15580
  #clientID;
13901
15581
  #clientToServer;
13902
15582
  #serverToClient;
13903
15583
  #send;
15584
+ #onFatalError;
13904
15585
  #queries = /* @__PURE__ */ new Map();
13905
15586
  #recentQueriesMaxSize;
13906
15587
  #recentQueries = /* @__PURE__ */ new Set();
@@ -13914,7 +15595,7 @@ var QueryManager = class {
13914
15595
  #metrics = newMetrics();
13915
15596
  #queryMetrics = /* @__PURE__ */ new Map();
13916
15597
  #slowMaterializeThreshold;
13917
- constructor(lc, mutationTracker, clientID, tables, send2, experimentalWatch, recentQueriesMaxSize, queryChangeThrottleMs, slowMaterializeThreshold) {
15598
+ constructor(lc, mutationTracker, clientID, tables, send2, experimentalWatch, recentQueriesMaxSize, queryChangeThrottleMs, slowMaterializeThreshold, onFatalError) {
13918
15599
  this.#lc = lc.withContext("QueryManager");
13919
15600
  this.#clientID = clientID;
13920
15601
  this.#clientToServer = clientToServer(tables);
@@ -13924,6 +15605,7 @@ var QueryManager = class {
13924
15605
  this.#mutationTracker = mutationTracker;
13925
15606
  this.#queryChangeThrottleMs = queryChangeThrottleMs;
13926
15607
  this.#slowMaterializeThreshold = slowMaterializeThreshold;
15608
+ this.#onFatalError = onFatalError;
13927
15609
  this.#mutationTracker.onAllMutationsApplied(() => {
13928
15610
  if (this.#pendingRemovals.length === 0) {
13929
15611
  return;
@@ -14030,6 +15712,26 @@ var QueryManager = class {
14030
15712
  if (entry) {
14031
15713
  entry.gotCallbacks.forEach((callback) => callback(false, error));
14032
15714
  }
15715
+ if (error.error !== "app") {
15716
+ this.#onFatalError(
15717
+ new ProtocolError(
15718
+ error.error === "http" ? {
15719
+ kind: error_kind_enum_exports.TransformFailed,
15720
+ origin: error_origin_enum_exports.ZeroCache,
15721
+ reason: error_reason_enum_exports.HTTP,
15722
+ message: `HTTP ${error.status} transforming queries`,
15723
+ status: error.status,
15724
+ queryIDs: []
15725
+ } : {
15726
+ kind: error_kind_enum_exports.TransformFailed,
15727
+ origin: error_origin_enum_exports.ZeroCache,
15728
+ reason: error_reason_enum_exports.Internal,
15729
+ message: `Unknown error transforming queries`,
15730
+ queryIDs: []
15731
+ }
15732
+ )
15733
+ );
15734
+ }
14033
15735
  }
14034
15736
  }
14035
15737
  addCustom(ast, { name, args }, ttl, gotCallback) {
@@ -14845,20 +16547,20 @@ var Zero = class _Zero {
14845
16547
  };
14846
16548
  #zeroContext;
14847
16549
  queryDelegate;
14848
- #connectResolver = resolver11();
14849
16550
  #pendingPullsByRequestID = /* @__PURE__ */ new Map();
14850
16551
  #lastMutationIDReceived = 0;
14851
16552
  #socket = void 0;
14852
16553
  #socketResolver = resolver11();
14853
16554
  /**
14854
- * This resolver is only used for rejections. It is awaited in the connected
14855
- * state (including when waiting for a pong). It is rejected when we get an
14856
- * invalid message or an 'error' message.
16555
+ * Utility promise that resolves when the socket transitions to connected.
16556
+ * It rejects if we hit an error or timeout before the connected message.
16557
+ * Used by push/pull helpers to queue work until the connection is usable.
14857
16558
  */
14858
- #rejectMessageError = void 0;
16559
+ #connectResolver = resolver11();
14859
16560
  #closeAbortController = new AbortController();
14860
16561
  #visibilityWatcher;
14861
16562
  #connectionManager;
16563
+ #connection;
14862
16564
  #activeClientsManager;
14863
16565
  #inspector;
14864
16566
  #connectStart = void 0;
@@ -14894,7 +16596,10 @@ var Zero = class _Zero {
14894
16596
  slowMaterializeThreshold = 5e3
14895
16597
  } = options;
14896
16598
  if (!userID) {
14897
- throw new Error("ZeroOptions.userID must not be empty.");
16599
+ throw new ClientError({
16600
+ kind: client_error_kind_enum_exports.Internal,
16601
+ message: "ZeroOptions.userID must not be empty."
16602
+ });
14898
16603
  }
14899
16604
  const server = getServer(options.server);
14900
16605
  this.#enableAnalytics = shouldEnableAnalytics(
@@ -14912,9 +16617,10 @@ var Zero = class _Zero {
14912
16617
  }
14913
16618
  }
14914
16619
  if (hiddenTabDisconnectDelay < 0) {
14915
- throw new Error(
14916
- "ZeroOptions.hiddenTabDisconnectDelay must not be negative."
14917
- );
16620
+ throw new ClientError({
16621
+ kind: client_error_kind_enum_exports.Internal,
16622
+ message: "ZeroOptions.hiddenTabDisconnectDelay must not be negative."
16623
+ });
14918
16624
  }
14919
16625
  this.#onlineManager = new OnlineManager();
14920
16626
  if (onOnlineChange) {
@@ -14933,7 +16639,12 @@ var Zero = class _Zero {
14933
16639
  });
14934
16640
  const { enableLegacyMutators = true, enableLegacyQueries = true } = schema;
14935
16641
  const replicacheMutators = {
14936
- [CRUD_MUTATION_NAME]: enableLegacyMutators ? makeCRUDMutator(schema) : () => Promise.reject(new Error("Zero CRUD mutators are not enabled."))
16642
+ [CRUD_MUTATION_NAME]: enableLegacyMutators ? makeCRUDMutator(schema) : () => Promise.reject(
16643
+ new ClientError({
16644
+ kind: client_error_kind_enum_exports.Internal,
16645
+ message: "Zero CRUD mutators are not enabled."
16646
+ })
16647
+ )
14937
16648
  };
14938
16649
  this.#ivmMain = new IVMSourceBranch(schema.tables);
14939
16650
  function assertUnique(key) {
@@ -14959,7 +16670,10 @@ var Zero = class _Zero {
14959
16670
  const lc = new ZeroLogContext(logOptions.logLevel, {}, logSink);
14960
16671
  this.#mutationTracker = new MutationTracker(
14961
16672
  lc,
14962
- (upTo) => this.#send(["ackMutationResponses", upTo])
16673
+ (upTo) => this.#send(["ackMutationResponses", upTo]),
16674
+ (error) => {
16675
+ this.#disconnect(lc, error);
16676
+ }
14963
16677
  );
14964
16678
  if (options.mutators) {
14965
16679
  for (const [namespaceOrKey, mutatorOrMutators] of Object.entries(
@@ -15065,6 +16779,7 @@ var Zero = class _Zero {
15065
16779
  this.#server = server;
15066
16780
  this.userID = userID;
15067
16781
  this.#lc = lc.withContext("clientID", rep.clientID);
16782
+ this.#connection = new ConnectionImpl(this.#connectionManager, this.#lc);
15068
16783
  this.#mutationTracker.setClientIDAndWatch(
15069
16784
  rep.clientID,
15070
16785
  rep.experimentalWatch.bind(rep)
@@ -15135,7 +16850,10 @@ var Zero = class _Zero {
15135
16850
  rep.experimentalWatch.bind(rep),
15136
16851
  maxRecentQueries,
15137
16852
  options.queryChangeThrottleMs ?? DEFAULT_QUERY_CHANGE_THROTTLE_MS,
15138
- slowMaterializeThreshold
16853
+ slowMaterializeThreshold,
16854
+ (error) => {
16855
+ this.#disconnect(lc, error);
16856
+ }
15139
16857
  );
15140
16858
  this.#clientToServer = clientToServer(schema.tables);
15141
16859
  this.#deleteClientsManager = new DeleteClientsManager(
@@ -15326,6 +17044,25 @@ var Zero = class _Zero {
15326
17044
  * will throw an error.
15327
17045
  */
15328
17046
  mutateBatch;
17047
+ /**
17048
+ * The connection API for managing Zero's connection lifecycle.
17049
+ *
17050
+ * Use this to monitor connection state and manually control connections.
17051
+ *
17052
+ * @example
17053
+ * ```ts
17054
+ * // Subscribe to connection state changes
17055
+ * z.connection.state.subscribe(state => {
17056
+ * console.log('Connection state:', state.name);
17057
+ * });
17058
+ *
17059
+ * // Manually resume connection from error state
17060
+ * await z.connection.connect();
17061
+ * ```
17062
+ */
17063
+ get connection() {
17064
+ return this.#connection;
17065
+ }
15329
17066
  /**
15330
17067
  * Whether this Zero instance has been closed.
15331
17068
  *
@@ -15371,7 +17108,6 @@ var Zero = class _Zero {
15371
17108
  throw e;
15372
17109
  } finally {
15373
17110
  this.#connectionManager.closed();
15374
- this.#connectionManager.cleanup();
15375
17111
  }
15376
17112
  }
15377
17113
  #onMessage = (e) => {
@@ -15381,11 +17117,6 @@ var Zero = class _Zero {
15381
17117
  lc.debug?.("ignoring message because already closed");
15382
17118
  return;
15383
17119
  }
15384
- const rejectInvalidMessage = (e2) => this.#rejectMessageError?.reject(
15385
- new Error(
15386
- `Invalid message received from server: ${e2 instanceof Error ? e2.message + ". " : ""}${data}`
15387
- )
15388
- );
15389
17120
  let downMessage;
15390
17121
  const { data } = e;
15391
17122
  try {
@@ -15395,7 +17126,11 @@ var Zero = class _Zero {
15395
17126
  "passthrough"
15396
17127
  );
15397
17128
  } catch (e2) {
15398
- rejectInvalidMessage(e2);
17129
+ const invalidMessageError = new ClientError({
17130
+ kind: client_error_kind_enum_exports.InvalidMessage,
17131
+ message: `Invalid message received from server: ${e2 instanceof Error ? e2.message + ". " : ""}${data}`
17132
+ });
17133
+ this.#disconnect(lc, invalidMessageError);
15399
17134
  return;
15400
17135
  }
15401
17136
  this.#messageCount++;
@@ -15430,9 +17165,14 @@ var Zero = class _Zero {
15430
17165
  break;
15431
17166
  case "inspect":
15432
17167
  break;
15433
- default:
15434
- msgType;
15435
- rejectInvalidMessage();
17168
+ default: {
17169
+ const invalidMessageError = new ClientError({
17170
+ kind: client_error_kind_enum_exports.InvalidMessage,
17171
+ message: `Invalid message received from server: ${data}`
17172
+ });
17173
+ this.#disconnect(lc, invalidMessageError);
17174
+ return;
17175
+ }
15436
17176
  }
15437
17177
  };
15438
17178
  #onOpen = () => {
@@ -15481,11 +17221,10 @@ var Zero = class _Zero {
15481
17221
  return;
15482
17222
  }
15483
17223
  lc.info?.(`${kind}: ${message}}`);
15484
- const error = new ServerError(downMessage[1]);
17224
+ const error = new ProtocolError(downMessage[1]);
15485
17225
  lc.error?.(`${error.kind}:
15486
17226
 
15487
17227
  ${error.errorBody.message}`, error);
15488
- this.#rejectMessageError?.reject(error);
15489
17228
  lc.debug?.("Rejecting connect resolver due to error", error);
15490
17229
  this.#connectResolver.reject(error);
15491
17230
  this.#disconnect(lc, error);
@@ -15691,8 +17430,14 @@ ${error.errorBody.message}`, error);
15691
17430
  }
15692
17431
  }
15693
17432
  #disconnect(lc, reason, closeCode) {
15694
- if (this.#connectionManager.is(connection_status_enum_exports.Connecting)) {
17433
+ if (shouldReportConnectError(reason)) {
15695
17434
  this.#connectErrorCount++;
17435
+ this.#metrics.lastConnectError.set(getLastConnectErrorValue(reason));
17436
+ this.#metrics.timeToConnectMs.set(DID_NOT_CONNECT_VALUE);
17437
+ this.#metrics.setConnectError(reason);
17438
+ if (this.#connectErrorCount % CHECK_CONNECTIVITY_ON_ERROR_FREQUENCY === 1) {
17439
+ this.#checkConnectivity(`connectErrorCount=${this.#connectErrorCount}`);
17440
+ }
15696
17441
  }
15697
17442
  lc.info?.("disconnecting", {
15698
17443
  navigatorOnline: localNavigator?.onLine,
@@ -15705,8 +17450,8 @@ ${error.errorBody.message}`, error);
15705
17450
  connectionState: this.#connectionManager.state,
15706
17451
  connectErrorCount: this.#connectErrorCount
15707
17452
  });
15708
- const connectionState = this.#connectionManager.state.name;
15709
- switch (connectionState) {
17453
+ const connectionStatus = this.#connectionManager.state.name;
17454
+ switch (connectionStatus) {
15710
17455
  case connection_status_enum_exports.Connected: {
15711
17456
  if (this.#connectStart !== void 0) {
15712
17457
  lc.error?.(
@@ -15715,26 +17460,15 @@ ${error.errorBody.message}`, error);
15715
17460
  }
15716
17461
  break;
15717
17462
  }
15718
- case connection_status_enum_exports.Disconnected:
15719
- case connection_status_enum_exports.Connecting: {
15720
- this.#metrics.lastConnectError.set(getLastConnectErrorValue(reason));
15721
- this.#metrics.timeToConnectMs.set(DID_NOT_CONNECT_VALUE);
15722
- this.#metrics.setConnectError(reason);
15723
- if (this.#connectErrorCount % CHECK_CONNECTIVITY_ON_ERROR_FREQUENCY === 1) {
15724
- this.#checkConnectivity(
15725
- `connectErrorCount=${this.#connectErrorCount}`
15726
- );
15727
- }
15728
- if (this.#connectStart === void 0) {
15729
- lc.error?.(
15730
- "disconnect() called while connecting but connect start time is undefined."
15731
- );
15732
- }
15733
- break;
15734
- }
15735
17463
  case connection_status_enum_exports.Closed:
15736
- lc.error?.("disconnect() called while closed");
17464
+ lc.debug?.("disconnect() called while closed");
15737
17465
  return;
17466
+ case connection_status_enum_exports.Disconnected:
17467
+ case connection_status_enum_exports.Connecting:
17468
+ case connection_status_enum_exports.Error:
17469
+ break;
17470
+ default:
17471
+ unreachable(connectionStatus);
15738
17472
  }
15739
17473
  this.#socketResolver = resolver11();
15740
17474
  lc.debug?.("Creating new connect resolver");
@@ -15749,11 +17483,22 @@ ${error.errorBody.message}`, error);
15749
17483
  this.#socket = void 0;
15750
17484
  this.#lastMutationIDSent = NULL_LAST_MUTATION_ID_SENT;
15751
17485
  this.#pokeHandler.handleDisconnect();
15752
- const isStillConnecting = reason instanceof ClientError && (reason.kind === client_error_kind_enum_exports.ConnectTimeout || reason.kind === client_error_kind_enum_exports.Hidden);
15753
- if (isStillConnecting) {
15754
- this.#connectionManager.connecting(reason);
15755
- } else {
15756
- this.#connectionManager.disconnected(reason);
17486
+ const transition = getErrorConnectionTransition(reason);
17487
+ switch (transition.status) {
17488
+ case connection_status_enum_exports.Error:
17489
+ this.#connectionManager.error(transition.reason);
17490
+ break;
17491
+ case connection_status_enum_exports.Disconnected:
17492
+ this.#connectionManager.disconnected(transition.reason);
17493
+ break;
17494
+ case connection_status_enum_exports.Closed:
17495
+ this.#connectionManager.closed();
17496
+ break;
17497
+ case NO_STATUS_TRANSITION:
17498
+ this.#connectionManager.connecting(transition.reason);
17499
+ break;
17500
+ default:
17501
+ unreachable(transition);
15757
17502
  }
15758
17503
  }
15759
17504
  #handlePokeStart(_lc, pokeMessage) {
@@ -15872,7 +17617,7 @@ ${error.errorBody.message}`, error);
15872
17617
  this.#lc.info?.(`Starting Zero version: ${this.version}`);
15873
17618
  if (this.#server === null) {
15874
17619
  this.#lc.info?.("No socket origin provided, not starting connect loop.");
15875
- this.#connectionManager.disconnected(
17620
+ this.#connectionManager.error(
15876
17621
  new ClientError({
15877
17622
  kind: client_error_kind_enum_exports.NoSocketOrigin,
15878
17623
  message: "No server socket origin provided"
@@ -15892,22 +17637,29 @@ ${error.errorBody.message}`, error);
15892
17637
  await this.#updateAuthToken(bareLogContext);
15893
17638
  let needsReauth = false;
15894
17639
  let lastReauthAttemptAt;
15895
- let gotError = false;
15896
- let backoffMs = RUN_LOOP_INTERVAL_MS;
17640
+ let backoffMs;
15897
17641
  let additionalConnectParams;
15898
17642
  while (this.#connectionManager.shouldContinueRunLoop()) {
15899
17643
  runLoopCounter++;
15900
17644
  let lc = getLogContext();
15901
17645
  backoffMs = RUN_LOOP_INTERVAL_MS;
15902
17646
  try {
15903
- switch (this.#connectionManager.state.name) {
17647
+ const currentState = this.#connectionManager.state;
17648
+ switch (currentState.name) {
15904
17649
  case connection_status_enum_exports.Connecting:
15905
17650
  case connection_status_enum_exports.Disconnected: {
15906
17651
  if (this.#visibilityWatcher.visibilityState === "hidden") {
15907
17652
  this.#metrics.setDisconnectedWaitingForVisible();
15908
17653
  this.#totalToConnectStart = void 0;
15909
17654
  }
15910
- await this.#visibilityWatcher.waitForVisible();
17655
+ const visibilityResult = await promiseRace({
17656
+ visible: this.#visibilityWatcher.waitForVisible(),
17657
+ stateChange: this.#connectionManager.waitForStateChange()
17658
+ });
17659
+ if (visibilityResult.key === "stateChange") {
17660
+ throwIfConnectionError(visibilityResult.result);
17661
+ break;
17662
+ }
15911
17663
  if (needsReauth) {
15912
17664
  lastReauthAttemptAt = Date.now();
15913
17665
  await this.#updateAuthToken(lc, "invalid-token");
@@ -15917,13 +17669,10 @@ ${error.errorBody.message}`, error);
15917
17669
  }
15918
17670
  await this.#connect(lc, additionalConnectParams);
15919
17671
  additionalConnectParams = void 0;
15920
- if (this.closed) {
15921
- break;
15922
- }
17672
+ throwIfConnectionError(this.#connectionManager.state);
15923
17673
  assert(this.#socket);
15924
17674
  lc = getLogContext();
15925
17675
  lc.debug?.("Connected successfully");
15926
- gotError = false;
15927
17676
  needsReauth = false;
15928
17677
  this.#setOnline(true);
15929
17678
  break;
@@ -15935,51 +17684,52 @@ ${error.errorBody.message}`, error);
15935
17684
  PING_INTERVAL_MS,
15936
17685
  controller.signal
15937
17686
  );
15938
- this.#rejectMessageError = resolver11();
15939
- const PING = 0;
15940
- const HIDDEN = 2;
15941
- const raceResult = await promiseRace([
15942
- pingTimeoutPromise,
15943
- pingTimeoutAborted,
15944
- this.#visibilityWatcher.waitForHidden(),
15945
- this.#connectionManager.waitForStateChange(),
15946
- this.#rejectMessageError.promise
15947
- ]);
15948
- if (this.closed) {
15949
- this.#rejectMessageError = void 0;
15950
- break;
15951
- }
15952
- switch (raceResult) {
15953
- case PING: {
15954
- const pingResult = await this.#ping(
15955
- lc,
15956
- this.#rejectMessageError.promise
15957
- );
15958
- if (pingResult === TimedOut) {
15959
- gotError = true;
15960
- }
17687
+ const raceResult = await promiseRace({
17688
+ waitForPing: pingTimeoutPromise,
17689
+ waitForPingAborted: pingTimeoutAborted,
17690
+ tabHidden: this.#visibilityWatcher.waitForHidden(),
17691
+ stateChange: this.#connectionManager.waitForStateChange()
17692
+ });
17693
+ switch (raceResult.key) {
17694
+ case "waitForPing": {
17695
+ await this.#ping(lc);
15961
17696
  break;
15962
17697
  }
15963
- case HIDDEN:
15964
- this.#disconnect(
15965
- lc,
15966
- new ClientError({
15967
- kind: client_error_kind_enum_exports.Hidden,
15968
- message: "Connection closed because tab was hidden"
15969
- })
15970
- );
17698
+ case "waitForPingAborted":
17699
+ break;
17700
+ case "tabHidden": {
17701
+ const hiddenError = new ClientError({
17702
+ kind: client_error_kind_enum_exports.Hidden,
17703
+ message: "Connection closed because tab was hidden"
17704
+ });
17705
+ this.#disconnect(lc, hiddenError);
15971
17706
  this.#setOnline(false);
15972
17707
  break;
17708
+ }
17709
+ case "stateChange":
17710
+ throwIfConnectionError(raceResult.result);
17711
+ break;
17712
+ default:
17713
+ unreachable(raceResult);
15973
17714
  }
15974
- this.#rejectMessageError = void 0;
17715
+ break;
17716
+ }
17717
+ case connection_status_enum_exports.Error: {
17718
+ lc.info?.(
17719
+ `Run loop paused in error state. Call zero.connection.connect() to resume.`,
17720
+ currentState.reason
17721
+ );
17722
+ await this.#connectionManager.waitForStateChange();
15975
17723
  break;
15976
17724
  }
15977
17725
  case connection_status_enum_exports.Closed:
15978
- this.#rejectMessageError = void 0;
15979
17726
  break;
17727
+ default:
17728
+ unreachable(currentState);
15980
17729
  }
15981
17730
  } catch (ex) {
15982
- if (!this.#connectionManager.is(connection_status_enum_exports.Connected)) {
17731
+ const isClientClosedError = isClientError(ex) && ex.kind === client_error_kind_enum_exports.ClientClosed;
17732
+ if (!this.#connectionManager.is(connection_status_enum_exports.Connected) && !isClientClosedError) {
15983
17733
  const level = isAuthError(ex) ? "warn" : "error";
15984
17734
  const kind = isServerError(ex) ? ex.kind : "Unknown Error";
15985
17735
  lc[level]?.("Failed to connect", ex, kind, {
@@ -15994,38 +17744,56 @@ ${error.errorBody.message}`, error);
15994
17744
  "exception:",
15995
17745
  ex
15996
17746
  );
15997
- if (isAuthError(ex)) {
15998
- const now = Date.now();
15999
- const msSinceLastReauthAttempt = lastReauthAttemptAt === void 0 ? Number.POSITIVE_INFINITY : now - lastReauthAttemptAt;
16000
- needsReauth = true;
16001
- if (msSinceLastReauthAttempt > RUN_LOOP_INTERVAL_MS) {
16002
- continue;
17747
+ const transition = getErrorConnectionTransition(ex);
17748
+ switch (transition.status) {
17749
+ case NO_STATUS_TRANSITION: {
17750
+ const backoffParams = getBackoffParams(transition.reason);
17751
+ if (backoffParams) {
17752
+ if (backoffParams.minBackoffMs !== void 0) {
17753
+ backoffMs = Math.max(backoffMs, backoffParams.minBackoffMs);
17754
+ }
17755
+ if (backoffParams.maxBackoffMs !== void 0) {
17756
+ backoffMs = Math.min(backoffMs, backoffParams.maxBackoffMs);
17757
+ }
17758
+ additionalConnectParams = backoffParams.reconnectParams;
17759
+ }
17760
+ if (isAuthError(transition.reason)) {
17761
+ const now = Date.now();
17762
+ const msSinceLastReauthAttempt = lastReauthAttemptAt === void 0 ? Number.POSITIVE_INFINITY : now - lastReauthAttemptAt;
17763
+ needsReauth = true;
17764
+ if (msSinceLastReauthAttempt > RUN_LOOP_INTERVAL_MS) {
17765
+ continue;
17766
+ }
17767
+ }
17768
+ this.#setOnline(false);
17769
+ lc.debug?.(
17770
+ "Sleeping",
17771
+ backoffMs,
17772
+ "ms before reconnecting due to error, state:",
17773
+ this.#connectionManager.state
17774
+ );
17775
+ await sleep(backoffMs);
17776
+ break;
16003
17777
  }
16004
- }
16005
- if (isServerError(ex) || isClientError(ex) && (ex.kind === client_error_kind_enum_exports.ConnectTimeout || ex.kind === client_error_kind_enum_exports.AbruptClose || ex.kind === client_error_kind_enum_exports.CleanClose)) {
16006
- gotError = true;
16007
- }
16008
- const backoffError = isBackoffError(ex);
16009
- if (backoffError) {
16010
- if (backoffError.minBackoffMs !== void 0) {
16011
- backoffMs = Math.max(backoffMs, backoffError.minBackoffMs);
17778
+ case connection_status_enum_exports.Error: {
17779
+ lc.debug?.("Fatal error encountered, transitioning to error state");
17780
+ this.#setOnline(false);
17781
+ this.#connectionManager.error(transition.reason);
17782
+ break;
17783
+ }
17784
+ case connection_status_enum_exports.Disconnected: {
17785
+ this.#setOnline(false);
17786
+ this.#connectionManager.disconnected(transition.reason);
17787
+ break;
16012
17788
  }
16013
- if (backoffError.maxBackoffMs !== void 0) {
16014
- backoffMs = Math.min(backoffMs, backoffError.maxBackoffMs);
17789
+ case connection_status_enum_exports.Closed: {
17790
+ this.#setOnline(false);
17791
+ break;
16015
17792
  }
16016
- additionalConnectParams = backoffError.reconnectParams;
17793
+ default:
17794
+ unreachable(transition);
16017
17795
  }
16018
17796
  }
16019
- if (gotError) {
16020
- this.#setOnline(false);
16021
- lc.debug?.(
16022
- "Sleeping",
16023
- backoffMs,
16024
- "ms before reconnecting due to error, state:",
16025
- this.#connectionManager.state
16026
- );
16027
- await sleep(backoffMs);
16028
- }
16029
17797
  }
16030
17798
  }
16031
17799
  async #puller(req, requestID) {
@@ -16061,17 +17829,18 @@ ${error.errorBody.message}`, error);
16061
17829
  const pullResponseResolver = resolver11();
16062
17830
  this.#pendingPullsByRequestID.set(requestID, pullResponseResolver);
16063
17831
  try {
16064
- const TIMEOUT = 0;
16065
- const RESPONSE = 1;
16066
- const raceResult = await promiseRace([
16067
- sleep(PULL_TIMEOUT_MS),
16068
- pullResponseResolver.promise
16069
- ]);
16070
- switch (raceResult) {
16071
- case TIMEOUT:
17832
+ const raceResult = await promiseRace({
17833
+ timeout: sleep(PULL_TIMEOUT_MS),
17834
+ success: pullResponseResolver.promise
17835
+ });
17836
+ switch (raceResult.key) {
17837
+ case "timeout":
16072
17838
  lc.debug?.("Mutation recovery pull timed out");
16073
- throw new Error("Pull timed out");
16074
- case RESPONSE: {
17839
+ throw new ClientError({
17840
+ kind: client_error_kind_enum_exports.PullTimeout,
17841
+ message: "Pull timed out"
17842
+ });
17843
+ case "success": {
16075
17844
  lc.debug?.("Returning mutation recovery pull response");
16076
17845
  const response = await pullResponseResolver.promise;
16077
17846
  return {
@@ -16087,10 +17856,15 @@ ${error.errorBody.message}`, error);
16087
17856
  };
16088
17857
  }
16089
17858
  default:
16090
- unreachable();
17859
+ unreachable(raceResult);
16091
17860
  }
16092
17861
  } finally {
16093
- pullResponseResolver.reject("timed out");
17862
+ pullResponseResolver.reject(
17863
+ new ClientError({
17864
+ kind: client_error_kind_enum_exports.PullTimeout,
17865
+ message: "Pull timed out"
17866
+ })
17867
+ );
16094
17868
  this.#pendingPullsByRequestID.delete(requestID);
16095
17869
  }
16096
17870
  }
@@ -16100,6 +17874,8 @@ ${error.errorBody.message}`, error);
16100
17874
  /**
16101
17875
  * A rough heuristic for whether the client is currently online and
16102
17876
  * authenticated.
17877
+ *
17878
+ * @deprecated Use `connection` instead, which provides more detailed connection state.
16103
17879
  */
16104
17880
  get online() {
16105
17881
  return this.#onlineManager.online;
@@ -16111,15 +17887,14 @@ ${error.errorBody.message}`, error);
16111
17887
  *
16112
17888
  * @param listener - The listener to subscribe to.
16113
17889
  * @returns A function to unsubscribe the listener.
17890
+ *
17891
+ * @deprecated Use `connection` instead, which provides more detailed connection state.
16114
17892
  */
16115
17893
  onOnline = (listener) => this.#onlineManager.subscribe(listener);
16116
17894
  /**
16117
17895
  * Starts a ping and waits for a pong.
16118
- *
16119
- * If it takes too long to get a pong we disconnect and this returns
16120
- * {@linkcode PingResult.TimedOut}.
16121
17896
  */
16122
- async #ping(lc, messageErrorRejectionPromise) {
17897
+ async #ping(lc) {
16123
17898
  lc.debug?.("pinging");
16124
17899
  const { promise, resolve } = resolver11();
16125
17900
  this.#onPong = resolve;
@@ -16127,25 +17902,37 @@ ${error.errorBody.message}`, error);
16127
17902
  const t0 = performance.now();
16128
17903
  assert(this.#socket);
16129
17904
  send(this.#socket, pingMessage);
16130
- const connected = await promiseRace([
16131
- promise,
16132
- sleep(PING_TIMEOUT_MS),
16133
- messageErrorRejectionPromise
16134
- ]) === 0;
17905
+ const raceResult = await promiseRace({
17906
+ waitForPong: promise,
17907
+ pingTimeout: sleep(PING_TIMEOUT_MS),
17908
+ stateChange: this.#connectionManager.waitForStateChange()
17909
+ });
16135
17910
  const delta = performance.now() - t0;
16136
- if (!connected) {
16137
- lc.info?.("ping failed in", delta, "ms - disconnecting");
16138
- this.#disconnect(
16139
- lc,
16140
- new ClientError({
17911
+ switch (raceResult.key) {
17912
+ case "waitForPong": {
17913
+ lc.debug?.("ping succeeded in", delta, "ms");
17914
+ return;
17915
+ }
17916
+ case "pingTimeout": {
17917
+ lc.info?.("ping failed in", delta, "ms - disconnecting");
17918
+ const pingTimeoutError = new ClientError({
16141
17919
  kind: client_error_kind_enum_exports.PingTimeout,
16142
- message: "Server ping request timed out"
16143
- })
16144
- );
16145
- return TimedOut;
17920
+ message: "Server ping request failed"
17921
+ });
17922
+ this.#disconnect(lc, pingTimeoutError);
17923
+ throw pingTimeoutError;
17924
+ }
17925
+ case "stateChange": {
17926
+ lc.debug?.(
17927
+ "ping aborted due to connection state change",
17928
+ raceResult.result
17929
+ );
17930
+ throwIfConnectionError(raceResult.result);
17931
+ break;
17932
+ }
17933
+ default:
17934
+ unreachable(raceResult);
16146
17935
  }
16147
- lc.debug?.("ping succeeded in", delta, "ms");
16148
- return Success;
16149
17936
  }
16150
17937
  // Sends a set of metrics to the server. Throws unless the server
16151
17938
  // returns 200.
@@ -16304,9 +18091,6 @@ function addWebSocketIDFromSocketToLogContext({ url }, lc) {
16304
18091
  function addWebSocketIDToLogContext(wsid, lc) {
16305
18092
  return lc.withContext("wsid", wsid);
16306
18093
  }
16307
- function promiseRace(ps) {
16308
- return Promise.race(ps.map((p, i) => p.then(() => i)));
16309
- }
16310
18094
  function assertValidRunOptions2(_options) {
16311
18095
  }
16312
18096
  async function makeActiveClientsManager(clientGroupID, clientID, signal, onDelete) {
@@ -16326,12 +18110,14 @@ export {
16326
18110
  dropDatabase,
16327
18111
  dropAllDatabases,
16328
18112
  TransactionClosedError,
18113
+ error_kind_enum_exports,
18114
+ error_origin_enum_exports,
18115
+ error_reason_enum_exports,
16329
18116
  transformRequestMessageSchema,
16330
18117
  transformResponseMessageSchema,
16331
- error_kind_enum_exports,
16332
18118
  table,
16333
- string2 as string,
16334
- number2 as number,
18119
+ string4 as string,
18120
+ number4 as number,
16335
18121
  boolean,
16336
18122
  json,
16337
18123
  enumeration,
@@ -16344,7 +18130,10 @@ export {
16344
18130
  newQuerySymbol,
16345
18131
  AbstractQuery,
16346
18132
  clientToServer,
18133
+ client_error_kind_enum_exports,
18134
+ connection_status_enum_exports,
18135
+ ClientError,
16347
18136
  update_needed_reason_type_enum_exports,
16348
18137
  Zero
16349
18138
  };
16350
- //# sourceMappingURL=chunk-MXPHMVU7.js.map
18139
+ //# sourceMappingURL=chunk-AIPM77UE.js.map