@rocicorp/zero 0.26.1 → 0.26.2-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 (1086) hide show
  1. package/out/_virtual/_@oxc-project_runtime@0.115.0/helpers/usingCtx.js +57 -0
  2. package/out/_virtual/_rolldown/runtime.js +27 -0
  3. package/out/analyze-query/src/bin-analyze.js +195 -283
  4. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  5. package/out/analyze-query/src/bin-transform.js +35 -40
  6. package/out/analyze-query/src/bin-transform.js.map +1 -1
  7. package/out/analyze-query/src/explain-queries.js +11 -13
  8. package/out/analyze-query/src/explain-queries.js.map +1 -1
  9. package/out/analyze-query/src/run-ast.js +68 -103
  10. package/out/analyze-query/src/run-ast.js.map +1 -1
  11. package/out/ast-to-zql/src/ast-to-zql.js +105 -153
  12. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  13. package/out/ast-to-zql/src/bin.js +57 -62
  14. package/out/ast-to-zql/src/bin.js.map +1 -1
  15. package/out/ast-to-zql/src/format.js +14 -13
  16. package/out/ast-to-zql/src/format.js.map +1 -1
  17. package/out/datadog/src/datadog-log-sink.js +148 -213
  18. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  19. package/out/otel/src/enabled.js +9 -11
  20. package/out/otel/src/enabled.js.map +1 -1
  21. package/out/otel/src/log-options.js +25 -35
  22. package/out/otel/src/log-options.js.map +1 -1
  23. package/out/otel/src/maybe-time.js +13 -14
  24. package/out/otel/src/maybe-time.js.map +1 -1
  25. package/out/otel/src/span.js +23 -26
  26. package/out/otel/src/span.js.map +1 -1
  27. package/out/otel/src/test-log-config.js +11 -10
  28. package/out/otel/src/test-log-config.js.map +1 -1
  29. package/out/otel/src/version.js +6 -5
  30. package/out/otel/src/version.js.map +1 -1
  31. package/out/replicache/src/async-iterable-to-array.js +8 -9
  32. package/out/replicache/src/async-iterable-to-array.js.map +1 -1
  33. package/out/replicache/src/bg-interval.js +28 -35
  34. package/out/replicache/src/bg-interval.js.map +1 -1
  35. package/out/replicache/src/btree/diff.js +6 -5
  36. package/out/replicache/src/btree/diff.js.map +1 -1
  37. package/out/replicache/src/btree/node.js +281 -372
  38. package/out/replicache/src/btree/node.js.map +1 -1
  39. package/out/replicache/src/btree/read.js +155 -256
  40. package/out/replicache/src/btree/read.js.map +1 -1
  41. package/out/replicache/src/btree/splice.js +60 -80
  42. package/out/replicache/src/btree/splice.js.map +1 -1
  43. package/out/replicache/src/btree/write.js +134 -158
  44. package/out/replicache/src/btree/write.js.map +1 -1
  45. package/out/replicache/src/call-default-fetch.js +28 -32
  46. package/out/replicache/src/call-default-fetch.js.map +1 -1
  47. package/out/replicache/src/config.js +2 -0
  48. package/out/replicache/src/connection-loop-delegates.js +31 -33
  49. package/out/replicache/src/connection-loop-delegates.js.map +1 -1
  50. package/out/replicache/src/connection-loop.js +174 -240
  51. package/out/replicache/src/connection-loop.js.map +1 -1
  52. package/out/replicache/src/cookies.js +22 -32
  53. package/out/replicache/src/cookies.js.map +1 -1
  54. package/out/replicache/src/dag/chunk.js +44 -50
  55. package/out/replicache/src/dag/chunk.js.map +1 -1
  56. package/out/replicache/src/dag/gc.js +94 -114
  57. package/out/replicache/src/dag/gc.js.map +1 -1
  58. package/out/replicache/src/dag/key.js +9 -11
  59. package/out/replicache/src/dag/key.js.map +1 -1
  60. package/out/replicache/src/dag/lazy-store.js +458 -510
  61. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  62. package/out/replicache/src/dag/store-impl.js +147 -178
  63. package/out/replicache/src/dag/store-impl.js.map +1 -1
  64. package/out/replicache/src/dag/store.js +19 -22
  65. package/out/replicache/src/dag/store.js.map +1 -1
  66. package/out/replicache/src/dag/visitor.js +23 -21
  67. package/out/replicache/src/dag/visitor.js.map +1 -1
  68. package/out/replicache/src/db/commit.js +209 -283
  69. package/out/replicache/src/db/commit.js.map +1 -1
  70. package/out/replicache/src/db/index.js +79 -122
  71. package/out/replicache/src/db/index.js.map +1 -1
  72. package/out/replicache/src/db/read.js +44 -60
  73. package/out/replicache/src/db/read.js.map +1 -1
  74. package/out/replicache/src/db/rebase.js +22 -77
  75. package/out/replicache/src/db/rebase.js.map +1 -1
  76. package/out/replicache/src/db/write.js +162 -296
  77. package/out/replicache/src/db/write.js.map +1 -1
  78. package/out/replicache/src/deleted-clients.js +59 -87
  79. package/out/replicache/src/deleted-clients.js.map +1 -1
  80. package/out/replicache/src/error-responses.js +18 -26
  81. package/out/replicache/src/error-responses.js.map +1 -1
  82. package/out/replicache/src/expo-sqlite.js +2 -0
  83. package/out/replicache/src/frozen-json.js +74 -108
  84. package/out/replicache/src/frozen-json.js.map +1 -1
  85. package/out/replicache/src/get-default-puller.js +34 -46
  86. package/out/replicache/src/get-default-puller.js.map +1 -1
  87. package/out/replicache/src/get-default-pusher.js +25 -33
  88. package/out/replicache/src/get-default-pusher.js.map +1 -1
  89. package/out/replicache/src/get-kv-store-provider.js +18 -20
  90. package/out/replicache/src/get-kv-store-provider.js.map +1 -1
  91. package/out/replicache/src/hash.js +29 -29
  92. package/out/replicache/src/hash.js.map +1 -1
  93. package/out/replicache/src/http-request-info.js +9 -8
  94. package/out/replicache/src/http-request-info.js.map +1 -1
  95. package/out/replicache/src/impl.js +2 -0
  96. package/out/replicache/src/index-defs.js +17 -28
  97. package/out/replicache/src/index-defs.js.map +1 -1
  98. package/out/replicache/src/kv/expo-sqlite/store.js +52 -50
  99. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  100. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +71 -68
  101. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  102. package/out/replicache/src/kv/idb-store.js +144 -168
  103. package/out/replicache/src/kv/idb-store.js.map +1 -1
  104. package/out/replicache/src/kv/mem-store.js +57 -45
  105. package/out/replicache/src/kv/mem-store.js.map +1 -1
  106. package/out/replicache/src/kv/op-sqlite/store.js +56 -62
  107. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  108. package/out/replicache/src/kv/op-sqlite/types.d.ts.map +1 -1
  109. package/out/replicache/src/kv/op-sqlite/types.js +7 -6
  110. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  111. package/out/replicache/src/kv/read-impl.js +26 -25
  112. package/out/replicache/src/kv/read-impl.js.map +1 -1
  113. package/out/replicache/src/kv/sqlite-store.js +194 -207
  114. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  115. package/out/replicache/src/kv/throw-if-closed.js +12 -19
  116. package/out/replicache/src/kv/throw-if-closed.js.map +1 -1
  117. package/out/replicache/src/kv/write-impl-base.js +44 -56
  118. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  119. package/out/replicache/src/kv/write-impl.js +22 -26
  120. package/out/replicache/src/kv/write-impl.js.map +1 -1
  121. package/out/replicache/src/lazy.js +10 -11
  122. package/out/replicache/src/lazy.js.map +1 -1
  123. package/out/replicache/src/log-options.js +14 -7
  124. package/out/replicache/src/log-options.js.map +1 -1
  125. package/out/replicache/src/make-idb-name.js +14 -9
  126. package/out/replicache/src/make-idb-name.js.map +1 -1
  127. package/out/replicache/src/mutation-recovery.js +12 -0
  128. package/out/replicache/src/mutation-recovery.js.map +1 -0
  129. package/out/replicache/src/new-client-channel.js +34 -42
  130. package/out/replicache/src/new-client-channel.js.map +1 -1
  131. package/out/replicache/src/on-persist-channel.js +26 -29
  132. package/out/replicache/src/on-persist-channel.js.map +1 -1
  133. package/out/replicache/src/op-sqlite.js +2 -0
  134. package/out/replicache/src/patch-operation.js +27 -36
  135. package/out/replicache/src/patch-operation.js.map +1 -1
  136. package/out/replicache/src/pending-mutations.js +14 -12
  137. package/out/replicache/src/pending-mutations.js.map +1 -1
  138. package/out/replicache/src/persist/client-gc.js +36 -51
  139. package/out/replicache/src/persist/client-gc.js.map +1 -1
  140. package/out/replicache/src/persist/client-group-gc.js +29 -36
  141. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  142. package/out/replicache/src/persist/client-groups.js +80 -154
  143. package/out/replicache/src/persist/client-groups.js.map +1 -1
  144. package/out/replicache/src/persist/clients.js +212 -307
  145. package/out/replicache/src/persist/clients.js.map +1 -1
  146. package/out/replicache/src/persist/collect-idb-databases.js +109 -171
  147. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  148. package/out/replicache/src/persist/gather-mem-only-visitor.js +23 -24
  149. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  150. package/out/replicache/src/persist/gather-not-cached-visitor.js +35 -33
  151. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  152. package/out/replicache/src/persist/heartbeat.js +31 -41
  153. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  154. package/out/replicache/src/persist/idb-databases-store-db-name.js +9 -12
  155. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
  156. package/out/replicache/src/persist/idb-databases-store.js +78 -97
  157. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  158. package/out/replicache/src/persist/make-client-id.js +13 -9
  159. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  160. package/out/replicache/src/persist/persist.js +113 -174
  161. package/out/replicache/src/persist/persist.js.map +1 -1
  162. package/out/replicache/src/persist/refresh.js +94 -183
  163. package/out/replicache/src/persist/refresh.js.map +1 -1
  164. package/out/replicache/src/process-scheduler.js +122 -143
  165. package/out/replicache/src/process-scheduler.js.map +1 -1
  166. package/out/replicache/src/pusher.js +21 -26
  167. package/out/replicache/src/pusher.js.map +1 -1
  168. package/out/replicache/src/replicache-impl.js +844 -1184
  169. package/out/replicache/src/replicache-impl.js.map +1 -1
  170. package/out/replicache/src/report-error.js +9 -6
  171. package/out/replicache/src/report-error.js.map +1 -1
  172. package/out/replicache/src/request-idle.js +13 -11
  173. package/out/replicache/src/request-idle.js.map +1 -1
  174. package/out/replicache/src/scan-iterator.d.ts.map +1 -1
  175. package/out/replicache/src/scan-iterator.js +108 -135
  176. package/out/replicache/src/scan-iterator.js.map +1 -1
  177. package/out/replicache/src/scan-options.js +33 -39
  178. package/out/replicache/src/scan-options.js.map +1 -1
  179. package/out/replicache/src/set-interval-with-signal.js +11 -10
  180. package/out/replicache/src/set-interval-with-signal.js.map +1 -1
  181. package/out/replicache/src/sqlite.js +2 -0
  182. package/out/replicache/src/subscriptions.js +222 -338
  183. package/out/replicache/src/subscriptions.js.map +1 -1
  184. package/out/replicache/src/sync/diff.js +52 -65
  185. package/out/replicache/src/sync/diff.js.map +1 -1
  186. package/out/replicache/src/sync/ids.js +8 -9
  187. package/out/replicache/src/sync/ids.js.map +1 -1
  188. package/out/replicache/src/sync/patch.js +34 -45
  189. package/out/replicache/src/sync/patch.js.map +1 -1
  190. package/out/replicache/src/sync/pull-error.js +15 -15
  191. package/out/replicache/src/sync/pull-error.js.map +1 -1
  192. package/out/replicache/src/sync/pull.js +145 -283
  193. package/out/replicache/src/sync/pull.js.map +1 -1
  194. package/out/replicache/src/sync/push.js +64 -79
  195. package/out/replicache/src/sync/push.js.map +1 -1
  196. package/out/replicache/src/sync/request-id.js +23 -15
  197. package/out/replicache/src/sync/request-id.js.map +1 -1
  198. package/out/replicache/src/sync/sync-head-name.js +6 -5
  199. package/out/replicache/src/sync/sync-head-name.js.map +1 -1
  200. package/out/replicache/src/to-error.js +7 -8
  201. package/out/replicache/src/to-error.js.map +1 -1
  202. package/out/replicache/src/transaction-closed-error.js +15 -15
  203. package/out/replicache/src/transaction-closed-error.js.map +1 -1
  204. package/out/replicache/src/transactions.js +120 -140
  205. package/out/replicache/src/transactions.js.map +1 -1
  206. package/out/replicache/src/version.js +9 -5
  207. package/out/replicache/src/version.js.map +1 -1
  208. package/out/replicache/src/with-transactions.js +23 -20
  209. package/out/replicache/src/with-transactions.js.map +1 -1
  210. package/out/shared/src/abort-error.js +7 -6
  211. package/out/shared/src/abort-error.js.map +1 -1
  212. package/out/shared/src/arrays.js +35 -42
  213. package/out/shared/src/arrays.js.map +1 -1
  214. package/out/shared/src/asserts.js +21 -45
  215. package/out/shared/src/asserts.js.map +1 -1
  216. package/out/shared/src/bigint-json.js +42 -38
  217. package/out/shared/src/bigint-json.js.map +1 -1
  218. package/out/shared/src/binary-search.js +27 -18
  219. package/out/shared/src/binary-search.js.map +1 -1
  220. package/out/shared/src/broadcast-channel.js +20 -23
  221. package/out/shared/src/broadcast-channel.js.map +1 -1
  222. package/out/shared/src/browser-env.js +11 -17
  223. package/out/shared/src/browser-env.js.map +1 -1
  224. package/out/shared/src/btree-set.js +419 -481
  225. package/out/shared/src/btree-set.js.map +1 -1
  226. package/out/shared/src/cache.js +43 -36
  227. package/out/shared/src/cache.js.map +1 -1
  228. package/out/shared/src/centroid.js +24 -26
  229. package/out/shared/src/centroid.js.map +1 -1
  230. package/out/shared/src/config.js +6 -6
  231. package/out/shared/src/config.js.map +1 -1
  232. package/out/shared/src/custom-key-map.js +54 -58
  233. package/out/shared/src/custom-key-map.js.map +1 -1
  234. package/out/shared/src/custom-key-set.js +53 -51
  235. package/out/shared/src/custom-key-set.js.map +1 -1
  236. package/out/shared/src/deep-clone.js +30 -41
  237. package/out/shared/src/deep-clone.js.map +1 -1
  238. package/out/shared/src/deep-merge.js +25 -24
  239. package/out/shared/src/deep-merge.js.map +1 -1
  240. package/out/shared/src/document-visible.js +63 -70
  241. package/out/shared/src/document-visible.js.map +1 -1
  242. package/out/shared/src/dotenv.js +7 -3
  243. package/out/shared/src/dotenv.js.map +1 -1
  244. package/out/shared/src/error.js +43 -64
  245. package/out/shared/src/error.js.map +1 -1
  246. package/out/shared/src/has-own.js +6 -5
  247. package/out/shared/src/has-own.js.map +1 -1
  248. package/out/shared/src/hash.js +15 -14
  249. package/out/shared/src/hash.js.map +1 -1
  250. package/out/shared/src/iterables.js +34 -47
  251. package/out/shared/src/iterables.js.map +1 -1
  252. package/out/shared/src/json-schema.js +25 -30
  253. package/out/shared/src/json-schema.js.map +1 -1
  254. package/out/shared/src/json.js +90 -129
  255. package/out/shared/src/json.js.map +1 -1
  256. package/out/shared/src/logging-test-utils.js +9 -11
  257. package/out/shared/src/logging-test-utils.js.map +1 -1
  258. package/out/shared/src/logging.js +75 -95
  259. package/out/shared/src/logging.js.map +1 -1
  260. package/out/shared/src/must.js +7 -8
  261. package/out/shared/src/must.js.map +1 -1
  262. package/out/shared/src/navigator.js +6 -5
  263. package/out/shared/src/navigator.js.map +1 -1
  264. package/out/shared/src/object-traversal.js +23 -23
  265. package/out/shared/src/object-traversal.js.map +1 -1
  266. package/out/shared/src/objects.js +15 -18
  267. package/out/shared/src/objects.js.map +1 -1
  268. package/out/shared/src/options.js +225 -302
  269. package/out/shared/src/options.js.map +1 -1
  270. package/out/shared/src/parse-big-int.js +12 -11
  271. package/out/shared/src/parse-big-int.js.map +1 -1
  272. package/out/shared/src/promise-race.js +21 -17
  273. package/out/shared/src/promise-race.js.map +1 -1
  274. package/out/shared/src/queue.js +124 -124
  275. package/out/shared/src/queue.js.map +1 -1
  276. package/out/shared/src/rand.js +13 -7
  277. package/out/shared/src/rand.js.map +1 -1
  278. package/out/shared/src/random-uint64.js +8 -7
  279. package/out/shared/src/random-uint64.js.map +1 -1
  280. package/out/shared/src/random-values.js +8 -11
  281. package/out/shared/src/random-values.js.map +1 -1
  282. package/out/shared/src/record-proxy.js +68 -57
  283. package/out/shared/src/record-proxy.js.map +1 -1
  284. package/out/shared/src/resolved-promises.js +9 -11
  285. package/out/shared/src/resolved-promises.js.map +1 -1
  286. package/out/shared/src/sentinels.js +9 -12
  287. package/out/shared/src/sentinels.js.map +1 -1
  288. package/out/shared/src/set-utils.js +41 -63
  289. package/out/shared/src/set-utils.js.map +1 -1
  290. package/out/shared/src/size-of-value.js +55 -51
  291. package/out/shared/src/size-of-value.js.map +1 -1
  292. package/out/shared/src/sleep.js +50 -45
  293. package/out/shared/src/sleep.js.map +1 -1
  294. package/out/shared/src/string-compare.js +8 -11
  295. package/out/shared/src/string-compare.js.map +1 -1
  296. package/out/shared/src/subscribable.js +34 -33
  297. package/out/shared/src/subscribable.js.map +1 -1
  298. package/out/shared/src/tdigest-schema.js +11 -7
  299. package/out/shared/src/tdigest-schema.js.map +1 -1
  300. package/out/shared/src/tdigest.js +197 -270
  301. package/out/shared/src/tdigest.js.map +1 -1
  302. package/out/shared/src/valita.js +145 -174
  303. package/out/shared/src/valita.js.map +1 -1
  304. package/out/z2s/src/compiler.d.ts.map +1 -1
  305. package/out/z2s/src/compiler.js +238 -468
  306. package/out/z2s/src/compiler.js.map +1 -1
  307. package/out/z2s/src/sql.d.ts +0 -1
  308. package/out/z2s/src/sql.d.ts.map +1 -1
  309. package/out/z2s/src/sql.js +149 -194
  310. package/out/z2s/src/sql.js.map +1 -1
  311. package/out/zero/package.js +193 -0
  312. package/out/zero/package.js.map +1 -0
  313. package/out/zero/src/adapters/drizzle.js +1 -6
  314. package/out/zero/src/adapters/pg.js +1 -6
  315. package/out/zero/src/adapters/postgresjs.js +1 -6
  316. package/out/zero/src/adapters/prisma.js +1 -5
  317. package/out/zero/src/analyze-query.js +1 -1
  318. package/out/zero/src/ast-to-zql.js +1 -1
  319. package/out/zero/src/bindings.js +6 -21
  320. package/out/zero/src/build-schema.js +5 -1
  321. package/out/zero/src/build-schema.js.map +1 -1
  322. package/out/zero/src/change-protocol/v0.js +3 -5
  323. package/out/zero/src/cli.js +2 -2
  324. package/out/zero/src/deploy-permissions.js +1 -1
  325. package/out/zero/src/expo-sqlite.js +2 -4
  326. package/out/zero/src/op-sqlite.js +2 -4
  327. package/out/zero/src/pg.js +2 -20
  328. package/out/zero/src/react-native.js +16 -12
  329. package/out/zero/src/react-native.js.map +1 -1
  330. package/out/zero/src/react.js +3 -12
  331. package/out/zero/src/server/runner/main.js +2 -0
  332. package/out/zero/src/server.js +2 -17
  333. package/out/zero/src/solid.js +3 -12
  334. package/out/zero/src/sqlite.js +2 -6
  335. package/out/zero/src/transform-query.js +1 -1
  336. package/out/zero/src/zero-cache-dev.js +124 -151
  337. package/out/zero/src/zero-cache-dev.js.map +1 -1
  338. package/out/zero/src/zero-out.js +9 -6
  339. package/out/zero/src/zero-out.js.map +1 -1
  340. package/out/zero/src/zero.js +6 -55
  341. package/out/zero/src/zqlite.js +2 -7
  342. package/out/zero-cache/src/auth/auth.js +138 -172
  343. package/out/zero-cache/src/auth/auth.js.map +1 -1
  344. package/out/zero-cache/src/auth/jwt.js +25 -33
  345. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  346. package/out/zero-cache/src/auth/load-permissions.js +54 -62
  347. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  348. package/out/zero-cache/src/auth/read-authorizer.js +70 -80
  349. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  350. package/out/zero-cache/src/auth/write-authorizer.js +284 -432
  351. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  352. package/out/zero-cache/src/config/network.js +31 -45
  353. package/out/zero-cache/src/config/network.js.map +1 -1
  354. package/out/zero-cache/src/config/normalize.js +81 -83
  355. package/out/zero-cache/src/config/normalize.js.map +1 -1
  356. package/out/zero-cache/src/config/server-context.js +32 -29
  357. package/out/zero-cache/src/config/server-context.js.map +1 -1
  358. package/out/zero-cache/src/config/zero-config.js +753 -833
  359. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  360. package/out/zero-cache/src/custom/fetch.js +183 -230
  361. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  362. package/out/zero-cache/src/custom-queries/transform-query.js +93 -99
  363. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  364. package/out/zero-cache/src/db/create.js +27 -29
  365. package/out/zero-cache/src/db/create.js.map +1 -1
  366. package/out/zero-cache/src/db/delete-lite-db.js +11 -7
  367. package/out/zero-cache/src/db/delete-lite-db.js.map +1 -1
  368. package/out/zero-cache/src/db/lite-tables.js +118 -158
  369. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  370. package/out/zero-cache/src/db/migration-lite.js +110 -178
  371. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  372. package/out/zero-cache/src/db/migration.js +82 -151
  373. package/out/zero-cache/src/db/migration.js.map +1 -1
  374. package/out/zero-cache/src/db/mode-enum.js +8 -9
  375. package/out/zero-cache/src/db/mode-enum.js.map +1 -1
  376. package/out/zero-cache/src/db/pg-copy.js +56 -54
  377. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  378. package/out/zero-cache/src/db/pg-to-lite.js +74 -110
  379. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  380. package/out/zero-cache/src/db/pg-type-parser.js +19 -36
  381. package/out/zero-cache/src/db/pg-type-parser.js.map +1 -1
  382. package/out/zero-cache/src/db/run-transaction.js +19 -20
  383. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  384. package/out/zero-cache/src/db/specs.js +42 -78
  385. package/out/zero-cache/src/db/specs.js.map +1 -1
  386. package/out/zero-cache/src/db/statements.js +52 -59
  387. package/out/zero-cache/src/db/statements.js.map +1 -1
  388. package/out/zero-cache/src/db/transaction-pool.js +376 -400
  389. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  390. package/out/zero-cache/src/db/warmup.js +13 -24
  391. package/out/zero-cache/src/db/warmup.js.map +1 -1
  392. package/out/zero-cache/src/observability/events.js +89 -99
  393. package/out/zero-cache/src/observability/events.js.map +1 -1
  394. package/out/zero-cache/src/observability/metrics.js +30 -54
  395. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  396. package/out/zero-cache/src/scripts/decommission.js +42 -47
  397. package/out/zero-cache/src/scripts/decommission.js.map +1 -1
  398. package/out/zero-cache/src/scripts/deploy-permissions.js +106 -144
  399. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  400. package/out/zero-cache/src/scripts/permissions.js +86 -107
  401. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  402. package/out/zero-cache/src/server/anonymous-otel-start.js +306 -440
  403. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  404. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  405. package/out/zero-cache/src/server/change-streamer.js +57 -130
  406. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  407. package/out/zero-cache/src/server/inspector-delegate.js +89 -100
  408. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  409. package/out/zero-cache/src/server/logging.js +18 -26
  410. package/out/zero-cache/src/server/logging.js.map +1 -1
  411. package/out/zero-cache/src/server/main.js +85 -142
  412. package/out/zero-cache/src/server/main.js.map +1 -1
  413. package/out/zero-cache/src/server/mutator.js +16 -13
  414. package/out/zero-cache/src/server/mutator.js.map +1 -1
  415. package/out/zero-cache/src/server/otel-diag-logger.js +42 -49
  416. package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
  417. package/out/zero-cache/src/server/otel-log-sink.js +34 -44
  418. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  419. package/out/zero-cache/src/server/otel-start.js +43 -51
  420. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  421. package/out/zero-cache/src/server/priority-op.js +27 -25
  422. package/out/zero-cache/src/server/priority-op.js.map +1 -1
  423. package/out/zero-cache/src/server/reaper.js +32 -43
  424. package/out/zero-cache/src/server/reaper.js.map +1 -1
  425. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  426. package/out/zero-cache/src/server/replicator.js +41 -57
  427. package/out/zero-cache/src/server/replicator.js.map +1 -1
  428. package/out/zero-cache/src/server/runner/main.js +7 -8
  429. package/out/zero-cache/src/server/runner/main.js.map +1 -1
  430. package/out/zero-cache/src/server/runner/run-worker.js +56 -52
  431. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  432. package/out/zero-cache/src/server/runner/runtime.js +26 -32
  433. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  434. package/out/zero-cache/src/server/runner/zero-dispatcher.js +22 -27
  435. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  436. package/out/zero-cache/src/server/syncer.js +79 -148
  437. package/out/zero-cache/src/server/syncer.js.map +1 -1
  438. package/out/zero-cache/src/server/worker-dispatcher.js +84 -113
  439. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  440. package/out/zero-cache/src/server/worker-urls.d.ts +2 -1
  441. package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
  442. package/out/zero-cache/src/server/worker-urls.js +14 -18
  443. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  444. package/out/zero-cache/src/server/write-worker.js +2 -0
  445. package/out/zero-cache/src/services/analyze.js +61 -130
  446. package/out/zero-cache/src/services/analyze.js.map +1 -1
  447. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +420 -419
  448. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  449. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +111 -114
  450. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  451. package/out/zero-cache/src/services/change-source/common/replica-schema.js +80 -148
  452. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  453. package/out/zero-cache/src/services/change-source/custom/change-source.js +154 -216
  454. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  455. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js +11 -14
  456. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  457. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +168 -212
  458. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  459. package/out/zero-cache/src/services/change-source/pg/change-source.js +672 -892
  460. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  461. package/out/zero-cache/src/services/change-source/pg/decommission.js +19 -23
  462. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  463. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +258 -411
  464. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  465. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js +59 -65
  466. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  467. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js +218 -247
  468. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  469. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +100 -142
  470. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  471. package/out/zero-cache/src/services/change-source/pg/lsn.js +17 -19
  472. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  473. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +88 -98
  474. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  475. package/out/zero-cache/src/services/change-source/pg/schema/init.js +96 -177
  476. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  477. package/out/zero-cache/src/services/change-source/pg/schema/published.js +69 -107
  478. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  479. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +151 -212
  480. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  481. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +22 -53
  482. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  483. package/out/zero-cache/src/services/change-source/protocol/current/control.js +24 -12
  484. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  485. package/out/zero-cache/src/services/change-source/protocol/current/data.js +180 -290
  486. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  487. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js +21 -33
  488. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  489. package/out/zero-cache/src/services/change-source/protocol/current/json.js +7 -18
  490. package/out/zero-cache/src/services/change-source/protocol/current/json.js.map +1 -1
  491. package/out/zero-cache/src/services/change-source/protocol/current/path.js +24 -5
  492. package/out/zero-cache/src/services/change-source/protocol/current/path.js.map +1 -1
  493. package/out/zero-cache/src/services/change-source/protocol/current/status.js +25 -19
  494. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  495. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +24 -16
  496. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  497. package/out/zero-cache/src/services/change-source/protocol/current.js +51 -46
  498. package/out/zero-cache/src/services/change-source/protocol/current.js.map +1 -1
  499. package/out/zero-cache/src/services/change-source/protocol/mod.js +2 -0
  500. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +165 -171
  501. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  502. package/out/zero-cache/src/services/change-streamer/broadcast.js +163 -169
  503. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  504. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +154 -221
  505. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  506. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  507. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +340 -299
  508. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  509. package/out/zero-cache/src/services/change-streamer/change-streamer.js +17 -24
  510. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  511. package/out/zero-cache/src/services/change-streamer/forwarder.js +84 -103
  512. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  513. package/out/zero-cache/src/services/change-streamer/replica-monitor.js +49 -43
  514. package/out/zero-cache/src/services/change-streamer/replica-monitor.js.map +1 -1
  515. package/out/zero-cache/src/services/change-streamer/schema/init.js +61 -89
  516. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  517. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +20 -1
  518. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  519. package/out/zero-cache/src/services/change-streamer/schema/tables.js +131 -109
  520. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  521. package/out/zero-cache/src/services/change-streamer/snapshot.js +26 -28
  522. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  523. package/out/zero-cache/src/services/change-streamer/storer.js +434 -513
  524. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  525. package/out/zero-cache/src/services/change-streamer/subscriber.js +142 -155
  526. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  527. package/out/zero-cache/src/services/heapz.js +18 -20
  528. package/out/zero-cache/src/services/heapz.js.map +1 -1
  529. package/out/zero-cache/src/services/http-service.js +59 -57
  530. package/out/zero-cache/src/services/http-service.js.map +1 -1
  531. package/out/zero-cache/src/services/life-cycle.js +182 -214
  532. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  533. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +102 -81
  534. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  535. package/out/zero-cache/src/services/litestream/commands.js +144 -205
  536. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  537. package/out/zero-cache/src/services/mutagen/error.js +10 -14
  538. package/out/zero-cache/src/services/mutagen/error.js.map +1 -1
  539. package/out/zero-cache/src/services/mutagen/mutagen.js +166 -264
  540. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  541. package/out/zero-cache/src/services/mutagen/pusher.js +372 -487
  542. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  543. package/out/zero-cache/src/services/replicator/change-processor.js +483 -592
  544. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  545. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +4 -2
  546. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  547. package/out/zero-cache/src/services/replicator/incremental-sync.js +118 -143
  548. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  549. package/out/zero-cache/src/services/replicator/notifier.js +52 -28
  550. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  551. package/out/zero-cache/src/services/replicator/replication-status.js +105 -128
  552. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  553. package/out/zero-cache/src/services/replicator/replicator.d.ts +2 -1
  554. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  555. package/out/zero-cache/src/services/replicator/replicator.js +32 -34
  556. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  557. package/out/zero-cache/src/services/replicator/schema/change-log.js +101 -133
  558. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  559. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +145 -174
  560. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  561. package/out/zero-cache/src/services/replicator/schema/constants.js +11 -5
  562. package/out/zero-cache/src/services/replicator/schema/constants.js.map +1 -1
  563. package/out/zero-cache/src/services/replicator/schema/replication-state.js +56 -107
  564. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  565. package/out/zero-cache/src/services/replicator/schema/table-metadata.js +81 -66
  566. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  567. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +69 -0
  568. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -0
  569. package/out/zero-cache/src/services/replicator/write-worker-client.js +96 -0
  570. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -0
  571. package/out/zero-cache/src/services/replicator/write-worker.js +68 -0
  572. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -0
  573. package/out/zero-cache/src/services/run-ast.js +79 -120
  574. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  575. package/out/zero-cache/src/services/runner.js +39 -41
  576. package/out/zero-cache/src/services/runner.js.map +1 -1
  577. package/out/zero-cache/src/services/running-state.js +129 -134
  578. package/out/zero-cache/src/services/running-state.js.map +1 -1
  579. package/out/zero-cache/src/services/statz.js +139 -200
  580. package/out/zero-cache/src/services/statz.js.map +1 -1
  581. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +46 -49
  582. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  583. package/out/zero-cache/src/services/view-syncer/client-handler.js +257 -299
  584. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  585. package/out/zero-cache/src/services/view-syncer/client-schema.js +52 -82
  586. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  587. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +85 -107
  588. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  589. package/out/zero-cache/src/services/view-syncer/cvr-store.js +604 -757
  590. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  591. package/out/zero-cache/src/services/view-syncer/cvr.js +631 -739
  592. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  593. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +60 -40
  594. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  595. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +95 -178
  596. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  597. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  598. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +572 -722
  599. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  600. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  601. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +246 -257
  602. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  603. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +59 -45
  604. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  605. package/out/zero-cache/src/services/view-syncer/schema/init.js +121 -189
  606. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
  607. package/out/zero-cache/src/services/view-syncer/schema/types.js +138 -263
  608. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  609. package/out/zero-cache/src/services/view-syncer/snapshotter.js +322 -335
  610. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  611. package/out/zero-cache/src/services/view-syncer/tracer.js +7 -6
  612. package/out/zero-cache/src/services/view-syncer/tracer.js.map +1 -1
  613. package/out/zero-cache/src/services/view-syncer/ttl-clock.js +9 -11
  614. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  615. package/out/zero-cache/src/services/view-syncer/view-syncer.js +1067 -1603
  616. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  617. package/out/zero-cache/src/types/error-with-level.js +19 -25
  618. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  619. package/out/zero-cache/src/types/http.js +17 -26
  620. package/out/zero-cache/src/types/http.js.map +1 -1
  621. package/out/zero-cache/src/types/lexi-version.js +28 -42
  622. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  623. package/out/zero-cache/src/types/lite.js +101 -121
  624. package/out/zero-cache/src/types/lite.js.map +1 -1
  625. package/out/zero-cache/src/types/names.js +6 -5
  626. package/out/zero-cache/src/types/names.js.map +1 -1
  627. package/out/zero-cache/src/types/pg-data-type.d.ts +1 -0
  628. package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
  629. package/out/zero-cache/src/types/pg-data-type.js +58 -73
  630. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  631. package/out/zero-cache/src/types/pg-types.js +12 -19
  632. package/out/zero-cache/src/types/pg-types.js.map +1 -1
  633. package/out/zero-cache/src/types/pg.js +144 -218
  634. package/out/zero-cache/src/types/pg.js.map +1 -1
  635. package/out/zero-cache/src/types/processes.js +95 -90
  636. package/out/zero-cache/src/types/processes.js.map +1 -1
  637. package/out/zero-cache/src/types/profiler.js +32 -27
  638. package/out/zero-cache/src/types/profiler.js.map +1 -1
  639. package/out/zero-cache/src/types/row-key.js +42 -30
  640. package/out/zero-cache/src/types/row-key.js.map +1 -1
  641. package/out/zero-cache/src/types/shards.js +36 -45
  642. package/out/zero-cache/src/types/shards.js.map +1 -1
  643. package/out/zero-cache/src/types/sql.js +20 -9
  644. package/out/zero-cache/src/types/sql.js.map +1 -1
  645. package/out/zero-cache/src/types/state-version.js +17 -23
  646. package/out/zero-cache/src/types/state-version.js.map +1 -1
  647. package/out/zero-cache/src/types/streams.js +234 -270
  648. package/out/zero-cache/src/types/streams.js.map +1 -1
  649. package/out/zero-cache/src/types/strings.js +10 -13
  650. package/out/zero-cache/src/types/strings.js.map +1 -1
  651. package/out/zero-cache/src/types/subscription.js +266 -226
  652. package/out/zero-cache/src/types/subscription.js.map +1 -1
  653. package/out/zero-cache/src/types/url-params.js +30 -39
  654. package/out/zero-cache/src/types/url-params.js.map +1 -1
  655. package/out/zero-cache/src/types/websocket-handoff.js +62 -75
  656. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  657. package/out/zero-cache/src/types/ws.js +43 -53
  658. package/out/zero-cache/src/types/ws.js.map +1 -1
  659. package/out/zero-cache/src/workers/connect-params.js +42 -43
  660. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  661. package/out/zero-cache/src/workers/connection.js +213 -282
  662. package/out/zero-cache/src/workers/connection.js.map +1 -1
  663. package/out/zero-cache/src/workers/mutator.js +22 -21
  664. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  665. package/out/zero-cache/src/workers/replicator.d.ts +7 -0
  666. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  667. package/out/zero-cache/src/workers/replicator.js +92 -97
  668. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  669. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +121 -203
  670. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  671. package/out/zero-cache/src/workers/syncer.js +147 -201
  672. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  673. package/out/zero-client/src/client/active-clients-manager.js +178 -187
  674. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  675. package/out/zero-client/src/client/bindings.js +11 -0
  676. package/out/zero-client/src/client/client-error-kind-enum.js +18 -29
  677. package/out/zero-client/src/client/client-error-kind-enum.js.map +1 -1
  678. package/out/zero-client/src/client/connection-manager.js +291 -346
  679. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  680. package/out/zero-client/src/client/connection-status-enum.js +20 -15
  681. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  682. package/out/zero-client/src/client/connection.js +92 -110
  683. package/out/zero-client/src/client/connection.js.map +1 -1
  684. package/out/zero-client/src/client/context.js +84 -100
  685. package/out/zero-client/src/client/context.js.map +1 -1
  686. package/out/zero-client/src/client/crud-impl.js +56 -88
  687. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  688. package/out/zero-client/src/client/crud.js +127 -129
  689. package/out/zero-client/src/client/crud.js.map +1 -1
  690. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  691. package/out/zero-client/src/client/custom.js +50 -74
  692. package/out/zero-client/src/client/custom.js.map +1 -1
  693. package/out/zero-client/src/client/delete-clients-manager.js +72 -93
  694. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  695. package/out/zero-client/src/client/enable-analytics.js +8 -16
  696. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  697. package/out/zero-client/src/client/error.js +118 -133
  698. package/out/zero-client/src/client/error.js.map +1 -1
  699. package/out/zero-client/src/client/http-string.js +7 -7
  700. package/out/zero-client/src/client/http-string.js.map +1 -1
  701. package/out/zero-client/src/client/inspector/client-group.js +21 -26
  702. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  703. package/out/zero-client/src/client/inspector/client.js +23 -26
  704. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  705. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +72 -73
  706. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  707. package/out/zero-client/src/client/inspector/inspector.js +46 -51
  708. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  709. package/out/zero-client/src/client/inspector/lazy-inspector.js +132 -192
  710. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  711. package/out/zero-client/src/client/inspector/query.js +72 -77
  712. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  713. package/out/zero-client/src/client/ivm-branch.js +118 -145
  714. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  715. package/out/zero-client/src/client/keys.js +15 -31
  716. package/out/zero-client/src/client/keys.js.map +1 -1
  717. package/out/zero-client/src/client/log-options.js +43 -57
  718. package/out/zero-client/src/client/log-options.js.map +1 -1
  719. package/out/zero-client/src/client/make-mutate-property.js +46 -29
  720. package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
  721. package/out/zero-client/src/client/make-replicache-mutators.js +80 -96
  722. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  723. package/out/zero-client/src/client/metric-name-enum.js +11 -15
  724. package/out/zero-client/src/client/metric-name-enum.js.map +1 -1
  725. package/out/zero-client/src/client/metrics.js +210 -237
  726. package/out/zero-client/src/client/metrics.js.map +1 -1
  727. package/out/zero-client/src/client/mutation-tracker.js +264 -354
  728. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  729. package/out/zero-client/src/client/mutator-proxy.js +122 -151
  730. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  731. package/out/zero-client/src/client/options.js +7 -10
  732. package/out/zero-client/src/client/options.js.map +1 -1
  733. package/out/zero-client/src/client/query-manager.js +305 -373
  734. package/out/zero-client/src/client/query-manager.js.map +1 -1
  735. package/out/zero-client/src/client/reload-error-handler.js +80 -101
  736. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  737. package/out/zero-client/src/client/server-option.js +30 -59
  738. package/out/zero-client/src/client/server-option.js.map +1 -1
  739. package/out/zero-client/src/client/update-needed-reason-type-enum.js +27 -9
  740. package/out/zero-client/src/client/update-needed-reason-type-enum.js.map +1 -1
  741. package/out/zero-client/src/client/version.js +9 -5
  742. package/out/zero-client/src/client/version.js.map +1 -1
  743. package/out/zero-client/src/client/zero-poke-handler.d.ts +1 -1
  744. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  745. package/out/zero-client/src/client/zero-poke-handler.js +205 -293
  746. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  747. package/out/zero-client/src/client/zero-rep.js +61 -68
  748. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  749. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  750. package/out/zero-client/src/client/zero.js +1367 -1834
  751. package/out/zero-client/src/client/zero.js.map +1 -1
  752. package/out/zero-client/src/mod.js +21 -0
  753. package/out/zero-client/src/util/nanoid.js +13 -18
  754. package/out/zero-client/src/util/nanoid.js.map +1 -1
  755. package/out/zero-client/src/util/socket.js +6 -5
  756. package/out/zero-client/src/util/socket.js.map +1 -1
  757. package/out/zero-pg/src/mod.js +10 -0
  758. package/out/zero-protocol/src/analyze-query-result.js +108 -148
  759. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  760. package/out/zero-protocol/src/application-error.js +36 -34
  761. package/out/zero-protocol/src/application-error.js.map +1 -1
  762. package/out/zero-protocol/src/ast.js +236 -309
  763. package/out/zero-protocol/src/ast.js.map +1 -1
  764. package/out/zero-protocol/src/change-desired-queries.js +8 -13
  765. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  766. package/out/zero-protocol/src/client-schema.js +21 -42
  767. package/out/zero-protocol/src/client-schema.js.map +1 -1
  768. package/out/zero-protocol/src/close-connection.js +20 -12
  769. package/out/zero-protocol/src/close-connection.js.map +1 -1
  770. package/out/zero-protocol/src/connect.js +37 -52
  771. package/out/zero-protocol/src/connect.js.map +1 -1
  772. package/out/zero-protocol/src/custom-queries.js +34 -65
  773. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  774. package/out/zero-protocol/src/data.js +6 -9
  775. package/out/zero-protocol/src/data.js.map +1 -1
  776. package/out/zero-protocol/src/delete-clients.js +11 -17
  777. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  778. package/out/zero-protocol/src/down.js +11 -23
  779. package/out/zero-protocol/src/down.js.map +1 -1
  780. package/out/zero-protocol/src/error-kind-enum.js +24 -41
  781. package/out/zero-protocol/src/error-kind-enum.js.map +1 -1
  782. package/out/zero-protocol/src/error-origin-enum.js +8 -9
  783. package/out/zero-protocol/src/error-origin-enum.js.map +1 -1
  784. package/out/zero-protocol/src/error-reason-enum.js +12 -17
  785. package/out/zero-protocol/src/error-reason-enum.js.map +1 -1
  786. package/out/zero-protocol/src/error.js +76 -152
  787. package/out/zero-protocol/src/error.js.map +1 -1
  788. package/out/zero-protocol/src/inspect-down.js +51 -74
  789. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  790. package/out/zero-protocol/src/inspect-up.js +28 -46
  791. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  792. package/out/zero-protocol/src/mutation-id.js +9 -9
  793. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  794. package/out/zero-protocol/src/mutation-type-enum.js +7 -7
  795. package/out/zero-protocol/src/mutation-type-enum.js.map +1 -1
  796. package/out/zero-protocol/src/mutations-patch.js +21 -16
  797. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  798. package/out/zero-protocol/src/ping.js +8 -9
  799. package/out/zero-protocol/src/ping.js.map +1 -1
  800. package/out/zero-protocol/src/poke.js +53 -59
  801. package/out/zero-protocol/src/poke.js.map +1 -1
  802. package/out/zero-protocol/src/pong.js +8 -9
  803. package/out/zero-protocol/src/pong.js.map +1 -1
  804. package/out/zero-protocol/src/primary-key.js +9 -19
  805. package/out/zero-protocol/src/primary-key.js.map +1 -1
  806. package/out/zero-protocol/src/protocol-version.js +5 -11
  807. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  808. package/out/zero-protocol/src/pull.js +16 -28
  809. package/out/zero-protocol/src/pull.js.map +1 -1
  810. package/out/zero-protocol/src/push.js +162 -209
  811. package/out/zero-protocol/src/push.js.map +1 -1
  812. package/out/zero-protocol/src/queries-patch.js +22 -30
  813. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  814. package/out/zero-protocol/src/query-hash.js +14 -17
  815. package/out/zero-protocol/src/query-hash.js.map +1 -1
  816. package/out/zero-protocol/src/row-patch.js +23 -30
  817. package/out/zero-protocol/src/row-patch.js.map +1 -1
  818. package/out/zero-protocol/src/up.js +11 -22
  819. package/out/zero-protocol/src/up.js.map +1 -1
  820. package/out/zero-protocol/src/update-auth.js +8 -13
  821. package/out/zero-protocol/src/update-auth.js.map +1 -1
  822. package/out/zero-protocol/src/version.js +8 -9
  823. package/out/zero-protocol/src/version.js.map +1 -1
  824. package/out/zero-react/src/bindings.js +12 -0
  825. package/out/zero-react/src/mod.js +5 -0
  826. package/out/zero-react/src/use-connection-state.js +14 -11
  827. package/out/zero-react/src/use-connection-state.js.map +1 -1
  828. package/out/zero-react/src/use-query.js +283 -281
  829. package/out/zero-react/src/use-query.js.map +1 -1
  830. package/out/zero-react/src/use-zero-online.js +17 -11
  831. package/out/zero-react/src/use-zero-online.js.map +1 -1
  832. package/out/zero-react/src/zero-provider.js +53 -69
  833. package/out/zero-react/src/zero-provider.js.map +1 -1
  834. package/out/zero-react/src/zero.js +22 -0
  835. package/out/zero-schema/src/builder/relationship-builder.js +25 -21
  836. package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
  837. package/out/zero-schema/src/builder/schema-builder.js +51 -79
  838. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  839. package/out/zero-schema/src/builder/table-builder.js +99 -116
  840. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  841. package/out/zero-schema/src/compiled-permissions.js +21 -25
  842. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  843. package/out/zero-schema/src/name-mapper.js +31 -47
  844. package/out/zero-schema/src/name-mapper.js.map +1 -1
  845. package/out/zero-schema/src/permissions.js +94 -181
  846. package/out/zero-schema/src/permissions.js.map +1 -1
  847. package/out/zero-schema/src/schema-config.js +26 -32
  848. package/out/zero-schema/src/schema-config.js.map +1 -1
  849. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  850. package/out/zero-server/src/adapters/drizzle.js +79 -76
  851. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  852. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  853. package/out/zero-server/src/adapters/pg.js +79 -55
  854. package/out/zero-server/src/adapters/pg.js.map +1 -1
  855. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  856. package/out/zero-server/src/adapters/postgresjs.js +66 -40
  857. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  858. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  859. package/out/zero-server/src/adapters/prisma.js +75 -55
  860. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  861. package/out/zero-server/src/custom.d.ts.map +1 -1
  862. package/out/zero-server/src/custom.js +188 -265
  863. package/out/zero-server/src/custom.js.map +1 -1
  864. package/out/zero-server/src/logging.js +6 -5
  865. package/out/zero-server/src/logging.js.map +1 -1
  866. package/out/zero-server/src/mod.js +8 -0
  867. package/out/zero-server/src/pg-query-executor.js +14 -17
  868. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  869. package/out/zero-server/src/process-mutations.js +293 -365
  870. package/out/zero-server/src/process-mutations.js.map +1 -1
  871. package/out/zero-server/src/push-processor.js +33 -49
  872. package/out/zero-server/src/push-processor.js.map +1 -1
  873. package/out/zero-server/src/queries/process-queries.js +106 -96
  874. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  875. package/out/zero-server/src/schema.js +98 -144
  876. package/out/zero-server/src/schema.js.map +1 -1
  877. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  878. package/out/zero-server/src/zql-database.js +54 -69
  879. package/out/zero-server/src/zql-database.js.map +1 -1
  880. package/out/zero-solid/src/bindings.js +12 -0
  881. package/out/zero-solid/src/mod.js +5 -0
  882. package/out/zero-solid/src/solid-view.js +135 -227
  883. package/out/zero-solid/src/solid-view.js.map +1 -1
  884. package/out/zero-solid/src/use-connection-state.js +18 -14
  885. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  886. package/out/zero-solid/src/use-query.js +55 -100
  887. package/out/zero-solid/src/use-query.js.map +1 -1
  888. package/out/zero-solid/src/use-zero-online.js +18 -12
  889. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  890. package/out/zero-solid/src/use-zero.js +65 -77
  891. package/out/zero-solid/src/use-zero.js.map +1 -1
  892. package/out/zero-solid/src/zero.js +22 -0
  893. package/out/zero-types/src/format.js +8 -7
  894. package/out/zero-types/src/format.js.map +1 -1
  895. package/out/zero-types/src/name-mapper.js +34 -47
  896. package/out/zero-types/src/name-mapper.js.map +1 -1
  897. package/out/zql/src/builder/builder.d.ts.map +1 -1
  898. package/out/zql/src/builder/builder.js +315 -476
  899. package/out/zql/src/builder/builder.js.map +1 -1
  900. package/out/zql/src/builder/debug-delegate.js +69 -74
  901. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  902. package/out/zql/src/builder/filter.js +116 -140
  903. package/out/zql/src/builder/filter.js.map +1 -1
  904. package/out/zql/src/builder/like.js +41 -46
  905. package/out/zql/src/builder/like.js.map +1 -1
  906. package/out/zql/src/error.js +10 -9
  907. package/out/zql/src/error.js.map +1 -1
  908. package/out/zql/src/ivm/array-view.js +89 -91
  909. package/out/zql/src/ivm/array-view.js.map +1 -1
  910. package/out/zql/src/ivm/constraint.js +65 -74
  911. package/out/zql/src/ivm/constraint.js.map +1 -1
  912. package/out/zql/src/ivm/data.js +61 -48
  913. package/out/zql/src/ivm/data.js.map +1 -1
  914. package/out/zql/src/ivm/exists.js +164 -213
  915. package/out/zql/src/ivm/exists.js.map +1 -1
  916. package/out/zql/src/ivm/fan-in.js +62 -59
  917. package/out/zql/src/ivm/fan-in.js.map +1 -1
  918. package/out/zql/src/ivm/fan-out.js +52 -61
  919. package/out/zql/src/ivm/fan-out.js.map +1 -1
  920. package/out/zql/src/ivm/filter-operators.js +91 -96
  921. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  922. package/out/zql/src/ivm/filter-push.js +22 -26
  923. package/out/zql/src/ivm/filter-push.js.map +1 -1
  924. package/out/zql/src/ivm/filter.js +41 -35
  925. package/out/zql/src/ivm/filter.js.map +1 -1
  926. package/out/zql/src/ivm/flipped-join.js +282 -391
  927. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  928. package/out/zql/src/ivm/join-utils.js +85 -115
  929. package/out/zql/src/ivm/join-utils.js.map +1 -1
  930. package/out/zql/src/ivm/join.js +162 -231
  931. package/out/zql/src/ivm/join.js.map +1 -1
  932. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +21 -25
  933. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  934. package/out/zql/src/ivm/memory-source.js +364 -503
  935. package/out/zql/src/ivm/memory-source.js.map +1 -1
  936. package/out/zql/src/ivm/memory-storage.js +33 -34
  937. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  938. package/out/zql/src/ivm/operator.js +13 -15
  939. package/out/zql/src/ivm/operator.js.map +1 -1
  940. package/out/zql/src/ivm/push-accumulated.js +267 -270
  941. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  942. package/out/zql/src/ivm/skip.js +91 -104
  943. package/out/zql/src/ivm/skip.js.map +1 -1
  944. package/out/zql/src/ivm/stream.js +10 -10
  945. package/out/zql/src/ivm/stream.js.map +1 -1
  946. package/out/zql/src/ivm/take.js +422 -569
  947. package/out/zql/src/ivm/take.js.map +1 -1
  948. package/out/zql/src/ivm/union-fan-in.js +157 -231
  949. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  950. package/out/zql/src/ivm/union-fan-out.js +38 -43
  951. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  952. package/out/zql/src/ivm/view-apply-change.js +166 -255
  953. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  954. package/out/zql/src/mutate/crud.js +35 -34
  955. package/out/zql/src/mutate/crud.js.map +1 -1
  956. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  957. package/out/zql/src/mutate/custom.js +7 -11
  958. package/out/zql/src/mutate/custom.js.map +1 -1
  959. package/out/zql/src/mutate/mutator-registry.js +67 -71
  960. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  961. package/out/zql/src/mutate/mutator.js +26 -25
  962. package/out/zql/src/mutate/mutator.js.map +1 -1
  963. package/out/zql/src/planner/planner-builder.js +134 -239
  964. package/out/zql/src/planner/planner-builder.js.map +1 -1
  965. package/out/zql/src/planner/planner-connection.js +222 -212
  966. package/out/zql/src/planner/planner-connection.js.map +1 -1
  967. package/out/zql/src/planner/planner-constraint.js +15 -7
  968. package/out/zql/src/planner/planner-constraint.js.map +1 -1
  969. package/out/zql/src/planner/planner-debug.js +199 -224
  970. package/out/zql/src/planner/planner-debug.js.map +1 -1
  971. package/out/zql/src/planner/planner-fan-in.js +146 -162
  972. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  973. package/out/zql/src/planner/planner-fan-out.js +62 -74
  974. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  975. package/out/zql/src/planner/planner-graph.js +302 -334
  976. package/out/zql/src/planner/planner-graph.js.map +1 -1
  977. package/out/zql/src/planner/planner-join.js +255 -240
  978. package/out/zql/src/planner/planner-join.js.map +1 -1
  979. package/out/zql/src/planner/planner-node.js +10 -6
  980. package/out/zql/src/planner/planner-node.js.map +1 -1
  981. package/out/zql/src/planner/planner-source.js +15 -22
  982. package/out/zql/src/planner/planner-source.js.map +1 -1
  983. package/out/zql/src/planner/planner-terminus.js +28 -28
  984. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  985. package/out/zql/src/query/complete-ordering.js +37 -61
  986. package/out/zql/src/query/complete-ordering.js.map +1 -1
  987. package/out/zql/src/query/create-builder.js +14 -22
  988. package/out/zql/src/query/create-builder.js.map +1 -1
  989. package/out/zql/src/query/error.js +10 -12
  990. package/out/zql/src/query/error.js.map +1 -1
  991. package/out/zql/src/query/escape-like.js +6 -5
  992. package/out/zql/src/query/escape-like.js.map +1 -1
  993. package/out/zql/src/query/expression.js +138 -157
  994. package/out/zql/src/query/expression.js.map +1 -1
  995. package/out/zql/src/query/measure-push-operator.js +35 -38
  996. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  997. package/out/zql/src/query/metrics-delegate.js +7 -7
  998. package/out/zql/src/query/metrics-delegate.js.map +1 -1
  999. package/out/zql/src/query/named.js +52 -51
  1000. package/out/zql/src/query/named.js.map +1 -1
  1001. package/out/zql/src/query/query-delegate-base.js +190 -238
  1002. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  1003. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  1004. package/out/zql/src/query/query-impl.js +271 -405
  1005. package/out/zql/src/query/query-impl.js.map +1 -1
  1006. package/out/zql/src/query/query-internals.js +16 -8
  1007. package/out/zql/src/query/query-internals.js.map +1 -1
  1008. package/out/zql/src/query/query-registry.js +83 -98
  1009. package/out/zql/src/query/query-registry.js.map +1 -1
  1010. package/out/zql/src/query/query.d.ts.map +1 -1
  1011. package/out/zql/src/query/query.js +2 -0
  1012. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  1013. package/out/zql/src/query/runnable-query-impl.js +30 -55
  1014. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  1015. package/out/zql/src/query/static-query.js +7 -14
  1016. package/out/zql/src/query/static-query.js.map +1 -1
  1017. package/out/zql/src/query/ttl.js +45 -67
  1018. package/out/zql/src/query/ttl.js.map +1 -1
  1019. package/out/zql/src/query/validate-input.js +23 -20
  1020. package/out/zql/src/query/validate-input.js.map +1 -1
  1021. package/out/zqlite/src/database-storage.js +99 -103
  1022. package/out/zqlite/src/database-storage.js.map +1 -1
  1023. package/out/zqlite/src/db.js +206 -249
  1024. package/out/zqlite/src/db.js.map +1 -1
  1025. package/out/zqlite/src/explain-queries.js +11 -13
  1026. package/out/zqlite/src/explain-queries.js.map +1 -1
  1027. package/out/zqlite/src/internal/sql-inline.js +54 -37
  1028. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  1029. package/out/zqlite/src/internal/sql.js +17 -15
  1030. package/out/zqlite/src/internal/sql.js.map +1 -1
  1031. package/out/zqlite/src/internal/statement-cache.js +117 -92
  1032. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  1033. package/out/zqlite/src/mod.js +5 -0
  1034. package/out/zqlite/src/query-builder.js +81 -172
  1035. package/out/zqlite/src/query-builder.js.map +1 -1
  1036. package/out/zqlite/src/query-delegate.js +45 -55
  1037. package/out/zqlite/src/query-delegate.js.map +1 -1
  1038. package/out/zqlite/src/resolve-scalar-subqueries.js +134 -124
  1039. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  1040. package/out/zqlite/src/sqlite-cost-model.js +92 -97
  1041. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  1042. package/out/zqlite/src/sqlite-stat-fanout.js +304 -286
  1043. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  1044. package/out/zqlite/src/table-source.js +281 -455
  1045. package/out/zqlite/src/table-source.js.map +1 -1
  1046. package/package.json +7 -7
  1047. package/out/replicache/src/db/index-operation-enum.js +0 -7
  1048. package/out/replicache/src/db/index-operation-enum.js.map +0 -1
  1049. package/out/replicache/src/db/meta-type-enum.js +0 -7
  1050. package/out/replicache/src/db/meta-type-enum.js.map +0 -1
  1051. package/out/replicache/src/format-version-enum.js +0 -11
  1052. package/out/replicache/src/format-version-enum.js.map +0 -1
  1053. package/out/replicache/src/http-status-unauthorized.js +0 -5
  1054. package/out/replicache/src/http-status-unauthorized.js.map +0 -1
  1055. package/out/replicache/src/invoke-kind-enum.js +0 -7
  1056. package/out/replicache/src/invoke-kind-enum.js.map +0 -1
  1057. package/out/replicache/src/sync/handle-pull-response-result-type-enum.js +0 -9
  1058. package/out/replicache/src/sync/handle-pull-response-result-type-enum.js.map +0 -1
  1059. package/out/zero/package.json.js +0 -9
  1060. package/out/zero/package.json.js.map +0 -1
  1061. package/out/zero/src/adapters/drizzle.js.map +0 -1
  1062. package/out/zero/src/adapters/pg.js.map +0 -1
  1063. package/out/zero/src/adapters/postgresjs.js.map +0 -1
  1064. package/out/zero/src/adapters/prisma.js.map +0 -1
  1065. package/out/zero/src/analyze-query.js.map +0 -1
  1066. package/out/zero/src/ast-to-zql.js.map +0 -1
  1067. package/out/zero/src/bindings.js.map +0 -1
  1068. package/out/zero/src/change-protocol/v0.js.map +0 -1
  1069. package/out/zero/src/cli.js.map +0 -1
  1070. package/out/zero/src/deploy-permissions.js.map +0 -1
  1071. package/out/zero/src/expo-sqlite.js.map +0 -1
  1072. package/out/zero/src/op-sqlite.js.map +0 -1
  1073. package/out/zero/src/pg.js.map +0 -1
  1074. package/out/zero/src/react.js.map +0 -1
  1075. package/out/zero/src/server.js.map +0 -1
  1076. package/out/zero/src/solid.js.map +0 -1
  1077. package/out/zero/src/sqlite.js.map +0 -1
  1078. package/out/zero/src/transform-query.js.map +0 -1
  1079. package/out/zero/src/zero.js.map +0 -1
  1080. package/out/zero/src/zqlite.js.map +0 -1
  1081. package/out/zero-cache/src/db/postgres-replica-identity-enum.js +0 -11
  1082. package/out/zero-cache/src/db/postgres-replica-identity-enum.js.map +0 -1
  1083. package/out/zero-cache/src/db/postgres-type-class-enum.js +0 -17
  1084. package/out/zero-cache/src/db/postgres-type-class-enum.js.map +0 -1
  1085. package/out/zero-cache/src/services/change-streamer/error-type-enum.js +0 -9
  1086. package/out/zero-cache/src/services/change-streamer/error-type-enum.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"planner-graph.js","sources":["../../../../../zql/src/planner/planner-graph.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {PlanDebugger} from './planner-debug.ts';\nimport type {PlannerConnection} from './planner-connection.ts';\nimport type {PlannerConstraint} from './planner-constraint.ts';\nimport type {PlannerFanIn} from './planner-fan-in.ts';\nimport type {PlannerFanOut} from './planner-fan-out.ts';\nimport type {PlannerJoin} from './planner-join.ts';\nimport {omitFanout} from './planner-node.ts';\nimport type {PlannerNode} from './planner-node.ts';\nimport {PlannerSource, type ConnectionCostModel} from './planner-source.ts';\nimport type {PlannerTerminus} from './planner-terminus.ts';\n\n/**\n * Captured state of a plan for comparison and restoration.\n */\nexport type PlanState = {\n connections: Array<{limit: number | undefined}>;\n joins: Array<{type: 'semi' | 'flipped'}>;\n fanOuts: Array<{type: 'FO' | 'UFO'}>;\n fanIns: Array<{type: 'FI' | 'UFI'}>;\n connectionConstraints: Array<Map<string, PlannerConstraint | undefined>>;\n};\n\n/**\n * Maximum number of flippable joins to attempt exhaustive enumeration.\n * With n flippable joins, we explore 2^n plans.\n * 10 joins = 1024 plans (~100-200ms), 12 joins = 4096 plans (~400ms - 1 second)\n */\nconst MAX_FLIPPABLE_JOINS = 9;\n\n/**\n * Cached information about FanOut→FanIn relationships.\n * Computed once during planning to avoid redundant BFS traversals.\n */\ntype FOFIInfo = {\n fi: PlannerFanIn | undefined;\n joinsBetween: PlannerJoin[];\n};\n\nexport class PlannerGraph {\n // Sources indexed by table name\n readonly #sources = new Map<string, PlannerSource>();\n\n // The final output node where constraint propagation starts\n #terminus: PlannerTerminus | undefined = undefined;\n\n // Collections of nodes with mutable planning state\n joins: PlannerJoin[] = [];\n fanOuts: PlannerFanOut[] = [];\n fanIns: PlannerFanIn[] = [];\n connections: PlannerConnection[] = [];\n\n /**\n * Reset all planning state back to initial values for another planning pass.\n * Resets only mutable planning state - graph structure is unchanged.\n *\n * This allows replanning the same query graph with different strategies.\n */\n resetPlanningState() {\n for (const j of this.joins) j.reset();\n for (const fo of this.fanOuts) fo.reset();\n for (const fi of this.fanIns) fi.reset();\n for (const c of this.connections) c.reset();\n }\n\n /**\n * Create and register a source (table) in the graph.\n */\n addSource(name: string, model: ConnectionCostModel): PlannerSource {\n assert(\n !this.#sources.has(name),\n `Source ${name} already exists in the graph`,\n );\n const source = new PlannerSource(name, model);\n this.#sources.set(name, source);\n return source;\n }\n\n /**\n * Get a source by table name.\n */\n getSource(name: string): PlannerSource {\n const source = this.#sources.get(name);\n assert(source !== undefined, `Source ${name} not found in the graph`);\n return source;\n }\n\n /**\n * Check if a source exists by table name.\n */\n hasSource(name: string): boolean {\n return this.#sources.has(name);\n }\n\n /**\n * Set the terminus (final output) node of the graph.\n * Constraint propagation starts from this node.\n */\n setTerminus(terminus: PlannerTerminus): void {\n this.#terminus = terminus;\n }\n\n /**\n * Initiate constraint propagation from the terminus node.\n * This sends constraints up through the graph to update\n * connection cost estimates.\n */\n propagateConstraints(planDebugger?: PlanDebugger): void {\n assert(\n this.#terminus !== undefined,\n 'Cannot propagate constraints without a terminus node',\n );\n this.#terminus.propagateConstraints(planDebugger);\n }\n\n /**\n * Calculate total cost of the current plan.\n * Total cost includes both startup cost (one-time, e.g., sorting) and running cost.\n */\n getTotalCost(planDebugger?: PlanDebugger): number {\n const estimate = must(this.#terminus).estimateCost(planDebugger);\n return estimate.cost + estimate.startupCost;\n }\n\n /**\n * Capture a lightweight snapshot of the current planning state.\n * Used for backtracking during multi-start greedy search.\n *\n * Captures mutable state including pinned flags, join types, and\n * constraint maps to avoid needing repropagation on restore.\n *\n * @returns A snapshot that can be restored via restorePlanningSnapshot()\n */\n capturePlanningSnapshot(): PlanState {\n return {\n connections: this.connections.map(c => ({\n limit: c.limit,\n })),\n joins: this.joins.map(j => ({type: j.type})),\n fanOuts: this.fanOuts.map(fo => ({type: fo.type})),\n fanIns: this.fanIns.map(fi => ({type: fi.type})),\n connectionConstraints: this.connections.map(c => c.captureConstraints()),\n };\n }\n\n /**\n * Restore planning state from a previously captured snapshot.\n * Used for backtracking when a planning attempt fails.\n *\n * Restores pinned flags, join types, and constraint maps, eliminating\n * the need for repropagation.\n *\n * @param state - Snapshot created by capturePlanningSnapshot()\n */\n restorePlanningSnapshot(state: PlanState): void {\n this.#validateSnapshotShape(state);\n this.#restoreConnections(state);\n this.#restoreJoins(state);\n this.#restoreFanNodes(state);\n }\n\n /**\n * Validate that snapshot shape matches current graph structure.\n */\n #validateSnapshotShape(state: PlanState): void {\n assert(\n this.connections.length === state.connections.length,\n 'Plan state mismatch: connections',\n );\n assert(\n this.joins.length === state.joins.length,\n 'Plan state mismatch: joins',\n );\n assert(\n this.fanOuts.length === state.fanOuts.length,\n 'Plan state mismatch: fanOuts',\n );\n assert(\n this.fanIns.length === state.fanIns.length,\n 'Plan state mismatch: fanIns',\n );\n assert(\n this.connections.length === state.connectionConstraints.length,\n 'Plan state mismatch: connectionConstraints',\n );\n }\n\n /**\n * Restore connection pinned flags, limits, and constraint maps.\n */\n #restoreConnections(state: PlanState): void {\n for (let i = 0; i < this.connections.length; i++) {\n this.connections[i].limit = state.connections[i].limit;\n this.connections[i].restoreConstraints(state.connectionConstraints[i]);\n }\n }\n\n /**\n * Restore join types and pinned flags.\n */\n #restoreJoins(state: PlanState): void {\n for (let i = 0; i < this.joins.length; i++) {\n const join = this.joins[i];\n const targetState = state.joins[i];\n\n // Reset to initial state first\n join.reset();\n\n // Apply target state\n if (targetState.type === 'flipped' && join.type !== 'flipped') {\n join.flip();\n }\n assert(\n targetState.type === join.type,\n 'join is not in the correct state after reset',\n );\n }\n }\n\n /**\n * Restore FanOut and FanIn types.\n */\n #restoreFanNodes(state: PlanState): void {\n for (let i = 0; i < this.fanOuts.length; i++) {\n const fo = this.fanOuts[i];\n const targetType = state.fanOuts[i].type;\n if (targetType === 'UFO' && fo.type === 'FO') {\n fo.convertToUFO();\n }\n }\n\n for (let i = 0; i < this.fanIns.length; i++) {\n const fi = this.fanIns[i];\n const targetType = state.fanIns[i].type;\n if (targetType === 'UFI' && fi.type === 'FI') {\n fi.convertToUFI();\n }\n }\n }\n\n /**\n * Main planning algorithm using exhaustive join flip enumeration.\n *\n * Enumerates all possible flip patterns for flippable joins (2^n for n flippable joins).\n * Each pattern represents a different query execution plan. We evaluate the cost of each\n * plan and select the one with the lowest cost.\n *\n * Connections are used only for cost estimation - the flip patterns determine the plan.\n * FanOut/FanIn states (FO/UFO and FI/UFI) are automatically derived from join flip states.\n *\n * @param planDebugger - Optional debugger to receive structured events during planning\n * @param lc - Optional logger for warnings\n */\n plan(planDebugger?: PlanDebugger, lc?: LogContext): void {\n // Get all flippable joins\n const flippableJoins = this.joins.filter(j => j.isFlippable());\n\n // Too many flippable joins - skip optimization and run as-is\n if (flippableJoins.length > MAX_FLIPPABLE_JOINS) {\n lc?.warn?.(\n `Query has ${flippableJoins.length} EXISTS checks which would require ` +\n `${2 ** flippableJoins.length} plan evaluations. Skipping optimization.`,\n );\n return;\n }\n\n // Build FO→FI cache once to avoid redundant BFS traversals in each iteration\n const fofiCache = buildFOFICache(this);\n\n const numPatterns =\n flippableJoins.length === 0 ? 0 : 2 ** flippableJoins.length;\n let bestCost = Infinity;\n let bestPlan: PlanState | undefined = undefined;\n let bestAttemptNumber = -1;\n\n // Enumerate all flip patterns\n for (let pattern = 0; pattern < numPatterns; pattern++) {\n // Reset to initial state\n this.resetPlanningState();\n\n if (planDebugger) {\n planDebugger.log({\n type: 'attempt-start',\n attemptNumber: pattern,\n totalAttempts: numPatterns,\n });\n }\n\n // Apply flip pattern (treat pattern as bitmask)\n // Bit i set to 1 means flip join i\n for (let i = 0; i < flippableJoins.length; i++) {\n if (pattern & (1 << i)) {\n flippableJoins[i].flip();\n }\n }\n\n // Derive FO/UFO and FI/UFI states from join flip states\n checkAndConvertFOFI(fofiCache);\n\n // Propagate unlimiting for flipped joins\n propagateUnlimitForFlippedJoins(this);\n\n // Propagate constraints through the graph\n this.propagateConstraints(planDebugger);\n\n if (planDebugger) {\n planDebugger.log({\n type: 'constraints-propagated',\n attemptNumber: pattern,\n connectionConstraints: this.connections.map(c => {\n const constraintCosts = c.getConstraintCostsForDebug();\n const constraintCostsWithoutFanout: Record<\n string,\n Omit<(typeof constraintCosts)[string], 'fanout'>\n > = {};\n for (const [key, cost] of Object.entries(constraintCosts)) {\n constraintCostsWithoutFanout[key] = omitFanout(cost);\n }\n return {\n connection: c.name,\n constraints: c.getConstraintsForDebug(),\n constraintCosts: constraintCostsWithoutFanout,\n };\n }),\n });\n }\n\n // Evaluate this plan\n const totalCost = this.getTotalCost(planDebugger);\n\n if (planDebugger) {\n planDebugger.log({\n type: 'plan-complete',\n attemptNumber: pattern,\n totalCost,\n flipPattern: pattern, // Bitmask of which joins are flipped\n planSnapshot: this.capturePlanningSnapshot(),\n joinStates: this.joins.map(j => {\n const info = j.getDebugInfo();\n return {\n join: info.name,\n type: info.type,\n };\n }),\n });\n }\n\n // Track best plan\n if (totalCost < bestCost) {\n bestCost = totalCost;\n bestPlan = this.capturePlanningSnapshot();\n bestAttemptNumber = pattern;\n }\n }\n\n // Restore best plan\n if (bestPlan) {\n this.restorePlanningSnapshot(bestPlan);\n // Propagate constraints to ensure all derived state is consistent\n this.propagateConstraints(planDebugger);\n\n if (planDebugger) {\n planDebugger.log({\n type: 'best-plan-selected',\n bestAttemptNumber,\n totalCost: bestCost,\n flipPattern: bestAttemptNumber, // The best attempt number is also the flip pattern\n joinStates: this.joins.map(j => ({\n join: j.getName(),\n type: j.type,\n })),\n });\n }\n } else {\n assert(\n numPatterns === 0,\n 'no plan was found but flippable joins did exist!',\n );\n }\n }\n}\n\n/**\n * Build cache of FO→FI relationships and joins between them.\n * Called once at the start of planning to avoid redundant BFS traversals.\n */\nfunction buildFOFICache(graph: PlannerGraph): Map<PlannerFanOut, FOFIInfo> {\n const cache = new Map<PlannerFanOut, FOFIInfo>();\n\n for (const fo of graph.fanOuts) {\n const info = findFIAndJoins(fo);\n cache.set(fo, info);\n }\n\n return cache;\n}\n\n/**\n * Check if any joins downstream of a FanOut (before reaching FanIn) are flipped.\n * If so, convert the FO to UFO and the FI to UFI.\n *\n * This must be called after join flipping and before propagateConstraints.\n */\nfunction checkAndConvertFOFI(fofiCache: Map<PlannerFanOut, FOFIInfo>): void {\n for (const [fo, info] of fofiCache) {\n const hasFlippedJoin = info.joinsBetween.some(j => j.type === 'flipped');\n if (info.fi && hasFlippedJoin) {\n fo.convertToUFO();\n info.fi.convertToUFI();\n }\n }\n}\n\n/**\n * Traverse from a FanOut through its outputs to find the corresponding FanIn\n * and collect all joins along the way.\n */\nfunction findFIAndJoins(fo: PlannerFanOut): FOFIInfo {\n const joinsBetween: PlannerJoin[] = [];\n let fi: PlannerFanIn | undefined = undefined;\n\n // BFS through FO outputs to find FI and collect joins\n const queue: PlannerNode[] = [...fo.outputs];\n const visited = new Set<PlannerNode>();\n\n while (queue.length > 0) {\n const node = must(queue.shift());\n if (visited.has(node)) continue;\n visited.add(node);\n\n switch (node.kind) {\n case 'join':\n joinsBetween.push(node);\n queue.push(node.output);\n break;\n case 'fan-out':\n // Nested FO - traverse its outputs\n queue.push(...node.outputs);\n break;\n case 'fan-in':\n // Found the FI - this is the boundary, don't traverse further\n fi = node;\n break;\n case 'connection':\n // Shouldn't happen in a well-formed graph\n break;\n case 'terminus':\n // Reached the end without finding FI\n break;\n }\n }\n\n return {fi, joinsBetween};\n}\n\n/**\n * Propagate unlimiting to all flipped joins in the graph.\n * When a join is flipped, its child becomes the outer loop and should no longer\n * be limited by EXISTS semantics.\n *\n * This must be called after join flipping and before propagateConstraints.\n */\nfunction propagateUnlimitForFlippedJoins(graph: PlannerGraph): void {\n for (const join of graph.joins) {\n if (join.type === 'flipped') {\n join.propagateUnlimit();\n }\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"planner-graph.js","names":["#sources","#terminus","#validateSnapshotShape","#restoreConnections","#restoreJoins","#restoreFanNodes"],"sources":["../../../../../zql/src/planner/planner-graph.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {PlanDebugger} from './planner-debug.ts';\nimport type {PlannerConnection} from './planner-connection.ts';\nimport type {PlannerConstraint} from './planner-constraint.ts';\nimport type {PlannerFanIn} from './planner-fan-in.ts';\nimport type {PlannerFanOut} from './planner-fan-out.ts';\nimport type {PlannerJoin} from './planner-join.ts';\nimport {omitFanout} from './planner-node.ts';\nimport type {PlannerNode} from './planner-node.ts';\nimport {PlannerSource, type ConnectionCostModel} from './planner-source.ts';\nimport type {PlannerTerminus} from './planner-terminus.ts';\n\n/**\n * Captured state of a plan for comparison and restoration.\n */\nexport type PlanState = {\n connections: Array<{limit: number | undefined}>;\n joins: Array<{type: 'semi' | 'flipped'}>;\n fanOuts: Array<{type: 'FO' | 'UFO'}>;\n fanIns: Array<{type: 'FI' | 'UFI'}>;\n connectionConstraints: Array<Map<string, PlannerConstraint | undefined>>;\n};\n\n/**\n * Maximum number of flippable joins to attempt exhaustive enumeration.\n * With n flippable joins, we explore 2^n plans.\n * 10 joins = 1024 plans (~100-200ms), 12 joins = 4096 plans (~400ms - 1 second)\n */\nconst MAX_FLIPPABLE_JOINS = 9;\n\n/**\n * Cached information about FanOut→FanIn relationships.\n * Computed once during planning to avoid redundant BFS traversals.\n */\ntype FOFIInfo = {\n fi: PlannerFanIn | undefined;\n joinsBetween: PlannerJoin[];\n};\n\nexport class PlannerGraph {\n // Sources indexed by table name\n readonly #sources = new Map<string, PlannerSource>();\n\n // The final output node where constraint propagation starts\n #terminus: PlannerTerminus | undefined = undefined;\n\n // Collections of nodes with mutable planning state\n joins: PlannerJoin[] = [];\n fanOuts: PlannerFanOut[] = [];\n fanIns: PlannerFanIn[] = [];\n connections: PlannerConnection[] = [];\n\n /**\n * Reset all planning state back to initial values for another planning pass.\n * Resets only mutable planning state - graph structure is unchanged.\n *\n * This allows replanning the same query graph with different strategies.\n */\n resetPlanningState() {\n for (const j of this.joins) j.reset();\n for (const fo of this.fanOuts) fo.reset();\n for (const fi of this.fanIns) fi.reset();\n for (const c of this.connections) c.reset();\n }\n\n /**\n * Create and register a source (table) in the graph.\n */\n addSource(name: string, model: ConnectionCostModel): PlannerSource {\n assert(\n !this.#sources.has(name),\n `Source ${name} already exists in the graph`,\n );\n const source = new PlannerSource(name, model);\n this.#sources.set(name, source);\n return source;\n }\n\n /**\n * Get a source by table name.\n */\n getSource(name: string): PlannerSource {\n const source = this.#sources.get(name);\n assert(source !== undefined, `Source ${name} not found in the graph`);\n return source;\n }\n\n /**\n * Check if a source exists by table name.\n */\n hasSource(name: string): boolean {\n return this.#sources.has(name);\n }\n\n /**\n * Set the terminus (final output) node of the graph.\n * Constraint propagation starts from this node.\n */\n setTerminus(terminus: PlannerTerminus): void {\n this.#terminus = terminus;\n }\n\n /**\n * Initiate constraint propagation from the terminus node.\n * This sends constraints up through the graph to update\n * connection cost estimates.\n */\n propagateConstraints(planDebugger?: PlanDebugger): void {\n assert(\n this.#terminus !== undefined,\n 'Cannot propagate constraints without a terminus node',\n );\n this.#terminus.propagateConstraints(planDebugger);\n }\n\n /**\n * Calculate total cost of the current plan.\n * Total cost includes both startup cost (one-time, e.g., sorting) and running cost.\n */\n getTotalCost(planDebugger?: PlanDebugger): number {\n const estimate = must(this.#terminus).estimateCost(planDebugger);\n return estimate.cost + estimate.startupCost;\n }\n\n /**\n * Capture a lightweight snapshot of the current planning state.\n * Used for backtracking during multi-start greedy search.\n *\n * Captures mutable state including pinned flags, join types, and\n * constraint maps to avoid needing repropagation on restore.\n *\n * @returns A snapshot that can be restored via restorePlanningSnapshot()\n */\n capturePlanningSnapshot(): PlanState {\n return {\n connections: this.connections.map(c => ({\n limit: c.limit,\n })),\n joins: this.joins.map(j => ({type: j.type})),\n fanOuts: this.fanOuts.map(fo => ({type: fo.type})),\n fanIns: this.fanIns.map(fi => ({type: fi.type})),\n connectionConstraints: this.connections.map(c => c.captureConstraints()),\n };\n }\n\n /**\n * Restore planning state from a previously captured snapshot.\n * Used for backtracking when a planning attempt fails.\n *\n * Restores pinned flags, join types, and constraint maps, eliminating\n * the need for repropagation.\n *\n * @param state - Snapshot created by capturePlanningSnapshot()\n */\n restorePlanningSnapshot(state: PlanState): void {\n this.#validateSnapshotShape(state);\n this.#restoreConnections(state);\n this.#restoreJoins(state);\n this.#restoreFanNodes(state);\n }\n\n /**\n * Validate that snapshot shape matches current graph structure.\n */\n #validateSnapshotShape(state: PlanState): void {\n assert(\n this.connections.length === state.connections.length,\n 'Plan state mismatch: connections',\n );\n assert(\n this.joins.length === state.joins.length,\n 'Plan state mismatch: joins',\n );\n assert(\n this.fanOuts.length === state.fanOuts.length,\n 'Plan state mismatch: fanOuts',\n );\n assert(\n this.fanIns.length === state.fanIns.length,\n 'Plan state mismatch: fanIns',\n );\n assert(\n this.connections.length === state.connectionConstraints.length,\n 'Plan state mismatch: connectionConstraints',\n );\n }\n\n /**\n * Restore connection pinned flags, limits, and constraint maps.\n */\n #restoreConnections(state: PlanState): void {\n for (let i = 0; i < this.connections.length; i++) {\n this.connections[i].limit = state.connections[i].limit;\n this.connections[i].restoreConstraints(state.connectionConstraints[i]);\n }\n }\n\n /**\n * Restore join types and pinned flags.\n */\n #restoreJoins(state: PlanState): void {\n for (let i = 0; i < this.joins.length; i++) {\n const join = this.joins[i];\n const targetState = state.joins[i];\n\n // Reset to initial state first\n join.reset();\n\n // Apply target state\n if (targetState.type === 'flipped' && join.type !== 'flipped') {\n join.flip();\n }\n assert(\n targetState.type === join.type,\n 'join is not in the correct state after reset',\n );\n }\n }\n\n /**\n * Restore FanOut and FanIn types.\n */\n #restoreFanNodes(state: PlanState): void {\n for (let i = 0; i < this.fanOuts.length; i++) {\n const fo = this.fanOuts[i];\n const targetType = state.fanOuts[i].type;\n if (targetType === 'UFO' && fo.type === 'FO') {\n fo.convertToUFO();\n }\n }\n\n for (let i = 0; i < this.fanIns.length; i++) {\n const fi = this.fanIns[i];\n const targetType = state.fanIns[i].type;\n if (targetType === 'UFI' && fi.type === 'FI') {\n fi.convertToUFI();\n }\n }\n }\n\n /**\n * Main planning algorithm using exhaustive join flip enumeration.\n *\n * Enumerates all possible flip patterns for flippable joins (2^n for n flippable joins).\n * Each pattern represents a different query execution plan. We evaluate the cost of each\n * plan and select the one with the lowest cost.\n *\n * Connections are used only for cost estimation - the flip patterns determine the plan.\n * FanOut/FanIn states (FO/UFO and FI/UFI) are automatically derived from join flip states.\n *\n * @param planDebugger - Optional debugger to receive structured events during planning\n * @param lc - Optional logger for warnings\n */\n plan(planDebugger?: PlanDebugger, lc?: LogContext): void {\n // Get all flippable joins\n const flippableJoins = this.joins.filter(j => j.isFlippable());\n\n // Too many flippable joins - skip optimization and run as-is\n if (flippableJoins.length > MAX_FLIPPABLE_JOINS) {\n lc?.warn?.(\n `Query has ${flippableJoins.length} EXISTS checks which would require ` +\n `${2 ** flippableJoins.length} plan evaluations. Skipping optimization.`,\n );\n return;\n }\n\n // Build FO→FI cache once to avoid redundant BFS traversals in each iteration\n const fofiCache = buildFOFICache(this);\n\n const numPatterns =\n flippableJoins.length === 0 ? 0 : 2 ** flippableJoins.length;\n let bestCost = Infinity;\n let bestPlan: PlanState | undefined = undefined;\n let bestAttemptNumber = -1;\n\n // Enumerate all flip patterns\n for (let pattern = 0; pattern < numPatterns; pattern++) {\n // Reset to initial state\n this.resetPlanningState();\n\n if (planDebugger) {\n planDebugger.log({\n type: 'attempt-start',\n attemptNumber: pattern,\n totalAttempts: numPatterns,\n });\n }\n\n // Apply flip pattern (treat pattern as bitmask)\n // Bit i set to 1 means flip join i\n for (let i = 0; i < flippableJoins.length; i++) {\n if (pattern & (1 << i)) {\n flippableJoins[i].flip();\n }\n }\n\n // Derive FO/UFO and FI/UFI states from join flip states\n checkAndConvertFOFI(fofiCache);\n\n // Propagate unlimiting for flipped joins\n propagateUnlimitForFlippedJoins(this);\n\n // Propagate constraints through the graph\n this.propagateConstraints(planDebugger);\n\n if (planDebugger) {\n planDebugger.log({\n type: 'constraints-propagated',\n attemptNumber: pattern,\n connectionConstraints: this.connections.map(c => {\n const constraintCosts = c.getConstraintCostsForDebug();\n const constraintCostsWithoutFanout: Record<\n string,\n Omit<(typeof constraintCosts)[string], 'fanout'>\n > = {};\n for (const [key, cost] of Object.entries(constraintCosts)) {\n constraintCostsWithoutFanout[key] = omitFanout(cost);\n }\n return {\n connection: c.name,\n constraints: c.getConstraintsForDebug(),\n constraintCosts: constraintCostsWithoutFanout,\n };\n }),\n });\n }\n\n // Evaluate this plan\n const totalCost = this.getTotalCost(planDebugger);\n\n if (planDebugger) {\n planDebugger.log({\n type: 'plan-complete',\n attemptNumber: pattern,\n totalCost,\n flipPattern: pattern, // Bitmask of which joins are flipped\n planSnapshot: this.capturePlanningSnapshot(),\n joinStates: this.joins.map(j => {\n const info = j.getDebugInfo();\n return {\n join: info.name,\n type: info.type,\n };\n }),\n });\n }\n\n // Track best plan\n if (totalCost < bestCost) {\n bestCost = totalCost;\n bestPlan = this.capturePlanningSnapshot();\n bestAttemptNumber = pattern;\n }\n }\n\n // Restore best plan\n if (bestPlan) {\n this.restorePlanningSnapshot(bestPlan);\n // Propagate constraints to ensure all derived state is consistent\n this.propagateConstraints(planDebugger);\n\n if (planDebugger) {\n planDebugger.log({\n type: 'best-plan-selected',\n bestAttemptNumber,\n totalCost: bestCost,\n flipPattern: bestAttemptNumber, // The best attempt number is also the flip pattern\n joinStates: this.joins.map(j => ({\n join: j.getName(),\n type: j.type,\n })),\n });\n }\n } else {\n assert(\n numPatterns === 0,\n 'no plan was found but flippable joins did exist!',\n );\n }\n }\n}\n\n/**\n * Build cache of FO→FI relationships and joins between them.\n * Called once at the start of planning to avoid redundant BFS traversals.\n */\nfunction buildFOFICache(graph: PlannerGraph): Map<PlannerFanOut, FOFIInfo> {\n const cache = new Map<PlannerFanOut, FOFIInfo>();\n\n for (const fo of graph.fanOuts) {\n const info = findFIAndJoins(fo);\n cache.set(fo, info);\n }\n\n return cache;\n}\n\n/**\n * Check if any joins downstream of a FanOut (before reaching FanIn) are flipped.\n * If so, convert the FO to UFO and the FI to UFI.\n *\n * This must be called after join flipping and before propagateConstraints.\n */\nfunction checkAndConvertFOFI(fofiCache: Map<PlannerFanOut, FOFIInfo>): void {\n for (const [fo, info] of fofiCache) {\n const hasFlippedJoin = info.joinsBetween.some(j => j.type === 'flipped');\n if (info.fi && hasFlippedJoin) {\n fo.convertToUFO();\n info.fi.convertToUFI();\n }\n }\n}\n\n/**\n * Traverse from a FanOut through its outputs to find the corresponding FanIn\n * and collect all joins along the way.\n */\nfunction findFIAndJoins(fo: PlannerFanOut): FOFIInfo {\n const joinsBetween: PlannerJoin[] = [];\n let fi: PlannerFanIn | undefined = undefined;\n\n // BFS through FO outputs to find FI and collect joins\n const queue: PlannerNode[] = [...fo.outputs];\n const visited = new Set<PlannerNode>();\n\n while (queue.length > 0) {\n const node = must(queue.shift());\n if (visited.has(node)) continue;\n visited.add(node);\n\n switch (node.kind) {\n case 'join':\n joinsBetween.push(node);\n queue.push(node.output);\n break;\n case 'fan-out':\n // Nested FO - traverse its outputs\n queue.push(...node.outputs);\n break;\n case 'fan-in':\n // Found the FI - this is the boundary, don't traverse further\n fi = node;\n break;\n case 'connection':\n // Shouldn't happen in a well-formed graph\n break;\n case 'terminus':\n // Reached the end without finding FI\n break;\n }\n }\n\n return {fi, joinsBetween};\n}\n\n/**\n * Propagate unlimiting to all flipped joins in the graph.\n * When a join is flipped, its child becomes the outer loop and should no longer\n * be limited by EXISTS semantics.\n *\n * This must be called after join flipping and before propagateConstraints.\n */\nfunction propagateUnlimitForFlippedJoins(graph: PlannerGraph): void {\n for (const join of graph.joins) {\n if (join.type === 'flipped') {\n join.propagateUnlimit();\n }\n }\n}\n"],"mappings":"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"}
@@ -1,246 +1,261 @@
1
1
  import { assert } from "../../../shared/src/asserts.js";
2
- import { mergeConstraints } from "./planner-constraint.js";
3
2
  import { omitFanout } from "./planner-node.js";
3
+ import { mergeConstraints } from "./planner-constraint.js";
4
+ //#region ../zql/src/planner/planner-join.ts
5
+ /**
6
+ * Translate constraints for a flipped join from parent space to child space.
7
+ * Matches the runtime behavior of FlippedJoin.fetch() which translates
8
+ * parent constraints to child constraints using index-based key mapping.
9
+ *
10
+ * Example:
11
+ * parentConstraint = {issueID: undefined, projectID: undefined}
12
+ * childConstraint = {id: undefined, projectID: undefined}
13
+ * incomingConstraint = {issueID: 5}
14
+ * result = {id: 5} // issueID at index 0 maps to id at index 0
15
+ */
4
16
  function translateConstraintsForFlippedJoin(incomingConstraint, parentConstraint, childConstraint) {
5
- if (!incomingConstraint) return void 0;
6
- const parentKeys = Object.keys(parentConstraint);
7
- const childKeys = Object.keys(childConstraint);
8
- const translated = {};
9
- for (const [key, value] of Object.entries(incomingConstraint)) {
10
- const index = parentKeys.indexOf(key);
11
- if (index !== -1) {
12
- translated[childKeys[index]] = value;
13
- }
14
- }
15
- return Object.keys(translated).length > 0 ? translated : void 0;
16
- }
17
- class PlannerJoin {
18
- kind = "join";
19
- #parent;
20
- #child;
21
- #parentConstraint;
22
- #childConstraint;
23
- #flippable;
24
- planId;
25
- #output;
26
- // Set once during graph construction
27
- // Reset between planning attempts
28
- #type;
29
- #initialType;
30
- constructor(parent, child, parentConstraint, childConstraint, flippable, planId, initialType = "semi") {
31
- this.#type = initialType;
32
- this.#initialType = initialType;
33
- this.#parent = parent;
34
- this.#child = child;
35
- this.#childConstraint = childConstraint;
36
- this.#parentConstraint = parentConstraint;
37
- this.#flippable = flippable;
38
- this.planId = planId;
39
- }
40
- setOutput(node) {
41
- this.#output = node;
42
- }
43
- get output() {
44
- assert(this.#output !== void 0, "Output not set");
45
- return this.#output;
46
- }
47
- closestJoinOrSource() {
48
- return "join";
49
- }
50
- flipIfNeeded(input) {
51
- if (input === this.#child) {
52
- this.flip();
53
- } else {
54
- assert(
55
- input === this.#parent,
56
- "Can only flip a join from one of its inputs"
57
- );
58
- }
59
- }
60
- flip() {
61
- assert(this.#type === "semi", "Can only flip a semi-join");
62
- if (!this.#flippable) {
63
- throw new UnflippableJoinError(
64
- "Cannot flip a non-flippable join (e.g., NOT EXISTS)"
65
- );
66
- }
67
- this.#type = "flipped";
68
- }
69
- get type() {
70
- return this.#type;
71
- }
72
- isFlippable() {
73
- return this.#flippable;
74
- }
75
- /**
76
- * Propagate unlimiting when this join is flipped.
77
- * When a join is flipped:
78
- * 1. Child becomes outer loop → produces all rows (unlimited)
79
- * 2. Parent is fetched once per child row → effectively unlimited
80
- *
81
- * Example: If child produces 896 rows, parent is fetched 896 times.
82
- * Even if each fetch returns 1 row, parent produces 896 total rows.
83
- *
84
- * Propagation rules:
85
- * - Connection: call unlimit()
86
- * - Semi-join: continue to parent (outer loop)
87
- * - Flipped join: stop (already unlimited when it was flipped)
88
- * - Fan-out/Fan-in: propagate to all inputs
89
- */
90
- propagateUnlimit() {
91
- assert(this.#type === "flipped", "Can only unlimit a flipped join");
92
- this.#child.propagateUnlimitFromFlippedJoin();
93
- }
94
- /**
95
- * Called when a parent join is flipped and this join is part of its child subgraph.
96
- * Continue propagation to parent (the outer loop).
97
- * If we are hitting a semi-join, the parent drives.
98
- * If we are hitting a flip-join, well now we have to unlimit its parent too!
99
- */
100
- propagateUnlimitFromFlippedJoin() {
101
- this.#parent.propagateUnlimitFromFlippedJoin();
102
- }
103
- propagateConstraints(branchPattern, constraint, from, planDebugger) {
104
- planDebugger?.log({
105
- type: "node-constraint",
106
- nodeType: "join",
107
- node: this.getName(),
108
- branchPattern,
109
- constraint,
110
- from: from ? getNodeName(from) : "unknown"
111
- });
112
- if (this.#type === "semi") {
113
- this.#child.propagateConstraints(
114
- branchPattern,
115
- this.#childConstraint,
116
- this,
117
- planDebugger
118
- );
119
- this.#parent.propagateConstraints(
120
- branchPattern,
121
- constraint,
122
- this,
123
- planDebugger
124
- );
125
- } else if (this.#type === "flipped") {
126
- const translatedConstraint = translateConstraintsForFlippedJoin(
127
- constraint,
128
- this.#parentConstraint,
129
- this.#childConstraint
130
- );
131
- this.#child.propagateConstraints(
132
- branchPattern,
133
- translatedConstraint,
134
- this,
135
- planDebugger
136
- );
137
- this.#parent.propagateConstraints(
138
- branchPattern,
139
- mergeConstraints(constraint, this.#parentConstraint),
140
- this,
141
- planDebugger
142
- );
143
- }
144
- }
145
- reset() {
146
- this.#type = this.#initialType;
147
- }
148
- estimateCost(downstreamChildSelectivity, branchPattern, planDebugger) {
149
- const child = this.#child.estimateCost(1, branchPattern, planDebugger);
150
- const fanoutFactor = child.fanout(Object.keys(this.#childConstraint));
151
- const scaledChildSelectivity = 1 - Math.pow(1 - child.selectivity, fanoutFactor.fanout);
152
- const parent = this.#parent.estimateCost(
153
- // Selectivity flows up the graph from child to parent
154
- // so we can determine the total selectivity of all ANDed exists checks.
155
- this.#type === "flipped" ? 1 * downstreamChildSelectivity : scaledChildSelectivity * downstreamChildSelectivity,
156
- branchPattern,
157
- planDebugger
158
- );
159
- let costEstimate;
160
- if (this.type === "semi") {
161
- costEstimate = {
162
- startupCost: parent.startupCost,
163
- scanEst: parent.limit === void 0 ? parent.returnedRows : Math.min(
164
- parent.returnedRows,
165
- downstreamChildSelectivity === 0 ? 0 : parent.limit / downstreamChildSelectivity
166
- ),
167
- cost: parent.cost + parent.scanEst * (child.startupCost + child.cost + child.scanEst),
168
- returnedRows: parent.returnedRows * child.selectivity,
169
- selectivity: child.selectivity * parent.selectivity,
170
- limit: parent.limit,
171
- fanout: parent.fanout
172
- };
173
- } else {
174
- costEstimate = {
175
- startupCost: child.startupCost,
176
- scanEst: parent.limit === void 0 ? parent.returnedRows * child.returnedRows : Math.min(
177
- parent.returnedRows * child.returnedRows,
178
- downstreamChildSelectivity === 0 ? 0 : parent.limit / downstreamChildSelectivity
179
- ),
180
- cost: child.cost + child.scanEst * (parent.startupCost + parent.cost + parent.scanEst),
181
- // the child selectivity is not relevant here because it has already been taken into account via the flipping.
182
- // I.e., `child.returnedRows` is the estimated number of rows produced by the child _after_ taking filtering into account.
183
- returnedRows: parent.returnedRows * child.returnedRows,
184
- selectivity: parent.selectivity * child.selectivity,
185
- limit: parent.limit,
186
- fanout: parent.fanout
187
- };
188
- }
189
- if (planDebugger) {
190
- planDebugger.log({
191
- type: "node-cost",
192
- nodeType: "join",
193
- node: this.getName(),
194
- branchPattern,
195
- downstreamChildSelectivity,
196
- costEstimate: omitFanout(costEstimate),
197
- joinType: this.#type
198
- });
199
- }
200
- return costEstimate;
201
- }
202
- /**
203
- * Get a human-readable name for this join for debugging.
204
- * Format: "parentName ⋈ childName"
205
- */
206
- getName() {
207
- const parentName = getNodeName(this.#parent);
208
- const childName = getNodeName(this.#child);
209
- return `${parentName} ⋈ ${childName}`;
210
- }
211
- /**
212
- * Get debug information about this join's state.
213
- */
214
- getDebugInfo() {
215
- return {
216
- name: this.getName(),
217
- type: this.#type,
218
- planId: this.planId
219
- };
220
- }
221
- }
222
- class UnflippableJoinError extends Error {
223
- constructor(message) {
224
- super(message);
225
- this.name = "UnflippableJoinError";
226
- }
17
+ if (!incomingConstraint) return void 0;
18
+ const parentKeys = Object.keys(parentConstraint);
19
+ const childKeys = Object.keys(childConstraint);
20
+ const translated = {};
21
+ for (const [key, value] of Object.entries(incomingConstraint)) {
22
+ const index = parentKeys.indexOf(key);
23
+ if (index !== -1) translated[childKeys[index]] = value;
24
+ }
25
+ return Object.keys(translated).length > 0 ? translated : void 0;
227
26
  }
27
+ /**
28
+ * Semi-join overhead multiplier.
29
+ *
30
+ * Semi-joins represent correlated subqueries (EXISTS checks) which have
31
+ * execution overhead compared to flipped joins, even when logical row counts
32
+ * are identical. This overhead comes from:
33
+ * - Need to execute a separate correlation check for each parent row
34
+ * - Cannot leverage combined constraint checking as effectively as flipped joins
35
+ *
36
+ * A multiplier of 1.5 means semi-joins are estimated to be ~50% more expensive
37
+ * than equivalent flipped joins, which empirically matches observed performance
38
+ * differences in production workloads (e.g., 1.7x in zbugs benchmarks).
39
+ *
40
+ * Flipped joins have a different overhead in that they become unlimited. This
41
+ * is accounted for when propagating unlimits rather than here.
42
+ */
43
+ /**
44
+ * Represents a join between two data streams (parent and child).
45
+ *
46
+ * # Dual-State Pattern
47
+ * Like all planner nodes, PlannerJoin separates:
48
+ * 1. IMMUTABLE STRUCTURE: Parent/child nodes, constraints, flippability
49
+ * 2. MUTABLE STATE: Join type (semi/flipped), pinned status
50
+ *
51
+ * # Join Flipping
52
+ * A join can be in two states:
53
+ * - 'semi': Parent is outer loop, child is inner (semi-join for EXISTS)
54
+ * - 'flipped': Child is outer loop, parent is inner
55
+ *
56
+ * Flipping is the key optimization: choosing which table scans first.
57
+ * NOT EXISTS joins cannot be flipped (#flippable = false).
58
+ *
59
+ * # Constraint Propagation
60
+ * - Semi-join: Sends childConstraint to child, forwards received constraints to parent
61
+ * - Flipped join: Sends undefined to child, merges parentConstraint with received to parent
62
+ * - Unpinned join: Only forwards constraints to parent (doesn't constrain child yet)
63
+ *
64
+ * # Lifecycle
65
+ * 1. Construct with immutable structure (parent, child, constraints, flippability)
66
+ * 2. Wire to output node during graph construction
67
+ * 3. Planning calls flipIfNeeded() based on connection selection order
68
+ * 4. pin() locks the join type once chosen
69
+ * 5. reset() clears mutable state (type → 'semi', pinned → false)
70
+ */
71
+ var PlannerJoin = class {
72
+ kind = "join";
73
+ #parent;
74
+ #child;
75
+ #parentConstraint;
76
+ #childConstraint;
77
+ #flippable;
78
+ planId;
79
+ #output;
80
+ #type;
81
+ #initialType;
82
+ constructor(parent, child, parentConstraint, childConstraint, flippable, planId, initialType = "semi") {
83
+ this.#type = initialType;
84
+ this.#initialType = initialType;
85
+ this.#parent = parent;
86
+ this.#child = child;
87
+ this.#childConstraint = childConstraint;
88
+ this.#parentConstraint = parentConstraint;
89
+ this.#flippable = flippable;
90
+ this.planId = planId;
91
+ }
92
+ setOutput(node) {
93
+ this.#output = node;
94
+ }
95
+ get output() {
96
+ assert(this.#output !== void 0, "Output not set");
97
+ return this.#output;
98
+ }
99
+ closestJoinOrSource() {
100
+ return "join";
101
+ }
102
+ flipIfNeeded(input) {
103
+ if (input === this.#child) this.flip();
104
+ else assert(input === this.#parent, "Can only flip a join from one of its inputs");
105
+ }
106
+ flip() {
107
+ assert(this.#type === "semi", "Can only flip a semi-join");
108
+ if (!this.#flippable) throw new UnflippableJoinError("Cannot flip a non-flippable join (e.g., NOT EXISTS)");
109
+ this.#type = "flipped";
110
+ }
111
+ get type() {
112
+ return this.#type;
113
+ }
114
+ isFlippable() {
115
+ return this.#flippable;
116
+ }
117
+ /**
118
+ * Propagate unlimiting when this join is flipped.
119
+ * When a join is flipped:
120
+ * 1. Child becomes outer loop → produces all rows (unlimited)
121
+ * 2. Parent is fetched once per child row → effectively unlimited
122
+ *
123
+ * Example: If child produces 896 rows, parent is fetched 896 times.
124
+ * Even if each fetch returns 1 row, parent produces 896 total rows.
125
+ *
126
+ * Propagation rules:
127
+ * - Connection: call unlimit()
128
+ * - Semi-join: continue to parent (outer loop)
129
+ * - Flipped join: stop (already unlimited when it was flipped)
130
+ * - Fan-out/Fan-in: propagate to all inputs
131
+ */
132
+ propagateUnlimit() {
133
+ assert(this.#type === "flipped", "Can only unlimit a flipped join");
134
+ this.#child.propagateUnlimitFromFlippedJoin();
135
+ }
136
+ /**
137
+ * Called when a parent join is flipped and this join is part of its child subgraph.
138
+ * Continue propagation to parent (the outer loop).
139
+ * If we are hitting a semi-join, the parent drives.
140
+ * If we are hitting a flip-join, well now we have to unlimit its parent too!
141
+ */
142
+ propagateUnlimitFromFlippedJoin() {
143
+ this.#parent.propagateUnlimitFromFlippedJoin();
144
+ }
145
+ propagateConstraints(branchPattern, constraint, from, planDebugger) {
146
+ planDebugger?.log({
147
+ type: "node-constraint",
148
+ nodeType: "join",
149
+ node: this.getName(),
150
+ branchPattern,
151
+ constraint,
152
+ from: from ? getNodeName(from) : "unknown"
153
+ });
154
+ if (this.#type === "semi") {
155
+ this.#child.propagateConstraints(branchPattern, this.#childConstraint, this, planDebugger);
156
+ this.#parent.propagateConstraints(branchPattern, constraint, this, planDebugger);
157
+ } else if (this.#type === "flipped") {
158
+ const translatedConstraint = translateConstraintsForFlippedJoin(constraint, this.#parentConstraint, this.#childConstraint);
159
+ this.#child.propagateConstraints(branchPattern, translatedConstraint, this, planDebugger);
160
+ this.#parent.propagateConstraints(branchPattern, mergeConstraints(constraint, this.#parentConstraint), this, planDebugger);
161
+ }
162
+ }
163
+ reset() {
164
+ this.#type = this.#initialType;
165
+ }
166
+ estimateCost(downstreamChildSelectivity, branchPattern, planDebugger) {
167
+ /**
168
+ * downstreamChildSelectivity accumulates up a parent chain, not
169
+ * up child chains. Child chains represent independent sub-graphs.
170
+ * So we pass 1 for `downstreamChildSelectivity` when estimating child cost.
171
+ * Put another way, downstreamChildSelectivity impacts how many parent
172
+ * rows are returned.
173
+ */
174
+ const child = this.#child.estimateCost(1, branchPattern, planDebugger);
175
+ const fanoutFactor = child.fanout(Object.keys(this.#childConstraint));
176
+ const scaledChildSelectivity = 1 - Math.pow(1 - child.selectivity, fanoutFactor.fanout);
177
+ /**
178
+ * How selective is the graph from this point forward?
179
+ * If we are _very_ selective then we must scan more parent rows
180
+ * before finding a match.
181
+ * E.g., if childSelectivity = 0.1 and downstreamChildSelectivity = 0.5
182
+ * then we only pass 5% of parent rows (0.1 * 0.5 = 0.05).
183
+ *
184
+ * This is used to estimate how many rows will be pulled from the parent
185
+ * when trying to satisfy downstream constraints and a limit.
186
+ *
187
+ * NOTE: We do not know if the probabilities are correlated so we assume independence.
188
+ * This is a fundamental limitation of the planner.
189
+ */
190
+ const parent = this.#parent.estimateCost(this.#type === "flipped" ? 1 * downstreamChildSelectivity : scaledChildSelectivity * downstreamChildSelectivity, branchPattern, planDebugger);
191
+ let costEstimate;
192
+ if (this.type === "semi") costEstimate = {
193
+ startupCost: parent.startupCost,
194
+ scanEst: parent.limit === void 0 ? parent.returnedRows : Math.min(parent.returnedRows, downstreamChildSelectivity === 0 ? 0 : parent.limit / downstreamChildSelectivity),
195
+ cost: parent.cost + parent.scanEst * (child.startupCost + child.cost + child.scanEst),
196
+ returnedRows: parent.returnedRows * child.selectivity,
197
+ selectivity: child.selectivity * parent.selectivity,
198
+ limit: parent.limit,
199
+ fanout: parent.fanout
200
+ };
201
+ else costEstimate = {
202
+ startupCost: child.startupCost,
203
+ scanEst: parent.limit === void 0 ? parent.returnedRows * child.returnedRows : Math.min(parent.returnedRows * child.returnedRows, downstreamChildSelectivity === 0 ? 0 : parent.limit / downstreamChildSelectivity),
204
+ cost: child.cost + child.scanEst * (parent.startupCost + parent.cost + parent.scanEst),
205
+ returnedRows: parent.returnedRows * child.returnedRows,
206
+ selectivity: parent.selectivity * child.selectivity,
207
+ limit: parent.limit,
208
+ fanout: parent.fanout
209
+ };
210
+ if (planDebugger) planDebugger.log({
211
+ type: "node-cost",
212
+ nodeType: "join",
213
+ node: this.getName(),
214
+ branchPattern,
215
+ downstreamChildSelectivity,
216
+ costEstimate: omitFanout(costEstimate),
217
+ joinType: this.#type
218
+ });
219
+ return costEstimate;
220
+ }
221
+ /**
222
+ * Get a human-readable name for this join for debugging.
223
+ * Format: "parentName ⋈ childName"
224
+ */
225
+ getName() {
226
+ return `${getNodeName(this.#parent)} ⋈ ${getNodeName(this.#child)}`;
227
+ }
228
+ /**
229
+ * Get debug information about this join's state.
230
+ */
231
+ getDebugInfo() {
232
+ return {
233
+ name: this.getName(),
234
+ type: this.#type,
235
+ planId: this.planId
236
+ };
237
+ }
238
+ };
239
+ var UnflippableJoinError = class extends Error {
240
+ constructor(message) {
241
+ super(message);
242
+ this.name = "UnflippableJoinError";
243
+ }
244
+ };
245
+ /**
246
+ * Get a human-readable name for any planner node.
247
+ * Used for debugging and tracing.
248
+ */
228
249
  function getNodeName(node) {
229
- switch (node.kind) {
230
- case "connection":
231
- return node.name;
232
- case "join":
233
- return node.getName();
234
- case "fan-out":
235
- return "FO";
236
- case "fan-in":
237
- return "FI";
238
- case "terminus":
239
- return "terminus";
240
- }
250
+ switch (node.kind) {
251
+ case "connection": return node.name;
252
+ case "join": return node.getName();
253
+ case "fan-out": return "FO";
254
+ case "fan-in": return "FI";
255
+ case "terminus": return "terminus";
256
+ }
241
257
  }
242
- export {
243
- PlannerJoin,
244
- UnflippableJoinError
245
- };
246
- //# sourceMappingURL=planner-join.js.map
258
+ //#endregion
259
+ export { PlannerJoin };
260
+
261
+ //# sourceMappingURL=planner-join.js.map