@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,4 +1,6 @@
1
1
  import { assert, unreachable } from "../../../../shared/src/asserts.js";
2
+ import { getOrInsertComputed } from "../../../../shared/src/map.js";
3
+ import { newArray } from "../../../../shared/src/arrays.js";
2
4
  import { must } from "../../../../shared/src/must.js";
3
5
  import { h64 } from "../../../../shared/src/hash.js";
4
6
  import { Internal, InvalidConnectionRequest, InvalidConnectionRequestBaseCookie, Rehome } from "../../../../zero-protocol/src/error-kind-enum.js";
@@ -10,24 +12,28 @@ import { manualSpan, startAsyncSpan, startSpan } from "../../../../otel/src/span
10
12
  import { ZERO_VERSION_COLUMN_NAME } from "../replicator/schema/constants.js";
11
13
  import { transformAndHashQuery } from "../../auth/read-authorizer.js";
12
14
  import { randInt } from "../../../../shared/src/rand.js";
15
+ import { LogThrottle } from "../../observability/log-throttle.js";
13
16
  import { getOrCreateCounter, getOrCreateLatencyHistogram, getOrCreateNativeHistogram, getOrCreateUpDownCounter, getOrCreateValueHistogram } from "../../observability/metrics.js";
14
17
  import { rowIDString } from "../../types/row-key.js";
15
18
  import "../replicator/schema/replication-state.js";
16
- import { parseSignature } from "./row-set-signature.js";
19
+ import { planWarningMessage } from "./plan-warnings.js";
20
+ import { shouldCutOffPush } from "./push-cutoff.js";
21
+ import { queryShape } from "./query-shape.js";
17
22
  import { ResetPipelinesSignal } from "./snapshotter.js";
18
- import "./pipeline-driver.js";
19
23
  import { Subscription } from "../../types/subscription.js";
20
24
  import { CustomKeyMap } from "../../../../shared/src/custom-key-map.js";
21
25
  import { ttlClockAsNumber, ttlClockFromNumber } from "./ttl-clock.js";
22
26
  import { EMPTY_CVR_VERSION, cmpVersions, versionFromString, versionString, versionToCookie } from "./schema/types.js";
23
27
  import { ProtocolErrorWithLevel, getLogLevel, wrapWithProtocolError } from "../../types/error-with-level.js";
24
28
  import { isAuthErrorBody } from "../../auth/auth.js";
29
+ import { AdvancementMetrics } from "./advancement-metrics.js";
25
30
  import { ClientHandler, startPoke } from "./client-handler.js";
26
31
  import { tracer } from "./tracer.js";
27
32
  import { CVRStore, ClientNotFoundError } from "./cvr-store.js";
28
33
  import { CVRConfigDrivenUpdater, CVRQueryDrivenUpdater, classifyQueriesForHydration, nextEvictionTime } from "./cvr.js";
29
34
  import { E2EServingLagTracker } from "./e2e-serving-lag.js";
30
35
  import { HydrationBudget } from "./hydration-budget.js";
36
+ import { HydrationCircuitBreaker } from "./hydration-circuit-breaker.js";
31
37
  import { handleInspect } from "./inspect-handler.js";
32
38
  import { QueryCoveringIndex } from "./query-covering.js";
33
39
  import { resolver } from "@rocicorp/resolver";
@@ -51,6 +57,36 @@ function shutdownBeforeInitializationError() {
51
57
  * use a timer to update the ttlClock every minute.
52
58
  */
53
59
  var TTL_CLOCK_INTERVAL = 6e4;
60
+ /**
61
+ * A slow query is typically slow for every client group that runs it, so
62
+ * slow hydrations are logged at most once per query shape per this window,
63
+ * per process. See {@link LogThrottle}.
64
+ */
65
+ var SLOW_HYDRATION_LOG_WINDOW_MS = 5 * 6e4;
66
+ /** See `ViewSyncerService.#logRebuilds()`. */
67
+ var REBUILD_LOG_INTERVAL_MS = 6e4;
68
+ var REBUILD_LOG_MIN_MS = 1e3;
69
+ function newRebuildLog() {
70
+ return {
71
+ /** The batches that hydrated queries again. */
72
+ batches: 0,
73
+ /** How many of them were not read, which hydrates every query again. */
74
+ batchesNotRead: 0,
75
+ /** The queries that they abandoned, and why. */
76
+ queries: 0,
77
+ estimate: 0,
78
+ read: 0,
79
+ cutoff: 0,
80
+ /** How many of those were hydrated again, and how long that took. */
81
+ hydrated: 0,
82
+ hydrationTimeMs: 0,
83
+ /** How many were removed instead. */
84
+ timedOut: 0,
85
+ rejectedByCircuitBreaker: 0,
86
+ evictedForHydrationBudget: 0
87
+ };
88
+ }
89
+ var slowHydrationLogThrottle = new LogThrottle({ windowMs: SLOW_HYDRATION_LOG_WINDOW_MS });
54
90
  var ViewSyncerService = class {
55
91
  id;
56
92
  createdAtMs = Date.now();
@@ -62,6 +98,7 @@ var ViewSyncerService = class {
62
98
  #drainCoordinator;
63
99
  #keepaliveMs;
64
100
  #slowHydrateThreshold;
101
+ #hydrationCircuitBreaker;
65
102
  #lastConnectTime = Date.now();
66
103
  /**
67
104
  * The TTL clock is used to determine the time at which queries are considered
@@ -89,6 +126,13 @@ var ViewSyncerService = class {
89
126
  #lock = new Lock();
90
127
  #cvrStore;
91
128
  #stopped = resolver();
129
+ /**
130
+ * Set when {@link #cleanup} begins. Lock tasks that were in flight when the
131
+ * view-syncer was stopped may still complete after the timers have been
132
+ * cleared; this flag prevents them from scheduling new timers, which would
133
+ * otherwise outlive the service (and retain everything it references).
134
+ */
135
+ #shuttingDown = false;
92
136
  #initialized = resolver();
93
137
  #cvr;
94
138
  /**
@@ -103,7 +147,8 @@ var ViewSyncerService = class {
103
147
  * updates are processed via `#syncQueryPipelineSet`.
104
148
  *
105
149
  * Resets to `false` if `#advancePipelines` returns a `ResetPipelinesSignal`
106
- * and pipelines must be reset and rehydrated.
150
+ * and pipelines must be reset and rehydrated, or if a reloaded CVR is ahead
151
+ * of the pipelines (see `#resetPipelinesIfBehindCVR`).
107
152
  */
108
153
  #pipelinesHydrated = false;
109
154
  #servedVersion = null;
@@ -129,6 +174,7 @@ var ViewSyncerService = class {
129
174
  description: "Observations of sync.e2e_serving_lag that came out negative and were clamped to zero. Non-zero means the upstream database clock is running ahead of this pod by more than the entire pipeline latency, so sync.e2e_serving_lag is biased low and reads healthier than reality. See replication.upstream_clock_skew for the magnitude.",
130
175
  unit: "{observation}"
131
176
  });
177
+ #advancementMetrics = new AdvancementMetrics();
132
178
  #transactionAdvanceTime = getOrCreateLatencyHistogram("sync", "advance-time", "Time to advance all queries for a given client group after applying a new transaction to the replica.");
133
179
  #queryTransformations = getOrCreateCounter("sync", "query.transformations", "Number of query transformations performed");
134
180
  #queryTransformationTime = getOrCreateLatencyHistogram("sync", "query.transformation-time", "Time to transform custom queries via API server.");
@@ -181,14 +227,78 @@ var ViewSyncerService = class {
181
227
  ]
182
228
  });
183
229
  #queryEvictions = getOrCreateCounter("sync", "query_evictions", {
184
- description: "Number of inactive queries evicted, grouped by reason.",
230
+ description: "Number of queries evicted from the CVR ahead of their removal by the client, grouped by reason. Inactive queries are evicted by ttl and hydration-budget; hydration-timeout and hydration-circuit-breaker evict active queries as well.",
231
+ unit: "{query}"
232
+ });
233
+ #hydrationTimeouts = getOrCreateCounter("sync", "hydration_timeouts", {
234
+ description: "Number of query hydrations aborted for exceeding the query hydration timeout.",
235
+ unit: "{query}"
236
+ });
237
+ #hydrationCircuitBreakerRejections = getOrCreateCounter("sync", "hydration_circuit_breaker_rejections", {
238
+ description: "Number of queries rejected without hydration because their hydration circuit breaker was open.",
185
239
  unit: "{query}"
186
240
  });
187
241
  #inspectorDelegate;
188
242
  #config;
243
+ /**
244
+ * Set when `costBasedSyncEnabled`: advancements are then bounded by
245
+ * cutting off the queries this says to and hydrating them again in the
246
+ * same poke, instead of by the advancement time limit that resets every
247
+ * pipeline of the client group.
248
+ */
249
+ #pushCutoff;
250
+ /**
251
+ * Shared by the client groups of the sync worker. Set when
252
+ * `costBasedSyncEnabled`.
253
+ */
254
+ #pacer;
255
+ /**
256
+ * The time that the pipelines took for the batch being processed, if the
257
+ * pipelines were advanced: reading the changes, pushing them, and
258
+ * hydrating queries again. Unlike the processing time of the advancement,
259
+ * this leaves out the time spent awaiting I/O (e.g. the CVR flush), during
260
+ * which other client groups run.
261
+ */
262
+ #batchTimeMs;
263
+ #pipelineTime = { ms: 0 };
264
+ /** What the client group's batches have been taking, for pacing. */
265
+ #smoothedBatchTimeMs;
266
+ /** Ends the wait between batches, if the client group is in one. */
267
+ #endBatchWait;
268
+ /** The waits between batches since the last time they were logged. */
269
+ #batchWaitLog = {
270
+ loggedAt: -Infinity,
271
+ waits: 0,
272
+ waitedMs: 0
273
+ };
274
+ /** What batches have hydrated again since that was last logged. */
275
+ #rebuildLog = newRebuildLog();
276
+ #rebuildsLoggedAt = -Infinity;
277
+ #queryRebuilds = getOrCreateCounter("sync", "query-rebuilds", {
278
+ description: "Number of queries hydrated again by an advancement instead of being pushed (all of) its changes, by reason: \"estimate\" if pushing them to it was estimated to cost more, \"read\" if reading them was, for the queries that were left to push them to, or \"cutoff\" if the pushes had taken as long as hydrating the query did",
279
+ unit: "{query}"
280
+ });
281
+ #queryRebuildTime = getOrCreateLatencyHistogram("sync", "query-rebuild-time", "Time to hydrate a query again in an advancement.");
282
+ #pushEstimateRatio = getOrCreateValueHistogram("sync", "push-estimate-ratio", {
283
+ description: "The estimated time to push the changes of an advancement to a query, divided by the time it took, for queries that were pushed all of the changes",
284
+ unit: "1",
285
+ bucketBoundaries: [
286
+ .1,
287
+ .25,
288
+ .5,
289
+ .8,
290
+ 1.25,
291
+ 2,
292
+ 4,
293
+ 10
294
+ ]
295
+ });
296
+ #batchWaitTime = getOrCreateLatencyHistogram("sync", "batch-wait-time", "Time a client group is made to wait between advancements by pacing.");
189
297
  #runPriorityOp;
190
- constructor(config, lc, shard, taskID, clientGroupID, cvrDb, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, inspectorDelegate, connContextManager, customQueryTransformer, runPriorityOp, keepaliveMs = DEFAULT_KEEPALIVE_MS, setTimeoutFn = setTimeout.bind(globalThis), now = performance.now.bind(performance)) {
298
+ constructor(config, lc, shard, taskID, clientGroupID, cvrDb, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, inspectorDelegate, connContextManager, customQueryTransformer, runPriorityOp, keepaliveMs = DEFAULT_KEEPALIVE_MS, setTimeoutFn = setTimeout.bind(globalThis), now = performance.now.bind(performance), pushCutoff = shouldCutOffPush, pacer) {
191
299
  this.#config = config;
300
+ this.#pushCutoff = config.costBasedSyncEnabled ? pushCutoff : void 0;
301
+ this.#pacer = config.costBasedSyncEnabled ? pacer : void 0;
192
302
  this.id = clientGroupID;
193
303
  this.connContextManager = connContextManager;
194
304
  this.#shard = shard;
@@ -203,6 +313,7 @@ var ViewSyncerService = class {
203
313
  this.#cvrStore = new CVRStore(lc, cvrDb, shard, taskID, clientGroupID, () => this.#stateChanges.cancel());
204
314
  this.#setTimeout = setTimeoutFn;
205
315
  this.#now = now;
316
+ this.#hydrationCircuitBreaker = new HydrationCircuitBreaker(config.viewSyncerQueryHydrationTimeoutMs ?? 0, void 0, now);
206
317
  this.#runPriorityOp = runPriorityOp;
207
318
  this.keepalive();
208
319
  }
@@ -229,11 +340,13 @@ var ViewSyncerService = class {
229
340
  this.#stateChanges.cancel();
230
341
  return;
231
342
  }
343
+ let reloaded = false;
232
344
  if (!this.#cvr) {
233
345
  this.#lc.debug?.("loading cvr");
234
346
  this.#cvr = await this.#runPriorityOp(lc, "loading cvr", () => this.#cvrStore.load(lc, this.#lastConnectTime));
235
347
  this.#ttlClock = this.#cvr.ttlClock;
236
348
  this.#ttlClockBase = Date.now();
349
+ reloaded = true;
237
350
  } else {
238
351
  const now = Date.now();
239
352
  this.#cvr = {
@@ -242,6 +355,10 @@ var ViewSyncerService = class {
242
355
  };
243
356
  }
244
357
  try {
358
+ if (reloaded && this.#resetPipelinesIfBehindCVR(lc, this.#cvr)) {
359
+ const connCtx = this.connContextManager.getBackgroundConnectionContext();
360
+ if (connCtx) await this.#maybeHydratePipelines(lc, this.#cvr, connCtx);
361
+ }
245
362
  await fn(lc, this.#cvr);
246
363
  } catch (e) {
247
364
  this.#cvr = void 0;
@@ -251,11 +368,47 @@ var ViewSyncerService = class {
251
368
  }
252
369
  });
253
370
  }
371
+ /**
372
+ * The CVR is reloaded after an error clears the cached copy. By then another
373
+ * view-syncer may have taken over the client group and flushed the CVR at a
374
+ * version ahead of this instance's hydrated pipelines (e.g. its replica was
375
+ * further ahead). The pipelines can no longer be diffed against the CVR, so
376
+ * reset them and let `#maybeHydratePipelines` rehydrate once the replica has
377
+ * caught up to the CVR.
378
+ *
379
+ * A CVR behind the pipelines is expected (advancements that do not change
380
+ * the CVR are not flushed) and is handled by the normal update path.
381
+ *
382
+ * Returns whether the pipelines were reset.
383
+ *
384
+ * Must be called from within the #lock.
385
+ */
386
+ #resetPipelinesIfBehindCVR(lc, cvr) {
387
+ if (!this.#pipelinesHydrated) return false;
388
+ const pipelineVersion = this.#pipelines.currentVersion();
389
+ if (pipelineVersion >= cvr.version.stateVersion) return false;
390
+ lc.info?.(`resetting pipelines: pipelines@${pipelineVersion} are behind reloaded cvr@${versionString(cvr.version)}`);
391
+ this.#pipelineResets.add(1, { reason: "behind-cvr" });
392
+ this.#pipelinesHydrated = false;
393
+ this.connContextManager.setSharedRetransformReady(false);
394
+ this.#pipelines.reset(must(cvr.clientSchema, "cvr.clientSchema missing after initialization"));
395
+ return true;
396
+ }
254
397
  readyState() {
255
- return Promise.race([this.#initialized.promise, this.#drainCoordinator.draining]);
398
+ return new Promise((resolve, reject) => {
399
+ const unsubscribe = this.#drainCoordinator.onDraining(() => resolve("draining"));
400
+ this.#initialized.promise.then((state) => {
401
+ unsubscribe();
402
+ resolve(state);
403
+ }, (err) => {
404
+ unsubscribe();
405
+ reject(err);
406
+ });
407
+ });
256
408
  }
257
409
  async run() {
258
410
  try {
411
+ this.#scheduleShutdown(this.#keepaliveMs);
259
412
  if (await this.readyState() === "draining") {
260
413
  this.#lc.debug?.(`draining view-syncer ${this.id} before running`);
261
414
  this.stop();
@@ -268,6 +421,7 @@ var ViewSyncerService = class {
268
421
  }
269
422
  assert(state === "version-ready", "state should be version-ready");
270
423
  this.#e2eServingLagTracker.onVersionReady(replicaState);
424
+ this.#batchTimeMs = void 0;
271
425
  await this.#runInLockWithCVR(async (lc, cvr) => {
272
426
  const clientSchema = must(cvr.clientSchema, "cvr.clientSchema missing after initialization");
273
427
  if (!this.#pipelines.initialized()) this.#pipelines.init(clientSchema);
@@ -276,19 +430,32 @@ var ViewSyncerService = class {
276
430
  lc.info?.(`resetting CVR: ${message}`);
277
431
  throw new ClientNotFoundError(message);
278
432
  }
433
+ let previousQueries;
279
434
  if (this.#pipelinesHydrated) {
280
435
  const result = await this.#advancePipelines(lc, cvr);
281
436
  if (result === "success") return;
282
- lc.info?.(`resetting pipelines: ${result.message}`);
437
+ lc.info?.(`resetting pipelines: ${result.message}${result.breakdown ? ` (${result.breakdown})` : ""}`);
283
438
  this.#pipelineResets.add(1, { reason: result.reason });
439
+ switch (result.reason) {
440
+ case "advancement-timeout":
441
+ case "scalar-subquery":
442
+ case "truncation":
443
+ case "schema-change":
444
+ if (!Object.values(cvr.queries).some((q) => q.type === "client")) previousQueries = new Map([...this.#pipelines.queries(), ...this.#pipelines.abandonedQueries()]);
445
+ break;
446
+ case "permissions-change": break;
447
+ default: unreachable(result.reason);
448
+ }
284
449
  this.#pipelines.reset(clientSchema);
285
450
  this.#pipelinesHydrated = false;
286
451
  this.connContextManager.setSharedRetransformReady(false);
287
452
  }
288
453
  const backgroundConnCtx = this.connContextManager.getBackgroundConnectionContext();
289
- if (backgroundConnCtx) await this.#maybeHydratePipelines(lc, cvr, backgroundConnCtx);
454
+ if (backgroundConnCtx) await this.#maybeHydratePipelines(lc, cvr, backgroundConnCtx, previousQueries);
290
455
  else lc.info?.("No validated background connection; deferring pipeline init");
456
+ if (this.#batchTimeMs !== void 0) this.#batchTimeMs += this.#totalHydrationTimeMs();
291
457
  });
458
+ if (this.#pacer && this.#batchTimeMs !== void 0) await this.#paceBatches(this.#pacer, this.#batchTimeMs);
292
459
  }
293
460
  if (this.#drainCoordinator.shouldDrain()) this.#drainCoordinator.drainNextIn(this.#totalHydrationTimeMs());
294
461
  await this.#cleanup();
@@ -324,9 +491,18 @@ var ViewSyncerService = class {
324
491
  * - Syncs missing, errored, or drifted queries via `#syncQueryPipelineSet`.
325
492
  * - Sets `#pipelinesHydrated = true` and enables shared retransformations.
326
493
  */
327
- async #maybeHydratePipelines(lc, cvr, connCtx) {
494
+ async #maybeHydratePipelines(lc, cvr, connCtx, previousQueries) {
328
495
  if (!this.#pipelines.initialized()) return;
329
- const version = this.#pipelines.advanceWithoutDiff();
496
+ let version;
497
+ try {
498
+ version = this.#pipelines.advanceWithoutDiff(this.#pushCutoff !== void 0);
499
+ } catch (e) {
500
+ if (!(e instanceof ResetPipelinesSignal)) throw e;
501
+ lc.info?.(`resetting pipelines: ${e.message}${e.breakdown ? ` (${e.breakdown})` : ""}`);
502
+ this.#pipelineResets.add(1, { reason: e.reason });
503
+ this.#pipelines.reset(must(cvr.clientSchema, "cvr.clientSchema missing after initialization"));
504
+ version = this.#pipelines.currentVersion();
505
+ }
330
506
  const cvrVer = versionString(cvr.version);
331
507
  if (version < cvr.version.stateVersion) {
332
508
  lc.debug?.(`replica@${version} is behind cvr@${cvrVer}`);
@@ -338,8 +514,8 @@ var ViewSyncerService = class {
338
514
  activeHydratedQueries: 0,
339
515
  inactiveHydratedQueries: 0
340
516
  };
341
- const driftedQueryIDs = await this.#hydrateUnchangedQueries(lc, cvr, connCtx, hydrationPassStats, hydrationBudget);
342
- await this.#syncQueryPipelineSet(lc, cvr, "missing", connCtx, driftedQueryIDs, hydrationBudget, hydrationPassStats);
517
+ const driftedQueryIDs = await this.#hydrateUnchangedQueries(lc, cvr, connCtx, hydrationPassStats, hydrationBudget, previousQueries);
518
+ await this.#syncQueryPipelineSet(lc, cvr, "missing", connCtx, driftedQueryIDs, hydrationBudget, hydrationPassStats, previousQueries);
343
519
  this.#pipelinesHydrated = true;
344
520
  this.connContextManager.setSharedRetransformReady(true);
345
521
  }
@@ -433,7 +609,14 @@ var ViewSyncerService = class {
433
609
  return true;
434
610
  }
435
611
  #shutdownTimer = null;
612
+ #stopShutdownTimer() {
613
+ if (this.#shutdownTimer !== null) {
614
+ clearTimeout(this.#shutdownTimer);
615
+ this.#shutdownTimer = null;
616
+ }
617
+ }
436
618
  #scheduleShutdown(delayMs = 0) {
619
+ if (this.#shuttingDown) return;
437
620
  this.#shutdownTimer ??= this.#setTimeout(() => {
438
621
  this.#shutdownTimer = null;
439
622
  this.#runInLockWithCVR(() => {}).catch((e) => this.#stateChanges.fail(e));
@@ -480,6 +663,7 @@ var ViewSyncerService = class {
480
663
  */
481
664
  #scheduleAuthMaintenance(lc) {
482
665
  this.#stopAuthMaintenanceTimer();
666
+ if (this.#shuttingDown) return;
483
667
  const plan = this.connContextManager.planMaintenance();
484
668
  if (plan.earliestDeadlineAt === void 0) {
485
669
  lc.debug?.("No auth maintenance wakeup scheduled");
@@ -585,17 +769,41 @@ var ViewSyncerService = class {
585
769
  this.#ttlClockBase = now;
586
770
  return ttlClock;
587
771
  }
588
- #flushUpdater(lc, updater) {
772
+ /**
773
+ * @param patchesPoked Whether patches computed against the updater's CVR
774
+ * have already been poked to clients. If so, the CVR is checked to be
775
+ * current even when the flush has nothing to write: another
776
+ * view-syncer may have already committed identical rows at a newer
777
+ * version, which would otherwise leave this one poking from a stale
778
+ * CVR whose version it cannot advance.
779
+ */
780
+ #flushUpdater(lc, updater, patchesPoked = false) {
589
781
  return startAsyncSpan(tracer, "vs.#flushUpdater", () => this.#runPriorityOp(lc, "flushing cvr", async () => {
590
782
  const now = Date.now();
591
783
  const ttlClock = this.#getTTLClock(now);
592
- const { cvr, flushed } = await updater.flush(lc, this.#lastConnectTime, now, ttlClock);
784
+ const { cvr, flushed } = await updater.flush(lc, this.#lastConnectTime, now, ttlClock, patchesPoked);
593
785
  if (flushed) this.#startTTLClockInterval(lc);
594
786
  return cvr;
595
787
  }));
596
788
  }
789
+ /**
790
+ * Flushes an updater whose changes have already been poked. If the flush
791
+ * fails (e.g. the CVR was concurrently modified), the poke is cancelled
792
+ * before the error propagates. The error may only fail the client that
793
+ * initiated the operation, and any other client left mid-poke would fail
794
+ * its next pokeStart.
795
+ */
796
+ async #flushPoked(lc, updater, pokers) {
797
+ try {
798
+ return await this.#flushUpdater(lc, updater, pokers.patchesSent);
799
+ } catch (e) {
800
+ await pokers.cancel();
801
+ throw e;
802
+ }
803
+ }
597
804
  #startTTLClockInterval(lc) {
598
805
  this.#stopTTLClockInterval();
806
+ if (this.#shuttingDown) return;
599
807
  this.#ttlClockInterval = this.#setTimeout(() => {
600
808
  this.#updateTTLClockInCVRWithoutLock(lc);
601
809
  this.#startTTLClockInterval(lc);
@@ -624,7 +832,7 @@ var ViewSyncerService = class {
624
832
  if (cmpVersions(cvr.version, this.#cvr.version) < 0) {
625
833
  const newCVR = this.#cvr;
626
834
  await startAsyncSpan(tracer, "vs.#updateCVRConfig.pokeClients", async () => {
627
- const pokers = startPoke(this.#getClients(cvr.version), newCVR.version);
835
+ const pokers = startPoke(lc, this.#getClients(cvr.version), newCVR.version);
628
836
  for (const patch of patches) await pokers.addPatch(patch);
629
837
  await pokers.end(newCVR.version);
630
838
  });
@@ -726,6 +934,7 @@ var ViewSyncerService = class {
726
934
  #scheduleExpireEviction(lc, cvr) {
727
935
  const { ttlClock } = cvr;
728
936
  this.#stopExpireTimer();
937
+ if (this.#shuttingDown) return;
729
938
  const next = nextEvictionTime(cvr);
730
939
  if (next === void 0) {
731
940
  lc.debug?.("no inactive queries with ttl");
@@ -753,7 +962,7 @@ var ViewSyncerService = class {
753
962
  *
754
963
  * This must be called from within the #lock.
755
964
  */
756
- async #hydrateUnchangedQueries(lc, cvr, connCtx, hydrationPassStats, hydrationBudget) {
965
+ async #hydrateUnchangedQueries(lc, cvr, connCtx, hydrationPassStats, hydrationBudget, previousQueries) {
757
966
  assert(this.#pipelines.initialized(), "pipelines must be initialized");
758
967
  const dbVersion = this.#pipelines.currentVersion();
759
968
  const cvrVersion = cvr.version;
@@ -766,9 +975,16 @@ var ViewSyncerService = class {
766
975
  const customQueries = /* @__PURE__ */ new Map();
767
976
  const otherQueries = [];
768
977
  const inactivatedCount = gotQueries.length - requiredGotQueries.length;
769
- for (const query of requiredGotQueries) if (query.type === "custom") customQueries.set(query.id, query);
770
- else otherQueries.push(query);
771
978
  const transformedQueries = [];
979
+ for (const query of requiredGotQueries) if (query.type === "custom") {
980
+ const previous = previousQueries?.get(query.id);
981
+ if (previous && previous.transformationHash === query.transformationHash) transformedQueries.push({
982
+ id: query.id,
983
+ transformationHash: previous.transformationHash,
984
+ transformedAst: previous.originalAst ?? previous.transformedAst
985
+ });
986
+ else customQueries.set(query.id, query);
987
+ } else otherQueries.push(query);
772
988
  let customErrorCount = 0;
773
989
  let customHashMismatchCount = 0;
774
990
  let otherHashMismatchCount = 0;
@@ -795,33 +1011,58 @@ var ViewSyncerService = class {
795
1011
  for (const { id: queryID, transformationHash, transformedAst } of transformedQueries) {
796
1012
  const query = cvr.queries[queryID];
797
1013
  const queryName = query.type === "custom" ? query.name : void 0;
1014
+ if (query.type !== "internal" && this.#hydrationCircuitBreaker.isOpen(transformationHash)) {
1015
+ lc.info?.(`skipping hydration of ${queryID}: hydration circuit breaker open`);
1016
+ continue;
1017
+ }
798
1018
  const covered = queryCoveringIndex ? this.#findQueryCoverageShadowHit(queryCoveringIndex, queryID, transformationHash, transformedAst, queryName) : void 0;
799
1019
  totalHydratedQueries++;
800
1020
  if (covered) {
801
1021
  coveredHydratedQueries++;
802
1022
  firstCoveredQuery ??= covered;
803
1023
  }
804
- const timer = new TimeSliceTimer(lc);
1024
+ const timer = this.#timer(lc, "hydration");
805
1025
  let count = 0;
1026
+ let timedOut = false;
806
1027
  await startAsyncSpan(tracer, "vs.#hydrateUnchangedQueries.addQuery", async (span) => {
807
1028
  span.setAttribute("queryHash", queryID);
808
1029
  span.setAttribute("transformationHash", transformationHash);
809
1030
  span.setAttribute("table", transformedAst.table);
810
1031
  if (queryName !== void 0) span.setAttribute("queryName", queryName);
811
- for (const change of this.#pipelines.addQuery(transformationHash, queryID, transformedAst, await timer.start(), queryName, "unchanged-query-rehydrate")) if (change === "yield") await timer.yieldProcess("yield in hydrateUnchangedQueries");
812
- else count++;
1032
+ for (const change of this.#pipelines.addQuery(transformationHash, queryID, transformedAst, await timer.start(), queryName, "unchanged-query-rehydrate")) if (change === "yield") {
1033
+ if (query.type !== "internal" && this.#hydrationCircuitBreaker.exceeded(timer.totalElapsed())) {
1034
+ timedOut = true;
1035
+ await timer.yieldProcess("yield in hydrateUnchangedQueries");
1036
+ break;
1037
+ }
1038
+ await timer.yieldProcess("yield in hydrateUnchangedQueries");
1039
+ } else count++;
813
1040
  });
814
1041
  const elapsed = timer.totalElapsed();
1042
+ if (timedOut) {
1043
+ this.#recordHydrationTimeout(lc, {
1044
+ id: queryID,
1045
+ ast: transformedAst,
1046
+ transformationHash,
1047
+ name: queryName
1048
+ }, elapsed, count);
1049
+ continue;
1050
+ }
815
1051
  hydrationPassStats.activeHydratedQueries++;
816
1052
  this.#hydrations.add(1);
817
1053
  this.#hydrationTime.recordMs(elapsed);
818
- this.#addQueryMaterializationServerMetric(transformationHash, elapsed);
819
- this.#inspectorDelegate.addQuery(transformationHash, transformedAst);
1054
+ this.#addQueryMaterializationServerMetric(queryID, elapsed);
1055
+ this.#inspectorDelegate.addQuery(queryID, transformedAst);
820
1056
  lc.debug?.(`hydrated ${count} rows for ${queryID} (${elapsed} ms)`);
1057
+ if (elapsed > this.#slowHydrateThreshold) this.#logSlowHydration(lc, {
1058
+ id: queryID,
1059
+ ast: transformedAst,
1060
+ transformationHash,
1061
+ name: queryName
1062
+ }, elapsed);
821
1063
  let drifted = false;
822
- const storedSigHex = cvr.queries[queryID]?.rowSetSignature;
823
- if (storedSigHex !== void 0 && storedSigHex !== null) {
824
- const priorSig = parseSignature(storedSigHex);
1064
+ const priorSig = this.#cvrStore.rowSetSignature(queryID);
1065
+ if (priorSig !== void 0) {
825
1066
  const candidateSig = this.#pipelines.rowSetSignature(queryID) ?? 0n;
826
1067
  if (priorSig !== candidateSig) {
827
1068
  lc.warn?.(`rowSetSignature drift for query ${queryID}: prior=${priorSig.toString(16)} new=${candidateSig.toString(16)} (${count} rows). Removing from pipelines for full re-execution.`);
@@ -877,11 +1118,7 @@ var ViewSyncerService = class {
877
1118
  return;
878
1119
  }
879
1120
  const appErrorGroups = /* @__PURE__ */ new Map();
880
- for (const err of errorOrErrors) for (const clientId of getAffectedClientIDs([err.id])) {
881
- const group = appErrorGroups.get(clientId) ?? [];
882
- group.push(err);
883
- appErrorGroups.set(clientId, group);
884
- }
1121
+ for (const err of errorOrErrors) for (const clientId of getAffectedClientIDs([err.id])) getOrInsertComputed(appErrorGroups, clientId, newArray).push(err);
885
1122
  for (const [clientId, errors] of appErrorGroups) this.#clients.get(clientId)?.sendQueryTransformApplicationErrors(errors);
886
1123
  }
887
1124
  #addQueryMaterializationServerMetric(queryID, elapsed) {
@@ -920,7 +1157,7 @@ var ViewSyncerService = class {
920
1157
  #syncQueryPipelineSet(lc, cvr, customQueryTransformMode, connCtx, driftedQueryIDs = /* @__PURE__ */ new Set(), hydrationBudget = new HydrationBudget(this.#config.viewSyncerHydrationBudgetMs ?? 0, this.#now), hydrationPassStats = {
921
1158
  activeHydratedQueries: 0,
922
1159
  inactiveHydratedQueries: 0
923
- }) {
1160
+ }, previousQueries) {
924
1161
  return startAsyncSpan(tracer, "vs.#syncQueryPipelineSet", async (span) => {
925
1162
  const start = performance.now();
926
1163
  span.setAttribute("clientGroupID", this.id);
@@ -951,7 +1188,13 @@ var ViewSyncerService = class {
951
1188
  });
952
1189
  }
953
1190
  };
954
- const shouldTransformCustomQuery = (query) => customQueryTransformMode === "all" || customQueryTransformMode && !this.#pipelines.queries().has(query.id);
1191
+ const shouldTransformCustomQuery = (query) => {
1192
+ if (customQueryTransformMode === "all") return true;
1193
+ if (this.#pipelines.queries().has(query.id)) return false;
1194
+ const previous = previousQueries?.get(query.id);
1195
+ if (previous && previous.transformationHash === query.transformationHash) return false;
1196
+ return true;
1197
+ };
955
1198
  const transformCustomQueries = async (queries) => {
956
1199
  if (!customQueryTransformer || queries.length === 0) return;
957
1200
  transformedCustomQueryCount += queries.length;
@@ -999,8 +1242,35 @@ var ViewSyncerService = class {
999
1242
  };
1000
1243
  const queriesToTransform = [...required, ...optionalToHydrate];
1001
1244
  transformOtherQueries(queriesToTransform);
1245
+ if (customQueryTransformMode === "missing" && previousQueries) {
1246
+ for (const query of queriesToTransform) if (query.type === "custom" && !this.#pipelines.queries().has(query.id)) {
1247
+ const previous = previousQueries.get(query.id);
1248
+ if (previous && previous.transformationHash === query.transformationHash) {
1249
+ this.#queryTransformationNoOps.add(1);
1250
+ transformedQueries.push({
1251
+ id: query.id,
1252
+ origQuery: query,
1253
+ transformed: {
1254
+ id: query.id,
1255
+ transformationHash: previous.transformationHash,
1256
+ transformedAst: previous.originalAst ?? previous.transformedAst
1257
+ }
1258
+ });
1259
+ }
1260
+ }
1261
+ }
1002
1262
  await transformCustomQueries(queriesToTransform.filter((query) => query.type === "custom" && shouldTransformCustomQuery(query)));
1003
- const removeQueriesQueryIds = new Set([...naturallyExpiredQueryIDs, ...erroredQueryIDs]);
1263
+ const circuitBrokenQueries = transformedQueries.filter(({ id, origQuery, transformed }) => origQuery.type !== "internal" && this.#pipelines.queries().get(id)?.transformationHash !== transformed.transformationHash && this.#hydrationCircuitBreaker.isOpen(transformed.transformationHash)).map(({ id, origQuery, transformed }) => ({
1264
+ id,
1265
+ transformationHash: transformed.transformationHash,
1266
+ name: origQuery.type === "custom" ? origQuery.name : void 0
1267
+ }));
1268
+ if (circuitBrokenQueries.length > 0) this.#rejectCircuitBrokenQueries(lc, cvr, circuitBrokenQueries);
1269
+ const removeQueriesQueryIds = new Set([
1270
+ ...naturallyExpiredQueryIDs,
1271
+ ...erroredQueryIDs,
1272
+ ...circuitBrokenQueries.map(({ id }) => id)
1273
+ ]);
1004
1274
  const addQueries = transformedQueries.map(({ id, origQuery, transformed }) => ({
1005
1275
  id,
1006
1276
  ast: transformed.transformedAst,
@@ -1011,7 +1281,7 @@ var ViewSyncerService = class {
1011
1281
  addQueries.sort((a, b) => must(hydrationOrder.get(a.id)) - must(hydrationOrder.get(b.id)));
1012
1282
  const requiredAddQueries = addQueries.filter((query) => requiredQueryIDs.has(query.id));
1013
1283
  const optionalAddQueries = addQueries.filter((query) => !requiredQueryIDs.has(query.id));
1014
- lc.info?.(`syncQueryPipelineSet: ${cvrQueryEntires.length} CVR queries, ${transformedCustomQueryCount} custom re-transformed, ${erroredQueryIDs.length} errored, ${removeQueriesQueryIds.size} to remove, ${addQueries.length} to add`);
1284
+ lc.info?.(`syncQueryPipelineSet: ${cvrQueryEntires.length} CVR queries, ${transformedCustomQueryCount} custom re-transformed, ${erroredQueryIDs.length} errored, ${circuitBrokenQueries.length} circuit-broken, ${removeQueriesQueryIds.size} to remove, ${addQueries.length} to add`);
1015
1285
  for (const q of addQueries) {
1016
1286
  const orig = cvr.queries[q.id];
1017
1287
  lc.debug?.("ViewSyncer adding query", q.ast, "transformed from", orig.type === "custom" ? orig.name : orig.ast);
@@ -1050,6 +1320,107 @@ var ViewSyncerService = class {
1050
1320
  record.count++;
1051
1321
  if (record.count >= THRASH_THRESHOLD) this.#lc.warn?.(`Query thrashing detected for query ${queryID}. ${record.count} replacements in 60s. This may indicate clients with different auth contexts connecting to the same client group.`);
1052
1322
  }
1323
+ /**
1324
+ * Records that hydrating `query` was aborted for exceeding the query
1325
+ * hydration timeout, and opens its circuit breaker.
1326
+ */
1327
+ #recordHydrationTimeout(lc, query, elapsedMs, rowCount) {
1328
+ this.#hydrationCircuitBreaker.trip(query.transformationHash);
1329
+ this.#hydrationTimeouts.add(1);
1330
+ if (!lc.warn) return;
1331
+ const shape = queryShape(query.ast);
1332
+ lc.warn("Query hydration aborted for exceeding the hydration timeout", {
1333
+ clientGroupID: this.id,
1334
+ queryHash: query.id,
1335
+ transformationHash: query.transformationHash,
1336
+ ...query.name !== void 0 && { queryName: query.name },
1337
+ queryShape: shape.hash,
1338
+ hydrationTimeoutMs: this.#hydrationCircuitBreaker.timeoutMs,
1339
+ hydrationElapsedMs: elapsedMs,
1340
+ ...rowCount !== void 0 && { hydrationRowCount: rowCount },
1341
+ circuitBreakerOpenMs: this.#hydrationCircuitBreaker.openMs,
1342
+ zql: shape.zql
1343
+ });
1344
+ }
1345
+ /**
1346
+ * Logs a hydration that exceeded the slow hydration threshold.
1347
+ *
1348
+ * The query is logged as its {@link queryShape}, with literal values
1349
+ * redacted, and each shape is logged at most once per
1350
+ * {@link SLOW_HYDRATION_LOG_WINDOW_MS}. The next log of a shape reports how
1351
+ * many slow hydrations of it were suppressed in the meantime.
1352
+ */
1353
+ #logSlowHydration(lc, query, elapsedMs) {
1354
+ if (!lc.warn) return;
1355
+ const stats = this.#pipelines.hydrationStats(query.id);
1356
+ const shape = stats?.shape ?? queryShape(query.ast);
1357
+ const suppressed = slowHydrationLogThrottle.admit(`${query.name ?? ""}:${shape.hash}`);
1358
+ if (suppressed === void 0) return;
1359
+ lc.warn("Slow query materialization", {
1360
+ zeroEvent: "query-slow-hydration",
1361
+ clientGroupID: this.id,
1362
+ queryHash: query.id,
1363
+ transformationHash: query.transformationHash,
1364
+ ...query.name !== void 0 && { queryName: query.name },
1365
+ queryShape: shape.hash,
1366
+ hydrationTimeMs: elapsedMs,
1367
+ ...stats && {
1368
+ hydrationRowCount: stats.rowCount,
1369
+ hydrationRowsRead: stats.rowsRead
1370
+ },
1371
+ ...stats !== void 0 && stats.planWarnings.length > 0 && { planWarnings: stats.planWarnings.map(planWarningMessage) },
1372
+ ...suppressed > 0 && { suppressedSinceLastLog: suppressed },
1373
+ zql: shape.zql
1374
+ });
1375
+ }
1376
+ /** Records that `query` was rejected without hydration by its open breaker. */
1377
+ #recordCircuitBreakerRejection(lc, query) {
1378
+ this.#hydrationCircuitBreakerRejections.add(1);
1379
+ lc.warn?.("Query rejected by its open hydration circuit breaker", {
1380
+ clientGroupID: this.id,
1381
+ queryHash: query.id,
1382
+ transformationHash: query.transformationHash,
1383
+ ...query.name !== void 0 && { queryName: query.name },
1384
+ hydrationTimeoutMs: this.#hydrationCircuitBreaker.timeoutMs,
1385
+ circuitBreakerOpenMs: this.#hydrationCircuitBreaker.openMs
1386
+ });
1387
+ }
1388
+ /**
1389
+ * Handles queries whose hydration circuit breaker is open: they are counted,
1390
+ * logged, and errored to the affected clients. The caller removes them from
1391
+ * the CVR.
1392
+ */
1393
+ #rejectCircuitBrokenQueries(lc, cvr, queries) {
1394
+ for (const query of queries) this.#recordCircuitBreakerRejection(lc, query);
1395
+ this.#queryEvictions.add(queries.length, { reason: "hydration-circuit-breaker" });
1396
+ this.#sendHydrationTimeoutErrors(cvr, queries);
1397
+ }
1398
+ /**
1399
+ * Sends a per-query error to every client that desires one of `queries`.
1400
+ * The error goes out as a `transformError` application error, which every
1401
+ * client understands as "this query errored" without affecting the
1402
+ * connection or the client's other queries.
1403
+ */
1404
+ #sendHydrationTimeoutErrors(cvr, queries) {
1405
+ const timeoutMs = this.#hydrationCircuitBreaker.timeoutMs;
1406
+ const errorsByClient = /* @__PURE__ */ new Map();
1407
+ for (const { id, name } of queries) {
1408
+ const query = cvr.queries[id];
1409
+ if (query === void 0 || query.type === "internal") continue;
1410
+ const error = {
1411
+ error: "app",
1412
+ id,
1413
+ name: name ?? (query.type === "custom" ? query.name : "legacy"),
1414
+ message: `Query hydration exceeded the ${timeoutMs}ms limit (ZERO_VIEW_SYNCER_QUERY_HYDRATION_TIMEOUT_MS) and was aborted`,
1415
+ details: {
1416
+ kind: "HydrationTimeout",
1417
+ timeoutMs
1418
+ }
1419
+ };
1420
+ for (const clientID of Object.keys(query.clientState)) getOrInsertComputed(errorsByClient, clientID, newArray).push(error);
1421
+ }
1422
+ for (const [clientID, errors] of errorsByClient) this.#clients.get(clientID)?.sendQueryTransformApplicationErrors(errors);
1423
+ }
1053
1424
  #recordHydrationBudgetExhaustion(lc, hydrationBudget, activeHydratedQueries, inactiveHydratedQueries, inactiveEvictedQueryIDs) {
1054
1425
  const elapsedMs = hydrationBudget.exhaustedAtMs;
1055
1426
  if (elapsedMs === void 0) return;
@@ -1076,7 +1447,7 @@ var ViewSyncerService = class {
1076
1447
  const stateVersion = this.#pipelines.currentVersion();
1077
1448
  lc = lc.withContext("stateVersion", stateVersion);
1078
1449
  lc.info?.(`hydrating ${addQueries.length} queries`);
1079
- const updater = new CVRQueryDrivenUpdater(this.#cvrStore, cvr, stateVersion, this.#pipelines.replicaVersion, (queryID) => this.#pipelines.rowSetSignature(queryID));
1450
+ const updater = new CVRQueryDrivenUpdater(this.#cvrStore, cvr, stateVersion, this.#pipelines.replicaVersion, this.#pipelines);
1080
1451
  const sameHashRehydratedQueryIDs = addQueries.filter((q) => cvr.queries[q.id]?.transformationHash === q.transformationHash).map((q) => q.id);
1081
1452
  const trackQueriesWillBumpVersion = stateVersion > cvr.version.stateVersion || removeQueries.length > 0 || addQueries.some((q) => cvr.queries[q.id]?.transformationHash !== q.transformationHash);
1082
1453
  if (sameHashRehydratedQueryIDs.length > 0 && !trackQueriesWillBumpVersion) {
@@ -1088,7 +1459,8 @@ var ViewSyncerService = class {
1088
1459
  }
1089
1460
  const { queryPatches, newVersion } = updater.trackQueries(lc, addQueries, removeQueries);
1090
1461
  if (hydrationBudget.limitMs !== 0 && optionalQueries.length > 0) assert(cmpVersions(cvr.version, newVersion) < 0, "Optional hydration requires a final poke version before row processing so a removal is actually poked");
1091
- const pokers = startPoke(this.#getClients(), newVersion);
1462
+ const clients = this.#getClients();
1463
+ const pokers = startPoke(lc, clients, newVersion);
1092
1464
  for (const patch of queryPatches) await pokers.addPatch(patch);
1093
1465
  for (const q of removeQueries) {
1094
1466
  this.#pipelines.removeQuery(q.id);
@@ -1096,7 +1468,7 @@ var ViewSyncerService = class {
1096
1468
  this.#queryReplacements.delete(q.id);
1097
1469
  }
1098
1470
  let totalProcessTime = 0;
1099
- const timer = new TimeSliceTimer(lc);
1471
+ const timer = this.#timer(lc, "hydration");
1100
1472
  const pipelines = this.#pipelines;
1101
1473
  const hydrations = this.#hydrations;
1102
1474
  const hydrationTime = this.#hydrationTime;
@@ -1106,8 +1478,11 @@ var ViewSyncerService = class {
1106
1478
  let firstCoveredQuery;
1107
1479
  const hydratedQueryIDs = [];
1108
1480
  const budgetEvictedQueryIDs = [];
1481
+ const timedOutQueries = [];
1482
+ const rejectedQueries = [];
1483
+ const circuitBreaker = this.#hydrationCircuitBreaker;
1109
1484
  const self = this;
1110
- await yieldProcess(lc);
1485
+ await (this.#pacer ? this.#pacer.yieldSlice("hydration") : yieldProcess(lc));
1111
1486
  function* hydrateQueries(queries, optional, slowHydrateThreshold) {
1112
1487
  for (let i = 0; i < queries.length; i++) {
1113
1488
  if (optional && hydrationBudget.exhausted()) {
@@ -1118,15 +1493,34 @@ var ViewSyncerService = class {
1118
1493
  let queryLC = lc.withContext("hash", q.id).withContext("queryHash", q.id).withContext("transformationHash", q.transformationHash);
1119
1494
  if (q.name !== void 0) queryLC = queryLC.withContext("queryName", q.name);
1120
1495
  queryLC.debug?.(`adding pipeline for query`, q.ast);
1496
+ const breakable = cvr.queries[q.id]?.type !== "internal";
1497
+ if (breakable && circuitBreaker.isOpen(q.transformationHash)) {
1498
+ rejectedQueries.push(q);
1499
+ self.#recordCircuitBreakerRejection(queryLC, q);
1500
+ continue;
1501
+ }
1121
1502
  const covered = queryCoveringIndex ? self.#findQueryCoverageShadowHit(queryCoveringIndex, q.id, q.transformationHash, q.ast, q.name) : void 0;
1122
1503
  totalHydratedQueries++;
1123
1504
  if (covered) {
1124
1505
  coveredHydratedQueries++;
1125
1506
  firstCoveredQuery ??= covered;
1126
1507
  }
1127
- yield* pipelines.addQuery(q.transformationHash, q.id, q.ast, timer.startWithoutYielding(), q.name, "query-set-sync");
1508
+ let timedOut = false;
1509
+ for (const change of pipelines.addQuery(q.transformationHash, q.id, q.ast, timer.startWithoutYielding(), q.name, "query-set-sync")) {
1510
+ if (change === "yield" && breakable && circuitBreaker.exceeded(timer.totalElapsed())) {
1511
+ timedOut = true;
1512
+ yield change;
1513
+ break;
1514
+ }
1515
+ yield change;
1516
+ }
1128
1517
  const elapsed = timer.stop();
1129
1518
  totalProcessTime += elapsed;
1519
+ if (timedOut) {
1520
+ timedOutQueries.push(q);
1521
+ self.#recordHydrationTimeout(queryLC, q, elapsed);
1522
+ continue;
1523
+ }
1130
1524
  hydratedQueryIDs.push(q.id);
1131
1525
  if (optional) hydrationPassStats.inactiveHydratedQueries++;
1132
1526
  else hydrationPassStats.activeHydratedQueries++;
@@ -1137,7 +1531,7 @@ var ViewSyncerService = class {
1137
1531
  transformationHash: q.transformationHash,
1138
1532
  ...q.name !== void 0 && { queryName: q.name }
1139
1533
  });
1140
- if (elapsed > slowHydrateThreshold) queryLC.warn?.("Slow query materialization", elapsed, q.ast);
1534
+ if (elapsed > slowHydrateThreshold) self.#logSlowHydration(queryLC, q, elapsed);
1141
1535
  manualSpan(tracer, "vs.addAndConsumeQuery", elapsed, {
1142
1536
  hash: q.id,
1143
1537
  transformationHash: q.transformationHash,
@@ -1151,7 +1545,20 @@ var ViewSyncerService = class {
1151
1545
  yield* hydrateQueries(requiredQueries, false, slowHydrateThreshold);
1152
1546
  yield* hydrateQueries(optionalQueries, true, slowHydrateThreshold);
1153
1547
  }
1154
- await this.#processChanges(lc, timer, generateRowChanges(this.#slowHydrateThreshold), updater, pokers);
1548
+ await this.#processChanges(lc, timer, generateRowChanges(this.#slowHydrateThreshold), (rows) => updater.received(lc, rows), pokers);
1549
+ const abortedQueries = [...timedOutQueries, ...rejectedQueries];
1550
+ if (abortedQueries.length > 0) {
1551
+ const abortedQueryIDs = abortedQueries.map(({ id }) => id);
1552
+ for (const patch of await updater.abortExecutedQueries(lc, abortedQueryIDs)) await pokers.addPatch(patch);
1553
+ for (const queryID of abortedQueryIDs) {
1554
+ this.#pipelines.removeQuery(queryID);
1555
+ this.#inspectorDelegate.removeQuery(queryID);
1556
+ this.#queryReplacements.delete(queryID);
1557
+ }
1558
+ if (timedOutQueries.length > 0) this.#queryEvictions.add(timedOutQueries.length, { reason: "hydration-timeout" });
1559
+ if (rejectedQueries.length > 0) this.#queryEvictions.add(rejectedQueries.length, { reason: "hydration-circuit-breaker" });
1560
+ this.#sendHydrationTimeoutErrors(cvr, abortedQueries);
1561
+ }
1155
1562
  for (const patch of updater.removeTrackedQueries(budgetEvictedQueryIDs)) await pokers.addPatch(patch);
1156
1563
  for (const queryID of budgetEvictedQueryIDs) {
1157
1564
  this.#pipelines.removeQuery(queryID);
@@ -1163,7 +1570,7 @@ var ViewSyncerService = class {
1163
1570
  await startAsyncSpan(tracer, "vs.#syncQueryPipelineSet.deleteUnreferencedRows", async () => {
1164
1571
  for (const patch of await updater.deleteUnreferencedRows(lc)) await pokers.addPatch(patch);
1165
1572
  });
1166
- this.#cvr = await this.#flushUpdater(lc, updater);
1573
+ this.#cvr = await this.#flushPoked(lc, updater, pokers);
1167
1574
  if (budgetEvictedQueryIDs.length > 0) this.#scheduleExpireEviction(lc, this.#cvr);
1168
1575
  const finalVersion = this.#cvr.version;
1169
1576
  await this.#catchupClients(lc, cvr, finalVersion, hydratedQueryIDs, pokers);
@@ -1195,7 +1602,7 @@ var ViewSyncerService = class {
1195
1602
  return startAsyncSpan(tracer, "vs.#catchupClients", async (span) => {
1196
1603
  current ??= cvr.version;
1197
1604
  const clients = this.#getClients();
1198
- const pokers = usePokers ?? startPoke(clients, cvr.version);
1605
+ const pokers = usePokers ?? startPoke(lc, clients, cvr.version);
1199
1606
  span.setAttribute("numClients", clients.length);
1200
1607
  const catchupFrom = clients.map((c) => c.version()).reduce((a, b) => cmpVersions(a, b) < 0 ? a : b, cvr.version);
1201
1608
  const rowPatches = this.#cvrStore.catchupRowPatches(lc, catchupFrom, cvr, current, excludeQueryHashes);
@@ -1242,7 +1649,7 @@ var ViewSyncerService = class {
1242
1649
  }
1243
1650
  });
1244
1651
  }
1245
- #processChanges(lc, timer, changes, updater, pokers) {
1652
+ #processChanges(lc, timer, changes, onBatch, pokers) {
1246
1653
  return startAsyncSpan(tracer, "vs.#processChanges", async () => {
1247
1654
  const start = performance.now();
1248
1655
  const rows = new CustomKeyMap(rowIDString);
@@ -1251,7 +1658,7 @@ var ViewSyncerService = class {
1251
1658
  const wallElapsed = performance.now() - start;
1252
1659
  total += rows.size;
1253
1660
  lc.debug?.(`processing ${rows.size} (of ${total}) rows (${wallElapsed} ms)`);
1254
- const patches = await updater.received(lc, rows);
1661
+ const patches = await onBatch(rows);
1255
1662
  await startAsyncSpan(tracer, "processBatch.flushToClient", async (span) => {
1256
1663
  span.setAttribute("patches", patches.length);
1257
1664
  for (const patch of patches) await pokers.addPatch(patch);
@@ -1316,32 +1723,304 @@ var ViewSyncerService = class {
1316
1723
  span.setAttribute("clientGroupID", this.id);
1317
1724
  assert(this.#pipelines.initialized(), "pipelines must be initialized (advancePipelines");
1318
1725
  const start = performance.now();
1319
- const timer = new TimeSliceTimer(lc);
1320
- const { version, numChanges, changes } = this.#pipelines.advance(timer);
1321
- lc = lc.withContext("newVersion", version);
1322
- const updater = new CVRQueryDrivenUpdater(this.#cvrStore, cvr, version, this.#pipelines.replicaVersion, (queryID) => this.#pipelines.rowSetSignature(queryID));
1323
- const pokers = startPoke(this.#getClients(cvr.version), updater.updatedVersion());
1324
- lc.debug?.(`applying ${numChanges} to advance to ${version}`);
1726
+ const timer = this.#timer(lc, "batch");
1727
+ let outcome = { outcome: "error" };
1728
+ let setupTimeMs;
1729
+ let rebuildTimeMs = 0;
1730
+ let evictedQueries = false;
1731
+ this.#pipelineTime.ms = 0;
1325
1732
  try {
1326
- await this.#processChanges(lc, await timer.start(), changes, updater, pokers);
1327
- } catch (e) {
1328
- if (e instanceof ResetPipelinesSignal) {
1329
- await pokers.cancel();
1330
- return e;
1733
+ let pokers;
1734
+ let updater;
1735
+ let version;
1736
+ let numChanges = 0;
1737
+ try {
1738
+ const advancement = this.#pipelines.advance(timer, this.#costBasedAdvance(cvr));
1739
+ version = advancement.version;
1740
+ numChanges = advancement.numChanges;
1741
+ lc = lc.withContext("newVersion", version);
1742
+ const targetVersion = cmpVersions(cvr.version, { stateVersion: version }) < 0 ? { stateVersion: version } : cvr.version;
1743
+ pokers = startPoke(lc, this.#getClients(cvr.version), targetVersion);
1744
+ lc.debug?.(`applying ${numChanges} to advance to ${version}`);
1745
+ setupTimeMs = performance.now() - start;
1746
+ await this.#processChanges(lc, await timer.start(), this.#timed(advancement.changes), (rows) => {
1747
+ updater ??= new CVRQueryDrivenUpdater(this.#cvrStore, cvr, version, this.#pipelines.replicaVersion, this.#pipelines);
1748
+ return updater.received(lc, rows);
1749
+ }, pokers);
1750
+ for (const { estimatedPushMs, pushTimeMs } of advancement.estimates()) if (pushTimeMs > 0) this.#pushEstimateRatio.record(estimatedPushMs / pushTimeMs);
1751
+ const abandoned = advancement.abandoned();
1752
+ if (abandoned.length > 0) {
1753
+ updater ??= new CVRQueryDrivenUpdater(this.#cvrStore, cvr, version, this.#pipelines.replicaVersion, this.#pipelines);
1754
+ timer.stop();
1755
+ ({rebuildTimeMs, evictedQueries} = await this.#rebuildAbandonedQueries(lc, cvr, abandoned, updater, pokers));
1756
+ }
1757
+ } catch (e) {
1758
+ setupTimeMs ??= performance.now() - start;
1759
+ if (e instanceof ResetPipelinesSignal) {
1760
+ await pokers?.cancel();
1761
+ this.#cvrStore.discardPending();
1762
+ outcome = {
1763
+ outcome: "reset",
1764
+ reason: e.reason
1765
+ };
1766
+ return e;
1767
+ }
1768
+ throw e;
1331
1769
  }
1332
- throw e;
1770
+ assert(pokers && version !== void 0, "advancement state missing");
1771
+ if (updater) {
1772
+ this.#cvr = await this.#flushPoked(lc, updater, pokers);
1773
+ if (evictedQueries) this.#scheduleExpireEviction(lc, this.#cvr);
1774
+ }
1775
+ const finalVersion = (this.#cvr ?? cvr).version;
1776
+ await startAsyncSpan(tracer, "vs.#advancePipelines.pokeEnd", () => pokers.end(finalVersion));
1777
+ this.#markVersionServed(version);
1778
+ const wallTime = performance.now() - start;
1779
+ const totalProcessTime = timer.totalElapsed() + rebuildTimeMs;
1780
+ lc.debug?.(`finished processing advancement of ${numChanges} changes ((process: ${totalProcessTime} ms, wall: ${wallTime} ms))`);
1781
+ this.#transactionAdvanceTime.recordMs(totalProcessTime);
1782
+ outcome = { outcome: "success" };
1783
+ return "success";
1784
+ } finally {
1785
+ const setupMs = must(setupTimeMs);
1786
+ const processingTimeMs = setupMs + timer.totalElapsed() + rebuildTimeMs;
1787
+ this.#batchTimeMs = setupMs + this.#pipelineTime.ms;
1788
+ const wallTimeMs = performance.now() - start;
1789
+ this.#advancementMetrics.record({
1790
+ processingTimeMs,
1791
+ setupTimeMs: setupMs,
1792
+ wallTimeMs
1793
+ }, outcome);
1333
1794
  }
1334
- this.#cvr = await this.#flushUpdater(lc, updater);
1335
- const finalVersion = this.#cvr.version;
1336
- await startAsyncSpan(tracer, "vs.#advancePipelines.pokeEnd", () => pokers.end(finalVersion));
1337
- this.#markVersionServed(version);
1338
- const wallTime = performance.now() - start;
1339
- const totalProcessTime = timer.totalElapsed();
1340
- lc.debug?.(`finished processing advancement of ${numChanges} changes ((process: ${totalProcessTime} ms, wall: ${wallTime} ms))`);
1341
- this.#transactionAdvanceTime.recordMs(totalProcessTime);
1342
- return "success";
1343
1795
  });
1344
1796
  }
1797
+ /**
1798
+ * What a cost-based advancement needs, or `undefined` if advancements are
1799
+ * bounded by the advancement time limit.
1800
+ */
1801
+ #costBasedAdvance(cvr) {
1802
+ const shouldCutOff = this.#pushCutoff;
1803
+ if (shouldCutOff === void 0) return;
1804
+ if (this.#pipelines.currentVersion() < cvr.version.stateVersion) return;
1805
+ return {
1806
+ shouldCutOff,
1807
+ rebuildMargin: this.#config.syncRebuildMargin ?? 2
1808
+ };
1809
+ }
1810
+ /**
1811
+ * Hydrates the queries whose pipelines an advancement abandoned, at the
1812
+ * snapshot it advanced to, within the advancement's CVR update and poke.
1813
+ * What the queries contributed to the update before they were abandoned
1814
+ * is retracted first.
1815
+ *
1816
+ * The hydrations are protected as they are in a hydration pass (see
1817
+ * {@link #addAndRemoveQueries}). A query that exceeds the query hydration
1818
+ * timeout, or whose circuit breaker is open, is removed and errored to its
1819
+ * clients. Inactive queries are hydrated last, and those not reached
1820
+ * before the hydration budget is spent are evicted.
1821
+ *
1822
+ * @returns the time spent hydrating, and whether inactive queries were
1823
+ * evicted.
1824
+ */
1825
+ async #rebuildAbandonedQueries(lc, cvr, abandoned, updater, pokers) {
1826
+ for (const patch of await updater.retractQueries(lc, abandoned.map((q) => q.queryID))) await pokers.addPatch(patch);
1827
+ const hydrationBudget = new HydrationBudget(this.#config.viewSyncerHydrationBudgetMs ?? 0, this.#now);
1828
+ const abandonedByID = new Map(abandoned.map((q) => [q.queryID, q]));
1829
+ const { required, optional } = classifyQueriesForHydration(abandoned.map((q) => must(cvr.queries[q.queryID])));
1830
+ const byRecord = (queries) => queries.map(({ id }) => must(abandonedByID.get(id)));
1831
+ const timer = this.#timer(lc, "batch");
1832
+ const pipelines = this.#pipelines;
1833
+ const circuitBreaker = this.#hydrationCircuitBreaker;
1834
+ const budgetEvicted = [];
1835
+ const timedOut = [];
1836
+ const rejected = [];
1837
+ const rebuilt = {
1838
+ active: 0,
1839
+ inactive: 0
1840
+ };
1841
+ const self = this;
1842
+ let total = 0;
1843
+ function* rebuild(queries, inactive) {
1844
+ for (let i = 0; i < queries.length; i++) {
1845
+ if (inactive && hydrationBudget.exhausted()) {
1846
+ budgetEvicted.push(...queries.slice(i));
1847
+ return;
1848
+ }
1849
+ const q = must(queries[i]);
1850
+ const hydrationQuery = {
1851
+ id: q.queryID,
1852
+ ast: q.originalAst,
1853
+ transformationHash: q.transformationHash,
1854
+ name: q.queryName
1855
+ };
1856
+ const breakable = cvr.queries[q.queryID]?.type !== "internal";
1857
+ if (breakable && circuitBreaker.isOpen(q.transformationHash)) {
1858
+ rejected.push(q);
1859
+ self.#recordCircuitBreakerRejection(lc, hydrationQuery);
1860
+ continue;
1861
+ }
1862
+ let aborted = false;
1863
+ for (const change of pipelines.addQuery(q.transformationHash, q.queryID, q.originalAst, timer.startWithoutYielding(), q.queryName, "unchanged-query-rehydrate")) {
1864
+ if (change === "yield" && breakable && circuitBreaker.exceeded(timer.totalElapsed())) {
1865
+ aborted = true;
1866
+ yield change;
1867
+ break;
1868
+ }
1869
+ yield change;
1870
+ }
1871
+ const elapsed = timer.stop();
1872
+ total += elapsed;
1873
+ if (aborted) {
1874
+ timedOut.push(q);
1875
+ self.#recordHydrationTimeout(lc, hydrationQuery, elapsed);
1876
+ continue;
1877
+ }
1878
+ if (inactive) rebuilt.inactive++;
1879
+ else rebuilt.active++;
1880
+ self.#queryRebuilds.add(1, { reason: q.reason });
1881
+ self.#queryRebuildTime.recordMs(elapsed);
1882
+ self.#addQueryMaterializationServerMetric(q.queryID, elapsed);
1883
+ if (elapsed > self.#slowHydrateThreshold) self.#logSlowHydration(lc, hydrationQuery, elapsed);
1884
+ }
1885
+ }
1886
+ function* rebuildAll() {
1887
+ yield* rebuild(byRecord(required), false);
1888
+ yield* rebuild(byRecord(optional), true);
1889
+ }
1890
+ await this.#processChanges(lc, timer, this.#timed(rebuildAll()), (rows) => updater.received(lc, rows), pokers);
1891
+ const abortedQueries = [...timedOut, ...rejected];
1892
+ if (abortedQueries.length > 0) {
1893
+ for (const patch of await updater.abortExecutedQueries(lc, abortedQueries.map((q) => q.queryID))) await pokers.addPatch(patch);
1894
+ if (timedOut.length > 0) this.#queryEvictions.add(timedOut.length, { reason: "hydration-timeout" });
1895
+ if (rejected.length > 0) this.#queryEvictions.add(rejected.length, { reason: "hydration-circuit-breaker" });
1896
+ this.#sendHydrationTimeoutErrors(cvr, abortedQueries.map((q) => ({
1897
+ id: q.queryID,
1898
+ name: q.queryName
1899
+ })));
1900
+ }
1901
+ const evictedQueryIDs = budgetEvicted.map((q) => q.queryID);
1902
+ for (const patch of updater.removeTrackedQueries(evictedQueryIDs)) await pokers.addPatch(patch);
1903
+ for (const { queryID } of [...abortedQueries, ...budgetEvicted]) {
1904
+ this.#pipelines.removeQuery(queryID);
1905
+ this.#inspectorDelegate.removeQuery(queryID);
1906
+ this.#queryReplacements.delete(queryID);
1907
+ }
1908
+ this.#recordHydrationBudgetExhaustion(lc, hydrationBudget, rebuilt.active, rebuilt.inactive, evictedQueryIDs);
1909
+ for (const patch of await updater.deleteUnreferencedRows(lc)) await pokers.addPatch(patch);
1910
+ this.#logRebuilds(lc, abandoned, {
1911
+ hydrated: rebuilt.active + rebuilt.inactive,
1912
+ hydrationTimeMs: total,
1913
+ timedOut: timedOut.length,
1914
+ rejectedByCircuitBreaker: rejected.length,
1915
+ evictedForHydrationBudget: budgetEvicted.length
1916
+ });
1917
+ return {
1918
+ rebuildTimeMs: total,
1919
+ evictedQueries: evictedQueryIDs.length > 0
1920
+ };
1921
+ }
1922
+ /**
1923
+ * Says in the log that this client group's batches hydrate queries again,
1924
+ * which can be every batch. Nothing else is logged at `info` for a batch,
1925
+ * so this is at most once a minute, for the batches since the last time,
1926
+ * and not before their hydrations add up to a second. Which queries they
1927
+ * were is in the query stats, by query shape (see `QueryStats`).
1928
+ */
1929
+ #logRebuilds(lc, abandoned, batch) {
1930
+ const log = this.#rebuildLog;
1931
+ log.batches++;
1932
+ log.queries += abandoned.length;
1933
+ for (const { reason } of abandoned) log[reason]++;
1934
+ if (abandoned.some((q) => q.reason === "read")) log.batchesNotRead++;
1935
+ log.hydrated += batch.hydrated;
1936
+ log.hydrationTimeMs += batch.hydrationTimeMs;
1937
+ log.timedOut += batch.timedOut;
1938
+ log.rejectedByCircuitBreaker += batch.rejectedByCircuitBreaker;
1939
+ log.evictedForHydrationBudget += batch.evictedForHydrationBudget;
1940
+ const now = this.#now();
1941
+ if (log.hydrationTimeMs < REBUILD_LOG_MIN_MS || now - this.#rebuildsLoggedAt < REBUILD_LOG_INTERVAL_MS) return;
1942
+ lc.info?.("Client group hydrated queries again in its batches of changes instead of pushing the changes to them", {
1943
+ clientGroupID: this.id,
1944
+ ...log
1945
+ });
1946
+ this.#rebuildsLoggedAt = now;
1947
+ this.#rebuildLog = newRebuildLog();
1948
+ }
1949
+ /**
1950
+ * Adds the time that the pipelines take to produce `values` to the time
1951
+ * of the batch being processed (see {@link #batchTimeMs}).
1952
+ */
1953
+ #timed(values) {
1954
+ return this.#pacer ? timeIteration(values, this.#pipelineTime) : values;
1955
+ }
1956
+ /**
1957
+ * A timer for a batch, or for the hydration of new queries, which has
1958
+ * priority over batches for the worker's time slices (see
1959
+ * `BatchPacer.yieldSlice()`).
1960
+ */
1961
+ #timer(lc, kind) {
1962
+ const pacer = this.#pacer;
1963
+ return new TimeSliceTimer(lc, pacer && (() => pacer.yieldSlice(kind)));
1964
+ }
1965
+ /**
1966
+ * Waits as long as the worker's pacer says before the next batch, after
1967
+ * one that took `batchTimeMs`. The wait is outside of the
1968
+ * lock, so connections and query changes are served as usual, at the
1969
+ * pipelines' current snapshot. `version-ready` notifications received in
1970
+ * the meantime are coalesced by the subscription, so the next batch covers
1971
+ * all of them.
1972
+ */
1973
+ async #paceBatches(pacer, batchTimeMs) {
1974
+ this.#smoothedBatchTimeMs = this.#smoothedBatchTimeMs === void 0 ? batchTimeMs : this.#smoothedBatchTimeMs + BATCH_TIME_SMOOTHING * (batchTimeMs - this.#smoothedBatchTimeMs);
1975
+ const processingMs = this.#smoothedBatchTimeMs * (1 + BATCH_WAIT_JITTER * (Math.random() * 2 - 1));
1976
+ const start = performance.now();
1977
+ let waited = false;
1978
+ for (;;) {
1979
+ const remaining = pacer.waitMs(processingMs) - (performance.now() - start);
1980
+ if (remaining <= 0 || !this.#stateChanges.active) break;
1981
+ waited = true;
1982
+ await new Promise((resolve) => {
1983
+ const timer = setTimeout(resolve, Math.min(remaining, BATCH_WAIT_STEP_MS));
1984
+ this.#endBatchWait = () => {
1985
+ clearTimeout(timer);
1986
+ resolve();
1987
+ };
1988
+ });
1989
+ this.#endBatchWait = void 0;
1990
+ }
1991
+ if (waited) {
1992
+ const waitedMs = performance.now() - start;
1993
+ this.#batchWaitTime.recordMs(waitedMs);
1994
+ this.#logBatchWait(pacer, waitedMs);
1995
+ }
1996
+ }
1997
+ /**
1998
+ * Says in the log that this client group is being held back, which the
1999
+ * worker's metrics do not tell one client group from another by. A client
2000
+ * group that is held back is after every batch, so this is at most once
2001
+ * a minute, for the waits since the last time, and not for waits that add
2002
+ * up to less than a second.
2003
+ */
2004
+ #logBatchWait(pacer, waitedMs) {
2005
+ const log = this.#batchWaitLog;
2006
+ log.waits++;
2007
+ log.waitedMs += waitedMs;
2008
+ const now = this.#now();
2009
+ if (log.waitedMs < BATCH_WAIT_LOG_MIN_MS || now - log.loggedAt < BATCH_WAIT_LOG_INTERVAL_MS) return;
2010
+ this.#lc.info?.("Client group is waiting between batches: its sync worker is over its share target", {
2011
+ clientGroupID: this.id,
2012
+ waits: log.waits,
2013
+ waitedMs: log.waitedMs,
2014
+ lastWaitMs: waitedMs,
2015
+ batchTimeMs: this.#smoothedBatchTimeMs,
2016
+ waitMultiplier: pacer.multiplier
2017
+ });
2018
+ this.#batchWaitLog = {
2019
+ loggedAt: now,
2020
+ waits: 0,
2021
+ waitedMs: 0
2022
+ };
2023
+ }
1345
2024
  async inspect(selector, msg) {
1346
2025
  await this.#runInLockForClient(selector, msg, this.#handleInspect);
1347
2026
  }
@@ -1351,7 +2030,7 @@ var ViewSyncerService = class {
1351
2030
  clientID,
1352
2031
  wsID: client.wsID
1353
2032
  });
1354
- return handleInspect(lc, body, cvr, client, this.#inspectorDelegate, this.id, this.#cvrStore, this.#config, connCtx);
2033
+ return handleInspect(lc, body, cvr, client, this.#inspectorDelegate, this.id, this, this.#cvrStore, this.#config, connCtx);
1355
2034
  };
1356
2035
  async #runBackgroundRetransform(lc) {
1357
2036
  const attemptRetransform = async (connCtx) => {
@@ -1435,18 +2114,22 @@ var ViewSyncerService = class {
1435
2114
  this.connContextManager.setSharedRetransformReady(false);
1436
2115
  this.#initialized.reject(shutdownBeforeInitializationError());
1437
2116
  this.#stateChanges.cancel();
2117
+ this.#endBatchWait?.();
1438
2118
  return this.#stopped.promise;
1439
2119
  }
1440
2120
  async #cleanup(err) {
2121
+ this.#shuttingDown = true;
1441
2122
  this.connContextManager.setSharedRetransformReady(false);
1442
2123
  this.#stopTTLClockInterval();
1443
2124
  this.#stopExpireTimer();
1444
2125
  this.#stopAuthMaintenanceTimer();
2126
+ this.#stopShutdownTimer();
1445
2127
  this.#customQueryTransformer?.destroy();
1446
2128
  for (const client of this.#clients.values()) if (err) client.fail(err);
1447
2129
  else client.close(`closed clientGroupID=${this.id}`);
1448
2130
  await this.#lock.withLock(() => {});
1449
2131
  this.#pipelines.destroy();
2132
+ this.#inspectorDelegate.clearAuthenticated(this.id, this);
1450
2133
  }
1451
2134
  /**
1452
2135
  * Test helper: Manually mark initialization as complete.
@@ -1502,15 +2185,49 @@ function hasExpiredQueries(cvr) {
1502
2185
  for (const q of Object.values(cvr.queries)) if (expired(ttlClock, q)) return true;
1503
2186
  return false;
1504
2187
  }
2188
+ /**
2189
+ * Iterates over `values`, adding the time spent producing them to
2190
+ * `total.ms`. The time that the consumer takes between values, including
2191
+ * any that it spends awaiting, is not counted.
2192
+ */
2193
+ function* timeIteration(values, total) {
2194
+ const iterator = values[Symbol.iterator]();
2195
+ try {
2196
+ for (;;) {
2197
+ const start = performance.now();
2198
+ const result = iterator.next();
2199
+ total.ms += performance.now() - start;
2200
+ if (result.done) return;
2201
+ yield result.value;
2202
+ }
2203
+ } finally {
2204
+ iterator.return?.();
2205
+ }
2206
+ }
2207
+ /** How often a client group that is waiting between batches asks again. */
2208
+ var BATCH_WAIT_STEP_MS = 250;
2209
+ /** See `ViewSyncerService.#logBatchWait()`. */
2210
+ var BATCH_WAIT_LOG_INTERVAL_MS = 6e4;
2211
+ var BATCH_WAIT_LOG_MIN_MS = 1e3;
2212
+ /** The weight of the latest batch in a client group's smoothed batch time. */
2213
+ var BATCH_TIME_SMOOTHING = .3;
2214
+ /** How far, as a fraction, a client group's wait is varied at random. */
2215
+ var BATCH_WAIT_JITTER = .3;
1505
2216
  var TimeSliceTimer = class {
1506
2217
  #total = 0;
1507
2218
  #start = 0;
1508
2219
  #lc;
1509
- constructor(lc) {
2220
+ #yieldSlice;
2221
+ /**
2222
+ * @param yieldSlice How the timer yields the process, if not by taking
2223
+ * turns with the rest of the worker's work (see `yieldProcess()`).
2224
+ */
2225
+ constructor(lc, yieldSlice) {
1510
2226
  this.#lc = lc;
2227
+ this.#yieldSlice = yieldSlice;
1511
2228
  }
1512
2229
  async start() {
1513
- await yieldProcess(this.#lc);
2230
+ await (this.#yieldSlice ? this.#yieldSlice() : yieldProcess(this.#lc));
1514
2231
  return this.startWithoutYielding();
1515
2232
  }
1516
2233
  startWithoutYielding() {
@@ -1520,7 +2237,7 @@ var TimeSliceTimer = class {
1520
2237
  }
1521
2238
  async yieldProcess(_msgForTesting) {
1522
2239
  this.#stopLap();
1523
- await yieldProcess(this.#lc);
2240
+ await (this.#yieldSlice ? this.#yieldSlice() : yieldProcess(this.#lc));
1524
2241
  this.#startLap();
1525
2242
  }
1526
2243
  #startLap() {