@rocicorp/zero 1.11.0-canary.4 → 1.11.0-canary.40

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 (1015) hide show
  1. package/out/analyze-query/src/analyze-cli.js +4 -4
  2. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  3. package/out/analyze-query/src/bin-analyze.js +13 -12
  4. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  5. package/out/analyze-query/src/bin-transform.js +1 -1
  6. package/out/analyze-query/src/bin-transform.js.map +1 -1
  7. package/out/ast-to-zql/src/ast-to-zql.d.ts +8 -1
  8. package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
  9. package/out/ast-to-zql/src/ast-to-zql.js +25 -25
  10. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  11. package/out/otel/src/log-options.d.ts +16 -0
  12. package/out/otel/src/log-options.d.ts.map +1 -1
  13. package/out/otel/src/log-options.js +60 -6
  14. package/out/otel/src/log-options.js.map +1 -1
  15. package/out/replicache/src/bg-interval.d.ts +2 -1
  16. package/out/replicache/src/bg-interval.d.ts.map +1 -1
  17. package/out/replicache/src/bg-interval.js +13 -4
  18. package/out/replicache/src/bg-interval.js.map +1 -1
  19. package/out/replicache/src/btree/node.d.ts.map +1 -1
  20. package/out/replicache/src/btree/node.js +3 -6
  21. package/out/replicache/src/btree/node.js.map +1 -1
  22. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  23. package/out/replicache/src/dag/gc.js +8 -11
  24. package/out/replicache/src/dag/gc.js.map +1 -1
  25. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
  26. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
  27. package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
  28. package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
  29. package/out/replicache/src/dag/lazy-store.d.ts +17 -4
  30. package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
  31. package/out/replicache/src/dag/lazy-store.js +35 -9
  32. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  33. package/out/replicache/src/dag/store-impl.d.ts +12 -2
  34. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  35. package/out/replicache/src/dag/store-impl.js +29 -9
  36. package/out/replicache/src/dag/store-impl.js.map +1 -1
  37. package/out/replicache/src/db/rebase.d.ts +14 -2
  38. package/out/replicache/src/db/rebase.d.ts.map +1 -1
  39. package/out/replicache/src/db/rebase.js +27 -5
  40. package/out/replicache/src/db/rebase.js.map +1 -1
  41. package/out/replicache/src/get-kv-store-provider.d.ts +1 -1
  42. package/out/replicache/src/get-kv-store-provider.d.ts.map +1 -1
  43. package/out/replicache/src/get-kv-store-provider.js +4 -4
  44. package/out/replicache/src/get-kv-store-provider.js.map +1 -1
  45. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  46. package/out/replicache/src/kv/expo-sqlite/store.js +28 -5
  47. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  48. package/out/replicache/src/kv/idb-store.d.ts +18 -0
  49. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  50. package/out/replicache/src/kv/idb-store.js +30 -2
  51. package/out/replicache/src/kv/idb-store.js.map +1 -1
  52. package/out/replicache/src/kv/mem-fallback-store.d.ts +54 -0
  53. package/out/replicache/src/kv/mem-fallback-store.d.ts.map +1 -0
  54. package/out/replicache/src/kv/mem-fallback-store.js +177 -0
  55. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -0
  56. package/out/replicache/src/kv/mem-store.d.ts +1 -0
  57. package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
  58. package/out/replicache/src/kv/mem-store.js +3 -0
  59. package/out/replicache/src/kv/mem-store.js.map +1 -1
  60. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  61. package/out/replicache/src/kv/op-sqlite/store.js +4 -4
  62. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  63. package/out/replicache/src/kv/sqlite-store.d.ts +22 -1
  64. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  65. package/out/replicache/src/kv/sqlite-store.js +159 -14
  66. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  67. package/out/replicache/src/kv/store.d.ts +6 -0
  68. package/out/replicache/src/kv/store.d.ts.map +1 -1
  69. package/out/replicache/src/new-client-channel.js.map +1 -1
  70. package/out/replicache/src/persist/client-gc.d.ts +2 -1
  71. package/out/replicache/src/persist/client-gc.d.ts.map +1 -1
  72. package/out/replicache/src/persist/client-gc.js +2 -2
  73. package/out/replicache/src/persist/client-gc.js.map +1 -1
  74. package/out/replicache/src/persist/client-group-gc.d.ts +2 -1
  75. package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
  76. package/out/replicache/src/persist/client-group-gc.js +2 -2
  77. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  78. package/out/replicache/src/persist/clients.d.ts +2 -2
  79. package/out/replicache/src/persist/collect-idb-databases.d.ts +28 -8
  80. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  81. package/out/replicache/src/persist/collect-idb-databases.js +97 -20
  82. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  83. package/out/replicache/src/persist/heartbeat.d.ts +2 -1
  84. package/out/replicache/src/persist/heartbeat.d.ts.map +1 -1
  85. package/out/replicache/src/persist/heartbeat.js +2 -2
  86. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  87. package/out/replicache/src/persist/idb-databases-store-db-name.js +1 -1
  88. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
  89. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  90. package/out/replicache/src/persist/persist.js +18 -8
  91. package/out/replicache/src/persist/persist.js.map +1 -1
  92. package/out/replicache/src/persist/refresh.js +6 -2
  93. package/out/replicache/src/persist/refresh.js.map +1 -1
  94. package/out/replicache/src/replicache-impl.d.ts +85 -3
  95. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  96. package/out/replicache/src/replicache-impl.js +321 -29
  97. package/out/replicache/src/replicache-impl.js.map +1 -1
  98. package/out/replicache/src/replicache-options.d.ts +9 -0
  99. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  100. package/out/replicache/src/storage-failure.d.ts +37 -0
  101. package/out/replicache/src/storage-failure.d.ts.map +1 -0
  102. package/out/replicache/src/storage-failure.js +31 -0
  103. package/out/replicache/src/storage-failure.js.map +1 -0
  104. package/out/shared/src/arrays.d.ts +5 -0
  105. package/out/shared/src/arrays.d.ts.map +1 -1
  106. package/out/shared/src/arrays.js +8 -10
  107. package/out/shared/src/arrays.js.map +1 -1
  108. package/out/shared/src/centroid.d.ts +0 -1
  109. package/out/shared/src/centroid.d.ts.map +1 -1
  110. package/out/shared/src/centroid.js +1 -4
  111. package/out/shared/src/centroid.js.map +1 -1
  112. package/out/shared/src/error.d.ts +11 -0
  113. package/out/shared/src/error.d.ts.map +1 -1
  114. package/out/shared/src/error.js +35 -1
  115. package/out/shared/src/error.js.map +1 -1
  116. package/out/shared/src/hash.d.ts.map +1 -1
  117. package/out/shared/src/hash.js +32 -7
  118. package/out/shared/src/hash.js.map +1 -1
  119. package/out/shared/src/iterables.d.ts +2 -0
  120. package/out/shared/src/iterables.d.ts.map +1 -1
  121. package/out/shared/src/iterables.js +18 -1
  122. package/out/shared/src/iterables.js.map +1 -1
  123. package/out/shared/src/map.d.ts +24 -2
  124. package/out/shared/src/map.d.ts.map +1 -1
  125. package/out/shared/src/map.js +18 -4
  126. package/out/shared/src/map.js.map +1 -1
  127. package/out/shared/src/options-types.d.ts +2 -2
  128. package/out/shared/src/options.d.ts.map +1 -1
  129. package/out/shared/src/options.js +10 -7
  130. package/out/shared/src/options.js.map +1 -1
  131. package/out/shared/src/random-values.js +12 -1
  132. package/out/shared/src/random-values.js.map +1 -1
  133. package/out/shared/src/ring-buffer.d.ts +10 -0
  134. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  135. package/out/shared/src/ring-buffer.js +26 -1
  136. package/out/shared/src/ring-buffer.js.map +1 -1
  137. package/out/shared/src/tdigest.d.ts +10 -0
  138. package/out/shared/src/tdigest.d.ts.map +1 -1
  139. package/out/shared/src/tdigest.js +147 -63
  140. package/out/shared/src/tdigest.js.map +1 -1
  141. package/out/shared/src/valita.d.ts +88 -0
  142. package/out/shared/src/valita.d.ts.map +1 -1
  143. package/out/shared/src/valita.js +141 -23
  144. package/out/shared/src/valita.js.map +1 -1
  145. package/out/z2s/src/compiler.d.ts.map +1 -1
  146. package/out/z2s/src/compiler.js +10 -6
  147. package/out/z2s/src/compiler.js.map +1 -1
  148. package/out/z2s/src/sql.d.ts.map +1 -1
  149. package/out/z2s/src/sql.js +9 -5
  150. package/out/z2s/src/sql.js.map +1 -1
  151. package/out/zero/package.js +5 -6
  152. package/out/zero/package.js.map +1 -1
  153. package/out/zero/src/zero.js +2 -1
  154. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  155. package/out/zero-cache/src/auth/write-authorizer.js +1 -0
  156. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  157. package/out/zero-cache/src/config/normalize.d.ts +1 -0
  158. package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
  159. package/out/zero-cache/src/config/normalize.js +46 -4
  160. package/out/zero-cache/src/config/normalize.js.map +1 -1
  161. package/out/zero-cache/src/config/zero-config.d.ts +146 -24
  162. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  163. package/out/zero-cache/src/config/zero-config.js +494 -158
  164. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  165. package/out/zero-cache/src/custom/fetch.d.ts +1 -1
  166. package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
  167. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  168. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  169. package/out/zero-cache/src/db/lite-tables.js +3 -4
  170. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  171. package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
  172. package/out/zero-cache/src/db/migration-lite.js +5 -3
  173. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  174. package/out/zero-cache/src/observability/events.js +4 -1
  175. package/out/zero-cache/src/observability/events.js.map +1 -1
  176. package/out/zero-cache/src/observability/log-throttle.d.ts +44 -0
  177. package/out/zero-cache/src/observability/log-throttle.d.ts.map +1 -0
  178. package/out/zero-cache/src/observability/log-throttle.js +76 -0
  179. package/out/zero-cache/src/observability/log-throttle.js.map +1 -0
  180. package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
  181. package/out/zero-cache/src/observability/metrics.js +2 -7
  182. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  183. package/out/zero-cache/src/scripts/permissions.d.ts +16 -0
  184. package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
  185. package/out/zero-cache/src/scripts/permissions.js +3 -3
  186. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  187. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  188. package/out/zero-cache/src/server/change-streamer.js +123 -87
  189. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  190. package/out/zero-cache/src/server/inspector-delegate.d.ts +28 -2
  191. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  192. package/out/zero-cache/src/server/inspector-delegate.js +37 -17
  193. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  194. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  195. package/out/zero-cache/src/server/main.js +13 -2
  196. package/out/zero-cache/src/server/main.js.map +1 -1
  197. package/out/zero-cache/src/server/mutator.js +2 -0
  198. package/out/zero-cache/src/server/mutator.js.map +1 -1
  199. package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
  200. package/out/zero-cache/src/server/reaper.js +2 -0
  201. package/out/zero-cache/src/server/reaper.js.map +1 -1
  202. package/out/zero-cache/src/server/replicator.d.ts +7 -0
  203. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  204. package/out/zero-cache/src/server/replicator.js +103 -22
  205. package/out/zero-cache/src/server/replicator.js.map +1 -1
  206. package/out/zero-cache/src/server/runner/run-worker.d.ts.map +1 -1
  207. package/out/zero-cache/src/server/runner/run-worker.js +12 -6
  208. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  209. package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
  210. package/out/zero-cache/src/server/runner/zero-dispatcher.js +5 -0
  211. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  212. package/out/zero-cache/src/server/slot-keeper.d.ts +26 -0
  213. package/out/zero-cache/src/server/slot-keeper.d.ts.map +1 -0
  214. package/out/zero-cache/src/server/slot-keeper.js +181 -0
  215. package/out/zero-cache/src/server/slot-keeper.js.map +1 -0
  216. package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
  217. package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
  218. package/out/zero-cache/src/server/syncer-assigner.js +72 -0
  219. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
  220. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  221. package/out/zero-cache/src/server/syncer.js +40 -2
  222. package/out/zero-cache/src/server/syncer.js.map +1 -1
  223. package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
  224. package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
  225. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  226. package/out/zero-cache/src/server/worker-urls.d.ts +1 -0
  227. package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
  228. package/out/zero-cache/src/server/worker-urls.js +2 -1
  229. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  230. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  231. package/out/zero-cache/src/services/analyze.js +11 -9
  232. package/out/zero-cache/src/services/analyze.js.map +1 -1
  233. package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
  234. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +198 -24
  235. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  236. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
  237. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +16 -4
  238. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  239. package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts +24 -0
  240. package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts.map +1 -0
  241. package/out/zero-cache/src/services/change-source/common/init-cleanup.js +44 -0
  242. package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -0
  243. package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +82 -2
  244. package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -1
  245. package/out/zero-cache/src/services/change-source/common/replica-restore.js +21 -10
  246. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  247. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +1 -0
  248. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  249. package/out/zero-cache/src/services/change-source/common/replica-schema.js +15 -3
  250. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  251. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +1 -1
  252. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
  253. package/out/zero-cache/src/services/change-source/custom/change-source.js +7 -3
  254. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  255. package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +9 -0
  256. package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
  257. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +207 -20
  258. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  259. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +65 -0
  260. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
  261. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +312 -0
  262. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
  263. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +31 -18
  264. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  265. package/out/zero-cache/src/services/change-source/pg/change-source.js +132 -157
  266. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  267. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +44 -2
  268. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  269. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +60 -23
  270. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  271. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +66 -1
  272. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
  273. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +207 -24
  274. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  275. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
  276. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
  277. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
  278. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
  279. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +66 -21
  280. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  281. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +274 -68
  282. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  283. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
  284. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
  285. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  286. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  287. package/out/zero-cache/src/services/change-source/pg/schema/init.js +46 -1
  288. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  289. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
  290. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
  291. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
  292. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
  293. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +68 -27
  294. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  295. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +116 -35
  296. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  297. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +68 -0
  298. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +1 -0
  299. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +141 -0
  300. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -0
  301. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +45 -2
  302. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
  303. package/out/zero-cache/src/services/change-source/protocol/current/data.js +10 -1
  304. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  305. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +60 -3
  306. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
  307. package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +23 -10
  308. package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
  309. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +17 -7
  310. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  311. package/out/zero-cache/src/services/change-source/protocol/current.js +2 -1
  312. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts +72 -0
  313. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts.map +1 -0
  314. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js +162 -0
  315. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -0
  316. package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts +50 -0
  317. package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts.map +1 -0
  318. package/out/zero-cache/src/services/change-streamer/backfill-state.js +268 -0
  319. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -0
  320. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
  321. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +6 -17
  322. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  324. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +59 -8
  325. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  326. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +8 -2
  327. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
  328. package/out/zero-cache/src/services/change-streamer/broadcast.js +24 -4
  329. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  330. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -4
  331. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
  332. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +28 -8
  333. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
  334. package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +17 -0
  335. package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +1 -1
  336. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +44 -1
  337. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
  338. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +54 -6
  339. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  340. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +145 -35
  341. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  342. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +36 -0
  343. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  344. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +252 -111
  345. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  346. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +161 -17
  347. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  348. package/out/zero-cache/src/services/change-streamer/change-streamer.js +33 -2
  349. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  350. package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts +24 -0
  351. package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts.map +1 -0
  352. package/out/zero-cache/src/services/change-streamer/drain-tracker.js +67 -0
  353. package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -0
  354. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
  355. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
  356. package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
  357. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  358. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +53 -0
  359. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts.map +1 -0
  360. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +156 -0
  361. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -0
  362. package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts +243 -0
  363. package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts.map +1 -0
  364. package/out/zero-cache/src/services/change-streamer/restore-admission.js +317 -0
  365. package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -0
  366. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +58 -1
  367. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  368. package/out/zero-cache/src/services/change-streamer/schema/tables.js +107 -16
  369. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  370. package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts +92 -0
  371. package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts.map +1 -0
  372. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +42 -0
  373. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -0
  374. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +14 -2
  375. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
  376. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +23 -10
  377. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  378. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +7 -69
  379. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
  380. package/out/zero-cache/src/services/change-streamer/snapshot.js +21 -53
  381. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  382. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
  383. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
  384. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
  385. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  386. package/out/zero-cache/src/services/change-streamer/storer.d.ts +95 -4
  387. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  388. package/out/zero-cache/src/services/change-streamer/storer.js +294 -84
  389. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  390. package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +485 -0
  391. package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -0
  392. package/out/zero-cache/src/services/change-streamer/subscribe.js +93 -0
  393. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -0
  394. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +80 -2
  395. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
  396. package/out/zero-cache/src/services/change-streamer/subscriber.js +157 -20
  397. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  398. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +19 -1
  399. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
  400. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +23 -3
  401. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  402. package/out/zero-cache/src/services/http-service.d.ts +7 -1
  403. package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
  404. package/out/zero-cache/src/services/http-service.js +14 -2
  405. package/out/zero-cache/src/services/http-service.js.map +1 -1
  406. package/out/zero-cache/src/services/life-cycle.d.ts +68 -2
  407. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  408. package/out/zero-cache/src/services/life-cycle.js +155 -19
  409. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  410. package/out/zero-cache/src/services/litestream/commands.d.ts +35 -3
  411. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  412. package/out/zero-cache/src/services/litestream/commands.js +137 -35
  413. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  414. package/out/zero-cache/src/services/litestream/config-v5.yml +6 -7
  415. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +51 -24
  416. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  417. package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +10 -2
  418. package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +1 -1
  419. package/out/zero-cache/src/services/litestream/litestream-controller.js +3 -2
  420. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  421. package/out/zero-cache/src/services/litestream/restore-progress.d.ts +24 -0
  422. package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +1 -0
  423. package/out/zero-cache/src/services/litestream/restore-progress.js +91 -0
  424. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -0
  425. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
  426. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  427. package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
  428. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  429. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  430. package/out/zero-cache/src/services/mutagen/pusher.js +5 -6
  431. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  432. package/out/zero-cache/src/services/plannerz.d.ts +163 -0
  433. package/out/zero-cache/src/services/plannerz.d.ts.map +1 -0
  434. package/out/zero-cache/src/services/plannerz.js +267 -0
  435. package/out/zero-cache/src/services/plannerz.js.map +1 -0
  436. package/out/zero-cache/src/services/profz.d.ts +30 -0
  437. package/out/zero-cache/src/services/profz.d.ts.map +1 -0
  438. package/out/zero-cache/src/services/profz.js +163 -0
  439. package/out/zero-cache/src/services/profz.js.map +1 -0
  440. package/out/zero-cache/src/services/replicator/change-log-cookies.js +1 -1
  441. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  442. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +5 -4
  443. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -1
  444. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +20 -22
  445. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  446. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  447. package/out/zero-cache/src/services/replicator/change-processor.js +51 -5
  448. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  449. package/out/zero-cache/src/services/replicator/drain-handler.d.ts +74 -0
  450. package/out/zero-cache/src/services/replicator/drain-handler.d.ts.map +1 -0
  451. package/out/zero-cache/src/services/replicator/drain-handler.js +185 -0
  452. package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -0
  453. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +6 -2
  454. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  455. package/out/zero-cache/src/services/replicator/incremental-sync.js +114 -28
  456. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  457. package/out/zero-cache/src/services/replicator/replication-status.d.ts +35 -1
  458. package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
  459. package/out/zero-cache/src/services/replicator/replication-status.js +99 -8
  460. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  461. package/out/zero-cache/src/services/replicator/replicator.d.ts +5 -1
  462. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  463. package/out/zero-cache/src/services/replicator/replicator.js +5 -2
  464. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  465. package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +16 -1
  466. package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +1 -1
  467. package/out/zero-cache/src/services/replicator/reporter/recorder.js +70 -27
  468. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  469. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +23 -2
  470. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -1
  471. package/out/zero-cache/src/services/replicator/schema/backfilling.js +54 -2
  472. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  473. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +6 -6
  474. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
  475. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +19 -14
  476. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  477. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +11 -3
  478. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
  479. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  480. package/out/zero-cache/src/services/replicator/write-worker.js +5 -1
  481. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  482. package/out/zero-cache/src/services/run-ast.d.ts +12 -0
  483. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  484. package/out/zero-cache/src/services/run-ast.js +42 -22
  485. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  486. package/out/zero-cache/src/services/runner.d.ts +2 -1
  487. package/out/zero-cache/src/services/runner.d.ts.map +1 -1
  488. package/out/zero-cache/src/services/runner.js +10 -2
  489. package/out/zero-cache/src/services/runner.js.map +1 -1
  490. package/out/zero-cache/src/services/statz.d.ts +4 -0
  491. package/out/zero-cache/src/services/statz.d.ts.map +1 -1
  492. package/out/zero-cache/src/services/statz.js +22 -5
  493. package/out/zero-cache/src/services/statz.js.map +1 -1
  494. package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts +26 -0
  495. package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts.map +1 -0
  496. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js +26 -0
  497. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -0
  498. package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts +79 -0
  499. package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts.map +1 -0
  500. package/out/zero-cache/src/services/view-syncer/batch-pacer.js +249 -0
  501. package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -0
  502. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +19 -2
  503. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  504. package/out/zero-cache/src/services/view-syncer/client-handler.js +42 -30
  505. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  506. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +27 -2
  507. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  508. package/out/zero-cache/src/services/view-syncer/cvr-store.js +86 -21
  509. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  510. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +75 -12
  511. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  512. package/out/zero-cache/src/services/view-syncer/cvr.js +234 -43
  513. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  514. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +81 -0
  515. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +1 -0
  516. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +128 -0
  517. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -0
  518. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
  519. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  520. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
  521. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  522. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
  523. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
  524. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
  525. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
  526. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +12 -2
  527. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
  528. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +29 -5
  529. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  530. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +165 -9
  531. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  532. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +953 -209
  533. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  534. package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +7 -0
  535. package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +1 -0
  536. package/out/zero-cache/src/services/view-syncer/plan-warnings.js +35 -0
  537. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -0
  538. package/out/zero-cache/src/services/view-syncer/push-cost.d.ts +132 -0
  539. package/out/zero-cache/src/services/view-syncer/push-cost.d.ts.map +1 -0
  540. package/out/zero-cache/src/services/view-syncer/push-cost.js +164 -0
  541. package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -0
  542. package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts +55 -0
  543. package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts.map +1 -0
  544. package/out/zero-cache/src/services/view-syncer/push-cutoff.js +56 -0
  545. package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -0
  546. package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
  547. package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -6
  548. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  549. package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +25 -0
  550. package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +1 -0
  551. package/out/zero-cache/src/services/view-syncer/query-shape.js +28 -0
  552. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -0
  553. package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +89 -0
  554. package/out/zero-cache/src/services/view-syncer/query-stats.d.ts.map +1 -0
  555. package/out/zero-cache/src/services/view-syncer/query-stats.js +233 -0
  556. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -0
  557. package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +2 -107
  558. package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
  559. package/out/zero-cache/src/services/view-syncer/schema/types.js +5 -20
  560. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  561. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +95 -0
  562. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +1 -0
  563. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +155 -0
  564. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -0
  565. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +229 -16
  566. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  567. package/out/zero-cache/src/services/view-syncer/snapshotter.js +455 -43
  568. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  569. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +8 -2
  570. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  571. package/out/zero-cache/src/services/view-syncer/view-syncer.js +788 -71
  572. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  573. package/out/zero-cache/src/types/pg-data-type.d.ts +2 -0
  574. package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
  575. package/out/zero-cache/src/types/pg-data-type.js +6 -1
  576. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  577. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  578. package/out/zero-cache/src/types/pg.js +2 -2
  579. package/out/zero-cache/src/types/pg.js.map +1 -1
  580. package/out/zero-cache/src/types/processes.d.ts +50 -0
  581. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  582. package/out/zero-cache/src/types/processes.js +43 -4
  583. package/out/zero-cache/src/types/processes.js.map +1 -1
  584. package/out/zero-cache/src/types/profiler.d.ts +12 -0
  585. package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
  586. package/out/zero-cache/src/types/profiler.js +46 -1
  587. package/out/zero-cache/src/types/profiler.js.map +1 -1
  588. package/out/zero-cache/src/types/row-key.d.ts +1 -15
  589. package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
  590. package/out/zero-cache/src/types/row-key.js +6 -8
  591. package/out/zero-cache/src/types/row-key.js.map +1 -1
  592. package/out/zero-cache/src/types/streams.d.ts +49 -7
  593. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  594. package/out/zero-cache/src/types/streams.js +190 -58
  595. package/out/zero-cache/src/types/streams.js.map +1 -1
  596. package/out/zero-cache/src/types/subscription.d.ts +15 -0
  597. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  598. package/out/zero-cache/src/types/subscription.js +123 -31
  599. package/out/zero-cache/src/types/subscription.js.map +1 -1
  600. package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
  601. package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
  602. package/out/zero-cache/src/types/websocket-handoff.js +18 -9
  603. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  604. package/out/zero-cache/src/types/ws.d.ts.map +1 -1
  605. package/out/zero-cache/src/types/ws.js +1 -16
  606. package/out/zero-cache/src/types/ws.js.map +1 -1
  607. package/out/zero-cache/src/workers/connect-params.d.ts +1 -0
  608. package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
  609. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  610. package/out/zero-cache/src/workers/connection.d.ts +2 -1
  611. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  612. package/out/zero-cache/src/workers/connection.js +9 -1
  613. package/out/zero-cache/src/workers/connection.js.map +1 -1
  614. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  615. package/out/zero-cache/src/workers/replicator.js +24 -7
  616. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  617. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  618. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
  619. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  620. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  621. package/out/zero-cache/src/workers/syncer.js +55 -4
  622. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  623. package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
  624. package/out/zero-client/src/client/active-clients-manager.js +4 -1
  625. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  626. package/out/zero-client/src/client/connection-manager.d.ts +20 -0
  627. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  628. package/out/zero-client/src/client/connection-manager.js +77 -13
  629. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  630. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  631. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  632. package/out/zero-client/src/client/connection-status-enum.js +3 -1
  633. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  634. package/out/zero-client/src/client/connection.d.ts +6 -0
  635. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  636. package/out/zero-client/src/client/connection.js +2 -1
  637. package/out/zero-client/src/client/connection.js.map +1 -1
  638. package/out/zero-client/src/client/context.d.ts +23 -13
  639. package/out/zero-client/src/client/context.d.ts.map +1 -1
  640. package/out/zero-client/src/client/context.js +94 -26
  641. package/out/zero-client/src/client/context.js.map +1 -1
  642. package/out/zero-client/src/client/crud-impl.d.ts.map +1 -1
  643. package/out/zero-client/src/client/crud-impl.js +1 -1
  644. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  645. package/out/zero-client/src/client/custom.d.ts +5 -4
  646. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  647. package/out/zero-client/src/client/custom.js +3 -3
  648. package/out/zero-client/src/client/custom.js.map +1 -1
  649. package/out/zero-client/src/client/inspector/lazy-inspector.js +1 -1
  650. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  651. package/out/zero-client/src/client/ivm-branch.js +20 -3
  652. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  653. package/out/zero-client/src/client/keys.d.ts.map +1 -1
  654. package/out/zero-client/src/client/keys.js +19 -1
  655. package/out/zero-client/src/client/keys.js.map +1 -1
  656. package/out/zero-client/src/client/make-mutate-property.d.ts +1 -1
  657. package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
  658. package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
  659. package/out/zero-client/src/client/make-replicache-mutators.d.ts.map +1 -1
  660. package/out/zero-client/src/client/make-replicache-mutators.js +1 -1
  661. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  662. package/out/zero-client/src/client/mutation-tracker.d.ts +2 -2
  663. package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
  664. package/out/zero-client/src/client/mutation-tracker.js +3 -7
  665. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  666. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  667. package/out/zero-client/src/client/mutator-proxy.js +9 -4
  668. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  669. package/out/zero-client/src/client/options.d.ts +33 -0
  670. package/out/zero-client/src/client/options.d.ts.map +1 -1
  671. package/out/zero-client/src/client/options.js.map +1 -1
  672. package/out/zero-client/src/client/query-manager.d.ts +9 -0
  673. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  674. package/out/zero-client/src/client/query-manager.js +47 -14
  675. package/out/zero-client/src/client/query-manager.js.map +1 -1
  676. package/out/zero-client/src/client/reload-error-handler.js +2 -2
  677. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  678. package/out/zero-client/src/client/storage-version.d.ts +23 -0
  679. package/out/zero-client/src/client/storage-version.d.ts.map +1 -0
  680. package/out/zero-client/src/client/version.js +1 -1
  681. package/out/zero-client/src/client/zero-rep.d.ts +1 -0
  682. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  683. package/out/zero-client/src/client/zero-rep.js +8 -6
  684. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  685. package/out/zero-client/src/client/zero.d.ts +18 -3
  686. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  687. package/out/zero-client/src/client/zero.js +86 -48
  688. package/out/zero-client/src/client/zero.js.map +1 -1
  689. package/out/zero-client/src/mod.d.ts +2 -1
  690. package/out/zero-client/src/mod.d.ts.map +1 -1
  691. package/out/zero-client/src/mod.js +1 -0
  692. package/out/zero-client/src/types/query-result.d.ts +2 -0
  693. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  694. package/out/zero-events/src/status.d.ts +64 -0
  695. package/out/zero-events/src/status.d.ts.map +1 -1
  696. package/out/zero-protocol/src/analyze-query-result.d.ts +12 -12
  697. package/out/zero-protocol/src/analyze-query-result.d.ts.map +1 -1
  698. package/out/zero-protocol/src/analyze-query-result.js +3 -3
  699. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  700. package/out/zero-protocol/src/ast.d.ts +24 -0
  701. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  702. package/out/zero-protocol/src/ast.js +39 -16
  703. package/out/zero-protocol/src/ast.js.map +1 -1
  704. package/out/zero-protocol/src/down.d.ts +36 -36
  705. package/out/zero-protocol/src/inspect-down.d.ts +31 -31
  706. package/out/zero-protocol/src/inspect-up.d.ts +158 -61
  707. package/out/zero-protocol/src/inspect-up.d.ts.map +1 -1
  708. package/out/zero-protocol/src/inspect-up.js +12 -6
  709. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  710. package/out/zero-protocol/src/protocol-version.d.ts +4 -1
  711. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  712. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  713. package/out/zero-protocol/src/queries-patch.js +2 -2
  714. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  715. package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
  716. package/out/zero-protocol/src/query-hash.js +2 -5
  717. package/out/zero-protocol/src/query-hash.js.map +1 -1
  718. package/out/zero-protocol/src/up.d.ts +766 -256
  719. package/out/zero-protocol/src/up.d.ts.map +1 -1
  720. package/out/zero-protocol/src/up.js +25 -3
  721. package/out/zero-protocol/src/up.js.map +1 -1
  722. package/out/zero-react/src/use-query.d.ts +5 -4
  723. package/out/zero-react/src/use-query.d.ts.map +1 -1
  724. package/out/zero-react/src/use-query.js +75 -8
  725. package/out/zero-react/src/use-query.js.map +1 -1
  726. package/out/zero-react/src/zero.js +1 -0
  727. package/out/zero-server/src/adapters/drizzle.d.ts +16 -4
  728. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  729. package/out/zero-server/src/adapters/drizzle.js +19 -11
  730. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  731. package/out/zero-server/src/adapters/kysely.d.ts +6 -3
  732. package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
  733. package/out/zero-server/src/adapters/kysely.js +16 -6
  734. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  735. package/out/zero-server/src/adapters/pg.d.ts +7 -2
  736. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  737. package/out/zero-server/src/adapters/pg.js +34 -10
  738. package/out/zero-server/src/adapters/pg.js.map +1 -1
  739. package/out/zero-server/src/adapters/postgresjs.d.ts +4 -2
  740. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  741. package/out/zero-server/src/adapters/postgresjs.js +15 -5
  742. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  743. package/out/zero-server/src/adapters/prisma.d.ts +17 -5
  744. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  745. package/out/zero-server/src/adapters/prisma.js +20 -6
  746. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  747. package/out/zero-server/src/closable-db-transaction.d.ts +16 -0
  748. package/out/zero-server/src/closable-db-transaction.d.ts.map +1 -0
  749. package/out/zero-server/src/closable-db-transaction.js +31 -0
  750. package/out/zero-server/src/closable-db-transaction.js.map +1 -0
  751. package/out/zero-server/src/custom.d.ts +10 -4
  752. package/out/zero-server/src/custom.d.ts.map +1 -1
  753. package/out/zero-server/src/custom.js +15 -6
  754. package/out/zero-server/src/custom.js.map +1 -1
  755. package/out/zero-server/src/logging.d.ts +2 -2
  756. package/out/zero-server/src/logging.d.ts.map +1 -1
  757. package/out/zero-server/src/logging.js +2 -2
  758. package/out/zero-server/src/logging.js.map +1 -1
  759. package/out/zero-server/src/mod.d.ts +2 -1
  760. package/out/zero-server/src/mod.d.ts.map +1 -1
  761. package/out/zero-server/src/pg-query-executor.d.ts +2 -2
  762. package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
  763. package/out/zero-server/src/pg-query-executor.js +2 -2
  764. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  765. package/out/zero-server/src/process-mutations.d.ts +25 -4
  766. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  767. package/out/zero-server/src/process-mutations.js +103 -52
  768. package/out/zero-server/src/process-mutations.js.map +1 -1
  769. package/out/zero-server/src/push-processor.d.ts +8 -2
  770. package/out/zero-server/src/push-processor.d.ts.map +1 -1
  771. package/out/zero-server/src/push-processor.js +12 -4
  772. package/out/zero-server/src/push-processor.js.map +1 -1
  773. package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
  774. package/out/zero-server/src/queries/process-queries.js +1 -1
  775. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  776. package/out/zero-server/src/schema.d.ts +2 -2
  777. package/out/zero-server/src/schema.d.ts.map +1 -1
  778. package/out/zero-server/src/schema.js +3 -2
  779. package/out/zero-server/src/schema.js.map +1 -1
  780. package/out/zero-server/src/transaction-options.d.ts +24 -0
  781. package/out/zero-server/src/transaction-options.d.ts.map +1 -0
  782. package/out/zero-server/src/transaction-options.js +11 -0
  783. package/out/zero-server/src/transaction-options.js.map +1 -0
  784. package/out/zero-server/src/zql-database.d.ts +21 -1
  785. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  786. package/out/zero-server/src/zql-database.js +61 -24
  787. package/out/zero-server/src/zql-database.js.map +1 -1
  788. package/out/zero-solid/src/solid-view.d.ts +17 -0
  789. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  790. package/out/zero-solid/src/solid-view.js +39 -1
  791. package/out/zero-solid/src/solid-view.js.map +1 -1
  792. package/out/zero-solid/src/use-query.js +1 -2
  793. package/out/zero-solid/src/use-query.js.map +1 -1
  794. package/out/zero-solid/src/zero.js +1 -0
  795. package/out/zql/src/builder/builder.d.ts +25 -0
  796. package/out/zql/src/builder/builder.d.ts.map +1 -1
  797. package/out/zql/src/builder/builder.js +69 -19
  798. package/out/zql/src/builder/builder.js.map +1 -1
  799. package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +43 -0
  800. package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +1 -0
  801. package/out/zql/src/builder/correlated-predicate-pushdown.js +161 -0
  802. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -0
  803. package/out/zql/src/builder/debug-delegate.d.ts +6 -1
  804. package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
  805. package/out/zql/src/builder/debug-delegate.js +14 -2
  806. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  807. package/out/zql/src/ivm/array-view.d.ts +29 -0
  808. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  809. package/out/zql/src/ivm/array-view.js +74 -16
  810. package/out/zql/src/ivm/array-view.js.map +1 -1
  811. package/out/zql/src/ivm/cap.d.ts +2 -1
  812. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  813. package/out/zql/src/ivm/cap.js +14 -4
  814. package/out/zql/src/ivm/cap.js.map +1 -1
  815. package/out/zql/src/ivm/data.d.ts.map +1 -1
  816. package/out/zql/src/ivm/data.js +8 -3
  817. package/out/zql/src/ivm/data.js.map +1 -1
  818. package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
  819. package/out/zql/src/ivm/deferred-input.js +3 -2
  820. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  821. package/out/zql/src/ivm/exists.d.ts +3 -1
  822. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  823. package/out/zql/src/ivm/exists.js +4 -1
  824. package/out/zql/src/ivm/exists.js.map +1 -1
  825. package/out/zql/src/ivm/fan-in.d.ts +6 -2
  826. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  827. package/out/zql/src/ivm/fan-in.js +13 -5
  828. package/out/zql/src/ivm/fan-in.js.map +1 -1
  829. package/out/zql/src/ivm/fan-out.d.ts +5 -2
  830. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  831. package/out/zql/src/ivm/fan-out.js +4 -0
  832. package/out/zql/src/ivm/fan-out.js.map +1 -1
  833. package/out/zql/src/ivm/filter-operators.d.ts +8 -6
  834. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  835. package/out/zql/src/ivm/filter-operators.js +19 -8
  836. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  837. package/out/zql/src/ivm/filter.d.ts +5 -2
  838. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  839. package/out/zql/src/ivm/filter.js +10 -4
  840. package/out/zql/src/ivm/filter.js.map +1 -1
  841. package/out/zql/src/ivm/flipped-join.d.ts +9 -4
  842. package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
  843. package/out/zql/src/ivm/flipped-join.js +97 -46
  844. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  845. package/out/zql/src/ivm/join-index-tap.d.ts +33 -0
  846. package/out/zql/src/ivm/join-index-tap.d.ts.map +1 -0
  847. package/out/zql/src/ivm/join-index-tap.js +70 -0
  848. package/out/zql/src/ivm/join-index-tap.js.map +1 -0
  849. package/out/zql/src/ivm/join-index.d.ts +35 -0
  850. package/out/zql/src/ivm/join-index.d.ts.map +1 -0
  851. package/out/zql/src/ivm/join-index.js +141 -0
  852. package/out/zql/src/ivm/join-index.js.map +1 -0
  853. package/out/zql/src/ivm/join-utils.d.ts +6 -0
  854. package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
  855. package/out/zql/src/ivm/join-utils.js +22 -1
  856. package/out/zql/src/ivm/join-utils.js.map +1 -1
  857. package/out/zql/src/ivm/join.d.ts +19 -1
  858. package/out/zql/src/ivm/join.d.ts.map +1 -1
  859. package/out/zql/src/ivm/join.js +107 -15
  860. package/out/zql/src/ivm/join.js.map +1 -1
  861. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  862. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  863. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
  864. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  865. package/out/zql/src/ivm/memory-source.d.ts +29 -4
  866. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  867. package/out/zql/src/ivm/memory-source.js +70 -34
  868. package/out/zql/src/ivm/memory-source.js.map +1 -1
  869. package/out/zql/src/ivm/memory-storage.d.ts +1 -0
  870. package/out/zql/src/ivm/memory-storage.d.ts.map +1 -1
  871. package/out/zql/src/ivm/memory-storage.js +1 -0
  872. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  873. package/out/zql/src/ivm/operator.d.ts +45 -10
  874. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  875. package/out/zql/src/ivm/operator.js +9 -4
  876. package/out/zql/src/ivm/operator.js.map +1 -1
  877. package/out/zql/src/ivm/push-accumulated.d.ts +6 -1
  878. package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
  879. package/out/zql/src/ivm/push-accumulated.js +47 -2
  880. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  881. package/out/zql/src/ivm/skip.d.ts +2 -1
  882. package/out/zql/src/ivm/skip.d.ts.map +1 -1
  883. package/out/zql/src/ivm/skip.js +3 -0
  884. package/out/zql/src/ivm/skip.js.map +1 -1
  885. package/out/zql/src/ivm/take-gate.d.ts +57 -0
  886. package/out/zql/src/ivm/take-gate.d.ts.map +1 -0
  887. package/out/zql/src/ivm/take-gate.js +106 -0
  888. package/out/zql/src/ivm/take-gate.js.map +1 -0
  889. package/out/zql/src/ivm/take.d.ts +8 -2
  890. package/out/zql/src/ivm/take.d.ts.map +1 -1
  891. package/out/zql/src/ivm/take.js +139 -103
  892. package/out/zql/src/ivm/take.js.map +1 -1
  893. package/out/zql/src/ivm/union-fan-in.d.ts +3 -0
  894. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  895. package/out/zql/src/ivm/union-fan-in.js +63 -10
  896. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  897. package/out/zql/src/ivm/union-fan-out.d.ts +2 -1
  898. package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
  899. package/out/zql/src/ivm/union-fan-out.js +5 -0
  900. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  901. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  902. package/out/zql/src/ivm/view-apply-change.js +9 -4
  903. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  904. package/out/zql/src/ivm/view.d.ts +15 -0
  905. package/out/zql/src/ivm/view.d.ts.map +1 -1
  906. package/out/zql/src/mutate/custom.d.ts +53 -1
  907. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  908. package/out/zql/src/mutate/custom.js.map +1 -1
  909. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  910. package/out/zql/src/mutate/mutator-registry.js +3 -3
  911. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  912. package/out/zql/src/mutate/mutator.d.ts +2 -2
  913. package/out/zql/src/mutate/mutator.d.ts.map +1 -1
  914. package/out/zql/src/mutate/mutator.js.map +1 -1
  915. package/out/zql/src/planner/planner-builder.d.ts +23 -3
  916. package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
  917. package/out/zql/src/planner/planner-builder.js +34 -17
  918. package/out/zql/src/planner/planner-builder.js.map +1 -1
  919. package/out/zql/src/planner/planner-connection.d.ts +58 -2
  920. package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
  921. package/out/zql/src/planner/planner-connection.js +103 -11
  922. package/out/zql/src/planner/planner-connection.js.map +1 -1
  923. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  924. package/out/zql/src/planner/planner-debug.js +3 -8
  925. package/out/zql/src/planner/planner-debug.js.map +1 -1
  926. package/out/zql/src/planner/planner-graph.d.ts +10 -0
  927. package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
  928. package/out/zql/src/planner/planner-graph.js +14 -0
  929. package/out/zql/src/planner/planner-graph.js.map +1 -1
  930. package/out/zql/src/planner/planner-source.d.ts +2 -2
  931. package/out/zql/src/planner/planner-source.d.ts.map +1 -1
  932. package/out/zql/src/planner/planner-source.js +2 -2
  933. package/out/zql/src/planner/planner-source.js.map +1 -1
  934. package/out/zql/src/planner/planner-warnings.d.ts +83 -0
  935. package/out/zql/src/planner/planner-warnings.d.ts.map +1 -0
  936. package/out/zql/src/planner/planner-warnings.js +78 -0
  937. package/out/zql/src/planner/planner-warnings.js.map +1 -0
  938. package/out/zql/src/query/expression.d.ts +2 -2
  939. package/out/zql/src/query/expression.d.ts.map +1 -1
  940. package/out/zql/src/query/expression.js.map +1 -1
  941. package/out/zql/src/query/measure-push-operator.d.ts +9 -2
  942. package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
  943. package/out/zql/src/query/measure-push-operator.js +52 -5
  944. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  945. package/out/zql/src/query/query-delegate-base.d.ts +4 -2
  946. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  947. package/out/zql/src/query/query-delegate-base.js +66 -33
  948. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  949. package/out/zql/src/query/query-delegate.d.ts +33 -6
  950. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  951. package/out/zql/src/query/query-impl.d.ts +1 -0
  952. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  953. package/out/zql/src/query/query-impl.js +6 -23
  954. package/out/zql/src/query/query-impl.js.map +1 -1
  955. package/out/zql/src/query/query-registry.js +1 -1
  956. package/out/zql/src/query/query-transitions.d.ts.map +1 -1
  957. package/out/zql/src/query/query-transitions.js +2 -5
  958. package/out/zql/src/query/query-transitions.js.map +1 -1
  959. package/out/zql/src/query/query.d.ts +26 -10
  960. package/out/zql/src/query/query.d.ts.map +1 -1
  961. package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
  962. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  963. package/out/zql/src/query/runnable-query-impl.js +2 -10
  964. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  965. package/out/zql/src/query/typed-view.d.ts +1 -1
  966. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  967. package/out/zqlite/src/database-storage.d.ts.map +1 -1
  968. package/out/zqlite/src/database-storage.js +9 -1
  969. package/out/zqlite/src/database-storage.js.map +1 -1
  970. package/out/zqlite/src/db.d.ts +17 -1
  971. package/out/zqlite/src/db.d.ts.map +1 -1
  972. package/out/zqlite/src/db.js +73 -30
  973. package/out/zqlite/src/db.js.map +1 -1
  974. package/out/zqlite/src/index-usage.d.ts +19 -0
  975. package/out/zqlite/src/index-usage.d.ts.map +1 -0
  976. package/out/zqlite/src/index-usage.js +49 -0
  977. package/out/zqlite/src/index-usage.js.map +1 -0
  978. package/out/zqlite/src/pending-delta.d.ts +110 -0
  979. package/out/zqlite/src/pending-delta.d.ts.map +1 -0
  980. package/out/zqlite/src/pending-delta.js +278 -0
  981. package/out/zqlite/src/pending-delta.js.map +1 -0
  982. package/out/zqlite/src/query-builder.d.ts +17 -1
  983. package/out/zqlite/src/query-builder.d.ts.map +1 -1
  984. package/out/zqlite/src/query-builder.js +111 -20
  985. package/out/zqlite/src/query-builder.js.map +1 -1
  986. package/out/zqlite/src/query-delegate.d.ts.map +1 -1
  987. package/out/zqlite/src/query-delegate.js +10 -7
  988. package/out/zqlite/src/query-delegate.js.map +1 -1
  989. package/out/zqlite/src/resolve-scalar-subqueries.d.ts +3 -1
  990. package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
  991. package/out/zqlite/src/resolve-scalar-subqueries.js +1 -0
  992. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  993. package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
  994. package/out/zqlite/src/sqlite-cost-model.js +53 -1
  995. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  996. package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
  997. package/out/zqlite/src/sqlite-stat-fanout.js +5 -31
  998. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  999. package/out/zqlite/src/sqlite-stat4-sample.d.ts +37 -0
  1000. package/out/zqlite/src/sqlite-stat4-sample.d.ts.map +1 -0
  1001. package/out/zqlite/src/sqlite-stat4-sample.js +61 -0
  1002. package/out/zqlite/src/sqlite-stat4-sample.js.map +1 -0
  1003. package/out/zqlite/src/table-source.d.ts +87 -2
  1004. package/out/zqlite/src/table-source.d.ts.map +1 -1
  1005. package/out/zqlite/src/table-source.js +276 -42
  1006. package/out/zqlite/src/table-source.js.map +1 -1
  1007. package/package.json +5 -6
  1008. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +0 -25
  1009. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +0 -1
  1010. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +0 -83
  1011. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +0 -1
  1012. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +0 -29
  1013. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +0 -1
  1014. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +0 -154
  1015. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +0 -1
@@ -1,6 +1,8 @@
1
1
  import { assert, unreachable } from "../../../../shared/src/asserts.js";
2
2
  import { deepEqual } from "../../../../shared/src/json.js";
3
+ import { getOrInsertComputed } from "../../../../shared/src/map.js";
3
4
  import { must } from "../../../../shared/src/must.js";
5
+ import { assignProperty } from "../../../../shared/src/objects.js";
4
6
  import { skipYields } from "../../../../zql/src/ivm/skip-yields.js";
5
7
  import { throwOutput } from "../../../../zql/src/ivm/operator.js";
6
8
  import { MeasurePushOperator } from "../../../../zql/src/query/measure-push-operator.js";
@@ -14,13 +16,20 @@ import { resolveSimpleScalarSubqueries } from "../../../../zqlite/src/resolve-sc
14
16
  import { randInt } from "../../../../shared/src/rand.js";
15
17
  import { createSQLiteCostModel } from "../../../../zqlite/src/sqlite-cost-model.js";
16
18
  import { reloadPermissionsIfChanged } from "../../auth/load-permissions.js";
19
+ import { LogThrottle } from "../../observability/log-throttle.js";
17
20
  import { getOrCreateCounter, getOrCreateLatencyHistogram } from "../../observability/metrics.js";
18
21
  import "../../types/row-key.js";
19
22
  import { getSubscriptionState } from "../replicator/schema/replication-state.js";
20
23
  import { checkClientSchema } from "./client-schema.js";
24
+ import { planWarningMessage } from "./plan-warnings.js";
25
+ import { PushCutoff } from "./push-cutoff.js";
26
+ import { PushCostEstimator, ReadCostEstimator, shouldRebuildInsteadOfReading, shouldStartOnRebuild } from "./push-cost.js";
27
+ import { queryShape } from "./query-shape.js";
21
28
  import { rowIDSignatureUnit } from "./row-set-signature.js";
22
29
  import { ResetPipelinesSignal } from "./snapshotter.js";
23
30
  //#region ../zero-cache/src/services/view-syncer/pipeline-driver.ts
31
+ /** The most queries a log of an advancement timeout lists. */
32
+ var ADVANCE_TIMEOUT_LOG_MAX_QUERIES = 3;
24
33
  /**
25
34
  * No matter how fast hydration is, advancement is given at least this long to
26
35
  * complete before doing a pipeline reset.
@@ -33,6 +42,8 @@ var MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS = 5;
33
42
  var MIN_PROJECTED_ADVANCEMENT_CHANGES = 16;
34
43
  var PROJECTED_ADVANCEMENT_RESET_MULTIPLIER = 1.5;
35
44
  var LATE_ADVANCEMENT_FINISH_PROGRESS = .8;
45
+ var planWarningLogThrottle = new LogThrottle({ windowMs: 60 * 6e4 });
46
+ var slowAdvanceLogThrottle = new LogThrottle({ windowMs: 5 * 6e4 });
36
47
  function randomID() {
37
48
  return randInt(1, Number.MAX_SAFE_INTEGER).toString(36);
38
49
  }
@@ -46,9 +57,11 @@ function advancementResetTimeLimitMs(totalHydrationTimeMs) {
46
57
  function minProjectedAdvancementSampleChanges(numChanges) {
47
58
  return Math.max(MIN_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES, Math.min(MAX_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES, Math.ceil(numChanges * PROJECTED_ADVANCEMENT_SAMPLE_FRACTION)));
48
59
  }
49
- function shouldResetProjectedAdvancement(elapsedMs, projectedTotalTimeMs, processedChanges, numChanges, totalHydrationTimeMs) {
50
- if (projectedTotalTimeMs === void 0 || numChanges < MIN_PROJECTED_ADVANCEMENT_CHANGES || processedChanges < minProjectedAdvancementSampleChanges(numChanges) || elapsedMs < MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS) return false;
51
- return projectedTotalTimeMs > advancementResetTimeLimitMs(totalHydrationTimeMs) * PROJECTED_ADVANCEMENT_RESET_MULTIPLIER;
60
+ function canProjectAdvancement(elapsedMs, projectedTotalTimeMs, processedChanges, numChanges) {
61
+ return projectedTotalTimeMs !== void 0 && numChanges >= MIN_PROJECTED_ADVANCEMENT_CHANGES && processedChanges >= minProjectedAdvancementSampleChanges(numChanges) && elapsedMs >= MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS;
62
+ }
63
+ function shouldResetProjectedAdvancement(elapsedMs, projectedTotalTimeMs, totalHydrationTimeMs) {
64
+ return projectedTotalTimeMs - elapsedMs > advancementResetTimeLimitMs(totalHydrationTimeMs) * PROJECTED_ADVANCEMENT_RESET_MULTIPLIER;
52
65
  }
53
66
  function shouldFinishLateAdvancement(processedChanges, numChanges) {
54
67
  return numChanges > 0 && processedChanges / numChanges >= LATE_ADVANCEMENT_FINISH_PROGRESS;
@@ -56,6 +69,14 @@ function shouldFinishLateAdvancement(processedChanges, numChanges) {
56
69
  function shouldResetSlowCurrentChange(currentChangeElapsedMs, totalHydrationTimeMs) {
57
70
  return currentChangeElapsedMs > MIN_ADVANCEMENT_TIME_LIMIT_MS && currentChangeElapsedMs > advancementResetTimeLimitMs(totalHydrationTimeMs);
58
71
  }
72
+ function formatAdvancementBreakdown(advanceContext, elapsed) {
73
+ const { diff, pushTimeMs, stage, currentChangeStartMs, currentTable } = advanceContext;
74
+ const totalPushMs = pushTimeMs + (stage === "push" && currentChangeStartMs !== void 0 ? Math.max(0, elapsed - currentChangeStartMs) : 0);
75
+ const stats = diff.stats;
76
+ const diffTimeMs = stats?.totalDiffMs ?? 0;
77
+ const clMs = stats ? ` [changelog: ${stats.changeLogReadMs.toFixed(1)}ms, parse: ${stats.parseMs.toFixed(1)}ms, rows: ${stats.rowReadMs.toFixed(1)}ms]` : "";
78
+ return `stage: ${stage}, diff: ${diffTimeMs.toFixed(1)}ms${clMs}, push: ${totalPushMs.toFixed(1)}ms` + (currentTable ? `, table: ${currentTable}` : "");
79
+ }
59
80
  /**
60
81
  * Manages the state of IVM pipelines for a given ViewSyncer (i.e. client group).
61
82
  */
@@ -67,39 +88,83 @@ var PipelineDriver = class {
67
88
  * query, maintained as RowChanges are yielded from {@link addQuery} and
68
89
  * {@link advance}. ADDs / REMOVEs XOR the row's unit in (XOR is
69
90
  * self-inverse, so one op serves both directions); EDITs are no-ops.
70
- * Hydration implicitly reseeds from `0n` because {@link addQuery} calls
71
- * {@link removeQuery} first, which deletes the entry.
91
+ * Hydration starts the query's entry at `0n` (the empty row set), so every
92
+ * hydrated query has one, even if it has no rows. A hydration that does not
93
+ * finish removes it.
72
94
  */
73
95
  #rowSetSignatures = /* @__PURE__ */ new Map();
96
+ /**
97
+ * IDs of the queries whose {@link #rowSetSignatures} entry changed since the
98
+ * last {@link clearChangedRowSetSignatures}, so that the CVR flush only has
99
+ * to look at those instead of every query.
100
+ */
101
+ #changedRowSetSignatures = /* @__PURE__ */ new Set();
74
102
  #lc;
75
103
  #snapshotter;
76
104
  #storage;
77
105
  #shardID;
78
106
  #logConfig;
79
107
  #config;
108
+ #deferredWrites;
80
109
  #tableSpecs = /* @__PURE__ */ new Map();
81
110
  #allTableNames = /* @__PURE__ */ new Set();
82
111
  #costModels;
112
+ #planWarningThresholds;
83
113
  #yieldThresholdMs;
84
114
  #streamer = null;
115
+ /** The row changes of the push in progress, until #push yields them. */
116
+ #pushedRowChanges = null;
85
117
  #hydrateContext = null;
86
118
  #advanceContext = null;
119
+ /**
120
+ * Whether a {@link CostBasedAdvance} has been set up and has not
121
+ * completed. It may already have removed pipelines, but the sources only
122
+ * move to the new snapshot when the iteration over its changes completes,
123
+ * so nothing can be hydrated until then. If the iteration is given up on
124
+ * or throws, they never do, and nothing can be hydrated until the
125
+ * pipelines are {@link reset()}.
126
+ */
127
+ #costBasedAdvanceIncomplete = false;
128
+ /**
129
+ * The queries abandoned by a {@link CostBasedAdvance} that have not been
130
+ * added again since.
131
+ */
132
+ #abandoned = /* @__PURE__ */ new Map();
133
+ #pushCosts = new PushCostEstimator();
134
+ #readCosts = new ReadCostEstimator();
87
135
  #replicaVersion = null;
88
136
  #primaryKeys = null;
89
137
  #permissions = null;
90
138
  #advanceTime = getOrCreateLatencyHistogram("sync", "ivm.advance-time", "Time to advance all queries for a given client group in response to a single change.");
91
139
  #conflictRowsDeleted = getOrCreateCounter("sync", "ivm.conflict-rows-deleted", "Number of rows deleted because they conflicted with added row");
140
+ #deferredWritesFallbacks = getOrCreateCounter("sync", "ivm.deferred-writes-fallbacks", "Number of advancements written through to the replica snapshot because their changes did not fit in the deferred IVM writes budget, from the start or partway (because of the bytes held, a change that needed more rows than were left, or more rows held than reserved)");
92
141
  #inspectorDelegate;
93
- constructor(lc, logConfig, snapshotter, shardID, storage, clientGroupID, inspectorDelegate, yieldThresholdMs, enablePlanner, config) {
142
+ #queryStats;
143
+ /**
144
+ * Passes the pipelines' metrics on to the inspector, and accounts the time
145
+ * spent pushing to each query to the advancement in progress.
146
+ */
147
+ #metricsDelegate = { addMetric: (metric, value, ...args) => {
148
+ this.#inspectorDelegate.addMetric(metric, value, ...args);
149
+ if (metric === "query-update-server") this.#recordAdvancePush(args[0], value);
150
+ } };
151
+ constructor(lc, logConfig, snapshotter, shardID, storage, clientGroupID, inspectorDelegate, yieldThresholdMs, enablePlanner, config, deferredWrites, queryStats) {
94
152
  this.#lc = lc.withContext("clientGroupID", clientGroupID);
95
153
  this.#snapshotter = snapshotter;
96
154
  this.#storage = storage;
97
155
  this.#shardID = shardID;
98
156
  this.#logConfig = logConfig;
99
157
  this.#config = config;
158
+ this.#deferredWrites = deferredWrites;
100
159
  this.#inspectorDelegate = inspectorDelegate;
101
160
  this.#costModels = enablePlanner ? /* @__PURE__ */ new WeakMap() : void 0;
161
+ const planWarningThresholds = {
162
+ rows: logConfig.planWarningRowThreshold,
163
+ cost: logConfig.planWarningCostThreshold
164
+ };
165
+ this.#planWarningThresholds = planWarningThresholds.rows > 0 || planWarningThresholds.cost > 0 ? planWarningThresholds : void 0;
102
166
  this.#yieldThresholdMs = yieldThresholdMs;
167
+ this.#queryStats = queryStats;
103
168
  }
104
169
  /**
105
170
  * Initializes the PipelineDriver to the current head of the database.
@@ -128,9 +193,12 @@ var PipelineDriver = class {
128
193
  this.#pipelines.delete(queryID);
129
194
  this.#destroyPipeline(queryID, pipeline, "reset");
130
195
  }
196
+ this.#abandoned.clear();
197
+ this.#costBasedAdvanceIncomplete = false;
131
198
  this.#tables.clear();
132
199
  this.#allTableNames.clear();
133
200
  this.#rowSetSignatures.clear();
201
+ this.#changedRowSetSignatures.clear();
134
202
  this.#initAndResetCommon(clientSchema);
135
203
  }
136
204
  #initAndResetCommon(clientSchema) {
@@ -140,11 +208,9 @@ var PipelineDriver = class {
140
208
  checkClientSchema(this.#shardID, clientSchema, this.#tableSpecs, fullTables);
141
209
  this.#allTableNames.clear();
142
210
  for (const table of fullTables.keys()) this.#allTableNames.add(table);
143
- const primaryKeys = this.#primaryKeys ?? /* @__PURE__ */ new Map();
211
+ const primaryKeys = buildRowKeys(clientSchema, this.#tableSpecs, this.#primaryKeys ?? void 0);
144
212
  this.#primaryKeys = primaryKeys;
145
- primaryKeys.clear();
146
- for (const [table, spec] of this.#tableSpecs.entries()) primaryKeys.set(table, spec.tableSpec.primaryKey);
147
- buildPrimaryKeys(clientSchema, primaryKeys);
213
+ this.#streamer ??= new Streamer(primaryKeys, this.#tableSpecs);
148
214
  const { replicaVersion } = getSubscriptionState(db);
149
215
  this.#replicaVersion = replicaVersion;
150
216
  }
@@ -173,10 +239,28 @@ var PipelineDriver = class {
173
239
  }
174
240
  return this.#permissions;
175
241
  }
176
- advanceWithoutDiff() {
177
- const { db, version } = this.#snapshotter.advanceWithoutDiff().curr;
178
- for (const table of this.#tables.values()) table.setDB(db.db);
179
- return version;
242
+ /**
243
+ * Advances the snapshot to the head of the database without diffing the
244
+ * change log, in preparation for hydrating queries at head.
245
+ *
246
+ * Throws a {@link ResetPipelinesSignal} if the change log records a
247
+ * schema change since the previous snapshot. The table specs (and any
248
+ * TableSources built from them) were computed at or before that snapshot
249
+ * and are stale with respect to the new head, so the caller must
250
+ * {@link reset()} before hydrating. ({@link advance()} detects this when
251
+ * the diff encounters the RESET op; this path skips the diff and so must
252
+ * check explicitly.)
253
+ *
254
+ * @param releasePreviousSnapshot Whether to release the snapshot that the
255
+ * driver was at, which is otherwise left open until the next
256
+ * advance (see `Snapshotter.releasePrevious()`).
257
+ */
258
+ advanceWithoutDiff(releasePreviousSnapshot = false) {
259
+ const { prev, curr } = this.#snapshotter.advanceWithoutDiff();
260
+ if (curr.schemaChangedSince(prev.version)) throw new ResetPipelinesSignal(`schema changed between ${prev.version} and ${curr.version}`, "schema-change");
261
+ for (const table of this.#tables.values()) table.setDB(curr.db.db);
262
+ if (releasePreviousSnapshot) this.#snapshotter.releasePrevious();
263
+ return curr.version;
180
264
  }
181
265
  #ensureCostModelExistsIfEnabled(db) {
182
266
  let existing = this.#costModels?.get(db);
@@ -196,7 +280,9 @@ var PipelineDriver = class {
196
280
  this.#pipelines.delete(queryID);
197
281
  this.#destroyPipeline(queryID, pipeline, "destroy");
198
282
  }
283
+ this.#tables.clear();
199
284
  this.#rowSetSignatures.clear();
285
+ this.#changedRowSetSignatures.clear();
200
286
  this.#storage.destroy();
201
287
  this.#snapshotter.destroy();
202
288
  }
@@ -204,20 +290,91 @@ var PipelineDriver = class {
204
290
  queries() {
205
291
  return this.#pipelines;
206
292
  }
293
+ /**
294
+ * The queries whose pipelines a {@link CostBasedAdvance} removed and that
295
+ * have not been hydrated again since, by query ID. They are not in
296
+ * {@link queries()}. A query whose hydration is started but does not
297
+ * finish is still one of them.
298
+ */
299
+ abandonedQueries() {
300
+ return this.#abandoned;
301
+ }
302
+ /**
303
+ * Stats from the hydration of the pipeline for `queryID`, or `undefined` if
304
+ * the query has no pipeline.
305
+ */
306
+ hydrationStats(queryID) {
307
+ const pipeline = this.#pipelines.get(queryID);
308
+ return pipeline ? {
309
+ rowCount: pipeline.hydrationRowCount,
310
+ rowsRead: pipeline.hydrationRowsRead,
311
+ planWarnings: pipeline.planWarnings,
312
+ shape: pipeline.shape
313
+ } : void 0;
314
+ }
315
+ /**
316
+ * Logs what the planner warned about the plan it chose for `query`, at
317
+ * most once per query shape per {@link PLAN_WARNING_LOG_WINDOW_MS}.
318
+ */
319
+ #logPlanWarnings(shape, { queryHash, transformationHash, queryName }, warnings) {
320
+ if (!this.#lc.warn) return;
321
+ const suppressed = planWarningLogThrottle.admit(`${queryName ?? ""}:${shape.hash}`);
322
+ if (suppressed === void 0) return;
323
+ const messages = warnings.map(planWarningMessage);
324
+ this.#lc.warn(`Query plan warning${queryName === void 0 ? "" : ` for ${queryName}`}: ` + messages.join(" "), {
325
+ zeroEvent: "query-plan-warning",
326
+ queryHash,
327
+ transformationHash,
328
+ ...queryName !== void 0 && { queryName },
329
+ queryShape: shape.hash,
330
+ warnings,
331
+ ...suppressed > 0 && { suppressedSinceLastLog: suppressed },
332
+ zql: shape.zql
333
+ });
334
+ }
335
+ #totalRowsRead() {
336
+ let total = 0;
337
+ for (const table of this.#tables.values()) total += table.rowsRead;
338
+ return total;
339
+ }
207
340
  totalHydrationTimeMs() {
208
341
  let total = 0;
209
342
  for (const pipeline of this.#pipelines.values()) total += pipeline.hydrationTimeMs;
210
343
  return total;
211
344
  }
212
- #logQueryPipelineLifecycle({ zeroEvent, pipelineRunID, queryHash, transformationHash, queryName, hydrationReason, stopReason, hydrationTimeMs, hydrationRowCount, pipelineLifetimeMs }) {
345
+ /**
346
+ * The rows the sources hold in memory for the advancement in progress.
347
+ * The advancement's reservation from the {@link DeferredWritesBudget}
348
+ * bounds this.
349
+ */
350
+ get pendingRows() {
351
+ let total = 0;
352
+ for (const source of this.#tables.values()) total += source.pendingRows;
353
+ return total;
354
+ }
355
+ /**
356
+ * The estimated bytes of {@link pendingRows}, which are added to the
357
+ * {@link DeferredWritesBudget}'s held bytes as the advancement goes.
358
+ */
359
+ get pendingBytes() {
360
+ let total = 0;
361
+ for (const source of this.#tables.values()) total += source.pendingBytes;
362
+ return total;
363
+ }
364
+ #logQueryPipelineLifecycle({ zeroEvent, pipelineRunID, queryHash, transformationHash, queryName, hydrationReason, stopReason, hydrationTimeMs, hydrationRowCount, hydrationRowsRead, pipelineLifetimeMs, abandonReason, estimatedPushMs, pushTimeMs, pushedChanges, level = "info" }) {
213
365
  let lc = this.#lc.withContext("zeroEvent", zeroEvent).withContext("pipelineRunID", pipelineRunID).withContext("queryHash", queryHash).withContext("transformationHash", transformationHash);
214
366
  if (queryName !== void 0) lc = lc.withContext("queryName", queryName);
215
367
  if (hydrationReason !== void 0) lc = lc.withContext("hydrationReason", hydrationReason);
216
368
  if (stopReason !== void 0) lc = lc.withContext("stopReason", stopReason);
217
369
  if (hydrationTimeMs !== void 0) lc = lc.withContext("hydrationTimeMs", hydrationTimeMs);
218
370
  if (hydrationRowCount !== void 0) lc = lc.withContext("hydrationRowCount", hydrationRowCount);
371
+ if (hydrationRowsRead !== void 0) lc = lc.withContext("hydrationRowsRead", hydrationRowsRead);
219
372
  if (pipelineLifetimeMs !== void 0) lc = lc.withContext("pipelineLifetimeMs", pipelineLifetimeMs);
220
- lc.info?.("query pipeline lifecycle");
373
+ if (abandonReason !== void 0) lc = lc.withContext("abandonReason", abandonReason);
374
+ if (estimatedPushMs !== void 0) lc = lc.withContext("estimatedPushMs", estimatedPushMs);
375
+ if (pushTimeMs !== void 0) lc = lc.withContext("pushTimeMs", pushTimeMs);
376
+ if (pushedChanges !== void 0) lc = lc.withContext("pushedChanges", pushedChanges);
377
+ lc[level]?.("query pipeline lifecycle");
221
378
  }
222
379
  /**
223
380
  * A `{scalar: true}` that cannot be honored degrades silently to a plain
@@ -232,35 +389,39 @@ var PipelineDriver = class {
232
389
  this.#lc.warn?.(`Ignoring {scalar: true} on the "${table}" subquery of query ${queryID}: it does not constrain every column of any unique key ${keys.length > 0 ? `[${keys}]` : "(none on this table)"} to a literal with "=", so it is not provably limited to one row. The gate runs as a plain EXISTS.`);
233
390
  }
234
391
  }
235
- #resolveScalarSubqueries(ast) {
236
- const companionRows = [];
392
+ #disableCorrelatedPredicatePushdown() {
393
+ return this.#config?.enableCorrelatedPredicatePushdown === false;
394
+ }
395
+ #resolveScalarSubqueries(ast, tables) {
237
396
  const companionInputs = [];
238
397
  const executor = (subqueryAST, childField) => {
239
398
  const input = buildPipeline(subqueryAST, {
240
- getSource: (name) => this.#getSource(name),
399
+ enableNotExists: true,
400
+ disableCorrelatedPredicatePushdown: this.#disableCorrelatedPredicatePushdown(),
401
+ getSource: (name) => {
402
+ tables.add(name);
403
+ return this.#getSource(name);
404
+ },
241
405
  createStorage: () => this.#createStorage(),
242
406
  decorateSourceInput: (input) => input,
243
407
  decorateInput: (input) => input,
244
408
  addEdge() {},
245
409
  decorateFilterInput: (input) => input
246
410
  }, "scalar-subquery");
247
- let node;
248
- for (const n of skipYields(input.fetch({}))) node ??= n;
249
- if (!node) {
250
- companionInputs.push(input);
251
- return;
252
- }
253
- companionRows.push({
254
- table: subqueryAST.table,
255
- row: node.row
256
- });
257
411
  companionInputs.push(input);
258
- return node.row[childField] ?? null;
412
+ return fetchScalarValue(input, childField);
259
413
  };
260
- const { ast: resolved, companions, ignoredScalarHints } = resolveSimpleScalarSubqueries(ast, this.#tableSpecs, executor);
414
+ let resolved;
415
+ let companions;
416
+ let ignoredScalarHints;
417
+ try {
418
+ ({ast: resolved, companions, ignoredScalarHints} = resolveSimpleScalarSubqueries(ast, this.#tableSpecs, executor));
419
+ } catch (e) {
420
+ for (const input of companionInputs) input.destroy();
421
+ throw e;
422
+ }
261
423
  return {
262
424
  ast: resolved,
263
- companionRows,
264
425
  companions,
265
426
  companionInputs,
266
427
  ignoredScalarHints
@@ -288,57 +449,74 @@ var PipelineDriver = class {
288
449
  assert(this.initialized(), "Pipeline driver must be initialized before adding queries");
289
450
  this.removeQuery(queryID, "replace-query");
290
451
  const pipelineRunID = randomID();
452
+ const shape = queryShape(query);
453
+ const level = this.#abandoned.has(queryID) ? "debug" : "info";
291
454
  this.#logQueryPipelineLifecycle({
292
455
  zeroEvent: "query-pipeline-hydrate-start",
293
456
  pipelineRunID,
294
457
  queryHash: queryID,
295
458
  transformationHash,
296
459
  queryName,
297
- hydrationReason
460
+ hydrationReason,
461
+ level
298
462
  });
299
- const debugDelegate = runtimeDebugFlags.trackRowsVended ? new Debug() : void 0;
463
+ const debugDelegate = runtimeDebugFlags.trackRowsVended ? new Debug(true) : void 0;
300
464
  const costModel = this.#ensureCostModelExistsIfEnabled(this.#snapshotter.current().db.db);
301
465
  assert(this.#advanceContext === null, "Cannot hydrate while advance is in progress");
466
+ assert(!this.#costBasedAdvanceIncomplete, "Cannot hydrate before the advance has completed");
302
467
  this.#hydrateContext = { timer };
468
+ const rowsReadAtStart = this.#totalRowsRead();
303
469
  let hydrationFinished = false;
304
470
  let hydrationFailed = false;
305
471
  let hydrationRowCount = 0;
472
+ let planWarnings = [];
473
+ const planWarningThresholds = this.#planWarningThresholds;
474
+ let builtInputs = [];
475
+ const tables = /* @__PURE__ */ new Set();
306
476
  try {
307
- const { ast: resolvedQuery, companionRows, companions: companionMeta, companionInputs, ignoredScalarHints } = this.#resolveScalarSubqueries(query);
477
+ this.#rowSetSignatures.set(queryID, 0n);
478
+ this.#changedRowSetSignatures.add(queryID);
479
+ const { ast: resolvedQuery, companions: companionMeta, companionInputs, ignoredScalarHints } = this.#resolveScalarSubqueries(query, tables);
480
+ builtInputs = [...companionInputs];
308
481
  this.#warnIgnoredScalarHints(queryID, ignoredScalarHints);
309
482
  const input = buildPipeline(resolvedQuery, {
310
483
  debug: debugDelegate,
311
484
  enableNotExists: true,
312
- getSource: (name) => this.#getSource(name),
485
+ disableCorrelatedPredicatePushdown: this.#disableCorrelatedPredicatePushdown(),
486
+ enablePlannerAwarePushdown: this.#config?.enablePlannerAwarePushdown !== false,
487
+ getSource: (name) => {
488
+ tables.add(name);
489
+ return this.#getSource(name);
490
+ },
313
491
  createStorage: () => this.#createStorage(),
314
- decorateSourceInput: (input, _queryID) => new MeasurePushOperator(new QueryFailureLoggingOperator(this.#lc, input, queryID, transformationHash, queryName), queryID, this.#inspectorDelegate, "query-update-server"),
492
+ decorateSourceInput: (input, _queryID) => new MeasurePushOperator(new QueryFailureLoggingOperator(this.#lc, input, queryID, transformationHash, queryName), queryID, this.#metricsDelegate, "query-update-server"),
315
493
  decorateInput: (input) => input,
316
494
  addEdge() {},
317
- decorateFilterInput: (input) => input
495
+ decorateFilterInput: (input) => input,
496
+ planWarnings: planWarningThresholds && {
497
+ thresholds: planWarningThresholds,
498
+ report: (warnings) => {
499
+ planWarnings = warnings;
500
+ }
501
+ }
318
502
  }, queryID, costModel);
503
+ builtInputs.push(input);
504
+ if (planWarnings.length > 0) this.#logPlanWarnings(shape, {
505
+ queryHash: queryID,
506
+ transformationHash,
507
+ queryName
508
+ }, planWarnings);
319
509
  const schema = input.getSchema();
320
- input.setOutput({ push: (change) => {
321
- const streamer = this.#streamer;
322
- assert(streamer, "must #startAccumulating() before pushing changes");
323
- streamer.accumulate(queryID, schema, [change]);
324
- return [];
325
- } });
326
- for (const change of hydrateInternal(input, queryID, must(this.#primaryKeys), this.#tableSpecs)) {
327
- if (change !== "yield") hydrationRowCount++;
328
- yield change;
329
- }
330
- for (const { table, row } of companionRows) {
331
- const primaryKey = mustGetPrimaryKey(this.#primaryKeys, table);
332
- hydrationRowCount++;
333
- yield {
334
- type: 0,
335
- queryID,
336
- table,
337
- rowKey: getRowKey(primaryKey, row),
338
- row
339
- };
510
+ input.setOutput({ push: (change) => this.#streamPushed(queryID, schema, change) });
511
+ for (let i = -1; i < companionInputs.length; i++) {
512
+ const pipeline = i < 0 ? input : companionInputs[i];
513
+ for (const change of must(this.#streamer).streamNodes(queryID, i < 0 ? schema : companionStreamSchema(pipeline, companionMeta[i]), 0, pipeline.fetch({}))) {
514
+ if (change !== "yield") hydrationRowCount++;
515
+ yield change;
516
+ }
340
517
  }
341
518
  const hydrationTimeMs = timer.totalElapsed();
519
+ const hydrationRowsRead = this.#totalRowsRead() - rowsReadAtStart;
342
520
  if (runtimeDebugFlags.trackRowCountsVended) {
343
521
  if (hydrationTimeMs > this.#logConfig.slowHydrateThreshold) {
344
522
  let totalRowsConsidered = 0;
@@ -356,7 +534,7 @@ var PipelineDriver = class {
356
534
  for (let i = 0; i < companionMeta.length; i++) {
357
535
  const meta = companionMeta[i];
358
536
  const companionInput = companionInputs[i];
359
- const companionSchema = companionInput.getSchema();
537
+ const companionSchema = companionStreamSchema(companionInput, meta);
360
538
  const { childField, resolvedValue } = meta;
361
539
  companionInput.setOutput({ push: (change) => {
362
540
  let newValue;
@@ -368,13 +546,10 @@ var PipelineDriver = class {
368
546
  case 1:
369
547
  newValue = void 0;
370
548
  break;
371
- case 3: return [];
549
+ case 3: return this.#streamPushed(queryID, companionSchema, change);
372
550
  }
373
551
  if (!scalarValuesEqual(newValue, resolvedValue)) throw new ResetPipelinesSignal(`Scalar subquery value changed for ${meta.ast.table}: ${String(resolvedValue)} -> ${String(newValue)}`, "scalar-subquery");
374
- const streamer = this.#streamer;
375
- assert(streamer, "must #startAccumulating() before pushing changes");
376
- streamer.accumulate(queryID, companionSchema, [change]);
377
- return [];
552
+ return this.#streamPushed(queryID, companionSchema, change);
378
553
  } });
379
554
  liveCompanions.push({
380
555
  input: companionInput,
@@ -387,15 +562,31 @@ var PipelineDriver = class {
387
562
  input,
388
563
  hydrationTimeMs,
389
564
  hydrationRowCount,
565
+ hydrationRowsRead,
566
+ planWarnings,
390
567
  hydrationReason,
391
568
  pipelineRunID,
392
569
  pipelineReadyAtMs,
393
570
  transformedAst: resolvedQuery,
571
+ originalAst: query,
572
+ shape,
394
573
  transformationHash,
395
574
  ...queryName !== void 0 && { queryName },
396
- companions: liveCompanions
575
+ companions: liveCompanions,
576
+ tables
397
577
  });
578
+ this.#abandoned.delete(queryID);
398
579
  hydrationFinished = true;
580
+ this.#queryStats?.recordHydration({
581
+ queryName,
582
+ shape
583
+ }, {
584
+ outcome: "finished",
585
+ timeMs: hydrationTimeMs,
586
+ rowCount: hydrationRowCount,
587
+ rowsRead: hydrationRowsRead,
588
+ planWarnings
589
+ });
399
590
  this.#logQueryPipelineLifecycle({
400
591
  zeroEvent: "query-pipeline-hydrate-finish",
401
592
  pipelineRunID,
@@ -404,10 +595,19 @@ var PipelineDriver = class {
404
595
  queryName,
405
596
  hydrationReason,
406
597
  hydrationTimeMs,
407
- hydrationRowCount
598
+ hydrationRowCount,
599
+ hydrationRowsRead,
600
+ level
408
601
  });
409
602
  } catch (e) {
410
603
  hydrationFailed = true;
604
+ this.#queryStats?.recordHydration({
605
+ queryName,
606
+ shape
607
+ }, {
608
+ outcome: "failed",
609
+ timeMs: timer.totalElapsed()
610
+ });
411
611
  this.#logQueryPipelineLifecycle({
412
612
  zeroEvent: "query-pipeline-hydrate-failed",
413
613
  pipelineRunID,
@@ -425,16 +625,30 @@ var PipelineDriver = class {
425
625
  }, "query hydration failed", e);
426
626
  throw e;
427
627
  } finally {
428
- if (!hydrationFinished && !hydrationFailed) this.#logQueryPipelineLifecycle({
429
- zeroEvent: "query-pipeline-hydrate-aborted",
430
- pipelineRunID,
431
- queryHash: queryID,
432
- transformationHash,
433
- queryName,
434
- hydrationReason,
435
- hydrationTimeMs: timer.totalElapsed(),
436
- hydrationRowCount
437
- });
628
+ if (!hydrationFinished && !hydrationFailed) {
629
+ this.#queryStats?.recordHydration({
630
+ queryName,
631
+ shape
632
+ }, {
633
+ outcome: "aborted",
634
+ timeMs: timer.totalElapsed()
635
+ });
636
+ this.#logQueryPipelineLifecycle({
637
+ zeroEvent: "query-pipeline-hydrate-aborted",
638
+ pipelineRunID,
639
+ queryHash: queryID,
640
+ transformationHash,
641
+ queryName,
642
+ hydrationReason,
643
+ hydrationTimeMs: timer.totalElapsed(),
644
+ hydrationRowCount
645
+ });
646
+ }
647
+ if (!hydrationFinished) {
648
+ for (const input of builtInputs) input.destroy();
649
+ this.#rowSetSignatures.delete(queryID);
650
+ this.#changedRowSetSignatures.delete(queryID);
651
+ }
438
652
  this.#hydrateContext = null;
439
653
  }
440
654
  }
@@ -443,14 +657,24 @@ var PipelineDriver = class {
443
657
  * was not added.
444
658
  */
445
659
  removeQuery(queryID, stopReason = "remove-query") {
660
+ this.#removeQuery(queryID, stopReason);
661
+ }
662
+ /**
663
+ * @param abandoned If an advancement is abandoning the query's pipeline,
664
+ * the record of that, which is logged.
665
+ */
666
+ #removeQuery(queryID, stopReason, abandoned) {
446
667
  const pipeline = this.#pipelines.get(queryID);
447
668
  if (pipeline) {
448
669
  this.#pipelines.delete(queryID);
449
- this.#destroyPipeline(queryID, pipeline, stopReason);
670
+ this.#destroyPipeline(queryID, pipeline, stopReason, abandoned);
450
671
  }
451
672
  this.#rowSetSignatures.delete(queryID);
673
+ this.#changedRowSetSignatures.delete(queryID);
674
+ if (stopReason !== "replace-query") this.#abandoned.delete(queryID);
675
+ if (stopReason === "remove-query") this.#pushCosts.forget(queryID);
452
676
  }
453
- #destroyPipeline(queryID, pipeline, stopReason) {
677
+ #destroyPipeline(queryID, pipeline, stopReason, abandoned) {
454
678
  this.#logQueryPipelineLifecycle({
455
679
  zeroEvent: "query-pipeline-stop",
456
680
  pipelineRunID: pipeline.pipelineRunID,
@@ -461,7 +685,14 @@ var PipelineDriver = class {
461
685
  stopReason,
462
686
  hydrationTimeMs: pipeline.hydrationTimeMs,
463
687
  hydrationRowCount: pipeline.hydrationRowCount,
464
- pipelineLifetimeMs: Date.now() - pipeline.pipelineReadyAtMs
688
+ pipelineLifetimeMs: Date.now() - pipeline.pipelineReadyAtMs,
689
+ ...abandoned && {
690
+ abandonReason: abandoned.reason,
691
+ estimatedPushMs: abandoned.estimatedPushMs,
692
+ pushTimeMs: abandoned.pushTimeMs,
693
+ pushedChanges: abandoned.changes,
694
+ level: "debug"
695
+ }
465
696
  });
466
697
  pipeline.input.destroy();
467
698
  for (const companion of pipeline.companions) companion.input.destroy();
@@ -475,6 +706,20 @@ var PipelineDriver = class {
475
706
  return this.#rowSetSignatures.get(queryID);
476
707
  }
477
708
  /**
709
+ * IDs of the queries whose {@link rowSetSignature} changed (by an ADD or
710
+ * REMOVE from {@link addQuery} or {@link advance}) since the last call to
711
+ * {@link clearChangedRowSetSignatures}.
712
+ */
713
+ changedRowSetSignatures() {
714
+ return this.#changedRowSetSignatures;
715
+ }
716
+ /**
717
+ * Called once the {@link changedRowSetSignatures} have been persisted.
718
+ */
719
+ clearChangedRowSetSignatures() {
720
+ this.#changedRowSetSignatures.clear();
721
+ }
722
+ /**
478
723
  * Wraps an iterable of RowChanges, XORing each row's unit hash into the
479
724
  * query's signature (ADDs and REMOVEs share the same op; EDITs are no-ops).
480
725
  * Used to intercept the yield streams from {@link addQuery} and
@@ -490,6 +735,7 @@ var PipelineDriver = class {
490
735
  rowKey: change.rowKey
491
736
  });
492
737
  this.#rowSetSignatures.set(change.queryID, cur ^ unit);
738
+ this.#changedRowSetSignatures.add(change.queryID);
493
739
  }
494
740
  yield change;
495
741
  }
@@ -510,44 +756,212 @@ var PipelineDriver = class {
510
756
  * measure the progress of the advancement and abort with a
511
757
  * {@link ResetPipelinesSignal} if it is estimated to take longer
512
758
  * than a hydration.
759
+ * @param costBased If given, the advancement is bounded query by query
760
+ * instead (see {@link CostBasedAdvance}).
513
761
  * @return The resulting row changes for all added queries. Note that the
514
762
  * `changes` must be iterated over in their entirety in order to
515
763
  * advance the database snapshot.
764
+ * @throws A {@link ResetPipelinesSignal} if `costBased` is given and the
765
+ * changes include a schema change, a truncation or a change of
766
+ * the permissions. It is thrown before any change is pushed or
767
+ * any pipeline is removed, as the caller resets the pipelines
768
+ * either way. Without `costBased`, it is iterating over the
769
+ * `changes` that throws it, on getting to that change.
516
770
  */
517
- advance(timer) {
771
+ advance(timer, costBased) {
518
772
  assert(this.initialized(), "Pipeline driver must be initialized before advancing");
519
- const diff = this.#snapshotter.advance(this.#tableSpecs, this.#allTableNames);
773
+ let diff;
774
+ let context;
775
+ if (costBased === void 0) diff = this.#snapshotter.advance(this.#tableSpecs, this.#allTableNames, this.#tables, "divergent");
776
+ else {
777
+ const { prev, curr } = this.#snapshotter.advanceWithoutDiff();
778
+ const counts = curr.countChangesSince(prev.version);
779
+ const reset = this.#snapshotter.pendingReset(this.#tableSpecs, counts);
780
+ if (reset) throw reset;
781
+ context = this.#startCostBasedAdvance(costBased, curr.version > prev.version, counts);
782
+ diff = this.#snapshotter.diff(this.#tableSpecs, this.#allTableNames, this.#tables, "divergent", counts, context.abandoned.length > 0 ? this.#tablesRead() : void 0);
783
+ this.#costBasedAdvanceIncomplete = true;
784
+ }
520
785
  const { prev, curr, changes } = diff;
521
786
  this.#lc.debug?.(`advance ${prev.version} => ${curr.version}: ${changes} changes`);
787
+ const progress = { changesProcessed: 0 };
522
788
  return {
523
789
  version: curr.version,
524
790
  numChanges: changes,
525
- changes: this.#trackRowSetSignatures(this.#advance(diff, timer, changes))
791
+ changes: this.#trackRowSetSignatures(this.#advance(diff, timer, changes, progress, context)),
792
+ abandoned: () => context?.abandoned ?? [],
793
+ estimates: () => context?.estimates ?? [],
794
+ progress: () => ({
795
+ changesScanned: diff.changesScanned,
796
+ changesProcessed: progress.changesProcessed,
797
+ changesSkipped: diff.changesSkipped
798
+ })
526
799
  };
527
800
  }
528
- *#advance(diff, timer, numChanges) {
801
+ /** The tables that the pipelines read. */
802
+ #tablesRead() {
803
+ const tables = /* @__PURE__ */ new Set();
804
+ for (const pipeline of this.#pipelines.values()) for (const table of pipeline.tables) tables.add(table);
805
+ return tables;
806
+ }
807
+ /**
808
+ * Removes the pipelines of the queries that are estimated to be cheaper to
809
+ * hydrate again than to push the advancement's changes to: first each
810
+ * query for what pushing costs it, and then the ones that are left for
811
+ * what reading the changes costs them together.
812
+ *
813
+ * @param canAbandon Whether pipelines can be removed, by this or by the
814
+ * cutoff.
815
+ * @param counts The rows that changed since the previous snapshot.
816
+ */
817
+ #startCostBasedAdvance({ shouldCutOff, rebuildMargin }, canAbandon, counts) {
818
+ const changes = counts.byTable;
819
+ const estimatedPushMs = /* @__PURE__ */ new Map();
820
+ const abandoned = [];
821
+ if (canAbandon) {
822
+ for (const [queryID, pipeline] of this.#pipelines) {
823
+ const estimate = this.#pushCosts.estimate(queryID, pipeline.tables, changes);
824
+ if (estimate === void 0) continue;
825
+ if (shouldStartOnRebuild(estimate, pipeline.hydrationTimeMs, rebuildMargin)) this.#abandon(abandoned, "estimate", pipeline, {
826
+ queryID,
827
+ pushTimeMs: 0,
828
+ changes: 0,
829
+ hydrationTimeMs: pipeline.hydrationTimeMs,
830
+ estimatedPushMs: estimate
831
+ });
832
+ else estimatedPushMs.set(queryID, estimate);
833
+ }
834
+ this.#abandonInsteadOfReading(counts, rebuildMargin, estimatedPushMs, abandoned);
835
+ }
836
+ return {
837
+ cutoff: new PushCutoff(canAbandon ? shouldCutOff : () => false),
838
+ entries: counts.total,
839
+ estimatedPushMs,
840
+ abandoned,
841
+ estimates: []
842
+ };
843
+ }
844
+ /**
845
+ * Removes the pipelines that are left, if reading the advancement's
846
+ * changes and pushing them to those is estimated to cost more than
847
+ * hydrating them again. The changes are then not read at all.
848
+ */
849
+ #abandonInsteadOfReading(counts, rebuildMargin, estimatedPushMs, abandoned) {
850
+ if (this.#pipelines.size === 0) return;
851
+ let entriesOfTablesRead = 0;
852
+ for (const table of this.#tablesRead()) entriesOfTablesRead += counts.byTable.get(table) ?? 0;
853
+ const queries = Array.from(this.#pipelines, ([queryID, pipeline]) => ({
854
+ queryID,
855
+ pipeline,
856
+ estimatedPushMs: estimatedPushMs.get(queryID),
857
+ hydrationTimeMs: pipeline.hydrationTimeMs
858
+ }));
859
+ const estimatedReadMs = this.#readCosts.estimate({
860
+ walk: counts.total,
861
+ parse: abandoned.length > 0 ? entriesOfTablesRead : counts.total,
862
+ lookup: entriesOfTablesRead
863
+ });
864
+ if (!shouldRebuildInsteadOfReading(estimatedReadMs, queries, rebuildMargin)) return;
865
+ let pushMs = 0;
866
+ let hydrationMs = 0;
867
+ for (const query of queries) {
868
+ pushMs += query.estimatedPushMs ?? 0;
869
+ hydrationMs += query.hydrationTimeMs;
870
+ }
871
+ this.#lc.debug?.("Not reading a batch of changes: hydrating its queries again is estimated to cost less", {
872
+ entries: counts.total,
873
+ entriesOfTablesRead,
874
+ estimatedReadMs,
875
+ estimatedPushMs: pushMs,
876
+ hydrationTimeMs: hydrationMs,
877
+ rebuildMargin,
878
+ queries: queries.length
879
+ });
880
+ for (const { queryID, pipeline, ...estimate } of queries) this.#abandon(abandoned, "read", pipeline, {
881
+ queryID,
882
+ pushTimeMs: 0,
883
+ changes: 0,
884
+ ...estimate
885
+ });
886
+ estimatedPushMs.clear();
887
+ }
888
+ #abandon(abandoned, reason, pipeline, progress) {
889
+ const { transformationHash, transformedAst, originalAst, queryName } = pipeline;
890
+ const query = {
891
+ ...progress,
892
+ reason,
893
+ transformationHash,
894
+ transformedAst,
895
+ originalAst,
896
+ ...queryName !== void 0 && { queryName }
897
+ };
898
+ this.#removeQuery(progress.queryID, "abandon-advance", query);
899
+ this.#abandoned.set(progress.queryID, query);
900
+ abandoned.push(query);
901
+ this.#queryStats?.recordAbandoned(pipeline, reason);
902
+ }
903
+ *#advance(diff, timer, numChanges, progress, costBased) {
529
904
  assert(this.#hydrateContext === null, "Cannot advance while hydration is in progress");
530
905
  const totalHydrationTimeMs = this.totalHydrationTimeMs();
531
- this.#advanceContext = {
906
+ const advanceContext = {
532
907
  timer,
908
+ progress,
909
+ diff,
910
+ completedChanges: 0,
533
911
  totalHydrationTimeMs,
534
912
  numChanges,
913
+ reservedRows: void 0,
914
+ heldBytes: 0,
535
915
  currentChangeStartMs: void 0,
536
- pos: 0
916
+ pos: 0,
917
+ currentTable: void 0,
918
+ queryStats: /* @__PURE__ */ new Map(),
919
+ costBased,
920
+ pushTimeMs: 0,
921
+ stage: "diff"
537
922
  };
538
- this.#lc.debug?.(`starting pipeline advancement of ${numChanges} changes with an advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`);
923
+ this.#advanceContext = advanceContext;
924
+ let timedOut = false;
925
+ let readToEnd = true;
539
926
  try {
540
- for (const { table, prevValues, nextValue } of diff) {
541
- if (this.#shouldAdvanceYieldMaybeAbortAdvance()) yield "yield";
927
+ advanceContext.reservedRows = this.#reserveDeferredWrites(numChanges);
928
+ const deferWrites = advanceContext.reservedRows !== void 0;
929
+ if (deferWrites) diff.setPrevWrites("none");
930
+ for (const table of this.#tables.values()) table.setDeferWrites(deferWrites);
931
+ this.#lc.debug?.(`starting pipeline advancement of ${numChanges} changes with an advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms (${deferWrites ? "deferred" : "write-through"}).`);
932
+ for (const { table, prevValues: probedPrevValues, nextValue, rowKey } of diff) {
933
+ advanceContext.stage = "between";
934
+ advanceContext.completedChanges = diff.changesScanned - 1;
935
+ if (this.#checkAdvance(advanceContext)) yield "yield";
936
+ if (costBased) {
937
+ this.#cutOffQueries(advanceContext, costBased, diff, table);
938
+ if (this.#pipelines.size === 0) {
939
+ readToEnd = false;
940
+ break;
941
+ }
942
+ }
542
943
  const start = timer.totalElapsed();
543
- const advanceContext = must(this.#advanceContext);
544
944
  advanceContext.currentChangeStartMs = start;
545
- let type;
945
+ advanceContext.currentTable = table;
946
+ advanceContext.stage = "push";
947
+ let holds = "fits";
948
+ let pushCompleted = false;
546
949
  try {
547
950
  try {
548
951
  const tableSource = this.#tables.get(table);
549
- if (!tableSource) continue;
952
+ if (!tableSource) {
953
+ pushCompleted = true;
954
+ continue;
955
+ }
550
956
  const primaryKey = mustGetPrimaryKey(this.#primaryKeys, table);
957
+ const isUnobservableAdd = probedPrevValues.length === 0 && nextValue !== null && !tableSource.mayAcceptRow(nextValue);
958
+ const isUnobservableEdit = probedPrevValues.length === 1 && nextValue !== null && !tableSource.mayAcceptRow(nextValue) && !tableSource.mayAcceptRow(probedPrevValues[0]) && deepEqual(getRowKey(primaryKey, probedPrevValues[0]), rowKey);
959
+ if (isUnobservableAdd || isUnobservableEdit) {
960
+ pushCompleted = true;
961
+ continue;
962
+ }
963
+ if (nextValue !== null && !this.#reserveSecondRow(advanceContext, rowKey, primaryKey)) holds = "rows";
964
+ const prevValues = tableSource.reconcilePendingConflicts(probedPrevValues, nextValue, rowKey, this.#tableSpecs.get(table)?.tableSpec.uniqueKeys ?? []);
551
965
  let editOldRow = void 0;
552
966
  for (const prevValue of prevValues) if (nextValue && deepEqual(getRowKey(primaryKey, prevValue), getRowKey(primaryKey, nextValue))) editOldRow = prevValue;
553
967
  else {
@@ -556,42 +970,318 @@ var PipelineDriver = class {
556
970
  }
557
971
  if (nextValue) if (editOldRow) yield* this.#push(tableSource, makeSourceChangeEdit(nextValue, editOldRow));
558
972
  else yield* this.#push(tableSource, makeSourceChangeAdd(nextValue));
973
+ pushCompleted = true;
559
974
  } finally {
560
975
  advanceContext.pos++;
976
+ if (pushCompleted) {
977
+ progress.changesProcessed++;
978
+ advanceContext.completedChanges = diff.changesScanned;
979
+ }
561
980
  }
562
- this.#shouldAdvanceYieldMaybeAbortAdvance(false);
981
+ this.#checkAdvance(advanceContext, false);
982
+ if (holds === "fits") holds = this.#holdPendingRows(advanceContext);
563
983
  } finally {
984
+ advanceContext.pushTimeMs += timer.totalElapsed() - start;
985
+ advanceContext.stage = "diff";
564
986
  advanceContext.currentChangeStartMs = void 0;
565
987
  }
566
988
  const elapsed = timer.totalElapsed() - start;
567
- this.#advanceTime.recordMs(elapsed, {
568
- table,
569
- type
570
- });
989
+ this.#advanceTime.recordMs(elapsed, { table });
990
+ if (holds !== "fits") yield* this.#writeThrough(advanceContext, diff, holds);
571
991
  }
992
+ advanceContext.completedChanges = diff.changesScanned;
572
993
  const { curr } = diff;
573
994
  for (const table of this.#tables.values()) table.setDB(curr.db.db);
995
+ this.#costBasedAdvanceIncomplete = false;
574
996
  this.#ensureCostModelExistsIfEnabled(curr.db.db);
575
997
  this.#lc.debug?.(`Advanced to ${curr.version}`);
998
+ this.#logSlowAdvances(advanceContext);
999
+ if (costBased) {
1000
+ this.#recordPushCosts(advanceContext, costBased, diff.changesScannedByTable);
1001
+ if (readToEnd && diff.changes > 0 && diff.stats) {
1002
+ const { changeLogReadMs, parseMs, rowReadMs } = diff.stats;
1003
+ this.#readCosts.record({
1004
+ walk: changeLogReadMs,
1005
+ parse: parseMs,
1006
+ lookup: rowReadMs
1007
+ }, {
1008
+ walk: costBased.entries,
1009
+ parse: diff.changesScanned,
1010
+ lookup: diff.changesLookedUp
1011
+ });
1012
+ }
1013
+ this.#snapshotter.releasePrevious();
1014
+ }
1015
+ } catch (e) {
1016
+ if (e instanceof ResetPipelinesSignal && e.reason === "advancement-timeout") {
1017
+ timedOut = true;
1018
+ this.#logAdvanceTimeout(advanceContext, e);
1019
+ }
1020
+ throw e;
576
1021
  } finally {
1022
+ if (advanceContext.reservedRows !== void 0) for (const table of this.#tables.values()) table.discardPendingChanges();
1023
+ this.#releaseDeferredWrites(advanceContext);
577
1024
  this.#advanceContext = null;
1025
+ this.#recordAdvanceStats(advanceContext, timedOut);
1026
+ }
1027
+ }
1028
+ /**
1029
+ * Checks the progress of the advancement. Returns whether it should yield.
1030
+ *
1031
+ * An advancement is bounded in one of two ways, never both. A
1032
+ * {@link CostBasedAdvance} cuts queries off one by one between changes
1033
+ * (see {@link #cutOffQueries}) and always runs to completion.
1034
+ * Without one, {@link #shouldAdvanceYieldMaybeAbortAdvance} aborts the
1035
+ * advancement with a {@link ResetPipelinesSignal} if it takes too long.
1036
+ */
1037
+ #checkAdvance(advanceContext, checkYield = true) {
1038
+ if (advanceContext.costBased === void 0) return this.#shouldAdvanceYieldMaybeAbortAdvance(checkYield);
1039
+ return checkYield && advanceContext.timer.elapsedLap() > this.#yieldThresholdMs();
1040
+ }
1041
+ /**
1042
+ * Removes the pipelines of the queries that the cutoff says to.
1043
+ *
1044
+ * @param nextTable The table of the change that `diff` has just yielded,
1045
+ * which has not been pushed yet.
1046
+ */
1047
+ #cutOffQueries({ queryStats }, costBased, diff, nextTable) {
1048
+ const cutOff = costBased.cutoff.takeCutOff((queryID) => {
1049
+ const pipeline = this.#pipelines.get(queryID);
1050
+ const stats = queryStats.get(queryID);
1051
+ return pipeline === void 0 || stats === void 0 ? void 0 : {
1052
+ queryID,
1053
+ pushTimeMs: stats.timeMs,
1054
+ changes: stats.changes,
1055
+ hydrationTimeMs: pipeline.hydrationTimeMs
1056
+ };
1057
+ });
1058
+ if (cutOff.length === 0) return;
1059
+ const entriesByTable = new Map(diff.changesScannedByTable);
1060
+ entriesByTable.set(nextTable, (entriesByTable.get(nextTable) ?? 1) - 1);
1061
+ for (const progress of cutOff) {
1062
+ const { queryID } = progress;
1063
+ const pipeline = must(this.#pipelines.get(queryID));
1064
+ this.#pushCosts.record(queryID, pipeline.tables, queryStats.get(queryID)?.timeMsByTable, entriesByTable);
1065
+ this.#queryStats?.recordAdvance(pipeline, {
1066
+ timeMs: progress.pushTimeMs,
1067
+ changes: progress.changes,
1068
+ timedOut: false
1069
+ });
1070
+ this.#abandon(costBased.abandoned, "cutoff", pipeline, {
1071
+ ...progress,
1072
+ estimatedPushMs: costBased.estimatedPushMs.get(queryID)
1073
+ });
1074
+ }
1075
+ }
1076
+ /**
1077
+ * Learns from a completed advancement what its changes cost the queries
1078
+ * that were pushed all of them.
1079
+ */
1080
+ #recordPushCosts({ queryStats }, { estimatedPushMs, estimates }, entriesByTable) {
1081
+ for (const [queryID, pipeline] of this.#pipelines) {
1082
+ const stats = queryStats.get(queryID);
1083
+ this.#pushCosts.record(queryID, pipeline.tables, stats?.timeMsByTable, entriesByTable);
1084
+ const estimate = estimatedPushMs.get(queryID);
1085
+ if (estimate !== void 0) estimates.push({
1086
+ queryID,
1087
+ estimatedPushMs: estimate,
1088
+ pushTimeMs: stats?.timeMs ?? 0
1089
+ });
1090
+ }
1091
+ }
1092
+ /** Accounts the time each query took in an advancement to its shape. */
1093
+ #recordAdvanceStats({ queryStats }, timedOut) {
1094
+ if (this.#queryStats === void 0) return;
1095
+ for (const [queryID, { timeMs, changes }] of queryStats) {
1096
+ const pipeline = this.#pipelines.get(queryID);
1097
+ if (pipeline !== void 0) this.#queryStats.recordAdvance(pipeline, {
1098
+ timeMs,
1099
+ changes,
1100
+ timedOut
1101
+ });
1102
+ }
1103
+ }
1104
+ /**
1105
+ * Decides how the sources apply an advancement's changes: in memory if
1106
+ * they fit in the worker's {@link DeferredWritesBudget}, and otherwise
1107
+ * written through to the `prev` snapshot. Returns the number of rows
1108
+ * reserved if they are held in memory.
1109
+ */
1110
+ #reserveDeferredWrites(numChanges) {
1111
+ const budget = this.#deferredWrites;
1112
+ if (!budget) return;
1113
+ if (budget.tryReserve(numChanges)) return numChanges;
1114
+ this.#deferredWritesFallbacks.add(1, { stage: "start" });
1115
+ this.#lc.debug?.(`writing through ${numChanges} changes: ${budget.reservedRows} rows of the deferred writes budget are reserved`);
1116
+ }
1117
+ /**
1118
+ * If the change log identifies the rows of a table by a key other than its
1119
+ * primary key here, an entry that sets a row can change its primary key,
1120
+ * which is two rows to a source: the old and the new. (An entry that removes
1121
+ * a row removes the one row its key identifies.) Reserves the second row for
1122
+ * such an entry, if the advancement holds its changes in memory, and
1123
+ * returns whether it fit.
1124
+ */
1125
+ #reserveSecondRow(advanceContext, rowKey, primaryKey) {
1126
+ if (advanceContext.reservedRows === void 0 || isKeyedBy(rowKey, primaryKey)) return true;
1127
+ if (!must(this.#deferredWrites).tryReserveMore(1)) return false;
1128
+ advanceContext.reservedRows++;
1129
+ return true;
1130
+ }
1131
+ /**
1132
+ * Writes the changes that an advancement holds in memory through to the
1133
+ * `prev` snapshot, and the rest of its changes after them, when they no
1134
+ * longer fit (see {@link HeldRows}). The advancement then continues as if
1135
+ * it had written through from the start.
1136
+ */
1137
+ *#writeThrough(advanceContext, diff, reason) {
1138
+ const budget = must(this.#deferredWrites);
1139
+ this.#deferredWritesFallbacks.add(1, {
1140
+ stage: "partway",
1141
+ reason
1142
+ });
1143
+ this.#lc.debug?.(`writing through (${reason}) at ${advanceContext.pos} of ${advanceContext.numChanges} changes, holding ${advanceContext.heldBytes} of the ${budget.heldBytes} estimated bytes held on this worker (budget: ${budget.maxBytes})`);
1144
+ diff.setPrevWrites("divergent");
1145
+ for (const source of this.#tables.values()) yield* source.writePendingChanges();
1146
+ this.#releaseDeferredWrites(advanceContext);
1147
+ }
1148
+ #releaseDeferredWrites(advanceContext) {
1149
+ const { reservedRows, heldBytes } = advanceContext;
1150
+ if (reservedRows !== void 0) {
1151
+ must(this.#deferredWrites).release(reservedRows, heldBytes);
1152
+ advanceContext.reservedRows = void 0;
1153
+ advanceContext.heldBytes = 0;
1154
+ }
1155
+ }
1156
+ #recordAdvancePush(queryID, timeMs) {
1157
+ const advance = this.#advanceContext;
1158
+ if (advance === null) return;
1159
+ const stats = getOrInsertComputed(advance.queryStats, queryID, () => ({
1160
+ timeMs: 0,
1161
+ changes: 0,
1162
+ lastPos: -1,
1163
+ timeMsByTable: /* @__PURE__ */ new Map()
1164
+ }));
1165
+ stats.timeMs += timeMs;
1166
+ advance.costBased?.cutoff.recordPush(queryID);
1167
+ if (stats.lastPos !== advance.pos) {
1168
+ stats.lastPos = advance.pos;
1169
+ stats.changes++;
1170
+ }
1171
+ const table = advance.currentTable;
1172
+ if (table !== void 0) stats.timeMsByTable.set(table, (stats.timeMsByTable.get(table) ?? 0) + timeMs);
1173
+ }
1174
+ /**
1175
+ * The identity of the query of the pipeline for `queryID` and its
1176
+ * {@link queryShape}, for logging.
1177
+ */
1178
+ #queryForLog(queryID) {
1179
+ const pipeline = this.#pipelines.get(queryID);
1180
+ if (pipeline === void 0) return;
1181
+ const { transformationHash, queryName, shape } = pipeline;
1182
+ return {
1183
+ queryName,
1184
+ shape,
1185
+ fields: {
1186
+ queryHash: queryID,
1187
+ transformationHash,
1188
+ ...queryName !== void 0 && { queryName },
1189
+ queryShape: shape.hash
1190
+ }
1191
+ };
1192
+ }
1193
+ /** Compute once for an admitted log, without clocks or allocations per change. */
1194
+ #advancementLogFields({ timer, diff, progress, completedChanges, queryStats, totalHydrationTimeMs }) {
1195
+ const advancementTimeMs = timer.totalElapsed();
1196
+ let queryPushTimeMs = 0;
1197
+ for (const stats of queryStats.values()) queryPushTimeMs += stats.timeMs;
1198
+ return {
1199
+ advancementTimeMs,
1200
+ queryPushTimeMs,
1201
+ outsideQueryPushTimeMs: Math.max(0, advancementTimeMs - queryPushTimeMs),
1202
+ totalHydrationTimeMs,
1203
+ changesScanned: diff.changesScanned,
1204
+ changesCompleted: completedChanges,
1205
+ changesProcessed: progress.changesProcessed,
1206
+ changesSkipped: diff.changesSkipped
1207
+ };
1208
+ }
1209
+ /**
1210
+ * Logs each query whose pushes took longer than the slow advance
1211
+ * threshold, at most once per query shape per
1212
+ * {@link SLOW_ADVANCE_LOG_WINDOW_MS}.
1213
+ */
1214
+ #logSlowAdvances(context) {
1215
+ if (!this.#lc.warn) return;
1216
+ const { queryStats, numChanges } = context;
1217
+ let advancementFields;
1218
+ for (const [queryID, stats] of queryStats) {
1219
+ if (stats.timeMs <= this.#logConfig.slowAdvanceThreshold) continue;
1220
+ const query = this.#queryForLog(queryID);
1221
+ if (query === void 0) continue;
1222
+ const suppressed = slowAdvanceLogThrottle.admit(`${query.queryName ?? ""}:${query.shape.hash}`);
1223
+ if (suppressed === void 0) continue;
1224
+ this.#lc.warn(`Slow query advancement${query.queryName === void 0 ? "" : ` for ${query.queryName}`}: ${Math.round(stats.timeMs)} ms for ${stats.changes} of ${numChanges} changes`, {
1225
+ zeroEvent: "query-slow-advance",
1226
+ ...query.fields,
1227
+ advanceTimeMs: stats.timeMs,
1228
+ changes: stats.changes,
1229
+ advancementChanges: numChanges,
1230
+ ...advancementFields ??= this.#advancementLogFields(context),
1231
+ timeMsByTable: Object.fromEntries(stats.timeMsByTable),
1232
+ ...suppressed > 0 && { suppressedSinceLastLog: suppressed },
1233
+ zql: query.shape.zql
1234
+ });
578
1235
  }
579
1236
  }
1237
+ /**
1238
+ * Logs the queries that took the most time in an advancement that timed
1239
+ * out, since the reset that follows would otherwise not say what was slow.
1240
+ * Throttled per query shape of the slowest query, with a shared fallback
1241
+ * when the timeout happens before any query push timings are recorded.
1242
+ */
1243
+ #logAdvanceTimeout(context, reset) {
1244
+ if (!this.#lc.warn) return;
1245
+ const { queryStats, numChanges } = context;
1246
+ const slowest = [...queryStats].toSorted(([, a], [, b]) => b.timeMs - a.timeMs).slice(0, ADVANCE_TIMEOUT_LOG_MAX_QUERIES).flatMap(([queryID, stats]) => {
1247
+ const query = this.#queryForLog(queryID);
1248
+ return query ? [{
1249
+ query,
1250
+ stats
1251
+ }] : [];
1252
+ });
1253
+ const leadingQuery = slowest[0]?.query;
1254
+ const suppressed = slowAdvanceLogThrottle.admit(leadingQuery ? `timeout:${leadingQuery.queryName ?? ""}:${leadingQuery.shape.hash}` : "timeout:outside-query-push");
1255
+ if (suppressed === void 0) return;
1256
+ const summary = slowest.map(({ query, stats }) => `${query.queryName ?? query.fields.queryHash} (${Math.round(stats.timeMs)} ms)`).join(", ");
1257
+ this.#lc.warn(`Advancement of ${numChanges} changes timed out. ` + (summary ? `The queries that took the most time: ${summary}` : "No query push timings were recorded."), {
1258
+ zeroEvent: "query-advance-timeout",
1259
+ reason: reset.message,
1260
+ advancementChanges: numChanges,
1261
+ ...this.#advancementLogFields(context),
1262
+ queries: slowest.map(({ query, stats }) => ({
1263
+ ...query.fields,
1264
+ advanceTimeMs: stats.timeMs,
1265
+ changes: stats.changes,
1266
+ zql: query.shape.zql
1267
+ })),
1268
+ ...suppressed > 0 && { suppressedSinceLastLog: suppressed }
1269
+ });
1270
+ }
580
1271
  /** Implements `BuilderDelegate.getSource()` */
581
1272
  #getSource(tableName) {
582
- let source = this.#tables.get(tableName);
583
- if (source) return source;
584
- const tableSpec = mustGetTableSpec(this.#tableSpecs, tableName);
585
- const primaryKey = mustGetPrimaryKey(this.#primaryKeys, tableName);
586
- const { db } = this.#snapshotter.current();
587
- source = new TableSource(this.#lc, this.#logConfig, db.db, tableName, tableSpec.zqlSpec, primaryKey, () => this.#shouldYield());
588
- this.#tables.set(tableName, source);
589
- this.#lc.debug?.(`created TableSource for ${tableName}`);
590
- return source;
1273
+ return getOrInsertComputed(this.#tables, tableName, (tableName) => {
1274
+ const tableSpec = mustGetTableSpec(this.#tableSpecs, tableName);
1275
+ const primaryKey = mustGetPrimaryKey(this.#primaryKeys, tableName);
1276
+ const { db } = this.#snapshotter.current();
1277
+ const source = new TableSource(this.#lc, this.#logConfig, db.db, tableName, tableSpec.zqlSpec, primaryKey, () => this.#shouldYield(), { skipUnobservableChanges: true });
1278
+ this.#lc.debug?.(`created TableSource for ${tableName}`);
1279
+ return source;
1280
+ });
591
1281
  }
592
1282
  #shouldYield() {
593
1283
  if (this.#hydrateContext) return this.#hydrateContext.timer.elapsedLap() > this.#yieldThresholdMs();
594
- if (this.#advanceContext) return this.#shouldAdvanceYieldMaybeAbortAdvance();
1284
+ if (this.#advanceContext) return this.#checkAdvance(this.#advanceContext);
595
1285
  throw new Error("shouldYield called outside of hydration or advancement");
596
1286
  }
597
1287
  /**
@@ -601,120 +1291,132 @@ var PipelineDriver = class {
601
1291
  * checks; a single pathological push always resets.
602
1292
  */
603
1293
  #shouldAdvanceYieldMaybeAbortAdvance(checkYield = true) {
604
- const { currentChangeStartMs, pos, numChanges, timer: advanceTimer, totalHydrationTimeMs } = must(this.#advanceContext);
1294
+ const { currentChangeStartMs, completedChanges, numChanges, timer: advanceTimer, totalHydrationTimeMs } = must(this.#advanceContext);
605
1295
  const elapsed = advanceTimer.totalElapsed();
606
1296
  const currentChangeElapsedMs = currentChangeStartMs === void 0 ? void 0 : elapsed - currentChangeStartMs;
607
- if (currentChangeElapsedMs !== void 0 && shouldResetSlowCurrentChange(currentChangeElapsedMs, totalHydrationTimeMs)) this.#throwSlowCurrentChangeReset(pos, numChanges, elapsed, currentChangeElapsedMs, totalHydrationTimeMs);
608
- const projectedTotalTimeMs = projectedAdvancementTimeMs(elapsed, pos, numChanges);
609
- const shouldFinish = shouldFinishLateAdvancement(pos, numChanges);
610
- if (!shouldFinish && shouldResetProjectedAdvancement(elapsed, projectedTotalTimeMs, pos, numChanges, totalHydrationTimeMs)) this.#throwProjectedAdvancementReset(pos, numChanges, elapsed, projectedTotalTimeMs, totalHydrationTimeMs);
611
- if (!shouldFinish && elapsed > MIN_ADVANCEMENT_TIME_LIMIT_MS && (elapsed > totalHydrationTimeMs || elapsed > totalHydrationTimeMs / 2 && pos <= numChanges / 2)) throw new ResetPipelinesSignal(`Advancement exceeded timeout at ${pos} of ${numChanges} changes after ${elapsed} ms. Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout");
1297
+ if (currentChangeElapsedMs !== void 0 && shouldResetSlowCurrentChange(currentChangeElapsedMs, totalHydrationTimeMs)) this.#throwSlowCurrentChangeReset(completedChanges, numChanges, elapsed, currentChangeElapsedMs, totalHydrationTimeMs);
1298
+ const projectedTotalTimeMs = projectedAdvancementTimeMs(elapsed, completedChanges, numChanges);
1299
+ if (!shouldFinishLateAdvancement(completedChanges, numChanges)) {
1300
+ if (canProjectAdvancement(elapsed, projectedTotalTimeMs, completedChanges, numChanges)) {
1301
+ const projectedTotal = must(projectedTotalTimeMs);
1302
+ if (shouldResetProjectedAdvancement(elapsed, projectedTotal, totalHydrationTimeMs)) this.#throwProjectedAdvancementReset(completedChanges, numChanges, elapsed, projectedTotal, totalHydrationTimeMs);
1303
+ } else if (elapsed > MIN_ADVANCEMENT_TIME_LIMIT_MS && elapsed > totalHydrationTimeMs) {
1304
+ const breakdown = formatAdvancementBreakdown(must(this.#advanceContext), elapsed);
1305
+ this.#lc.warn?.(`Advancement exceeded timeout at ${completedChanges} of ${numChanges} changes after ${elapsed.toFixed(1)} ms (${breakdown}). Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`);
1306
+ throw new ResetPipelinesSignal(`Advancement exceeded timeout at ${completedChanges} of ${numChanges} changes after ${elapsed} ms. Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout", breakdown);
1307
+ }
1308
+ }
612
1309
  return checkYield && advanceTimer.elapsedLap() > this.#yieldThresholdMs();
613
1310
  }
1311
+ /**
1312
+ * The rows an advancement holds in memory are bounded by its reservation,
1313
+ * but their width is not known in advance. So the bytes they are estimated
1314
+ * to hold are added to those held by the other advancements on this worker.
1315
+ * Says whether that takes them past the budget, or if the rows are not
1316
+ * bounded by the reservation after all.
1317
+ */
1318
+ #holdPendingRows(advanceContext) {
1319
+ const { reservedRows, heldBytes, pos, numChanges } = advanceContext;
1320
+ if (reservedRows === void 0) return "fits";
1321
+ const budget = must(this.#deferredWrites);
1322
+ const rows = this.pendingRows;
1323
+ const bytes = this.pendingBytes;
1324
+ advanceContext.heldBytes = bytes;
1325
+ const bytesFit = budget.holdBytes(bytes - heldBytes);
1326
+ if (rows > reservedRows) {
1327
+ budget.recordRowOverrun();
1328
+ this.#lc.error?.(`Advancement holds ${rows} rows at ${pos} of ${numChanges} changes, more than the ${reservedRows} it reserved. Writing through the rest.`);
1329
+ return "row-overrun";
1330
+ }
1331
+ return bytesFit ? "fits" : "bytes";
1332
+ }
614
1333
  #throwSlowCurrentChangeReset(pos, numChanges, elapsed, currentChangeElapsedMs, totalHydrationTimeMs) {
615
- throw new ResetPipelinesSignal(`Advancement exceeded timeout processing current change at ${pos} of ${numChanges} changes after ${currentChangeElapsedMs} ms (${elapsed} ms total). Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout");
1334
+ const breakdown = this.#advanceContext ? formatAdvancementBreakdown(this.#advanceContext, elapsed) : void 0;
1335
+ this.#lc.warn?.(`Advancement slow current change at ${pos} of ${numChanges} changes after ${currentChangeElapsedMs.toFixed(1)} ms (${elapsed.toFixed(1)} ms total)` + (breakdown ? ` (${breakdown})` : "") + `. Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`);
1336
+ throw new ResetPipelinesSignal(`Advancement exceeded timeout processing current change at ${pos} of ${numChanges} changes after ${currentChangeElapsedMs} ms (${elapsed} ms total). Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout", breakdown);
616
1337
  }
617
1338
  #throwProjectedAdvancementReset(pos, numChanges, elapsed, projectedTotalTimeMs, totalHydrationTimeMs) {
1339
+ const breakdown = this.#advanceContext ? formatAdvancementBreakdown(this.#advanceContext, elapsed) : void 0;
618
1340
  const projection = projectedTotalTimeMs === void 0 ? "" : ` Projected total advancement time is ${projectedTotalTimeMs} ms.`;
619
- throw new ResetPipelinesSignal(`Advancement projected to exceed hydration time at ${pos} of ${numChanges} changes after ${elapsed} ms.` + projection + ` Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout");
1341
+ this.#lc.warn?.(`Advancement projected timeout at ${pos} of ${numChanges} changes after ${elapsed.toFixed(1)} ms` + projection + (breakdown ? ` (${breakdown})` : "") + `. Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`);
1342
+ throw new ResetPipelinesSignal(`Advancement projected to exceed hydration time at ${pos} of ${numChanges} changes after ${elapsed} ms.` + projection + ` Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout", breakdown);
620
1343
  }
621
1344
  /** Implements `BuilderDelegate.createStorage()` */
622
1345
  #createStorage() {
623
1346
  return this.#storage.createStorage();
624
1347
  }
625
1348
  *#push(source, change) {
626
- this.#startAccumulating();
1349
+ assert(this.#pushedRowChanges === null, "push already in progress");
627
1350
  try {
1351
+ this.#pushedRowChanges = [];
628
1352
  for (const val of source.genPush(change)) {
629
1353
  if (val === "yield") yield "yield";
630
- for (const changeOrYield of this.#stopAccumulating().stream()) yield changeOrYield;
631
- this.#startAccumulating();
1354
+ const rowChanges = this.#pushedRowChanges;
1355
+ this.#pushedRowChanges = [];
1356
+ yield* rowChanges;
632
1357
  }
633
1358
  } finally {
634
- if (this.#streamer !== null) this.#stopAccumulating();
1359
+ this.#pushedRowChanges = null;
635
1360
  }
636
1361
  }
637
- #startAccumulating() {
638
- assert(this.#streamer === null, "Streamer already started");
639
- this.#streamer = new Streamer(must(this.#primaryKeys), this.#tableSpecs, (queryID, error) => this.#logQueryFailure(queryID, "query pipeline failed", error));
640
- }
641
- #stopAccumulating() {
642
- const streamer = this.#streamer;
643
- assert(streamer, "Streamer not started");
644
- this.#streamer = null;
645
- return streamer;
646
- }
647
- #logQueryFailure(queryID, message, error) {
648
- const pipeline = this.#pipelines.get(queryID);
649
- const queryInfo = pipeline ? {
650
- queryHash: queryID,
651
- transformationHash: pipeline.transformationHash,
652
- queryName: pipeline.queryName
653
- } : void 0;
654
- logQueryFailure(this.#lc, queryInfo, message, error);
1362
+ /**
1363
+ * Converts a change pushed out of a query pipeline into row changes during
1364
+ * the push. The relationships of a pushed node are lazy, and operators such
1365
+ * as Join compute them from the state of the push in progress: while a child
1366
+ * change is pushed to each matching parent in turn, parents not yet pushed
1367
+ * must not see it. Read after the push has moved on to the next parent, or
1368
+ * after it has finished, a node's relationships show the later state, and
1369
+ * rows that are also pushed separately are counted twice.
1370
+ */
1371
+ *#streamPushed(queryID, schema, change) {
1372
+ assert(this.#pushedRowChanges, "changes are only pushed by #push");
1373
+ for (const rowChange of must(this.#streamer).streamChange(queryID, schema, change)) {
1374
+ if (rowChange === "yield") {
1375
+ yield rowChange;
1376
+ continue;
1377
+ }
1378
+ must(this.#pushedRowChanges).push(rowChange);
1379
+ }
655
1380
  }
656
1381
  };
1382
+ /** Turns the output of query pipelines into the row changes sent to clients. */
657
1383
  var Streamer = class {
658
1384
  #primaryKeys;
659
1385
  #tableSpecs;
660
- #logQueryFailure;
661
- constructor(primaryKeys, tableSpecs, logQueryFailure) {
1386
+ constructor(primaryKeys, tableSpecs) {
662
1387
  this.#primaryKeys = primaryKeys;
663
1388
  this.#tableSpecs = tableSpecs;
664
- this.#logQueryFailure = logQueryFailure;
665
1389
  }
666
- #changes = [];
667
- accumulate(queryID, schema, changes) {
668
- this.#changes.push([
669
- queryID,
670
- schema,
671
- changes
672
- ]);
673
- return this;
674
- }
675
- *stream() {
676
- for (const [queryID, schema, changes] of this.#changes) try {
677
- yield* this.#streamChanges(queryID, schema, changes);
678
- } catch (e) {
679
- this.#logQueryFailure?.(queryID, e);
680
- throw e;
681
- }
682
- }
683
- *#streamChanges(queryID, schema, changes) {
1390
+ /** The row changes for a change pushed out of the pipeline of `queryID`. */
1391
+ *streamChange(queryID, schema, change) {
684
1392
  if (schema.system === "permissions") return;
685
- for (const change of changes) {
686
- if (change === "yield") {
687
- yield change;
688
- continue;
689
- }
690
- const type = change[0];
691
- switch (type) {
692
- case 1:
693
- case 0:
694
- yield* this.#streamNodes(queryID, schema, type, () => [change[1]]);
695
- break;
696
- case 3: {
697
- const child = change[2];
698
- const childSchema = must(schema.relationships[child.relationshipName]);
699
- yield* this.#streamChanges(queryID, childSchema, [child.change]);
700
- break;
701
- }
702
- case 2:
703
- yield* this.#streamNodes(queryID, schema, type, () => [{
704
- row: change[1].row,
705
- relationships: {}
706
- }]);
707
- break;
708
- default: unreachable(change[0]);
1393
+ const type = change[0];
1394
+ switch (type) {
1395
+ case 1:
1396
+ case 0:
1397
+ yield* this.streamNodes(queryID, schema, type, [change[1]]);
1398
+ break;
1399
+ case 3: {
1400
+ const child = change[2];
1401
+ yield* this.streamChange(queryID, must(schema.relationships[child.relationshipName]), child.change);
1402
+ break;
709
1403
  }
1404
+ case 2:
1405
+ yield* this.streamNodes(queryID, schema, type, [{
1406
+ row: change[1].row,
1407
+ relationships: {}
1408
+ }]);
1409
+ break;
1410
+ default: unreachable(change[0]);
710
1411
  }
711
1412
  }
712
- *#streamNodes(queryID, schema, op, nodes) {
1413
+ /** A row change of type `op` for each of `nodes` and their descendants. */
1414
+ *streamNodes(queryID, schema, op, nodes) {
713
1415
  const { tableName: table, system } = schema;
1416
+ if (system === "permissions") return;
714
1417
  const primaryKey = must(this.#primaryKeys.get(table));
715
1418
  const spec = must(this.#tableSpecs.get(table)).tableSpec;
716
- if (system === "permissions") return;
717
- for (const node of nodes()) {
1419
+ for (const node of nodes) {
718
1420
  if (node === "yield") {
719
1421
  yield node;
720
1422
  continue;
@@ -736,9 +1438,9 @@ var Streamer = class {
736
1438
  rowKey,
737
1439
  row: op === 1 ? void 0 : row
738
1440
  };
739
- for (const [relationship, children] of Object.entries(relationships)) {
1441
+ for (const relationship of Object.keys(relationships)) {
740
1442
  const childSchema = must(schema.relationships[relationship]);
741
- yield* this.#streamNodes(queryID, childSchema, op, children);
1443
+ if (childSchema.system !== "permissions") yield* this.streamNodes(queryID, childSchema, op, relationships[relationship]());
742
1444
  }
743
1445
  }
744
1446
  }
@@ -782,6 +1484,18 @@ var QueryFailureLoggingOperator = class {
782
1484
  throw e;
783
1485
  }
784
1486
  }
1487
+ *reconcile(_pusher) {
1488
+ if (this.#output.reconcile) try {
1489
+ yield* this.#output.reconcile(this);
1490
+ } catch (e) {
1491
+ logQueryFailure(this.#lc, {
1492
+ queryHash: this.#queryHash,
1493
+ transformationHash: this.#transformationHash,
1494
+ queryName: this.#queryName
1495
+ }, "query pipeline failed during reconcile", e);
1496
+ throw e;
1497
+ }
1498
+ }
785
1499
  };
786
1500
  function logQueryFailure(lc, queryInfo, message, error) {
787
1501
  if (error instanceof ResetPipelinesSignal) return;
@@ -792,43 +1506,73 @@ function logQueryFailure(lc, queryInfo, message, error) {
792
1506
  }
793
1507
  queryLC.error?.(message, error);
794
1508
  }
795
- function* toAdds(nodes) {
796
- for (const node of nodes) {
797
- if (node === "yield") {
798
- yield node;
799
- continue;
800
- }
801
- yield [
802
- 0,
803
- node,
804
- null
805
- ];
806
- }
807
- }
808
1509
  function getRowKey(cols, row) {
809
- return Object.fromEntries(cols.map((col) => [col, must(row[col])]));
1510
+ const rowKey = {};
1511
+ for (const col of cols) assignProperty(rowKey, col, must(row[col]));
1512
+ return rowKey;
1513
+ }
1514
+ /** Whether `rowKey` has exactly the columns of `primaryKey`. */
1515
+ function isKeyedBy(rowKey, primaryKey) {
1516
+ let cols = 0;
1517
+ for (const col in rowKey) {
1518
+ if (!primaryKey.includes(col)) return false;
1519
+ cols++;
1520
+ }
1521
+ return cols === primaryKey.length;
810
1522
  }
811
1523
  /**
812
1524
  * Core hydration logic used by {@link PipelineDriver#addQuery}, extracted to a
813
1525
  * function for reuse by the analyze-query RPC path so that analysis hydrates
814
- * queries the same way the view-syncer does in production.
1526
+ * queries the same way the view-syncer does in production. As there, the rows
1527
+ * of a table outside `clientSchema` are keyed by its key in the replica.
1528
+ */
1529
+ function hydrate(input, hash, clientSchema, tableSpecs) {
1530
+ return new Streamer(buildRowKeys(clientSchema, tableSpecs), tableSpecs).streamNodes(hash, input.getSchema(), 0, input.fetch({}));
1531
+ }
1532
+ /**
1533
+ * Returns the value of `childField` in the row of `input`, the pipeline of a
1534
+ * scalar subquery: `null` if the field is `NULL`, or `undefined` if there is
1535
+ * no row. Used by {@link PipelineDriver#addQuery} and the analyze-query RPC
1536
+ * path to resolve scalar subqueries the same way.
815
1537
  */
816
- function* hydrate(input, hash, clientSchema, tableSpecs) {
817
- const res = input.fetch({});
818
- yield* new Streamer(buildPrimaryKeys(clientSchema), tableSpecs).accumulate(hash, input.getSchema(), toAdds(res)).stream();
1538
+ function fetchScalarValue(input, childField) {
1539
+ let node;
1540
+ for (const n of skipYields(input.fetch({}))) node ??= n;
1541
+ if (!node) return;
1542
+ return node.row[childField] ?? null;
819
1543
  }
820
- function* hydrateInternal(input, hash, primaryKeys, tableSpecs) {
821
- const res = input.fetch({});
822
- yield* new Streamer(primaryKeys, tableSpecs).accumulate(hash, input.getSchema(), toAdds(res)).stream();
1544
+ /**
1545
+ * The schema the rows of a companion pipeline are streamed with. A companion is
1546
+ * built from the bare subquery, so its schema says `'client'` even when its
1547
+ * gate came from a permission rule. Rows read for a rule are never synced, so
1548
+ * such a companion takes the gate's system and the Streamer skips it, the rows
1549
+ * behind any EXISTS nested in it included.
1550
+ */
1551
+ function companionStreamSchema(input, { system }) {
1552
+ const schema = input.getSchema();
1553
+ return system === "permissions" ? {
1554
+ ...schema,
1555
+ system
1556
+ } : schema;
823
1557
  }
824
1558
  function buildPrimaryKeys(clientSchema, primaryKeys = /* @__PURE__ */ new Map()) {
825
1559
  for (const [tableName, { primaryKey }] of Object.entries(clientSchema.tables)) primaryKeys.set(tableName, primaryKey);
826
1560
  return primaryKeys;
827
1561
  }
1562
+ /**
1563
+ * Sets `primaryKeys` to the columns that key the synced rows of each table:
1564
+ * the table's primary key in `clientSchema`, or, for a table outside it, its
1565
+ * key in the replica.
1566
+ */
1567
+ function buildRowKeys(clientSchema, tableSpecs, primaryKeys = /* @__PURE__ */ new Map()) {
1568
+ primaryKeys.clear();
1569
+ for (const [table, spec] of tableSpecs.entries()) primaryKeys.set(table, spec.tableSpec.primaryKey);
1570
+ return buildPrimaryKeys(clientSchema, primaryKeys);
1571
+ }
828
1572
  function mustGetPrimaryKey(primaryKeys, table) {
829
1573
  const pKeys = must(primaryKeys, "primaryKey map must be non-null");
830
1574
  const rv = pKeys.get(table);
831
- assert(rv, () => `table '${table}' is not one of: ${[...pKeys.keys()].sort()}. Check the spelling and ensure that the table has a primary key.`);
1575
+ assert(rv, () => `table '${table}' is not one of: ${JSON.stringify([...pKeys.keys()].sort())}. Check the spelling and ensure that the table has a primary key.`);
832
1576
  return rv;
833
1577
  }
834
1578
  /**
@@ -841,6 +1585,6 @@ function scalarValuesEqual(a, b) {
841
1585
  return a === b;
842
1586
  }
843
1587
  //#endregion
844
- export { PipelineDriver, hydrate };
1588
+ export { PipelineDriver, fetchScalarValue, hydrate };
845
1589
 
846
1590
  //# sourceMappingURL=pipeline-driver.js.map