@rocicorp/zero 1.11.0-canary.1 → 1.11.0-canary.11

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 (628) hide show
  1. package/out/analyze-query/src/bin-analyze.js +9 -8
  2. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  3. package/out/replicache/src/btree/node.d.ts.map +1 -1
  4. package/out/replicache/src/btree/node.js +3 -6
  5. package/out/replicache/src/btree/node.js.map +1 -1
  6. package/out/replicache/src/btree/read.d.ts +12 -1
  7. package/out/replicache/src/btree/read.d.ts.map +1 -1
  8. package/out/replicache/src/btree/read.js +24 -12
  9. package/out/replicache/src/btree/read.js.map +1 -1
  10. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  11. package/out/replicache/src/dag/gc.js +8 -11
  12. package/out/replicache/src/dag/gc.js.map +1 -1
  13. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
  14. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
  15. package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
  16. package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
  17. package/out/replicache/src/dag/store-impl.d.ts +12 -2
  18. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  19. package/out/replicache/src/dag/store-impl.js +22 -8
  20. package/out/replicache/src/dag/store-impl.js.map +1 -1
  21. package/out/replicache/src/db/rebase.d.ts +14 -2
  22. package/out/replicache/src/db/rebase.d.ts.map +1 -1
  23. package/out/replicache/src/db/rebase.js +27 -5
  24. package/out/replicache/src/db/rebase.js.map +1 -1
  25. package/out/replicache/src/db/write.js.map +1 -1
  26. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  27. package/out/replicache/src/kv/expo-sqlite/store.js +28 -5
  28. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  29. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +15 -5
  30. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +1 -1
  31. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +25 -25
  32. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  33. package/out/replicache/src/kv/idb-store.d.ts +9 -0
  34. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  35. package/out/replicache/src/kv/idb-store.js +14 -2
  36. package/out/replicache/src/kv/idb-store.js.map +1 -1
  37. package/out/replicache/src/kv/mem-store.d.ts +1 -0
  38. package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
  39. package/out/replicache/src/kv/mem-store.js +3 -0
  40. package/out/replicache/src/kv/mem-store.js.map +1 -1
  41. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  42. package/out/replicache/src/kv/op-sqlite/store.js +1 -1
  43. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  44. package/out/replicache/src/kv/sqlite-store.d.ts +13 -1
  45. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  46. package/out/replicache/src/kv/sqlite-store.js +73 -6
  47. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  48. package/out/replicache/src/kv/store.d.ts +6 -0
  49. package/out/replicache/src/kv/store.d.ts.map +1 -1
  50. package/out/replicache/src/persist/collect-idb-databases.d.ts +10 -5
  51. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  52. package/out/replicache/src/persist/collect-idb-databases.js +16 -9
  53. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  54. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  55. package/out/replicache/src/persist/persist.js +13 -6
  56. package/out/replicache/src/persist/persist.js.map +1 -1
  57. package/out/replicache/src/persist/refresh.js +6 -2
  58. package/out/replicache/src/persist/refresh.js.map +1 -1
  59. package/out/replicache/src/replicache-impl.d.ts +14 -3
  60. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  61. package/out/replicache/src/replicache-impl.js +118 -11
  62. package/out/replicache/src/replicache-impl.js.map +1 -1
  63. package/out/replicache/src/replicache-options.d.ts +9 -0
  64. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  65. package/out/replicache/src/transactions.d.ts.map +1 -1
  66. package/out/replicache/src/transactions.js +1 -1
  67. package/out/replicache/src/transactions.js.map +1 -1
  68. package/out/shared/src/arrays.d.ts +5 -0
  69. package/out/shared/src/arrays.d.ts.map +1 -1
  70. package/out/shared/src/arrays.js +8 -10
  71. package/out/shared/src/arrays.js.map +1 -1
  72. package/out/shared/src/error.d.ts +11 -0
  73. package/out/shared/src/error.d.ts.map +1 -1
  74. package/out/shared/src/error.js +35 -1
  75. package/out/shared/src/error.js.map +1 -1
  76. package/out/shared/src/iterables.d.ts +2 -0
  77. package/out/shared/src/iterables.d.ts.map +1 -1
  78. package/out/shared/src/iterables.js +18 -1
  79. package/out/shared/src/iterables.js.map +1 -1
  80. package/out/shared/src/map.d.ts +24 -2
  81. package/out/shared/src/map.d.ts.map +1 -1
  82. package/out/shared/src/map.js +18 -4
  83. package/out/shared/src/map.js.map +1 -1
  84. package/out/shared/src/ring-buffer.d.ts +8 -0
  85. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  86. package/out/shared/src/ring-buffer.js +22 -1
  87. package/out/shared/src/ring-buffer.js.map +1 -1
  88. package/out/z2s/src/compiler.js +1 -1
  89. package/out/z2s/src/sql.d.ts.map +1 -1
  90. package/out/z2s/src/sql.js +2 -2
  91. package/out/z2s/src/sql.js.map +1 -1
  92. package/out/zero/package.js +3 -4
  93. package/out/zero/package.js.map +1 -1
  94. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  95. package/out/zero-cache/src/auth/write-authorizer.js +1 -0
  96. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  97. package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
  98. package/out/zero-cache/src/config/normalize.js +25 -1
  99. package/out/zero-cache/src/config/normalize.js.map +1 -1
  100. package/out/zero-cache/src/config/zero-config.d.ts +48 -0
  101. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  102. package/out/zero-cache/src/config/zero-config.js +130 -5
  103. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  104. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  105. package/out/zero-cache/src/db/lite-tables.js +3 -4
  106. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  107. package/out/zero-cache/src/observability/events.js +4 -1
  108. package/out/zero-cache/src/observability/events.js.map +1 -1
  109. package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
  110. package/out/zero-cache/src/observability/metrics.js +2 -7
  111. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  112. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  113. package/out/zero-cache/src/server/change-streamer.js +27 -10
  114. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  115. package/out/zero-cache/src/server/inspector-delegate.d.ts +18 -2
  116. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  117. package/out/zero-cache/src/server/inspector-delegate.js +22 -15
  118. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  119. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  120. package/out/zero-cache/src/server/main.js +8 -1
  121. package/out/zero-cache/src/server/main.js.map +1 -1
  122. package/out/zero-cache/src/server/mutator.js +2 -0
  123. package/out/zero-cache/src/server/mutator.js.map +1 -1
  124. package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
  125. package/out/zero-cache/src/server/reaper.js +2 -0
  126. package/out/zero-cache/src/server/reaper.js.map +1 -1
  127. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  128. package/out/zero-cache/src/server/replicator.js +12 -3
  129. package/out/zero-cache/src/server/replicator.js.map +1 -1
  130. package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
  131. package/out/zero-cache/src/server/runner/zero-dispatcher.js +3 -0
  132. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  133. package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
  134. package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
  135. package/out/zero-cache/src/server/syncer-assigner.js +72 -0
  136. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
  137. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  138. package/out/zero-cache/src/server/syncer.js +5 -1
  139. package/out/zero-cache/src/server/syncer.js.map +1 -1
  140. package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
  141. package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
  142. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  143. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  144. package/out/zero-cache/src/services/analyze.js +11 -9
  145. package/out/zero-cache/src/services/analyze.js.map +1 -1
  146. package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
  147. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +15 -3
  148. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  149. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
  150. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +15 -3
  151. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  152. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  153. package/out/zero-cache/src/services/change-source/common/replica-schema.js +2 -39
  154. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  155. package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts +156 -0
  156. package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts.map +1 -0
  157. package/out/zero-cache/src/services/change-source/pg/backfill-resume.js +15 -0
  158. package/out/zero-cache/src/services/change-source/pg/backfill-resume.js.map +1 -0
  159. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +25 -0
  160. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
  161. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +202 -0
  162. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
  163. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +14 -16
  164. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  165. package/out/zero-cache/src/services/change-source/pg/change-source.js +64 -143
  166. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  167. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +28 -2
  168. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  169. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +44 -21
  170. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  171. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
  172. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
  173. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
  174. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
  175. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +21 -15
  176. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  177. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +86 -23
  178. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  179. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
  180. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
  181. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  182. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  183. package/out/zero-cache/src/services/change-source/pg/schema/init.js +32 -1
  184. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  185. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
  186. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
  187. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
  188. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
  189. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +50 -27
  190. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  191. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +100 -34
  192. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  193. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  194. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +58 -7
  195. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  196. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +8 -2
  197. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
  198. package/out/zero-cache/src/services/change-streamer/broadcast.js +24 -4
  199. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  200. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -4
  201. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
  202. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +28 -8
  203. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
  204. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +5 -2
  205. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  206. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +21 -14
  207. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  208. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +11 -0
  209. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  210. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +97 -63
  211. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  212. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +12 -8
  213. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  214. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  215. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
  216. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
  217. package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
  218. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  219. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +1 -1
  220. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  221. package/out/zero-cache/src/services/change-streamer/schema/tables.js +4 -4
  222. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  223. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
  224. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +15 -3
  225. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  226. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +21 -1
  227. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
  228. package/out/zero-cache/src/services/change-streamer/snapshot.js +61 -21
  229. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  230. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
  231. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
  232. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
  233. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  234. package/out/zero-cache/src/services/change-streamer/storer.d.ts +2 -2
  235. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  236. package/out/zero-cache/src/services/change-streamer/storer.js +8 -5
  237. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  238. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +4 -1
  239. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
  240. package/out/zero-cache/src/services/change-streamer/subscriber.js +42 -0
  241. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  242. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +17 -1
  243. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
  244. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +19 -3
  245. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  246. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -1
  247. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +1 -0
  248. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -1
  249. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  250. package/out/zero-cache/src/services/life-cycle.js +3 -1
  251. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  252. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  253. package/out/zero-cache/src/services/litestream/commands.js +3 -1
  254. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  255. package/out/zero-cache/src/services/litestream/config-v5.yml +3 -4
  256. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +51 -24
  257. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  258. package/out/zero-cache/src/services/litestream/restore-progress.d.ts +24 -0
  259. package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +1 -0
  260. package/out/zero-cache/src/services/litestream/restore-progress.js +91 -0
  261. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -0
  262. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
  263. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  264. package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
  265. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  266. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  267. package/out/zero-cache/src/services/mutagen/pusher.js +5 -6
  268. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  269. package/out/zero-cache/src/services/profz.d.ts +7 -0
  270. package/out/zero-cache/src/services/profz.d.ts.map +1 -0
  271. package/out/zero-cache/src/services/profz.js +105 -0
  272. package/out/zero-cache/src/services/profz.js.map +1 -0
  273. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
  274. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +5 -4
  275. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -1
  276. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +20 -22
  277. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  278. package/out/zero-cache/src/services/replicator/change-processor.js +1 -0
  279. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  280. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +1 -1
  281. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  282. package/out/zero-cache/src/services/replicator/incremental-sync.js +57 -17
  283. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  284. package/out/zero-cache/src/services/replicator/replication-status.d.ts +35 -1
  285. package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
  286. package/out/zero-cache/src/services/replicator/replication-status.js +96 -6
  287. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  288. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  289. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +6 -6
  290. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
  291. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +19 -14
  292. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  293. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +4 -4
  294. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
  295. package/out/zero-cache/src/services/replicator/write-worker-client.js +2 -2
  296. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  297. package/out/zero-cache/src/services/replicator/write-worker.js +10 -4
  298. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  299. package/out/zero-cache/src/services/run-ast.d.ts +12 -0
  300. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  301. package/out/zero-cache/src/services/run-ast.js +26 -14
  302. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  303. package/out/zero-cache/src/services/runner.d.ts +2 -1
  304. package/out/zero-cache/src/services/runner.d.ts.map +1 -1
  305. package/out/zero-cache/src/services/runner.js +10 -2
  306. package/out/zero-cache/src/services/runner.js.map +1 -1
  307. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +1 -1
  308. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  309. package/out/zero-cache/src/services/view-syncer/client-handler.js +36 -31
  310. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  311. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +45 -0
  312. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  313. package/out/zero-cache/src/services/view-syncer/cvr.js +133 -1
  314. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  315. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
  316. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  317. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
  318. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  319. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +33 -0
  320. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +1 -0
  321. package/out/zero-cache/src/services/view-syncer/hydration-budget.js +62 -0
  322. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -0
  323. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
  324. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
  325. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
  326. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
  327. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
  328. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
  329. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +2 -2
  330. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  331. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +14 -1
  332. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  333. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +64 -30
  334. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  335. package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
  336. package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -6
  337. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  338. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +95 -0
  339. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +1 -0
  340. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +155 -0
  341. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -0
  342. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +48 -4
  343. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  344. package/out/zero-cache/src/services/view-syncer/snapshotter.js +125 -28
  345. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  346. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +11 -1
  347. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  348. package/out/zero-cache/src/services/view-syncer/view-syncer.js +512 -98
  349. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  350. package/out/zero-cache/src/types/processes.d.ts +39 -0
  351. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  352. package/out/zero-cache/src/types/processes.js +43 -4
  353. package/out/zero-cache/src/types/processes.js.map +1 -1
  354. package/out/zero-cache/src/types/profiler.d.ts +12 -0
  355. package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
  356. package/out/zero-cache/src/types/profiler.js +46 -1
  357. package/out/zero-cache/src/types/profiler.js.map +1 -1
  358. package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
  359. package/out/zero-cache/src/types/row-key.js +5 -5
  360. package/out/zero-cache/src/types/row-key.js.map +1 -1
  361. package/out/zero-cache/src/types/streams.d.ts +25 -9
  362. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  363. package/out/zero-cache/src/types/streams.js +118 -34
  364. package/out/zero-cache/src/types/streams.js.map +1 -1
  365. package/out/zero-cache/src/types/subscription.d.ts +4 -0
  366. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  367. package/out/zero-cache/src/types/subscription.js +71 -0
  368. package/out/zero-cache/src/types/subscription.js.map +1 -1
  369. package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
  370. package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
  371. package/out/zero-cache/src/types/websocket-handoff.js +18 -9
  372. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  373. package/out/zero-cache/src/types/ws.d.ts.map +1 -1
  374. package/out/zero-cache/src/types/ws.js +23 -8
  375. package/out/zero-cache/src/types/ws.js.map +1 -1
  376. package/out/zero-cache/src/workers/connect-params.d.ts +1 -0
  377. package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
  378. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  379. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  380. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
  381. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  382. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  383. package/out/zero-cache/src/workers/syncer.js +55 -4
  384. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  385. package/out/zero-client/src/client/connection-manager.d.ts +20 -0
  386. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  387. package/out/zero-client/src/client/connection-manager.js +77 -13
  388. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  389. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  390. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  391. package/out/zero-client/src/client/connection-status-enum.js +3 -1
  392. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  393. package/out/zero-client/src/client/connection.d.ts +6 -0
  394. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  395. package/out/zero-client/src/client/connection.js +2 -1
  396. package/out/zero-client/src/client/connection.js.map +1 -1
  397. package/out/zero-client/src/client/context.d.ts +27 -2
  398. package/out/zero-client/src/client/context.d.ts.map +1 -1
  399. package/out/zero-client/src/client/context.js +112 -1
  400. package/out/zero-client/src/client/context.js.map +1 -1
  401. package/out/zero-client/src/client/custom.js +2 -2
  402. package/out/zero-client/src/client/custom.js.map +1 -1
  403. package/out/zero-client/src/client/error.js +1 -1
  404. package/out/zero-client/src/client/inspector/lazy-inspector.js +2 -2
  405. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  406. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  407. package/out/zero-client/src/client/ivm-branch.js +20 -3
  408. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  409. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  410. package/out/zero-client/src/client/mutator-proxy.js +2 -1
  411. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  412. package/out/zero-client/src/client/options.d.ts +3 -0
  413. package/out/zero-client/src/client/options.d.ts.map +1 -1
  414. package/out/zero-client/src/client/options.js.map +1 -1
  415. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  416. package/out/zero-client/src/client/query-manager.js +44 -11
  417. package/out/zero-client/src/client/query-manager.js.map +1 -1
  418. package/out/zero-client/src/client/version.js +1 -1
  419. package/out/zero-client/src/client/zero-rep.d.ts +1 -0
  420. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  421. package/out/zero-client/src/client/zero-rep.js +9 -6
  422. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  423. package/out/zero-client/src/client/zero.d.ts +18 -3
  424. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  425. package/out/zero-client/src/client/zero.js +120 -32
  426. package/out/zero-client/src/client/zero.js.map +1 -1
  427. package/out/zero-client/src/types/query-result.d.ts +2 -0
  428. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  429. package/out/zero-events/src/status.d.ts +58 -0
  430. package/out/zero-events/src/status.d.ts.map +1 -1
  431. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  432. package/out/zero-protocol/src/ast.js +13 -14
  433. package/out/zero-protocol/src/ast.js.map +1 -1
  434. package/out/zero-protocol/src/poke.d.ts +6 -6
  435. package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
  436. package/out/zero-protocol/src/query-hash.js +2 -5
  437. package/out/zero-protocol/src/query-hash.js.map +1 -1
  438. package/out/zero-react/src/use-query.d.ts +5 -4
  439. package/out/zero-react/src/use-query.d.ts.map +1 -1
  440. package/out/zero-react/src/use-query.js +86 -9
  441. package/out/zero-react/src/use-query.js.map +1 -1
  442. package/out/zero-server/src/adapters/drizzle.d.ts +2 -1
  443. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  444. package/out/zero-server/src/adapters/drizzle.js +12 -7
  445. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  446. package/out/zero-server/src/adapters/kysely.d.ts +2 -1
  447. package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
  448. package/out/zero-server/src/adapters/kysely.js +8 -2
  449. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  450. package/out/zero-server/src/adapters/pg.d.ts +1 -0
  451. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  452. package/out/zero-server/src/adapters/pg.js +8 -2
  453. package/out/zero-server/src/adapters/pg.js.map +1 -1
  454. package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
  455. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  456. package/out/zero-server/src/adapters/postgresjs.js +7 -1
  457. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  458. package/out/zero-server/src/adapters/prisma.d.ts +3 -2
  459. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  460. package/out/zero-server/src/adapters/prisma.js +8 -2
  461. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  462. package/out/zero-server/src/custom.d.ts +5 -1
  463. package/out/zero-server/src/custom.d.ts.map +1 -1
  464. package/out/zero-server/src/custom.js +6 -3
  465. package/out/zero-server/src/custom.js.map +1 -1
  466. package/out/zero-server/src/mod.d.ts +1 -1
  467. package/out/zero-server/src/mod.d.ts.map +1 -1
  468. package/out/zero-server/src/pg-query-executor.d.ts +2 -2
  469. package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
  470. package/out/zero-server/src/pg-query-executor.js +2 -2
  471. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  472. package/out/zero-server/src/schema.d.ts +2 -2
  473. package/out/zero-server/src/schema.d.ts.map +1 -1
  474. package/out/zero-server/src/schema.js +2 -2
  475. package/out/zero-server/src/schema.js.map +1 -1
  476. package/out/zero-server/src/zql-database.d.ts +21 -1
  477. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  478. package/out/zero-server/src/zql-database.js +33 -2
  479. package/out/zero-server/src/zql-database.js.map +1 -1
  480. package/out/zero-solid/src/solid-view.d.ts +17 -0
  481. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  482. package/out/zero-solid/src/solid-view.js +39 -1
  483. package/out/zero-solid/src/solid-view.js.map +1 -1
  484. package/out/zero-solid/src/use-query.js +5 -3
  485. package/out/zero-solid/src/use-query.js.map +1 -1
  486. package/out/zql/src/builder/builder.d.ts +19 -0
  487. package/out/zql/src/builder/builder.d.ts.map +1 -1
  488. package/out/zql/src/builder/builder.js +38 -12
  489. package/out/zql/src/builder/builder.js.map +1 -1
  490. package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +43 -0
  491. package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +1 -0
  492. package/out/zql/src/builder/correlated-predicate-pushdown.js +161 -0
  493. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -0
  494. package/out/zql/src/builder/debug-delegate.d.ts +6 -1
  495. package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
  496. package/out/zql/src/builder/debug-delegate.js +14 -2
  497. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  498. package/out/zql/src/ivm/array-view.d.ts +29 -0
  499. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  500. package/out/zql/src/ivm/array-view.js +63 -12
  501. package/out/zql/src/ivm/array-view.js.map +1 -1
  502. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  503. package/out/zql/src/ivm/cap.js +10 -4
  504. package/out/zql/src/ivm/cap.js.map +1 -1
  505. package/out/zql/src/ivm/connection-index.d.ts +68 -0
  506. package/out/zql/src/ivm/connection-index.d.ts.map +1 -0
  507. package/out/zql/src/ivm/connection-index.js +149 -0
  508. package/out/zql/src/ivm/connection-index.js.map +1 -0
  509. package/out/zql/src/ivm/data.d.ts.map +1 -1
  510. package/out/zql/src/ivm/data.js +8 -3
  511. package/out/zql/src/ivm/data.js.map +1 -1
  512. package/out/zql/src/ivm/deferred-input.d.ts +44 -0
  513. package/out/zql/src/ivm/deferred-input.d.ts.map +1 -0
  514. package/out/zql/src/ivm/deferred-input.js +89 -0
  515. package/out/zql/src/ivm/deferred-input.js.map +1 -0
  516. package/out/zql/src/ivm/exists.d.ts +1 -1
  517. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  518. package/out/zql/src/ivm/exists.js +1 -1
  519. package/out/zql/src/ivm/exists.js.map +1 -1
  520. package/out/zql/src/ivm/fan-in.d.ts +2 -2
  521. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  522. package/out/zql/src/ivm/fan-in.js +6 -5
  523. package/out/zql/src/ivm/fan-in.js.map +1 -1
  524. package/out/zql/src/ivm/fan-out.d.ts +2 -2
  525. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  526. package/out/zql/src/ivm/fan-out.js.map +1 -1
  527. package/out/zql/src/ivm/filter-operators.d.ts +6 -6
  528. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  529. package/out/zql/src/ivm/filter-operators.js +10 -8
  530. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  531. package/out/zql/src/ivm/filter.d.ts +2 -2
  532. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  533. package/out/zql/src/ivm/filter.js +7 -4
  534. package/out/zql/src/ivm/filter.js.map +1 -1
  535. package/out/zql/src/ivm/flipped-join.d.ts +6 -4
  536. package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
  537. package/out/zql/src/ivm/flipped-join.js +20 -33
  538. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  539. package/out/zql/src/ivm/join-utils.d.ts +10 -0
  540. package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
  541. package/out/zql/src/ivm/join-utils.js +23 -1
  542. package/out/zql/src/ivm/join-utils.js.map +1 -1
  543. package/out/zql/src/ivm/join.d.ts +5 -1
  544. package/out/zql/src/ivm/join.d.ts.map +1 -1
  545. package/out/zql/src/ivm/join.js +91 -13
  546. package/out/zql/src/ivm/join.js.map +1 -1
  547. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  548. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  549. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
  550. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  551. package/out/zql/src/ivm/memory-source.d.ts +15 -3
  552. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  553. package/out/zql/src/ivm/memory-source.js +40 -19
  554. package/out/zql/src/ivm/memory-source.js.map +1 -1
  555. package/out/zql/src/ivm/take-gate.d.ts +35 -0
  556. package/out/zql/src/ivm/take-gate.d.ts.map +1 -0
  557. package/out/zql/src/ivm/take-gate.js +81 -0
  558. package/out/zql/src/ivm/take-gate.js.map +1 -0
  559. package/out/zql/src/ivm/take.d.ts +6 -1
  560. package/out/zql/src/ivm/take.d.ts.map +1 -1
  561. package/out/zql/src/ivm/take.js +104 -88
  562. package/out/zql/src/ivm/take.js.map +1 -1
  563. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  564. package/out/zql/src/ivm/union-fan-in.js +9 -7
  565. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  566. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  567. package/out/zql/src/ivm/view-apply-change.js +9 -4
  568. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  569. package/out/zql/src/ivm/view.d.ts +15 -0
  570. package/out/zql/src/ivm/view.d.ts.map +1 -1
  571. package/out/zql/src/mutate/custom.d.ts +24 -1
  572. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  573. package/out/zql/src/mutate/custom.js.map +1 -1
  574. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  575. package/out/zql/src/mutate/mutator-registry.js +2 -2
  576. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  577. package/out/zql/src/planner/planner-builder.d.ts +12 -3
  578. package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
  579. package/out/zql/src/planner/planner-builder.js +27 -17
  580. package/out/zql/src/planner/planner-builder.js.map +1 -1
  581. package/out/zql/src/planner/planner-connection.d.ts +15 -2
  582. package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
  583. package/out/zql/src/planner/planner-connection.js +73 -8
  584. package/out/zql/src/planner/planner-connection.js.map +1 -1
  585. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  586. package/out/zql/src/planner/planner-debug.js +3 -8
  587. package/out/zql/src/planner/planner-debug.js.map +1 -1
  588. package/out/zql/src/planner/planner-source.d.ts +2 -2
  589. package/out/zql/src/planner/planner-source.d.ts.map +1 -1
  590. package/out/zql/src/planner/planner-source.js +2 -2
  591. package/out/zql/src/planner/planner-source.js.map +1 -1
  592. package/out/zql/src/query/query-delegate-base.d.ts +9 -1
  593. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  594. package/out/zql/src/query/query-delegate-base.js +129 -33
  595. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  596. package/out/zql/src/query/query-delegate.d.ts +50 -1
  597. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  598. package/out/zql/src/query/query-impl.d.ts +13 -11
  599. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  600. package/out/zql/src/query/query-impl.js +366 -60
  601. package/out/zql/src/query/query-impl.js.map +1 -1
  602. package/out/zql/src/query/query-transitions.d.ts +171 -0
  603. package/out/zql/src/query/query-transitions.d.ts.map +1 -0
  604. package/out/zql/src/query/query-transitions.js +204 -0
  605. package/out/zql/src/query/query-transitions.js.map +1 -0
  606. package/out/zql/src/query/query.d.ts +11 -2
  607. package/out/zql/src/query/query.d.ts.map +1 -1
  608. package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
  609. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  610. package/out/zql/src/query/runnable-query-impl.js +13 -1
  611. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  612. package/out/zql/src/query/typed-view.d.ts +1 -1
  613. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  614. package/out/zqlite/src/db.d.ts +9 -1
  615. package/out/zqlite/src/db.d.ts.map +1 -1
  616. package/out/zqlite/src/db.js +8 -2
  617. package/out/zqlite/src/db.js.map +1 -1
  618. package/out/zqlite/src/query-delegate.d.ts.map +1 -1
  619. package/out/zqlite/src/query-delegate.js +5 -6
  620. package/out/zqlite/src/query-delegate.js.map +1 -1
  621. package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
  622. package/out/zqlite/src/sqlite-stat-fanout.js +3 -5
  623. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  624. package/out/zqlite/src/table-source.d.ts +15 -2
  625. package/out/zqlite/src/table-source.d.ts.map +1 -1
  626. package/out/zqlite/src/table-source.js +21 -10
  627. package/out/zqlite/src/table-source.js.map +1 -1
  628. package/package.json +3 -4
@@ -1,5 +1,6 @@
1
1
  import { assert, unreachable } from "../../../../shared/src/asserts.js";
2
2
  import { deepEqual } from "../../../../shared/src/json.js";
3
+ import { getOrInsertComputed } from "../../../../shared/src/map.js";
3
4
  import { must } from "../../../../shared/src/must.js";
4
5
  import { skipYields } from "../../../../zql/src/ivm/skip-yields.js";
5
6
  import { throwOutput } from "../../../../zql/src/ivm/operator.js";
@@ -173,10 +174,23 @@ var PipelineDriver = class {
173
174
  }
174
175
  return this.#permissions;
175
176
  }
177
+ /**
178
+ * Advances the snapshot to the head of the database without diffing the
179
+ * change log, in preparation for hydrating queries at head.
180
+ *
181
+ * Throws a {@link ResetPipelinesSignal} if the change log records a
182
+ * schema change since the previous snapshot. The table specs (and any
183
+ * TableSources built from them) were computed at or before that snapshot
184
+ * and are stale with respect to the new head, so the caller must
185
+ * {@link reset()} before hydrating. ({@link advance()} detects this when
186
+ * the diff encounters the RESET op; this path skips the diff and so must
187
+ * check explicitly.)
188
+ */
176
189
  advanceWithoutDiff() {
177
- const { db, version } = this.#snapshotter.advanceWithoutDiff().curr;
178
- for (const table of this.#tables.values()) table.setDB(db.db);
179
- return version;
190
+ const { prev, curr } = this.#snapshotter.advanceWithoutDiff();
191
+ if (curr.schemaChangedSince(prev.version)) throw new ResetPipelinesSignal(`schema changed between ${prev.version} and ${curr.version}`, "schema-change");
192
+ for (const table of this.#tables.values()) table.setDB(curr.db.db);
193
+ return curr.version;
180
194
  }
181
195
  #ensureCostModelExistsIfEnabled(db) {
182
196
  let existing = this.#costModels?.get(db);
@@ -196,6 +210,7 @@ var PipelineDriver = class {
196
210
  this.#pipelines.delete(queryID);
197
211
  this.#destroyPipeline(queryID, pipeline, "destroy");
198
212
  }
213
+ this.#tables.clear();
199
214
  this.#rowSetSignatures.clear();
200
215
  this.#storage.destroy();
201
216
  this.#snapshotter.destroy();
@@ -232,11 +247,15 @@ var PipelineDriver = class {
232
247
  this.#lc.warn?.(`Ignoring {scalar: true} on the "${table}" subquery of query ${queryID}: it does not constrain every column of any unique key ${keys.length > 0 ? `[${keys}]` : "(none on this table)"} to a literal with "=", so it is not provably limited to one row. The gate runs as a plain EXISTS.`);
233
248
  }
234
249
  }
250
+ #disableCorrelatedPredicatePushdown() {
251
+ return this.#config?.enableCorrelatedPredicatePushdown === false;
252
+ }
235
253
  #resolveScalarSubqueries(ast) {
236
254
  const companionRows = [];
237
255
  const companionInputs = [];
238
256
  const executor = (subqueryAST, childField) => {
239
257
  const input = buildPipeline(subqueryAST, {
258
+ disableCorrelatedPredicatePushdown: this.#disableCorrelatedPredicatePushdown(),
240
259
  getSource: (name) => this.#getSource(name),
241
260
  createStorage: () => this.#createStorage(),
242
261
  decorateSourceInput: (input) => input,
@@ -244,20 +263,25 @@ var PipelineDriver = class {
244
263
  addEdge() {},
245
264
  decorateFilterInput: (input) => input
246
265
  }, "scalar-subquery");
266
+ companionInputs.push(input);
247
267
  let node;
248
268
  for (const n of skipYields(input.fetch({}))) node ??= n;
249
- if (!node) {
250
- companionInputs.push(input);
251
- return;
252
- }
269
+ if (!node) return;
253
270
  companionRows.push({
254
271
  table: subqueryAST.table,
255
272
  row: node.row
256
273
  });
257
- companionInputs.push(input);
258
274
  return node.row[childField] ?? null;
259
275
  };
260
- const { ast: resolved, companions, ignoredScalarHints } = resolveSimpleScalarSubqueries(ast, this.#tableSpecs, executor);
276
+ let resolved;
277
+ let companions;
278
+ let ignoredScalarHints;
279
+ try {
280
+ ({ast: resolved, companions, ignoredScalarHints} = resolveSimpleScalarSubqueries(ast, this.#tableSpecs, executor));
281
+ } catch (e) {
282
+ for (const input of companionInputs) input.destroy();
283
+ throw e;
284
+ }
261
285
  return {
262
286
  ast: resolved,
263
287
  companionRows,
@@ -296,19 +320,23 @@ var PipelineDriver = class {
296
320
  queryName,
297
321
  hydrationReason
298
322
  });
299
- const debugDelegate = runtimeDebugFlags.trackRowsVended ? new Debug() : void 0;
323
+ const debugDelegate = runtimeDebugFlags.trackRowsVended ? new Debug(true) : void 0;
300
324
  const costModel = this.#ensureCostModelExistsIfEnabled(this.#snapshotter.current().db.db);
301
325
  assert(this.#advanceContext === null, "Cannot hydrate while advance is in progress");
302
326
  this.#hydrateContext = { timer };
303
327
  let hydrationFinished = false;
304
328
  let hydrationFailed = false;
305
329
  let hydrationRowCount = 0;
330
+ let builtInputs = [];
306
331
  try {
307
332
  const { ast: resolvedQuery, companionRows, companions: companionMeta, companionInputs, ignoredScalarHints } = this.#resolveScalarSubqueries(query);
333
+ builtInputs = [...companionInputs];
308
334
  this.#warnIgnoredScalarHints(queryID, ignoredScalarHints);
309
335
  const input = buildPipeline(resolvedQuery, {
310
336
  debug: debugDelegate,
311
337
  enableNotExists: true,
338
+ disableCorrelatedPredicatePushdown: this.#disableCorrelatedPredicatePushdown(),
339
+ enablePlannerAwarePushdown: this.#config?.enablePlannerAwarePushdown !== false,
312
340
  getSource: (name) => this.#getSource(name),
313
341
  createStorage: () => this.#createStorage(),
314
342
  decorateSourceInput: (input, _queryID) => new MeasurePushOperator(new QueryFailureLoggingOperator(this.#lc, input, queryID, transformationHash, queryName), queryID, this.#inspectorDelegate, "query-update-server"),
@@ -316,6 +344,7 @@ var PipelineDriver = class {
316
344
  addEdge() {},
317
345
  decorateFilterInput: (input) => input
318
346
  }, queryID, costModel);
347
+ builtInputs.push(input);
319
348
  const schema = input.getSchema();
320
349
  input.setOutput({ push: (change) => {
321
350
  const streamer = this.#streamer;
@@ -391,6 +420,7 @@ var PipelineDriver = class {
391
420
  pipelineRunID,
392
421
  pipelineReadyAtMs,
393
422
  transformedAst: resolvedQuery,
423
+ originalAst: query,
394
424
  transformationHash,
395
425
  ...queryName !== void 0 && { queryName },
396
426
  companions: liveCompanions
@@ -435,6 +465,11 @@ var PipelineDriver = class {
435
465
  hydrationTimeMs: timer.totalElapsed(),
436
466
  hydrationRowCount
437
467
  });
468
+ if (!hydrationFinished) {
469
+ for (const input of builtInputs) input.destroy();
470
+ this.#pruneUnusedTables();
471
+ this.#rowSetSignatures.delete(queryID);
472
+ }
438
473
  this.#hydrateContext = null;
439
474
  }
440
475
  }
@@ -447,9 +482,13 @@ var PipelineDriver = class {
447
482
  if (pipeline) {
448
483
  this.#pipelines.delete(queryID);
449
484
  this.#destroyPipeline(queryID, pipeline, stopReason);
485
+ this.#pruneUnusedTables();
450
486
  }
451
487
  this.#rowSetSignatures.delete(queryID);
452
488
  }
489
+ #pruneUnusedTables() {
490
+ for (const [table, source] of this.#tables.entries()) if (!source.hasConnections()) this.#tables.delete(table);
491
+ }
453
492
  #destroyPipeline(queryID, pipeline, stopReason) {
454
493
  this.#logQueryPipelineLifecycle({
455
494
  zeroEvent: "query-pipeline-stop",
@@ -516,7 +555,7 @@ var PipelineDriver = class {
516
555
  */
517
556
  advance(timer) {
518
557
  assert(this.initialized(), "Pipeline driver must be initialized before advancing");
519
- const diff = this.#snapshotter.advance(this.#tableSpecs, this.#allTableNames);
558
+ const diff = this.#snapshotter.advance(this.#tableSpecs, this.#allTableNames, this.#tables);
520
559
  const { prev, curr, changes } = diff;
521
560
  this.#lc.debug?.(`advance ${prev.version} => ${curr.version}: ${changes} changes`);
522
561
  return {
@@ -542,7 +581,6 @@ var PipelineDriver = class {
542
581
  const start = timer.totalElapsed();
543
582
  const advanceContext = must(this.#advanceContext);
544
583
  advanceContext.currentChangeStartMs = start;
545
- let type;
546
584
  try {
547
585
  try {
548
586
  const tableSource = this.#tables.get(table);
@@ -564,10 +602,7 @@ var PipelineDriver = class {
564
602
  advanceContext.currentChangeStartMs = void 0;
565
603
  }
566
604
  const elapsed = timer.totalElapsed() - start;
567
- this.#advanceTime.recordMs(elapsed, {
568
- table,
569
- type
570
- });
605
+ this.#advanceTime.recordMs(elapsed, { table });
571
606
  }
572
607
  const { curr } = diff;
573
608
  for (const table of this.#tables.values()) table.setDB(curr.db.db);
@@ -579,15 +614,14 @@ var PipelineDriver = class {
579
614
  }
580
615
  /** Implements `BuilderDelegate.getSource()` */
581
616
  #getSource(tableName) {
582
- let source = this.#tables.get(tableName);
583
- if (source) return source;
584
- const tableSpec = mustGetTableSpec(this.#tableSpecs, tableName);
585
- const primaryKey = mustGetPrimaryKey(this.#primaryKeys, tableName);
586
- const { db } = this.#snapshotter.current();
587
- source = new TableSource(this.#lc, this.#logConfig, db.db, tableName, tableSpec.zqlSpec, primaryKey, () => this.#shouldYield());
588
- this.#tables.set(tableName, source);
589
- this.#lc.debug?.(`created TableSource for ${tableName}`);
590
- return source;
617
+ return getOrInsertComputed(this.#tables, tableName, (tableName) => {
618
+ const tableSpec = mustGetTableSpec(this.#tableSpecs, tableName);
619
+ const primaryKey = mustGetPrimaryKey(this.#primaryKeys, tableName);
620
+ const { db } = this.#snapshotter.current();
621
+ const source = new TableSource(this.#lc, this.#logConfig, db.db, tableName, tableSpec.zqlSpec, primaryKey, () => this.#shouldYield(), { skipUnobservableChanges: true });
622
+ this.#lc.debug?.(`created TableSource for ${tableName}`);
623
+ return source;
624
+ });
591
625
  }
592
626
  #shouldYield() {
593
627
  if (this.#hydrateContext) return this.#hydrateContext.timer.elapsedLap() > this.#yieldThresholdMs();
@@ -813,13 +847,13 @@ function getRowKey(cols, row) {
813
847
  * function for reuse by the analyze-query RPC path so that analysis hydrates
814
848
  * queries the same way the view-syncer does in production.
815
849
  */
816
- function* hydrate(input, hash, clientSchema, tableSpecs) {
850
+ function hydrate(input, hash, clientSchema, tableSpecs) {
817
851
  const res = input.fetch({});
818
- yield* new Streamer(buildPrimaryKeys(clientSchema), tableSpecs).accumulate(hash, input.getSchema(), toAdds(res)).stream();
852
+ return new Streamer(buildPrimaryKeys(clientSchema), tableSpecs).accumulate(hash, input.getSchema(), toAdds(res)).stream();
819
853
  }
820
- function* hydrateInternal(input, hash, primaryKeys, tableSpecs) {
854
+ function hydrateInternal(input, hash, primaryKeys, tableSpecs) {
821
855
  const res = input.fetch({});
822
- yield* new Streamer(primaryKeys, tableSpecs).accumulate(hash, input.getSchema(), toAdds(res)).stream();
856
+ return new Streamer(primaryKeys, tableSpecs).accumulate(hash, input.getSchema(), toAdds(res)).stream();
823
857
  }
824
858
  function buildPrimaryKeys(clientSchema, primaryKeys = /* @__PURE__ */ new Map()) {
825
859
  for (const [tableName, { primaryKey }] of Object.entries(clientSchema.tables)) primaryKeys.set(tableName, primaryKey);
@@ -828,7 +862,7 @@ function buildPrimaryKeys(clientSchema, primaryKeys = /* @__PURE__ */ new Map())
828
862
  function mustGetPrimaryKey(primaryKeys, table) {
829
863
  const pKeys = must(primaryKeys, "primaryKey map must be non-null");
830
864
  const rv = pKeys.get(table);
831
- assert(rv, () => `table '${table}' is not one of: ${[...pKeys.keys()].sort()}. Check the spelling and ensure that the table has a primary key.`);
865
+ assert(rv, () => `table '${table}' is not one of: ${JSON.stringify([...pKeys.keys()].sort())}. Check the spelling and ensure that the table has a primary key.`);
832
866
  return rv;
833
867
  }
834
868
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-driver.js","names":["#tables","#pipelines","#rowSetSignatures","#lc","#snapshotter","#storage","#shardID","#logConfig","#config","#tableSpecs","#allTableNames","#costModels","#yieldThresholdMs","#advanceTime","#conflictRowsDeleted","#inspectorDelegate","#initAndResetCommon","#destroyPipeline","#primaryKeys","#replicaVersion","#permissions","#getSource","#createStorage","#trackRowSetSignatures","#addQueryImpl","#logQueryPipelineLifecycle","#ensureCostModelExistsIfEnabled","#advanceContext","#hydrateContext","#resolveScalarSubqueries","#warnIgnoredScalarHints","#streamer","#advance","#shouldAdvanceYieldMaybeAbortAdvance","#push","#shouldYield","#throwSlowCurrentChangeReset","#throwProjectedAdvancementReset","#startAccumulating","#stopAccumulating","#logQueryFailure","#changes","#streamChanges","#streamNodes","#input","#queryHash","#transformationHash","#queryName","#output"],"sources":["../../../../../../zero-cache/src/services/view-syncer/pipeline-driver.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert, unreachable} from '../../../../shared/src/asserts.ts';\nimport {deepEqual, type JSONValue} from '../../../../shared/src/json.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport {randInt} from '../../../../shared/src/rand.ts';\nimport type {AST, LiteralValue} from '../../../../zero-protocol/src/ast.ts';\nimport type {ClientSchema} from '../../../../zero-protocol/src/client-schema.ts';\nimport type {Row} from '../../../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../../../zero-protocol/src/primary-key.ts';\nimport {buildPipeline} from '../../../../zql/src/builder/builder.ts';\nimport {\n Debug,\n runtimeDebugFlags,\n} from '../../../../zql/src/builder/debug-delegate.ts';\nimport {ChangeIndex} from '../../../../zql/src/ivm/change-index.ts';\nimport {ChangeType} from '../../../../zql/src/ivm/change-type.ts';\nimport type {Change} from '../../../../zql/src/ivm/change.ts';\nimport type {Node} from '../../../../zql/src/ivm/data.ts';\nimport {\n skipYields,\n throwOutput,\n type FetchRequest,\n type Input,\n type Output,\n type Storage,\n} from '../../../../zql/src/ivm/operator.ts';\nimport type {SourceSchema} from '../../../../zql/src/ivm/schema.ts';\nimport {\n type Source,\n type SourceChange,\n type SourceInput,\n makeSourceChangeAdd,\n makeSourceChangeEdit,\n makeSourceChangeRemove,\n} from '../../../../zql/src/ivm/source.ts';\nimport type {ConnectionCostModel} from '../../../../zql/src/planner/planner-connection.ts';\nimport {MeasurePushOperator} from '../../../../zql/src/query/measure-push-operator.ts';\nimport type {ClientGroupStorage} from '../../../../zqlite/src/database-storage.ts';\nimport type {Database} from '../../../../zqlite/src/db.ts';\nimport {\n resolveSimpleScalarSubqueries,\n type CompanionSubquery,\n type IgnoredScalarHint,\n} from '../../../../zqlite/src/resolve-scalar-subqueries.ts';\nimport {createSQLiteCostModel} from '../../../../zqlite/src/sqlite-cost-model.ts';\nimport {TableSource} from '../../../../zqlite/src/table-source.ts';\nimport {\n reloadPermissionsIfChanged,\n type LoadedPermissions,\n} from '../../auth/load-permissions.ts';\nimport type {LogConfig, ZeroConfig} from '../../config/zero-config.ts';\nimport {computeZqlSpecs, mustGetTableSpec} from '../../db/lite-tables.ts';\nimport type {LiteAndZqlSpec, LiteTableSpec} from '../../db/specs.ts';\nimport {\n getOrCreateCounter,\n getOrCreateLatencyHistogram,\n} from '../../observability/metrics.ts';\nimport type {InspectorDelegate} from '../../server/inspector-delegate.ts';\nimport {type RowKey} from '../../types/row-key.ts';\nimport {type ShardID} from '../../types/shards.ts';\nimport {\n getSubscriptionState,\n ZERO_VERSION_COLUMN_NAME,\n} from '../replicator/schema/replication-state.ts';\nimport {checkClientSchema} from './client-schema.ts';\nimport {rowIDSignatureUnit} from './row-set-signature.ts';\nimport type {Snapshotter} from './snapshotter.ts';\nimport {ResetPipelinesSignal, type SnapshotDiff} from './snapshotter.ts';\n\ntype RowOp<Op extends Omit<ChangeType, ChangeType.CHILD>> = {\n readonly type: Op;\n readonly queryID: string;\n readonly table: string;\n readonly rowKey: Row;\n readonly row: Row;\n};\n\nexport type RowAdd = RowOp<ChangeType.ADD>;\n\nexport type RowRemove = RowOp<ChangeType.REMOVE>;\n\nexport type RowEdit = RowOp<ChangeType.EDIT>;\n\nexport type RowChange = RowAdd | RowRemove | RowEdit;\n\ntype CompanionPipeline = {\n readonly input: Input;\n readonly childField: string;\n readonly resolvedValue: LiteralValue | null | undefined;\n};\n\ntype Pipeline = {\n readonly input: Input;\n readonly hydrationTimeMs: number;\n readonly hydrationRowCount: number;\n readonly hydrationReason: PipelineHydrationReason;\n readonly pipelineRunID: string;\n readonly pipelineReadyAtMs: number;\n readonly transformedAst: AST;\n readonly transformationHash: string;\n readonly queryName?: string | undefined;\n readonly companions: readonly CompanionPipeline[];\n};\n\ntype QueryInfo = {\n readonly transformedAst: AST;\n readonly transformationHash: string;\n readonly queryName?: string | undefined;\n};\n\ntype QueryLogInfo = {\n readonly queryHash: string;\n readonly transformationHash: string;\n readonly queryName?: string | undefined;\n};\n\ntype QueryPipelineLifecycleEvent =\n | 'query-pipeline-hydrate-start'\n | 'query-pipeline-hydrate-finish'\n | 'query-pipeline-hydrate-failed'\n | 'query-pipeline-hydrate-aborted'\n | 'query-pipeline-stop';\n\nexport type PipelineHydrationReason =\n | 'query-set-sync'\n | 'unchanged-query-rehydrate';\n\ntype PipelineStopReason =\n | 'replace-query'\n | 'remove-query'\n | 'reset'\n | 'destroy';\n\ntype QueryPipelineLifecycleLog = {\n readonly zeroEvent: QueryPipelineLifecycleEvent;\n readonly pipelineRunID: string;\n readonly queryHash: string;\n readonly transformationHash: string;\n readonly queryName?: string | undefined;\n readonly hydrationReason?: PipelineHydrationReason | undefined;\n readonly stopReason?: PipelineStopReason | undefined;\n readonly hydrationTimeMs?: number | undefined;\n readonly hydrationRowCount?: number | undefined;\n readonly pipelineLifetimeMs?: number | undefined;\n};\n\ntype AdvanceContext = {\n readonly timer: Timer;\n readonly totalHydrationTimeMs: number;\n readonly numChanges: number;\n currentChangeStartMs: number | undefined;\n pos: number;\n};\n\ntype HydrateContext = {\n readonly timer: Timer;\n};\n\nexport type Timer = {\n elapsedLap: () => number;\n totalElapsed: () => number;\n};\n\n/**\n * No matter how fast hydration is, advancement is given at least this long to\n * complete before doing a pipeline reset.\n */\nconst MIN_ADVANCEMENT_TIME_LIMIT_MS = 50;\nconst MIN_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES = 8;\nconst PROJECTED_ADVANCEMENT_SAMPLE_FRACTION = 0.25;\nconst MAX_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES = 50;\nconst MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS = 5;\nconst MIN_PROJECTED_ADVANCEMENT_CHANGES = 16;\nconst PROJECTED_ADVANCEMENT_RESET_MULTIPLIER = 1.5;\nconst LATE_ADVANCEMENT_FINISH_PROGRESS = 0.8;\n\nfunction randomID() {\n return randInt(1, Number.MAX_SAFE_INTEGER).toString(36);\n}\n\nfunction projectedAdvancementTimeMs(\n elapsedMs: number,\n processedChanges: number,\n numChanges: number,\n): number | undefined {\n if (processedChanges <= 0 || numChanges <= 0) {\n return undefined;\n }\n return (elapsedMs / processedChanges) * numChanges;\n}\n\nfunction advancementResetTimeLimitMs(totalHydrationTimeMs: number): number {\n return Math.max(totalHydrationTimeMs, 1);\n}\n\nfunction minProjectedAdvancementSampleChanges(numChanges: number): number {\n return Math.max(\n MIN_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES,\n Math.min(\n MAX_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES,\n Math.ceil(numChanges * PROJECTED_ADVANCEMENT_SAMPLE_FRACTION),\n ),\n );\n}\n\nfunction shouldResetProjectedAdvancement(\n elapsedMs: number,\n projectedTotalTimeMs: number | undefined,\n processedChanges: number,\n numChanges: number,\n totalHydrationTimeMs: number,\n): boolean {\n if (\n projectedTotalTimeMs === undefined ||\n numChanges < MIN_PROJECTED_ADVANCEMENT_CHANGES ||\n processedChanges < minProjectedAdvancementSampleChanges(numChanges) ||\n elapsedMs < MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS\n ) {\n return false;\n }\n\n return (\n projectedTotalTimeMs >\n advancementResetTimeLimitMs(totalHydrationTimeMs) *\n PROJECTED_ADVANCEMENT_RESET_MULTIPLIER\n );\n}\n\nfunction shouldFinishLateAdvancement(\n processedChanges: number,\n numChanges: number,\n): boolean {\n return (\n numChanges > 0 &&\n processedChanges / numChanges >= LATE_ADVANCEMENT_FINISH_PROGRESS\n );\n}\n\nfunction shouldResetSlowCurrentChange(\n currentChangeElapsedMs: number,\n totalHydrationTimeMs: number,\n): boolean {\n return (\n currentChangeElapsedMs > MIN_ADVANCEMENT_TIME_LIMIT_MS &&\n currentChangeElapsedMs > advancementResetTimeLimitMs(totalHydrationTimeMs)\n );\n}\n\n/**\n * Manages the state of IVM pipelines for a given ViewSyncer (i.e. client group).\n */\nexport class PipelineDriver {\n readonly #tables = new Map<string, TableSource>();\n // Query id to pipeline\n readonly #pipelines = new Map<string, Pipeline>();\n /**\n * XOR signature of the set of rows currently attached to each active\n * query, maintained as RowChanges are yielded from {@link addQuery} and\n * {@link advance}. ADDs / REMOVEs XOR the row's unit in (XOR is\n * self-inverse, so one op serves both directions); EDITs are no-ops.\n * Hydration implicitly reseeds from `0n` because {@link addQuery} calls\n * {@link removeQuery} first, which deletes the entry.\n */\n readonly #rowSetSignatures = new Map<string, bigint>();\n\n readonly #lc: LogContext;\n readonly #snapshotter: Snapshotter;\n readonly #storage: ClientGroupStorage;\n readonly #shardID: ShardID;\n readonly #logConfig: LogConfig;\n readonly #config: ZeroConfig | undefined;\n readonly #tableSpecs = new Map<string, LiteAndZqlSpec>();\n readonly #allTableNames = new Set<string>();\n readonly #costModels: WeakMap<Database, ConnectionCostModel> | undefined;\n readonly #yieldThresholdMs: () => number;\n #streamer: Streamer | null = null;\n #hydrateContext: HydrateContext | null = null;\n #advanceContext: AdvanceContext | null = null;\n #replicaVersion: string | null = null;\n #primaryKeys: Map<string, PrimaryKey> | null = null;\n #permissions: LoadedPermissions | null = null;\n\n readonly #advanceTime = getOrCreateLatencyHistogram(\n 'sync',\n 'ivm.advance-time',\n 'Time to advance all queries for a given client group in response to a single change.',\n );\n\n readonly #conflictRowsDeleted = getOrCreateCounter(\n 'sync',\n 'ivm.conflict-rows-deleted',\n 'Number of rows deleted because they conflicted with added row',\n );\n\n readonly #inspectorDelegate: InspectorDelegate;\n\n constructor(\n lc: LogContext,\n logConfig: LogConfig,\n snapshotter: Snapshotter,\n shardID: ShardID,\n storage: ClientGroupStorage,\n clientGroupID: string,\n inspectorDelegate: InspectorDelegate,\n yieldThresholdMs: () => number,\n enablePlanner?: boolean,\n config?: ZeroConfig,\n ) {\n this.#lc = lc.withContext('clientGroupID', clientGroupID);\n this.#snapshotter = snapshotter;\n this.#storage = storage;\n this.#shardID = shardID;\n this.#logConfig = logConfig;\n this.#config = config;\n this.#inspectorDelegate = inspectorDelegate;\n this.#costModels = enablePlanner ? new WeakMap() : undefined;\n this.#yieldThresholdMs = yieldThresholdMs;\n }\n\n /**\n * Initializes the PipelineDriver to the current head of the database.\n * Queries can then be added (i.e. hydrated) with {@link addQuery()}.\n *\n * Must only be called once.\n */\n init(clientSchema: ClientSchema) {\n assert(!this.#snapshotter.initialized(), 'Already initialized');\n this.#snapshotter.init();\n this.#initAndResetCommon(clientSchema);\n }\n\n /**\n * @returns Whether the PipelineDriver has been initialized.\n */\n initialized(): boolean {\n return this.#snapshotter.initialized();\n }\n\n /**\n * Clears the current pipelines and TableSources, returning the PipelineDriver\n * to its initial state. This should be called in response to a schema change,\n * as TableSources need to be recomputed.\n */\n reset(clientSchema: ClientSchema) {\n for (const [queryID, pipeline] of this.#pipelines) {\n this.#pipelines.delete(queryID);\n this.#destroyPipeline(queryID, pipeline, 'reset');\n }\n this.#tables.clear();\n this.#allTableNames.clear();\n this.#rowSetSignatures.clear();\n this.#initAndResetCommon(clientSchema);\n }\n\n #initAndResetCommon(clientSchema: ClientSchema) {\n const {db} = this.#snapshotter.current();\n const fullTables = new Map<string, LiteTableSpec>();\n computeZqlSpecs(\n this.#lc,\n db.db,\n {includeBackfillingColumns: false},\n this.#tableSpecs,\n fullTables,\n );\n checkClientSchema(\n this.#shardID,\n clientSchema,\n this.#tableSpecs,\n fullTables,\n );\n this.#allTableNames.clear();\n for (const table of fullTables.keys()) {\n this.#allTableNames.add(table);\n }\n const primaryKeys = this.#primaryKeys ?? new Map<string, PrimaryKey>();\n this.#primaryKeys = primaryKeys;\n primaryKeys.clear();\n for (const [table, spec] of this.#tableSpecs.entries()) {\n primaryKeys.set(table, spec.tableSpec.primaryKey);\n }\n buildPrimaryKeys(clientSchema, primaryKeys);\n const {replicaVersion} = getSubscriptionState(db);\n this.#replicaVersion = replicaVersion;\n }\n\n /** @returns The replica version. The PipelineDriver must have been initialized. */\n get replicaVersion(): string {\n return must(this.#replicaVersion, 'Not yet initialized');\n }\n\n /**\n * Returns the current version of the database. This will reflect the\n * latest version change when calling {@link advance()} once the\n * iteration has begun.\n */\n currentVersion(): string {\n assert(this.initialized(), 'Not yet initialized');\n return this.#snapshotter.current().version;\n }\n\n /**\n * Returns the current upstream {app}.permissions, or `null` if none are defined.\n */\n currentPermissions(): LoadedPermissions | null {\n assert(this.initialized(), 'Not yet initialized');\n const res = reloadPermissionsIfChanged(\n this.#lc,\n this.#snapshotter.current().db,\n this.#shardID.appID,\n this.#permissions,\n this.#config,\n );\n if (res.changed) {\n this.#permissions = res.permissions;\n this.#lc.debug?.(\n 'Reloaded permissions',\n JSON.stringify(this.#permissions),\n );\n }\n return this.#permissions;\n }\n\n advanceWithoutDiff(): string {\n const {db, version} = this.#snapshotter.advanceWithoutDiff().curr;\n for (const table of this.#tables.values()) {\n table.setDB(db.db);\n }\n return version;\n }\n\n #ensureCostModelExistsIfEnabled(db: Database) {\n let existing = this.#costModels?.get(db);\n if (existing) {\n return existing;\n }\n if (this.#costModels) {\n const costModel = createSQLiteCostModel(db, this.#tableSpecs);\n this.#costModels.set(db, costModel);\n return costModel;\n }\n return undefined;\n }\n\n /**\n * Clears storage used for the pipelines. Call this when the\n * PipelineDriver will no longer be used.\n */\n destroy() {\n for (const [queryID, pipeline] of this.#pipelines) {\n this.#pipelines.delete(queryID);\n this.#destroyPipeline(queryID, pipeline, 'destroy');\n }\n this.#rowSetSignatures.clear();\n this.#storage.destroy();\n this.#snapshotter.destroy();\n }\n\n /** @return Map from query ID to PipelineInfo for all added queries. */\n queries(): ReadonlyMap<string, QueryInfo> {\n return this.#pipelines;\n }\n\n totalHydrationTimeMs(): number {\n let total = 0;\n for (const pipeline of this.#pipelines.values()) {\n total += pipeline.hydrationTimeMs;\n }\n return total;\n }\n\n #logQueryPipelineLifecycle({\n zeroEvent,\n pipelineRunID,\n queryHash,\n transformationHash,\n queryName,\n hydrationReason,\n stopReason,\n hydrationTimeMs,\n hydrationRowCount,\n pipelineLifetimeMs,\n }: QueryPipelineLifecycleLog): void {\n let lc = this.#lc\n .withContext('zeroEvent', zeroEvent)\n .withContext('pipelineRunID', pipelineRunID)\n .withContext('queryHash', queryHash)\n .withContext('transformationHash', transformationHash);\n if (queryName !== undefined) {\n lc = lc.withContext('queryName', queryName);\n }\n if (hydrationReason !== undefined) {\n lc = lc.withContext('hydrationReason', hydrationReason);\n }\n if (stopReason !== undefined) {\n lc = lc.withContext('stopReason', stopReason);\n }\n if (hydrationTimeMs !== undefined) {\n lc = lc.withContext('hydrationTimeMs', hydrationTimeMs);\n }\n if (hydrationRowCount !== undefined) {\n lc = lc.withContext('hydrationRowCount', hydrationRowCount);\n }\n if (pipelineLifetimeMs !== undefined) {\n lc = lc.withContext('pipelineLifetimeMs', pipelineLifetimeMs);\n }\n lc.info?.('query pipeline lifecycle');\n }\n\n /**\n * A `{scalar: true}` that cannot be honored degrades silently to a plain\n * EXISTS, so the author gets none of the plan they asked for and no signal\n * that they didn't. Say so, with the unique keys that were actually\n * available — the client schema knows only primary keys, so this is the only\n * place the advice can be correct.\n */\n #warnIgnoredScalarHints(queryID: string, hints: IgnoredScalarHint[]): void {\n for (const {table, uniqueKeys} of hints) {\n const keys = uniqueKeys.map(k => `(${k.join(', ')})`).join(', ');\n this.#lc.warn?.(\n `Ignoring {scalar: true} on the \"${table}\" subquery of query ` +\n `${queryID}: it does not constrain every column of any unique key ` +\n `${keys.length > 0 ? `[${keys}]` : '(none on this table)'} to a ` +\n `literal with \"=\", so it is not provably limited to one row. ` +\n `The gate runs as a plain EXISTS.`,\n );\n }\n }\n\n #resolveScalarSubqueries(ast: AST): {\n ast: AST;\n companionRows: {table: string; row: Row}[];\n companions: CompanionSubquery[];\n companionInputs: Input[];\n ignoredScalarHints: IgnoredScalarHint[];\n } {\n const companionRows: {table: string; row: Row}[] = [];\n const companionInputs: Input[] = [];\n\n const executor = (\n subqueryAST: AST,\n childField: string,\n ): LiteralValue | null | undefined => {\n const input = buildPipeline(\n subqueryAST,\n {\n getSource: name => this.#getSource(name),\n createStorage: () => this.#createStorage(),\n decorateSourceInput: (input: SourceInput): Input => input,\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n },\n 'scalar-subquery',\n );\n // Consume the full stream rather than using first() to avoid\n // triggering early return on Take's #initialFetch assertion.\n // The subquery AST already has limit: 1, so at most one row is produced.\n let node: Node | undefined;\n for (const n of skipYields(input.fetch({}))) {\n node ??= n;\n }\n if (!node) {\n // Keep the companion alive even with no results — it will\n // detect a future insert that creates the row.\n companionInputs.push(input);\n return undefined;\n }\n companionRows.push({table: subqueryAST.table, row: node.row as Row});\n companionInputs.push(input);\n return (node.row[childField] as LiteralValue) ?? null;\n };\n\n const {\n ast: resolved,\n companions,\n ignoredScalarHints,\n } = resolveSimpleScalarSubqueries(ast, this.#tableSpecs, executor);\n return {\n ast: resolved,\n companionRows,\n companions,\n companionInputs,\n ignoredScalarHints,\n };\n }\n\n /**\n * Adds a pipeline for the query. The method will hydrate the query using the\n * driver's current snapshot of the database and return a stream of results.\n * Henceforth, updates to the query will be returned when the driver is\n * {@link advance}d. The query and its pipeline can be removed with\n * {@link removeQuery()}.\n *\n * If a query with the same queryID is already added, the existing pipeline\n * will be removed and destroyed before adding the new pipeline.\n *\n * @param timer The caller-controlled {@link Timer} used to determine the\n * final hydration time. (The caller may pause and resume the timer\n * when yielding the thread for time-slicing).\n * @return The rows from the initial hydration of the query.\n */\n addQuery(\n transformationHash: string,\n queryID: string,\n query: AST,\n timer: Timer,\n queryName?: string,\n hydrationReason: PipelineHydrationReason = 'query-set-sync',\n ): Iterable<RowChange | 'yield'> {\n return this.#trackRowSetSignatures(\n this.#addQueryImpl(\n transformationHash,\n queryID,\n query,\n timer,\n queryName,\n hydrationReason,\n ),\n );\n }\n\n *#addQueryImpl(\n transformationHash: string,\n queryID: string,\n query: AST,\n timer: Timer,\n queryName?: string,\n hydrationReason: PipelineHydrationReason = 'query-set-sync',\n ): Iterable<RowChange | 'yield'> {\n assert(\n this.initialized(),\n 'Pipeline driver must be initialized before adding queries',\n );\n this.removeQuery(queryID, 'replace-query');\n const pipelineRunID = randomID();\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-hydrate-start',\n pipelineRunID,\n queryHash: queryID,\n transformationHash,\n queryName,\n hydrationReason,\n });\n const debugDelegate = runtimeDebugFlags.trackRowsVended\n ? new Debug()\n : undefined;\n\n const costModel = this.#ensureCostModelExistsIfEnabled(\n this.#snapshotter.current().db.db,\n );\n\n assert(\n this.#advanceContext === null,\n 'Cannot hydrate while advance is in progress',\n );\n this.#hydrateContext = {\n timer,\n };\n let hydrationFinished = false;\n let hydrationFailed = false;\n let hydrationRowCount = 0;\n try {\n const {\n ast: resolvedQuery,\n companionRows,\n companions: companionMeta,\n companionInputs,\n ignoredScalarHints,\n } = this.#resolveScalarSubqueries(query);\n\n this.#warnIgnoredScalarHints(queryID, ignoredScalarHints);\n\n const input = buildPipeline(\n resolvedQuery,\n {\n debug: debugDelegate,\n enableNotExists: true, // Server-side can handle NOT EXISTS\n getSource: name => this.#getSource(name),\n createStorage: () => this.#createStorage(),\n decorateSourceInput: (input: SourceInput, _queryID: string): Input =>\n new MeasurePushOperator(\n new QueryFailureLoggingOperator(\n this.#lc,\n input,\n queryID,\n transformationHash,\n queryName,\n ),\n queryID,\n this.#inspectorDelegate,\n 'query-update-server',\n ),\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n },\n queryID,\n costModel,\n );\n const schema = input.getSchema();\n input.setOutput({\n push: change => {\n const streamer = this.#streamer;\n assert(streamer, 'must #startAccumulating() before pushing changes');\n streamer.accumulate(queryID, schema, [change]);\n return [];\n },\n });\n\n for (const change of hydrateInternal(\n input,\n queryID,\n must(this.#primaryKeys),\n this.#tableSpecs,\n )) {\n if (change !== 'yield') {\n hydrationRowCount++;\n }\n yield change;\n }\n\n for (const {table, row} of companionRows) {\n const primaryKey = mustGetPrimaryKey(this.#primaryKeys, table);\n hydrationRowCount++;\n yield {\n type: ChangeType.ADD,\n queryID,\n table,\n rowKey: getRowKey(primaryKey, row),\n row,\n } as RowChange;\n }\n\n const hydrationTimeMs = timer.totalElapsed();\n if (runtimeDebugFlags.trackRowCountsVended) {\n if (hydrationTimeMs > this.#logConfig.slowHydrateThreshold) {\n let totalRowsConsidered = 0;\n const lc = this.#lc\n .withContext('queryID', queryID)\n .withContext('hydrationTimeMs', hydrationTimeMs);\n for (const tableName of this.#tables.keys()) {\n const entries = Object.entries(\n debugDelegate?.getVendedRowCounts()[tableName] ?? {},\n );\n totalRowsConsidered += entries.reduce(\n (acc, entry) => acc + entry[1],\n 0,\n );\n lc.info?.(tableName + ' VENDED: ', entries);\n }\n lc.info?.(`Total rows considered: ${totalRowsConsidered}`);\n }\n }\n debugDelegate?.reset();\n\n // Set up live companion pipelines for reactive scalar subquery monitoring.\n const liveCompanions: CompanionPipeline[] = [];\n for (let i = 0; i < companionMeta.length; i++) {\n const meta = companionMeta[i];\n const companionInput = companionInputs[i];\n const companionSchema = companionInput.getSchema();\n const {childField, resolvedValue} = meta;\n companionInput.setOutput({\n push: (change: Change) => {\n let newValue: LiteralValue | null | undefined;\n switch (change[ChangeIndex.TYPE]) {\n case ChangeType.ADD:\n case ChangeType.EDIT:\n newValue =\n (change[ChangeIndex.NODE].row[childField] as LiteralValue) ??\n null;\n break;\n case ChangeType.REMOVE:\n newValue = undefined;\n break;\n case ChangeType.CHILD:\n return [];\n }\n if (!scalarValuesEqual(newValue, resolvedValue)) {\n throw new ResetPipelinesSignal(\n `Scalar subquery value changed for ${meta.ast.table}: ` +\n `${String(resolvedValue)} -> ${String(newValue)}`,\n 'scalar-subquery',\n );\n }\n const streamer = this.#streamer;\n assert(\n streamer,\n 'must #startAccumulating() before pushing changes',\n );\n streamer.accumulate(queryID, companionSchema, [change]);\n return [];\n },\n });\n liveCompanions.push({input: companionInput, childField, resolvedValue});\n }\n\n // Note: This hydrationTime is a wall-clock overestimate, as it does\n // not take time slicing into account. The view-syncer resets this\n // to a more precise processing-time measurement with setHydrationTime().\n const pipelineReadyAtMs = Date.now();\n this.#pipelines.set(queryID, {\n input,\n hydrationTimeMs,\n hydrationRowCount,\n hydrationReason,\n pipelineRunID,\n pipelineReadyAtMs,\n transformedAst: resolvedQuery,\n transformationHash,\n ...(queryName !== undefined && {queryName}),\n companions: liveCompanions,\n });\n hydrationFinished = true;\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-hydrate-finish',\n pipelineRunID,\n queryHash: queryID,\n transformationHash,\n queryName,\n hydrationReason,\n hydrationTimeMs,\n hydrationRowCount,\n });\n } catch (e) {\n hydrationFailed = true;\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-hydrate-failed',\n pipelineRunID,\n queryHash: queryID,\n transformationHash,\n queryName,\n hydrationReason,\n hydrationTimeMs: timer.totalElapsed(),\n hydrationRowCount,\n });\n logQueryFailure(\n this.#lc,\n {queryHash: queryID, transformationHash, queryName},\n 'query hydration failed',\n e,\n );\n throw e;\n } finally {\n if (!hydrationFinished && !hydrationFailed) {\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-hydrate-aborted',\n pipelineRunID,\n queryHash: queryID,\n transformationHash,\n queryName,\n hydrationReason,\n hydrationTimeMs: timer.totalElapsed(),\n hydrationRowCount,\n });\n }\n this.#hydrateContext = null;\n }\n }\n\n /**\n * Removes the pipeline for the query. This is a no-op if the query\n * was not added.\n */\n removeQuery(\n queryID: string,\n stopReason: PipelineStopReason = 'remove-query',\n ) {\n const pipeline = this.#pipelines.get(queryID);\n if (pipeline) {\n this.#pipelines.delete(queryID);\n this.#destroyPipeline(queryID, pipeline, stopReason);\n }\n this.#rowSetSignatures.delete(queryID);\n }\n\n #destroyPipeline(\n queryID: string,\n pipeline: Pipeline,\n stopReason: PipelineStopReason,\n ): void {\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-stop',\n pipelineRunID: pipeline.pipelineRunID,\n queryHash: queryID,\n transformationHash: pipeline.transformationHash,\n queryName: pipeline.queryName,\n hydrationReason: pipeline.hydrationReason,\n stopReason,\n hydrationTimeMs: pipeline.hydrationTimeMs,\n hydrationRowCount: pipeline.hydrationRowCount,\n pipelineLifetimeMs: Date.now() - pipeline.pipelineReadyAtMs,\n });\n pipeline.input.destroy();\n for (const companion of pipeline.companions) {\n companion.input.destroy();\n }\n }\n\n /**\n * Current XOR signature of the row-set attached to `queryID`, or\n * `undefined` if no pipeline for the query is currently active.\n * Maintained incrementally by {@link addQuery} and {@link advance}.\n */\n rowSetSignature(queryID: string): bigint | undefined {\n return this.#rowSetSignatures.get(queryID);\n }\n\n /**\n * Wraps an iterable of RowChanges, XORing each row's unit hash into the\n * query's signature (ADDs and REMOVEs share the same op; EDITs are no-ops).\n * Used to intercept the yield streams from {@link addQuery} and\n * {@link advance}.\n */\n *#trackRowSetSignatures(\n changes: Iterable<RowChange | 'yield'>,\n ): Iterable<RowChange | 'yield'> {\n for (const change of changes) {\n if (change !== 'yield' && change.type !== ChangeType.EDIT) {\n const cur = this.#rowSetSignatures.get(change.queryID) ?? 0n;\n const unit = rowIDSignatureUnit({\n schema: '',\n table: change.table,\n rowKey: change.rowKey as RowKey,\n });\n this.#rowSetSignatures.set(change.queryID, cur ^ unit);\n }\n yield change;\n }\n }\n\n /**\n * Returns the value of the row with the given primary key `pk`,\n * or `undefined` if there is no such row. The pipeline must have been\n * initialized.\n */\n getRow(table: string, pk: RowKey): Row | undefined {\n assert(this.initialized(), 'Not yet initialized');\n const source = must(this.#tables.get(table));\n return source.getRow(pk as Row);\n }\n\n /**\n * Advances to the new head of the database.\n *\n * @param timer The caller-controlled {@link Timer} that will be used to\n * measure the progress of the advancement and abort with a\n * {@link ResetPipelinesSignal} if it is estimated to take longer\n * than a hydration.\n * @return The resulting row changes for all added queries. Note that the\n * `changes` must be iterated over in their entirety in order to\n * advance the database snapshot.\n */\n advance(timer: Timer): {\n version: string;\n numChanges: number;\n changes: Iterable<RowChange | 'yield'>;\n } {\n assert(\n this.initialized(),\n 'Pipeline driver must be initialized before advancing',\n );\n const diff = this.#snapshotter.advance(\n this.#tableSpecs,\n this.#allTableNames,\n );\n const {prev, curr, changes} = diff;\n this.#lc.debug?.(\n `advance ${prev.version} => ${curr.version}: ${changes} changes`,\n );\n\n return {\n version: curr.version,\n numChanges: changes,\n changes: this.#trackRowSetSignatures(this.#advance(diff, timer, changes)),\n };\n }\n\n *#advance(\n diff: SnapshotDiff,\n timer: Timer,\n numChanges: number,\n ): Iterable<RowChange | 'yield'> {\n assert(\n this.#hydrateContext === null,\n 'Cannot advance while hydration is in progress',\n );\n const totalHydrationTimeMs = this.totalHydrationTimeMs();\n this.#advanceContext = {\n timer,\n totalHydrationTimeMs,\n numChanges,\n currentChangeStartMs: undefined,\n pos: 0,\n };\n this.#lc.debug?.(\n `starting pipeline advancement of ${numChanges} changes with an ` +\n `advancement time limited based on total hydration time of ` +\n `${totalHydrationTimeMs} ms.`,\n );\n try {\n for (const {table, prevValues, nextValue} of diff) {\n // Advance progress is checked each time a row is fetched\n // from a TableSource during push processing, but some pushes\n // don't read any rows. Check progress here before processing\n // the next change.\n if (this.#shouldAdvanceYieldMaybeAbortAdvance()) {\n yield 'yield';\n }\n const start = timer.totalElapsed();\n const advanceContext = must(this.#advanceContext);\n advanceContext.currentChangeStartMs = start;\n\n let type;\n try {\n try {\n const tableSource = this.#tables.get(table);\n if (!tableSource) {\n // no pipelines read from this table, so no need to process the change\n continue;\n }\n const primaryKey = mustGetPrimaryKey(this.#primaryKeys, table);\n let editOldRow: Row | undefined = undefined;\n for (const prevValue of prevValues) {\n if (\n nextValue &&\n deepEqual(\n getRowKey(primaryKey, prevValue as Row) as JSONValue,\n getRowKey(primaryKey, nextValue as Row) as JSONValue,\n )\n ) {\n editOldRow = prevValue;\n } else {\n if (nextValue) {\n this.#conflictRowsDeleted.add(1);\n }\n yield* this.#push(\n tableSource,\n makeSourceChangeRemove(prevValue as Row),\n );\n }\n }\n if (nextValue) {\n if (editOldRow) {\n yield* this.#push(\n tableSource,\n makeSourceChangeEdit(nextValue as Row, editOldRow),\n );\n } else {\n yield* this.#push(\n tableSource,\n makeSourceChangeAdd(nextValue as Row),\n );\n }\n }\n } finally {\n advanceContext.pos++;\n }\n\n this.#shouldAdvanceYieldMaybeAbortAdvance(false);\n } finally {\n advanceContext.currentChangeStartMs = undefined;\n }\n\n const elapsed = timer.totalElapsed() - start;\n this.#advanceTime.recordMs(elapsed, {\n table,\n type,\n });\n }\n\n // Set the new snapshot on all TableSources.\n const {curr} = diff;\n for (const table of this.#tables.values()) {\n table.setDB(curr.db.db);\n }\n this.#ensureCostModelExistsIfEnabled(curr.db.db);\n this.#lc.debug?.(`Advanced to ${curr.version}`);\n } finally {\n this.#advanceContext = null;\n }\n }\n\n /** Implements `BuilderDelegate.getSource()` */\n #getSource(tableName: string): Source {\n let source = this.#tables.get(tableName);\n if (source) {\n return source;\n }\n\n const tableSpec = mustGetTableSpec(this.#tableSpecs, tableName);\n const primaryKey = mustGetPrimaryKey(this.#primaryKeys, tableName);\n\n const {db} = this.#snapshotter.current();\n source = new TableSource(\n this.#lc,\n this.#logConfig,\n db.db,\n tableName,\n tableSpec.zqlSpec,\n primaryKey,\n () => this.#shouldYield(),\n );\n this.#tables.set(tableName, source);\n this.#lc.debug?.(`created TableSource for ${tableName}`);\n return source;\n }\n\n #shouldYield(): boolean {\n if (this.#hydrateContext) {\n return this.#hydrateContext.timer.elapsedLap() > this.#yieldThresholdMs();\n }\n if (this.#advanceContext) {\n return this.#shouldAdvanceYieldMaybeAbortAdvance();\n }\n throw new Error('shouldYield called outside of hydration or advancement');\n }\n\n /**\n * Cancel advancement processing when either the whole batch projects to be\n * more expensive than hydration, or the current source change alone exceeds\n * the hydration budget. The late-finish exception only applies to batch-level\n * checks; a single pathological push always resets.\n */\n #shouldAdvanceYieldMaybeAbortAdvance(checkYield = true): boolean {\n const {\n currentChangeStartMs,\n pos,\n numChanges,\n timer: advanceTimer,\n totalHydrationTimeMs,\n } = must(this.#advanceContext);\n const elapsed = advanceTimer.totalElapsed();\n const currentChangeElapsedMs =\n currentChangeStartMs === undefined\n ? undefined\n : elapsed - currentChangeStartMs;\n if (\n currentChangeElapsedMs !== undefined &&\n shouldResetSlowCurrentChange(currentChangeElapsedMs, totalHydrationTimeMs)\n ) {\n this.#throwSlowCurrentChangeReset(\n pos,\n numChanges,\n elapsed,\n currentChangeElapsedMs,\n totalHydrationTimeMs,\n );\n }\n const projectedTotalTimeMs = projectedAdvancementTimeMs(\n elapsed,\n pos,\n numChanges,\n );\n const shouldFinish = shouldFinishLateAdvancement(pos, numChanges);\n if (\n !shouldFinish &&\n shouldResetProjectedAdvancement(\n elapsed,\n projectedTotalTimeMs,\n pos,\n numChanges,\n totalHydrationTimeMs,\n )\n ) {\n this.#throwProjectedAdvancementReset(\n pos,\n numChanges,\n elapsed,\n projectedTotalTimeMs,\n totalHydrationTimeMs,\n );\n }\n if (\n !shouldFinish &&\n elapsed > MIN_ADVANCEMENT_TIME_LIMIT_MS &&\n (elapsed > totalHydrationTimeMs ||\n (elapsed > totalHydrationTimeMs / 2 && pos <= numChanges / 2))\n ) {\n throw new ResetPipelinesSignal(\n `Advancement exceeded timeout at ${pos} of ${numChanges} changes ` +\n `after ${elapsed} ms. Advancement time limited based on total ` +\n `hydration time of ${totalHydrationTimeMs} ms.`,\n 'advancement-timeout',\n );\n }\n return checkYield && advanceTimer.elapsedLap() > this.#yieldThresholdMs();\n }\n\n #throwSlowCurrentChangeReset(\n pos: number,\n numChanges: number,\n elapsed: number,\n currentChangeElapsedMs: number,\n totalHydrationTimeMs: number,\n ): never {\n throw new ResetPipelinesSignal(\n `Advancement exceeded timeout processing current change at ${pos} of ` +\n `${numChanges} changes after ${currentChangeElapsedMs} ms ` +\n `(${elapsed} ms total). Advancement time limited based on total ` +\n `hydration time of ${totalHydrationTimeMs} ms.`,\n 'advancement-timeout',\n );\n }\n\n #throwProjectedAdvancementReset(\n pos: number,\n numChanges: number,\n elapsed: number,\n projectedTotalTimeMs: number | undefined,\n totalHydrationTimeMs: number,\n ): never {\n const projection =\n projectedTotalTimeMs === undefined\n ? ''\n : ` Projected total advancement time is ${projectedTotalTimeMs} ms.`;\n throw new ResetPipelinesSignal(\n `Advancement projected to exceed hydration time at ${pos} of ` +\n `${numChanges} changes after ${elapsed} ms.` +\n projection +\n ` Advancement time limited based on total hydration time of ` +\n `${totalHydrationTimeMs} ms.`,\n 'advancement-timeout',\n );\n }\n\n /** Implements `BuilderDelegate.createStorage()` */\n #createStorage(): Storage {\n return this.#storage.createStorage();\n }\n\n *#push(\n source: TableSource,\n change: SourceChange,\n ): Iterable<RowChange | 'yield'> {\n this.#startAccumulating();\n try {\n for (const val of source.genPush(change)) {\n if (val === 'yield') {\n yield 'yield';\n }\n for (const changeOrYield of this.#stopAccumulating().stream()) {\n yield changeOrYield;\n }\n this.#startAccumulating();\n }\n } finally {\n if (this.#streamer !== null) {\n this.#stopAccumulating();\n }\n }\n }\n\n #startAccumulating() {\n assert(this.#streamer === null, 'Streamer already started');\n this.#streamer = new Streamer(\n must(this.#primaryKeys),\n this.#tableSpecs,\n (queryID, error) =>\n this.#logQueryFailure(queryID, 'query pipeline failed', error),\n );\n }\n\n #stopAccumulating(): Streamer {\n const streamer = this.#streamer;\n assert(streamer, 'Streamer not started');\n this.#streamer = null;\n return streamer;\n }\n\n #logQueryFailure(queryID: string, message: string, error: unknown): void {\n const pipeline = this.#pipelines.get(queryID);\n const queryInfo = pipeline\n ? {\n queryHash: queryID,\n transformationHash: pipeline.transformationHash,\n queryName: pipeline.queryName,\n }\n : undefined;\n logQueryFailure(this.#lc, queryInfo, message, error);\n }\n}\n\nclass Streamer {\n readonly #primaryKeys: Map<string, PrimaryKey>;\n readonly #tableSpecs: Map<string, LiteAndZqlSpec>;\n readonly #logQueryFailure:\n | ((queryID: string, error: unknown) => void)\n | undefined;\n\n constructor(\n primaryKeys: Map<string, PrimaryKey>,\n tableSpecs: Map<string, LiteAndZqlSpec>,\n logQueryFailure?: (queryID: string, error: unknown) => void,\n ) {\n this.#primaryKeys = primaryKeys;\n this.#tableSpecs = tableSpecs;\n this.#logQueryFailure = logQueryFailure;\n }\n\n readonly #changes: [\n queryID: string,\n schema: SourceSchema,\n changes: Iterable<Change | 'yield'>,\n ][] = [];\n\n accumulate(\n queryID: string,\n schema: SourceSchema,\n changes: Iterable<Change | 'yield'>,\n ): this {\n this.#changes.push([queryID, schema, changes]);\n return this;\n }\n\n *stream(): Iterable<RowChange | 'yield'> {\n for (const [queryID, schema, changes] of this.#changes) {\n try {\n yield* this.#streamChanges(queryID, schema, changes);\n } catch (e) {\n this.#logQueryFailure?.(queryID, e);\n throw e;\n }\n }\n }\n\n *#streamChanges(\n queryID: string,\n schema: SourceSchema,\n changes: Iterable<Change | 'yield'>,\n ): Iterable<RowChange | 'yield'> {\n // We do not sync rows gathered by the permissions\n // system to the client.\n if (schema.system === 'permissions') {\n return;\n }\n\n for (const change of changes) {\n if (change === 'yield') {\n yield change;\n continue;\n }\n const type = change[ChangeIndex.TYPE];\n switch (type) {\n case ChangeType.REMOVE:\n case ChangeType.ADD: {\n yield* this.#streamNodes(queryID, schema, type, () => [\n change[ChangeIndex.NODE],\n ]);\n break;\n }\n\n case ChangeType.CHILD: {\n const child = change[ChangeIndex.CHILD_DATA];\n const childSchema = must(\n schema.relationships[child.relationshipName],\n );\n\n yield* this.#streamChanges(queryID, childSchema, [child.change]);\n break;\n }\n case ChangeType.EDIT:\n yield* this.#streamNodes(queryID, schema, type, () => [\n {row: change[ChangeIndex.NODE].row, relationships: {}},\n ]);\n break;\n default:\n unreachable(change[ChangeIndex.TYPE]);\n }\n }\n }\n\n *#streamNodes(\n queryID: string,\n schema: SourceSchema,\n op: ChangeType.ADD | ChangeType.REMOVE | ChangeType.EDIT,\n nodes: () => Iterable<Node | 'yield'>,\n ): Iterable<RowChange | 'yield'> {\n const {tableName: table, system} = schema;\n\n const primaryKey = must(this.#primaryKeys.get(table));\n const spec = must(this.#tableSpecs.get(table)).tableSpec;\n\n // We do not sync rows gathered by the permissions\n // system to the client.\n if (system === 'permissions') {\n return;\n }\n\n for (const node of nodes()) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n const {relationships} = node;\n let {row} = node;\n const rowKey = getRowKey(primaryKey, row);\n if (op !== ChangeType.REMOVE) {\n const rowVersion = row[ZERO_VERSION_COLUMN_NAME];\n if (\n typeof rowVersion === 'string' &&\n rowVersion < (spec.minRowVersion ?? '00')\n ) {\n row = {...row, [ZERO_VERSION_COLUMN_NAME]: spec.minRowVersion};\n }\n }\n\n yield {\n type: op,\n queryID,\n table,\n rowKey,\n row: op === ChangeType.REMOVE ? undefined : row,\n } as RowChange;\n\n for (const [relationship, children] of Object.entries(relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n yield* this.#streamNodes(queryID, childSchema, op, children);\n }\n }\n }\n}\n\nclass QueryFailureLoggingOperator implements Input, Output {\n readonly #lc: LogContext;\n readonly #input: Input;\n readonly #queryHash: string;\n readonly #transformationHash: string;\n readonly #queryName: string | undefined;\n #output: Output = throwOutput;\n\n constructor(\n lc: LogContext,\n input: Input,\n queryHash: string,\n transformationHash: string,\n queryName?: string,\n ) {\n this.#lc = lc;\n this.#input = input;\n this.#queryHash = queryHash;\n this.#transformationHash = transformationHash;\n this.#queryName = queryName;\n input.setOutput(this);\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n fetch(req: FetchRequest): Iterable<Node | 'yield'> {\n return this.#input.fetch(req);\n }\n\n *push(change: Change): Iterable<'yield'> {\n try {\n yield* this.#output.push(change, this);\n } catch (e) {\n logQueryFailure(\n this.#lc,\n {\n queryHash: this.#queryHash,\n transformationHash: this.#transformationHash,\n queryName: this.#queryName,\n },\n 'query pipeline failed',\n e,\n );\n throw e;\n }\n }\n}\n\nfunction logQueryFailure(\n lc: LogContext,\n queryInfo: QueryLogInfo | undefined,\n message: string,\n error: unknown,\n): void {\n if (error instanceof ResetPipelinesSignal) {\n return;\n }\n let queryLC = lc;\n if (queryInfo) {\n queryLC = queryLC\n .withContext('queryHash', queryInfo.queryHash)\n .withContext('transformationHash', queryInfo.transformationHash);\n if (queryInfo.queryName !== undefined) {\n queryLC = queryLC.withContext('queryName', queryInfo.queryName);\n }\n }\n queryLC.error?.(message, error);\n}\n\nfunction* toAdds(nodes: Iterable<Node | 'yield'>): Iterable<Change | 'yield'> {\n for (const node of nodes) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n yield [ChangeType.ADD, node, null];\n }\n}\n\nfunction getRowKey(cols: PrimaryKey, row: Row): RowKey {\n return Object.fromEntries(cols.map(col => [col, must(row[col])]));\n}\n\n/**\n * Core hydration logic used by {@link PipelineDriver#addQuery}, extracted to a\n * function for reuse by the analyze-query RPC path so that analysis hydrates\n * queries the same way the view-syncer does in production.\n */\nexport function* hydrate(\n input: Input,\n hash: string,\n clientSchema: ClientSchema,\n tableSpecs: Map<string, LiteAndZqlSpec>,\n): Iterable<RowChange | 'yield'> {\n const res = input.fetch({});\n const streamer = new Streamer(\n buildPrimaryKeys(clientSchema),\n tableSpecs,\n ).accumulate(hash, input.getSchema(), toAdds(res));\n yield* streamer.stream();\n}\n\nexport function* hydrateInternal(\n input: Input,\n hash: string,\n primaryKeys: Map<string, PrimaryKey>,\n tableSpecs: Map<string, LiteAndZqlSpec>,\n): Iterable<RowChange | 'yield'> {\n const res = input.fetch({});\n const streamer = new Streamer(primaryKeys, tableSpecs).accumulate(\n hash,\n input.getSchema(),\n toAdds(res),\n );\n yield* streamer.stream();\n}\n\nfunction buildPrimaryKeys(\n clientSchema: ClientSchema,\n primaryKeys: Map<string, PrimaryKey> = new Map<string, PrimaryKey>(),\n) {\n for (const [tableName, {primaryKey}] of Object.entries(clientSchema.tables)) {\n primaryKeys.set(tableName, primaryKey as unknown as PrimaryKey);\n }\n return primaryKeys;\n}\n\nfunction mustGetPrimaryKey(\n primaryKeys: Map<string, PrimaryKey> | null,\n table: string,\n): PrimaryKey {\n const pKeys = must(primaryKeys, 'primaryKey map must be non-null');\n\n const rv = pKeys.get(table);\n assert(\n rv,\n () =>\n // oxlint-disable-next-line e18e/prefer-array-to-sorted\n `table '${table}' is not one of: ${[...pKeys.keys()].sort()}. ` +\n `Check the spelling and ensure that the table has a primary key.`,\n );\n return rv;\n}\n\n/**\n * Compares two scalar subquery resolved values for equality.\n * Unlike `valuesEqual` in data.ts (which treats null != null for join\n * semantics), this uses identity semantics: undefined === undefined\n * (no row matched), null === null (row matched but field was NULL).\n */\nfunction scalarValuesEqual(\n a: LiteralValue | null | undefined,\n b: LiteralValue | null | undefined,\n): boolean {\n return a === b;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAuKA,IAAM,gCAAgC;AACtC,IAAM,2CAA2C;AACjD,IAAM,wCAAwC;AAC9C,IAAM,2CAA2C;AACjD,IAAM,sCAAsC;AAC5C,IAAM,oCAAoC;AAC1C,IAAM,yCAAyC;AAC/C,IAAM,mCAAmC;AAEzC,SAAS,WAAW;CAClB,OAAO,QAAQ,GAAG,OAAO,gBAAgB,EAAE,SAAS,EAAE;AACxD;AAEA,SAAS,2BACP,WACA,kBACA,YACoB;CACpB,IAAI,oBAAoB,KAAK,cAAc,GACzC;CAEF,OAAQ,YAAY,mBAAoB;AAC1C;AAEA,SAAS,4BAA4B,sBAAsC;CACzE,OAAO,KAAK,IAAI,sBAAsB,CAAC;AACzC;AAEA,SAAS,qCAAqC,YAA4B;CACxE,OAAO,KAAK,IACV,0CACA,KAAK,IACH,0CACA,KAAK,KAAK,aAAa,qCAAqC,CAC9D,CACF;AACF;AAEA,SAAS,gCACP,WACA,sBACA,kBACA,YACA,sBACS;CACT,IACE,yBAAyB,KAAA,KACzB,aAAa,qCACb,mBAAmB,qCAAqC,UAAU,KAClE,YAAY,qCAEZ,OAAO;CAGT,OACE,uBACA,4BAA4B,oBAAoB,IAC9C;AAEN;AAEA,SAAS,4BACP,kBACA,YACS;CACT,OACE,aAAa,KACb,mBAAmB,cAAc;AAErC;AAEA,SAAS,6BACP,wBACA,sBACS;CACT,OACE,yBAAyB,iCACzB,yBAAyB,4BAA4B,oBAAoB;AAE7E;;;;AAKA,IAAa,iBAAb,MAA4B;CAC1B,0BAAmB,IAAI,IAAyB;CAEhD,6BAAsB,IAAI,IAAsB;;;;;;;;;CAShD,oCAA6B,IAAI,IAAoB;CAErD;CACA;CACA;CACA;CACA;CACA;CACA,8BAAuB,IAAI,IAA4B;CACvD,iCAA0B,IAAI,IAAY;CAC1C;CACA;CACA,YAA6B;CAC7B,kBAAyC;CACzC,kBAAyC;CACzC,kBAAiC;CACjC,eAA+C;CAC/C,eAAyC;CAEzC,eAAwB,4BACtB,QACA,oBACA,sFACF;CAEA,uBAAgC,mBAC9B,QACA,6BACA,+DACF;CAEA;CAEA,YACE,IACA,WACA,aACA,SACA,SACA,eACA,mBACA,kBACA,eACA,QACA;EACA,KAAKG,MAAM,GAAG,YAAY,iBAAiB,aAAa;EACxD,KAAKC,eAAe;EACpB,KAAKC,WAAW;EAChB,KAAKC,WAAW;EAChB,KAAKC,aAAa;EAClB,KAAKC,UAAU;EACf,KAAKO,qBAAqB;EAC1B,KAAKJ,cAAc,gCAAgB,IAAI,QAAQ,IAAI,KAAA;EACnD,KAAKC,oBAAoB;CAC3B;;;;;;;CAQA,KAAK,cAA4B;EAC/B,OAAO,CAAC,KAAKR,aAAa,YAAY,GAAG,qBAAqB;EAC9D,KAAKA,aAAa,KAAK;EACvB,KAAKY,oBAAoB,YAAY;CACvC;;;;CAKA,cAAuB;EACrB,OAAO,KAAKZ,aAAa,YAAY;CACvC;;;;;;CAOA,MAAM,cAA4B;EAChC,KAAK,MAAM,CAAC,SAAS,aAAa,KAAKH,YAAY;GACjD,KAAKA,WAAW,OAAO,OAAO;GAC9B,KAAKgB,iBAAiB,SAAS,UAAU,OAAO;EAClD;EACA,KAAKjB,QAAQ,MAAM;EACnB,KAAKU,eAAe,MAAM;EAC1B,KAAKR,kBAAkB,MAAM;EAC7B,KAAKc,oBAAoB,YAAY;CACvC;CAEA,oBAAoB,cAA4B;EAC9C,MAAM,EAAC,OAAM,KAAKZ,aAAa,QAAQ;EACvC,MAAM,6BAAa,IAAI,IAA2B;EAClD,gBACE,KAAKD,KACL,GAAG,IACH,EAAC,2BAA2B,MAAK,GACjC,KAAKM,aACL,UACF;EACA,kBACE,KAAKH,UACL,cACA,KAAKG,aACL,UACF;EACA,KAAKC,eAAe,MAAM;EAC1B,KAAK,MAAM,SAAS,WAAW,KAAK,GAClC,KAAKA,eAAe,IAAI,KAAK;EAE/B,MAAM,cAAc,KAAKQ,gCAAgB,IAAI,IAAwB;EACrE,KAAKA,eAAe;EACpB,YAAY,MAAM;EAClB,KAAK,MAAM,CAAC,OAAO,SAAS,KAAKT,YAAY,QAAQ,GACnD,YAAY,IAAI,OAAO,KAAK,UAAU,UAAU;EAElD,iBAAiB,cAAc,WAAW;EAC1C,MAAM,EAAC,mBAAkB,qBAAqB,EAAE;EAChD,KAAKU,kBAAkB;CACzB;;CAGA,IAAI,iBAAyB;EAC3B,OAAO,KAAK,KAAKA,iBAAiB,qBAAqB;CACzD;;;;;;CAOA,iBAAyB;EACvB,OAAO,KAAK,YAAY,GAAG,qBAAqB;EAChD,OAAO,KAAKf,aAAa,QAAQ,EAAE;CACrC;;;;CAKA,qBAA+C;EAC7C,OAAO,KAAK,YAAY,GAAG,qBAAqB;EAChD,MAAM,MAAM,2BACV,KAAKD,KACL,KAAKC,aAAa,QAAQ,EAAE,IAC5B,KAAKE,SAAS,OACd,KAAKc,cACL,KAAKZ,OACP;EACA,IAAI,IAAI,SAAS;GACf,KAAKY,eAAe,IAAI;GACxB,KAAKjB,IAAI,QACP,wBACA,KAAK,UAAU,KAAKiB,YAAY,CAClC;EACF;EACA,OAAO,KAAKA;CACd;CAEA,qBAA6B;EAC3B,MAAM,EAAC,IAAI,YAAW,KAAKhB,aAAa,mBAAmB,EAAE;EAC7D,KAAK,MAAM,SAAS,KAAKJ,QAAQ,OAAO,GACtC,MAAM,MAAM,GAAG,EAAE;EAEnB,OAAO;CACT;CAEA,gCAAgC,IAAc;EAC5C,IAAI,WAAW,KAAKW,aAAa,IAAI,EAAE;EACvC,IAAI,UACF,OAAO;EAET,IAAI,KAAKA,aAAa;GACpB,MAAM,YAAY,sBAAsB,IAAI,KAAKF,WAAW;GAC5D,KAAKE,YAAY,IAAI,IAAI,SAAS;GAClC,OAAO;EACT;CAEF;;;;;CAMA,UAAU;EACR,KAAK,MAAM,CAAC,SAAS,aAAa,KAAKV,YAAY;GACjD,KAAKA,WAAW,OAAO,OAAO;GAC9B,KAAKgB,iBAAiB,SAAS,UAAU,SAAS;EACpD;EACA,KAAKf,kBAAkB,MAAM;EAC7B,KAAKG,SAAS,QAAQ;EACtB,KAAKD,aAAa,QAAQ;CAC5B;;CAGA,UAA0C;EACxC,OAAO,KAAKH;CACd;CAEA,uBAA+B;EAC7B,IAAI,QAAQ;EACZ,KAAK,MAAM,YAAY,KAAKA,WAAW,OAAO,GAC5C,SAAS,SAAS;EAEpB,OAAO;CACT;CAEA,2BAA2B,EACzB,WACA,eACA,WACA,oBACA,WACA,iBACA,YACA,iBACA,mBACA,sBACkC;EAClC,IAAI,KAAK,KAAKE,IACX,YAAY,aAAa,SAAS,EAClC,YAAY,iBAAiB,aAAa,EAC1C,YAAY,aAAa,SAAS,EAClC,YAAY,sBAAsB,kBAAkB;EACvD,IAAI,cAAc,KAAA,GAChB,KAAK,GAAG,YAAY,aAAa,SAAS;EAE5C,IAAI,oBAAoB,KAAA,GACtB,KAAK,GAAG,YAAY,mBAAmB,eAAe;EAExD,IAAI,eAAe,KAAA,GACjB,KAAK,GAAG,YAAY,cAAc,UAAU;EAE9C,IAAI,oBAAoB,KAAA,GACtB,KAAK,GAAG,YAAY,mBAAmB,eAAe;EAExD,IAAI,sBAAsB,KAAA,GACxB,KAAK,GAAG,YAAY,qBAAqB,iBAAiB;EAE5D,IAAI,uBAAuB,KAAA,GACzB,KAAK,GAAG,YAAY,sBAAsB,kBAAkB;EAE9D,GAAG,OAAO,0BAA0B;CACtC;;;;;;;;CASA,wBAAwB,SAAiB,OAAkC;EACzE,KAAK,MAAM,EAAC,OAAO,gBAAe,OAAO;GACvC,MAAM,OAAO,WAAW,KAAI,MAAK,IAAI,EAAE,KAAK,IAAI,EAAE,EAAE,EAAE,KAAK,IAAI;GAC/D,KAAKA,IAAI,OACP,mCAAmC,MAAM,sBACpC,QAAQ,yDACR,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK,uBAAuB,mGAG9D;EACF;CACF;CAEA,yBAAyB,KAMvB;EACA,MAAM,gBAA6C,CAAC;EACpD,MAAM,kBAA2B,CAAC;EAElC,MAAM,YACJ,aACA,eACoC;GACpC,MAAM,QAAQ,cACZ,aACA;IACE,YAAW,SAAQ,KAAKkB,WAAW,IAAI;IACvC,qBAAqB,KAAKC,eAAe;IACzC,sBAAsB,UAA8B;IACpD,gBAAe,UAAS;IACxB,UAAU,CAAC;IACX,sBAAqB,UAAS;GAChC,GACA,iBACF;GAIA,IAAI;GACJ,KAAK,MAAM,KAAK,WAAW,MAAM,MAAM,CAAC,CAAC,CAAC,GACxC,SAAS;GAEX,IAAI,CAAC,MAAM;IAGT,gBAAgB,KAAK,KAAK;IAC1B;GACF;GACA,cAAc,KAAK;IAAC,OAAO,YAAY;IAAO,KAAK,KAAK;GAAU,CAAC;GACnE,gBAAgB,KAAK,KAAK;GAC1B,OAAQ,KAAK,IAAI,eAAgC;EACnD;EAEA,MAAM,EACJ,KAAK,UACL,YACA,uBACE,8BAA8B,KAAK,KAAKb,aAAa,QAAQ;EACjE,OAAO;GACL,KAAK;GACL;GACA;GACA;GACA;EACF;CACF;;;;;;;;;;;;;;;;CAiBA,SACE,oBACA,SACA,OACA,OACA,WACA,kBAA2C,kBACZ;EAC/B,OAAO,KAAKc,uBACV,KAAKC,cACH,oBACA,SACA,OACA,OACA,WACA,eACF,CACF;CACF;CAEA,CAACA,cACC,oBACA,SACA,OACA,OACA,WACA,kBAA2C,kBACZ;EAC/B,OACE,KAAK,YAAY,GACjB,2DACF;EACA,KAAK,YAAY,SAAS,eAAe;EACzC,MAAM,gBAAgB,SAAS;EAC/B,KAAKC,2BAA2B;GAC9B,WAAW;GACX;GACA,WAAW;GACX;GACA;GACA;EACF,CAAC;EACD,MAAM,gBAAgB,kBAAkB,kBACpC,IAAI,MAAM,IACV,KAAA;EAEJ,MAAM,YAAY,KAAKC,gCACrB,KAAKtB,aAAa,QAAQ,EAAE,GAAG,EACjC;EAEA,OACE,KAAKuB,oBAAoB,MACzB,6CACF;EACA,KAAKC,kBAAkB,EACrB,MACF;EACA,IAAI,oBAAoB;EACxB,IAAI,kBAAkB;EACtB,IAAI,oBAAoB;EACxB,IAAI;GACF,MAAM,EACJ,KAAK,eACL,eACA,YAAY,eACZ,iBACA,uBACE,KAAKC,yBAAyB,KAAK;GAEvC,KAAKC,wBAAwB,SAAS,kBAAkB;GAExD,MAAM,QAAQ,cACZ,eACA;IACE,OAAO;IACP,iBAAiB;IACjB,YAAW,SAAQ,KAAKT,WAAW,IAAI;IACvC,qBAAqB,KAAKC,eAAe;IACzC,sBAAsB,OAAoB,aACxC,IAAI,oBACF,IAAI,4BACF,KAAKnB,KACL,OACA,SACA,oBACA,SACF,GACA,SACA,KAAKY,oBACL,qBACF;IACF,gBAAe,UAAS;IACxB,UAAU,CAAC;IACX,sBAAqB,UAAS;GAChC,GACA,SACA,SACF;GACA,MAAM,SAAS,MAAM,UAAU;GAC/B,MAAM,UAAU,EACd,OAAM,WAAU;IACd,MAAM,WAAW,KAAKgB;IACtB,OAAO,UAAU,kDAAkD;IACnE,SAAS,WAAW,SAAS,QAAQ,CAAC,MAAM,CAAC;IAC7C,OAAO,CAAC;GACV,EACF,CAAC;GAED,KAAK,MAAM,UAAU,gBACnB,OACA,SACA,KAAK,KAAKb,YAAY,GACtB,KAAKT,WACP,GAAG;IACD,IAAI,WAAW,SACb;IAEF,MAAM;GACR;GAEA,KAAK,MAAM,EAAC,OAAO,SAAQ,eAAe;IACxC,MAAM,aAAa,kBAAkB,KAAKS,cAAc,KAAK;IAC7D;IACA,MAAM;KACJ,MAAM;KACN;KACA;KACA,QAAQ,UAAU,YAAY,GAAG;KACjC;IACF;GACF;GAEA,MAAM,kBAAkB,MAAM,aAAa;GAC3C,IAAI,kBAAkB;QAChB,kBAAkB,KAAKX,WAAW,sBAAsB;KAC1D,IAAI,sBAAsB;KAC1B,MAAM,KAAK,KAAKJ,IACb,YAAY,WAAW,OAAO,EAC9B,YAAY,mBAAmB,eAAe;KACjD,KAAK,MAAM,aAAa,KAAKH,QAAQ,KAAK,GAAG;MAC3C,MAAM,UAAU,OAAO,QACrB,eAAe,mBAAmB,EAAE,cAAc,CAAC,CACrD;MACA,uBAAuB,QAAQ,QAC5B,KAAK,UAAU,MAAM,MAAM,IAC5B,CACF;MACA,GAAG,OAAO,YAAY,aAAa,OAAO;KAC5C;KACA,GAAG,OAAO,0BAA0B,qBAAqB;IAC3D;;GAEF,eAAe,MAAM;GAGrB,MAAM,iBAAsC,CAAC;GAC7C,KAAK,IAAI,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAK;IAC7C,MAAM,OAAO,cAAc;IAC3B,MAAM,iBAAiB,gBAAgB;IACvC,MAAM,kBAAkB,eAAe,UAAU;IACjD,MAAM,EAAC,YAAY,kBAAiB;IACpC,eAAe,UAAU,EACvB,OAAO,WAAmB;KACxB,IAAI;KACJ,QAAQ,OAAO,IAAf;MACE,KAAK;MACL,KAAK;OACH,WACG,OAAO,GAAkB,IAAI,eAC9B;OACF;MACF,KAAK;OACH,WAAW,KAAA;OACX;MACF,KAAK,GACH,OAAO,CAAC;KACZ;KACA,IAAI,CAAC,kBAAkB,UAAU,aAAa,GAC5C,MAAM,IAAI,qBACR,qCAAqC,KAAK,IAAI,MAAM,IAC/C,OAAO,aAAa,EAAE,MAAM,OAAO,QAAQ,KAChD,iBACF;KAEF,MAAM,WAAW,KAAK+B;KACtB,OACE,UACA,kDACF;KACA,SAAS,WAAW,SAAS,iBAAiB,CAAC,MAAM,CAAC;KACtD,OAAO,CAAC;IACV,EACF,CAAC;IACD,eAAe,KAAK;KAAC,OAAO;KAAgB;KAAY;IAAa,CAAC;GACxE;GAKA,MAAM,oBAAoB,KAAK,IAAI;GACnC,KAAK9B,WAAW,IAAI,SAAS;IAC3B;IACA;IACA;IACA;IACA;IACA;IACA,gBAAgB;IAChB;IACA,GAAI,cAAc,KAAA,KAAa,EAAC,UAAS;IACzC,YAAY;GACd,CAAC;GACD,oBAAoB;GACpB,KAAKwB,2BAA2B;IAC9B,WAAW;IACX;IACA,WAAW;IACX;IACA;IACA;IACA;IACA;GACF,CAAC;EACH,SAAS,GAAG;GACV,kBAAkB;GAClB,KAAKA,2BAA2B;IAC9B,WAAW;IACX;IACA,WAAW;IACX;IACA;IACA;IACA,iBAAiB,MAAM,aAAa;IACpC;GACF,CAAC;GACD,gBACE,KAAKtB,KACL;IAAC,WAAW;IAAS;IAAoB;GAAS,GAClD,0BACA,CACF;GACA,MAAM;EACR,UAAU;GACR,IAAI,CAAC,qBAAqB,CAAC,iBACzB,KAAKsB,2BAA2B;IAC9B,WAAW;IACX;IACA,WAAW;IACX;IACA;IACA;IACA,iBAAiB,MAAM,aAAa;IACpC;GACF,CAAC;GAEH,KAAKG,kBAAkB;EACzB;CACF;;;;;CAMA,YACE,SACA,aAAiC,gBACjC;EACA,MAAM,WAAW,KAAK3B,WAAW,IAAI,OAAO;EAC5C,IAAI,UAAU;GACZ,KAAKA,WAAW,OAAO,OAAO;GAC9B,KAAKgB,iBAAiB,SAAS,UAAU,UAAU;EACrD;EACA,KAAKf,kBAAkB,OAAO,OAAO;CACvC;CAEA,iBACE,SACA,UACA,YACM;EACN,KAAKuB,2BAA2B;GAC9B,WAAW;GACX,eAAe,SAAS;GACxB,WAAW;GACX,oBAAoB,SAAS;GAC7B,WAAW,SAAS;GACpB,iBAAiB,SAAS;GAC1B;GACA,iBAAiB,SAAS;GAC1B,mBAAmB,SAAS;GAC5B,oBAAoB,KAAK,IAAI,IAAI,SAAS;EAC5C,CAAC;EACD,SAAS,MAAM,QAAQ;EACvB,KAAK,MAAM,aAAa,SAAS,YAC/B,UAAU,MAAM,QAAQ;CAE5B;;;;;;CAOA,gBAAgB,SAAqC;EACnD,OAAO,KAAKvB,kBAAkB,IAAI,OAAO;CAC3C;;;;;;;CAQA,CAACqB,uBACC,SAC+B;EAC/B,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,WAAW,WAAW,OAAO,SAAS,GAAiB;IACzD,MAAM,MAAM,KAAKrB,kBAAkB,IAAI,OAAO,OAAO,KAAK;IAC1D,MAAM,OAAO,mBAAmB;KAC9B,QAAQ;KACR,OAAO,OAAO;KACd,QAAQ,OAAO;IACjB,CAAC;IACD,KAAKA,kBAAkB,IAAI,OAAO,SAAS,MAAM,IAAI;GACvD;GACA,MAAM;EACR;CACF;;;;;;CAOA,OAAO,OAAe,IAA6B;EACjD,OAAO,KAAK,YAAY,GAAG,qBAAqB;EAEhD,OADe,KAAK,KAAKF,QAAQ,IAAI,KAAK,CACnC,EAAO,OAAO,EAAS;CAChC;;;;;;;;;;;;CAaA,QAAQ,OAIN;EACA,OACE,KAAK,YAAY,GACjB,sDACF;EACA,MAAM,OAAO,KAAKI,aAAa,QAC7B,KAAKK,aACL,KAAKC,cACP;EACA,MAAM,EAAC,MAAM,MAAM,YAAW;EAC9B,KAAKP,IAAI,QACP,WAAW,KAAK,QAAQ,MAAM,KAAK,QAAQ,IAAI,QAAQ,SACzD;EAEA,OAAO;GACL,SAAS,KAAK;GACd,YAAY;GACZ,SAAS,KAAKoB,uBAAuB,KAAKS,SAAS,MAAM,OAAO,OAAO,CAAC;EAC1E;CACF;CAEA,CAACA,SACC,MACA,OACA,YAC+B;EAC/B,OACE,KAAKJ,oBAAoB,MACzB,+CACF;EACA,MAAM,uBAAuB,KAAK,qBAAqB;EACvD,KAAKD,kBAAkB;GACrB;GACA;GACA;GACA,sBAAsB,KAAA;GACtB,KAAK;EACP;EACA,KAAKxB,IAAI,QACP,oCAAoC,WAAW,6EAE1C,qBAAqB,KAC5B;EACA,IAAI;GACF,KAAK,MAAM,EAAC,OAAO,YAAY,eAAc,MAAM;IAKjD,IAAI,KAAK8B,qCAAqC,GAC5C,MAAM;IAER,MAAM,QAAQ,MAAM,aAAa;IACjC,MAAM,iBAAiB,KAAK,KAAKN,eAAe;IAChD,eAAe,uBAAuB;IAEtC,IAAI;IACJ,IAAI;KACF,IAAI;MACF,MAAM,cAAc,KAAK3B,QAAQ,IAAI,KAAK;MAC1C,IAAI,CAAC,aAEH;MAEF,MAAM,aAAa,kBAAkB,KAAKkB,cAAc,KAAK;MAC7D,IAAI,aAA8B,KAAA;MAClC,KAAK,MAAM,aAAa,YACtB,IACE,aACA,UACE,UAAU,YAAY,SAAgB,GACtC,UAAU,YAAY,SAAgB,CACxC,GAEA,aAAa;WACR;OACL,IAAI,WACF,KAAKJ,qBAAqB,IAAI,CAAC;OAEjC,OAAO,KAAKoB,MACV,aACA,uBAAuB,SAAgB,CACzC;MACF;MAEF,IAAI,WACF,IAAI,YACF,OAAO,KAAKA,MACV,aACA,qBAAqB,WAAkB,UAAU,CACnD;WAEA,OAAO,KAAKA,MACV,aACA,oBAAoB,SAAgB,CACtC;KAGN,UAAU;MACR,eAAe;KACjB;KAEA,KAAKD,qCAAqC,KAAK;IACjD,UAAU;KACR,eAAe,uBAAuB,KAAA;IACxC;IAEA,MAAM,UAAU,MAAM,aAAa,IAAI;IACvC,KAAKpB,aAAa,SAAS,SAAS;KAClC;KACA;IACF,CAAC;GACH;GAGA,MAAM,EAAC,SAAQ;GACf,KAAK,MAAM,SAAS,KAAKb,QAAQ,OAAO,GACtC,MAAM,MAAM,KAAK,GAAG,EAAE;GAExB,KAAK0B,gCAAgC,KAAK,GAAG,EAAE;GAC/C,KAAKvB,IAAI,QAAQ,eAAe,KAAK,SAAS;EAChD,UAAU;GACR,KAAKwB,kBAAkB;EACzB;CACF;;CAGA,WAAW,WAA2B;EACpC,IAAI,SAAS,KAAK3B,QAAQ,IAAI,SAAS;EACvC,IAAI,QACF,OAAO;EAGT,MAAM,YAAY,iBAAiB,KAAKS,aAAa,SAAS;EAC9D,MAAM,aAAa,kBAAkB,KAAKS,cAAc,SAAS;EAEjE,MAAM,EAAC,OAAM,KAAKd,aAAa,QAAQ;EACvC,SAAS,IAAI,YACX,KAAKD,KACL,KAAKI,YACL,GAAG,IACH,WACA,UAAU,SACV,kBACM,KAAK4B,aAAa,CAC1B;EACA,KAAKnC,QAAQ,IAAI,WAAW,MAAM;EAClC,KAAKG,IAAI,QAAQ,2BAA2B,WAAW;EACvD,OAAO;CACT;CAEA,eAAwB;EACtB,IAAI,KAAKyB,iBACP,OAAO,KAAKA,gBAAgB,MAAM,WAAW,IAAI,KAAKhB,kBAAkB;EAE1E,IAAI,KAAKe,iBACP,OAAO,KAAKM,qCAAqC;EAEnD,MAAM,IAAI,MAAM,wDAAwD;CAC1E;;;;;;;CAQA,qCAAqC,aAAa,MAAe;EAC/D,MAAM,EACJ,sBACA,KACA,YACA,OAAO,cACP,yBACE,KAAK,KAAKN,eAAe;EAC7B,MAAM,UAAU,aAAa,aAAa;EAC1C,MAAM,yBACJ,yBAAyB,KAAA,IACrB,KAAA,IACA,UAAU;EAChB,IACE,2BAA2B,KAAA,KAC3B,6BAA6B,wBAAwB,oBAAoB,GAEzE,KAAKS,6BACH,KACA,YACA,SACA,wBACA,oBACF;EAEF,MAAM,uBAAuB,2BAC3B,SACA,KACA,UACF;EACA,MAAM,eAAe,4BAA4B,KAAK,UAAU;EAChE,IACE,CAAC,gBACD,gCACE,SACA,sBACA,KACA,YACA,oBACF,GAEA,KAAKC,gCACH,KACA,YACA,SACA,sBACA,oBACF;EAEF,IACE,CAAC,gBACD,UAAU,kCACT,UAAU,wBACR,UAAU,uBAAuB,KAAK,OAAO,aAAa,IAE7D,MAAM,IAAI,qBACR,mCAAmC,IAAI,MAAM,WAAW,iBAC7C,QAAQ,iEACI,qBAAqB,OAC5C,qBACF;EAEF,OAAO,cAAc,aAAa,WAAW,IAAI,KAAKzB,kBAAkB;CAC1E;CAEA,6BACE,KACA,YACA,SACA,wBACA,sBACO;EACP,MAAM,IAAI,qBACR,6DAA6D,IAAI,MAC5D,WAAW,iBAAiB,uBAAuB,OAClD,QAAQ,wEACS,qBAAqB,OAC5C,qBACF;CACF;CAEA,gCACE,KACA,YACA,SACA,sBACA,sBACO;EACP,MAAM,aACJ,yBAAyB,KAAA,IACrB,KACA,wCAAwC,qBAAqB;EACnE,MAAM,IAAI,qBACR,qDAAqD,IAAI,MACpD,WAAW,iBAAiB,QAAQ,QACvC,aACA,8DACG,qBAAqB,OAC1B,qBACF;CACF;;CAGA,iBAA0B;EACxB,OAAO,KAAKP,SAAS,cAAc;CACrC;CAEA,CAAC6B,MACC,QACA,QAC+B;EAC/B,KAAKI,mBAAmB;EACxB,IAAI;GACF,KAAK,MAAM,OAAO,OAAO,QAAQ,MAAM,GAAG;IACxC,IAAI,QAAQ,SACV,MAAM;IAER,KAAK,MAAM,iBAAiB,KAAKC,kBAAkB,EAAE,OAAO,GAC1D,MAAM;IAER,KAAKD,mBAAmB;GAC1B;EACF,UAAU;GACR,IAAI,KAAKP,cAAc,MACrB,KAAKQ,kBAAkB;EAE3B;CACF;CAEA,qBAAqB;EACnB,OAAO,KAAKR,cAAc,MAAM,0BAA0B;EAC1D,KAAKA,YAAY,IAAI,SACnB,KAAK,KAAKb,YAAY,GACtB,KAAKT,cACJ,SAAS,UACR,KAAK+B,iBAAiB,SAAS,yBAAyB,KAAK,CACjE;CACF;CAEA,oBAA8B;EAC5B,MAAM,WAAW,KAAKT;EACtB,OAAO,UAAU,sBAAsB;EACvC,KAAKA,YAAY;EACjB,OAAO;CACT;CAEA,iBAAiB,SAAiB,SAAiB,OAAsB;EACvE,MAAM,WAAW,KAAK9B,WAAW,IAAI,OAAO;EAC5C,MAAM,YAAY,WACd;GACE,WAAW;GACX,oBAAoB,SAAS;GAC7B,WAAW,SAAS;EACtB,IACA,KAAA;EACJ,gBAAgB,KAAKE,KAAK,WAAW,SAAS,KAAK;CACrD;AACF;AAEA,IAAM,WAAN,MAAe;CACb;CACA;CACA;CAIA,YACE,aACA,YACA,iBACA;EACA,KAAKe,eAAe;EACpB,KAAKT,cAAc;EACnB,KAAK+B,mBAAmB;CAC1B;CAEA,WAIM,CAAC;CAEP,WACE,SACA,QACA,SACM;EACN,KAAKC,SAAS,KAAK;GAAC;GAAS;GAAQ;EAAO,CAAC;EAC7C,OAAO;CACT;CAEA,CAAC,SAAwC;EACvC,KAAK,MAAM,CAAC,SAAS,QAAQ,YAAY,KAAKA,UAC5C,IAAI;GACF,OAAO,KAAKC,eAAe,SAAS,QAAQ,OAAO;EACrD,SAAS,GAAG;GACV,KAAKF,mBAAmB,SAAS,CAAC;GAClC,MAAM;EACR;CAEJ;CAEA,CAACE,eACC,SACA,QACA,SAC+B;EAG/B,IAAI,OAAO,WAAW,eACpB;EAGF,KAAK,MAAM,UAAU,SAAS;GAC5B,IAAI,WAAW,SAAS;IACtB,MAAM;IACN;GACF;GACA,MAAM,OAAO,OAAO;GACpB,QAAQ,MAAR;IACE,KAAK;IACL,KAAK;KACH,OAAO,KAAKC,aAAa,SAAS,QAAQ,YAAY,CACpD,OAAO,EACT,CAAC;KACD;IAGF,KAAK,GAAkB;KACrB,MAAM,QAAQ,OAAO;KACrB,MAAM,cAAc,KAClB,OAAO,cAAc,MAAM,iBAC7B;KAEA,OAAO,KAAKD,eAAe,SAAS,aAAa,CAAC,MAAM,MAAM,CAAC;KAC/D;IACF;IACA,KAAK;KACH,OAAO,KAAKC,aAAa,SAAS,QAAQ,YAAY,CACpD;MAAC,KAAK,OAAO,GAAkB;MAAK,eAAe,CAAC;KAAC,CACvD,CAAC;KACD;IACF,SACE,YAAY,OAAO,EAAiB;GACxC;EACF;CACF;CAEA,CAACA,aACC,SACA,QACA,IACA,OAC+B;EAC/B,MAAM,EAAC,WAAW,OAAO,WAAU;EAEnC,MAAM,aAAa,KAAK,KAAKzB,aAAa,IAAI,KAAK,CAAC;EACpD,MAAM,OAAO,KAAK,KAAKT,YAAY,IAAI,KAAK,CAAC,EAAE;EAI/C,IAAI,WAAW,eACb;EAGF,KAAK,MAAM,QAAQ,MAAM,GAAG;GAC1B,IAAI,SAAS,SAAS;IACpB,MAAM;IACN;GACF;GACA,MAAM,EAAC,kBAAiB;GACxB,IAAI,EAAC,QAAO;GACZ,MAAM,SAAS,UAAU,YAAY,GAAG;GACxC,IAAI,OAAO,GAAmB;IAC5B,MAAM,aAAa,IAAI;IACvB,IACE,OAAO,eAAe,YACtB,cAAc,KAAK,iBAAiB,OAEpC,MAAM;KAAC,GAAG;MAAM,2BAA2B,KAAK;IAAa;GAEjE;GAEA,MAAM;IACJ,MAAM;IACN;IACA;IACA;IACA,KAAK,OAAO,IAAoB,KAAA,IAAY;GAC9C;GAEA,KAAK,MAAM,CAAC,cAAc,aAAa,OAAO,QAAQ,aAAa,GAAG;IACpE,MAAM,cAAc,KAAK,OAAO,cAAc,aAAa;IAC3D,OAAO,KAAKkC,aAAa,SAAS,aAAa,IAAI,QAAQ;GAC7D;EACF;CACF;AACF;AAEA,IAAM,8BAAN,MAA2D;CACzD;CACA;CACA;CACA;CACA;CACA,UAAkB;CAElB,YACE,IACA,OACA,WACA,oBACA,WACA;EACA,KAAKxC,MAAM;EACX,KAAKyC,SAAS;EACd,KAAKC,aAAa;EAClB,KAAKC,sBAAsB;EAC3B,KAAKC,aAAa;EAClB,MAAM,UAAU,IAAI;CACtB;CAEA,UAAU,QAAsB;EAC9B,KAAKC,UAAU;CACjB;CAEA,YAA0B;EACxB,OAAO,KAAKJ,OAAO,UAAU;CAC/B;CAEA,UAAgB;EACd,KAAKA,OAAO,QAAQ;CACtB;CAEA,MAAM,KAA6C;EACjD,OAAO,KAAKA,OAAO,MAAM,GAAG;CAC9B;CAEA,CAAC,KAAK,QAAmC;EACvC,IAAI;GACF,OAAO,KAAKI,QAAQ,KAAK,QAAQ,IAAI;EACvC,SAAS,GAAG;GACV,gBACE,KAAK7C,KACL;IACE,WAAW,KAAK0C;IAChB,oBAAoB,KAAKC;IACzB,WAAW,KAAKC;GAClB,GACA,yBACA,CACF;GACA,MAAM;EACR;CACF;AACF;AAEA,SAAS,gBACP,IACA,WACA,SACA,OACM;CACN,IAAI,iBAAiB,sBACnB;CAEF,IAAI,UAAU;CACd,IAAI,WAAW;EACb,UAAU,QACP,YAAY,aAAa,UAAU,SAAS,EAC5C,YAAY,sBAAsB,UAAU,kBAAkB;EACjE,IAAI,UAAU,cAAc,KAAA,GAC1B,UAAU,QAAQ,YAAY,aAAa,UAAU,SAAS;CAElE;CACA,QAAQ,QAAQ,SAAS,KAAK;AAChC;AAEA,UAAU,OAAO,OAA6D;CAC5E,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,SAAS,SAAS;GACpB,MAAM;GACN;EACF;EACA,MAAM;GAAC;GAAgB;GAAM;EAAI;CACnC;AACF;AAEA,SAAS,UAAU,MAAkB,KAAkB;CACrD,OAAO,OAAO,YAAY,KAAK,KAAI,QAAO,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC;AAClE;;;;;;AAOA,UAAiB,QACf,OACA,MACA,cACA,YAC+B;CAC/B,MAAM,MAAM,MAAM,MAAM,CAAC,CAAC;CAK1B,OAJiB,IAAI,SACnB,iBAAiB,YAAY,GAC7B,UACF,EAAE,WAAW,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,CACzC,EAAS,OAAO;AACzB;AAEA,UAAiB,gBACf,OACA,MACA,aACA,YAC+B;CAC/B,MAAM,MAAM,MAAM,MAAM,CAAC,CAAC;CAM1B,OALiB,IAAI,SAAS,aAAa,UAAU,EAAE,WACrD,MACA,MAAM,UAAU,GAChB,OAAO,GAAG,CAEL,EAAS,OAAO;AACzB;AAEA,SAAS,iBACP,cACA,8BAAuC,IAAI,IAAwB,GACnE;CACA,KAAK,MAAM,CAAC,WAAW,EAAC,iBAAgB,OAAO,QAAQ,aAAa,MAAM,GACxE,YAAY,IAAI,WAAW,UAAmC;CAEhE,OAAO;AACT;AAEA,SAAS,kBACP,aACA,OACY;CACZ,MAAM,QAAQ,KAAK,aAAa,iCAAiC;CAEjE,MAAM,KAAK,MAAM,IAAI,KAAK;CAC1B,OACE,UAGE,UAAU,MAAM,mBAAmB,CAAC,GAAG,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,kEAEhE;CACA,OAAO;AACT;;;;;;;AAQA,SAAS,kBACP,GACA,GACS;CACT,OAAO,MAAM;AACf"}
1
+ {"version":3,"file":"pipeline-driver.js","names":["#tables","#pipelines","#rowSetSignatures","#lc","#snapshotter","#storage","#shardID","#logConfig","#config","#tableSpecs","#allTableNames","#costModels","#yieldThresholdMs","#advanceTime","#conflictRowsDeleted","#inspectorDelegate","#initAndResetCommon","#destroyPipeline","#primaryKeys","#replicaVersion","#permissions","#disableCorrelatedPredicatePushdown","#getSource","#createStorage","#trackRowSetSignatures","#addQueryImpl","#logQueryPipelineLifecycle","#ensureCostModelExistsIfEnabled","#advanceContext","#hydrateContext","#resolveScalarSubqueries","#warnIgnoredScalarHints","#streamer","#pruneUnusedTables","#advance","#shouldAdvanceYieldMaybeAbortAdvance","#push","#shouldYield","#throwSlowCurrentChangeReset","#throwProjectedAdvancementReset","#startAccumulating","#stopAccumulating","#logQueryFailure","#changes","#streamChanges","#streamNodes","#input","#queryHash","#transformationHash","#queryName","#output"],"sources":["../../../../../../zero-cache/src/services/view-syncer/pipeline-driver.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert, unreachable} from '../../../../shared/src/asserts.ts';\nimport {deepEqual, type JSONValue} from '../../../../shared/src/json.ts';\nimport {getOrInsertComputed} from '../../../../shared/src/map.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport {randInt} from '../../../../shared/src/rand.ts';\nimport type {AST, LiteralValue} from '../../../../zero-protocol/src/ast.ts';\nimport type {ClientSchema} from '../../../../zero-protocol/src/client-schema.ts';\nimport type {Row} from '../../../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../../../zero-protocol/src/primary-key.ts';\nimport {buildPipeline} from '../../../../zql/src/builder/builder.ts';\nimport {\n Debug,\n runtimeDebugFlags,\n} from '../../../../zql/src/builder/debug-delegate.ts';\nimport {ChangeIndex} from '../../../../zql/src/ivm/change-index.ts';\nimport {ChangeType} from '../../../../zql/src/ivm/change-type.ts';\nimport type {Change} from '../../../../zql/src/ivm/change.ts';\nimport type {Node} from '../../../../zql/src/ivm/data.ts';\nimport {\n skipYields,\n throwOutput,\n type FetchRequest,\n type Input,\n type Output,\n type Storage,\n} from '../../../../zql/src/ivm/operator.ts';\nimport type {SourceSchema} from '../../../../zql/src/ivm/schema.ts';\nimport {\n type Source,\n type SourceChange,\n type SourceInput,\n makeSourceChangeAdd,\n makeSourceChangeEdit,\n makeSourceChangeRemove,\n} from '../../../../zql/src/ivm/source.ts';\nimport type {ConnectionCostModel} from '../../../../zql/src/planner/planner-connection.ts';\nimport {MeasurePushOperator} from '../../../../zql/src/query/measure-push-operator.ts';\nimport type {ClientGroupStorage} from '../../../../zqlite/src/database-storage.ts';\nimport type {Database} from '../../../../zqlite/src/db.ts';\nimport {\n resolveSimpleScalarSubqueries,\n type CompanionSubquery,\n type IgnoredScalarHint,\n} from '../../../../zqlite/src/resolve-scalar-subqueries.ts';\nimport {createSQLiteCostModel} from '../../../../zqlite/src/sqlite-cost-model.ts';\nimport {TableSource} from '../../../../zqlite/src/table-source.ts';\nimport {\n reloadPermissionsIfChanged,\n type LoadedPermissions,\n} from '../../auth/load-permissions.ts';\nimport type {LogConfig, ZeroConfig} from '../../config/zero-config.ts';\nimport {computeZqlSpecs, mustGetTableSpec} from '../../db/lite-tables.ts';\nimport type {LiteAndZqlSpec, LiteTableSpec} from '../../db/specs.ts';\nimport {\n getOrCreateCounter,\n getOrCreateLatencyHistogram,\n} from '../../observability/metrics.ts';\nimport type {InspectorDelegate} from '../../server/inspector-delegate.ts';\nimport {type RowKey} from '../../types/row-key.ts';\nimport {type ShardID} from '../../types/shards.ts';\nimport {\n getSubscriptionState,\n ZERO_VERSION_COLUMN_NAME,\n} from '../replicator/schema/replication-state.ts';\nimport {checkClientSchema} from './client-schema.ts';\nimport {rowIDSignatureUnit} from './row-set-signature.ts';\nimport type {Snapshotter} from './snapshotter.ts';\nimport {ResetPipelinesSignal, type SnapshotDiff} from './snapshotter.ts';\n\ntype RowOp<Op extends Omit<ChangeType, ChangeType.CHILD>> = {\n readonly type: Op;\n readonly queryID: string;\n readonly table: string;\n readonly rowKey: Row;\n readonly row: Row;\n};\n\nexport type RowAdd = RowOp<ChangeType.ADD>;\n\nexport type RowRemove = RowOp<ChangeType.REMOVE>;\n\nexport type RowEdit = RowOp<ChangeType.EDIT>;\n\nexport type RowChange = RowAdd | RowRemove | RowEdit;\n\ntype CompanionPipeline = {\n readonly input: Input;\n readonly childField: string;\n readonly resolvedValue: LiteralValue | null | undefined;\n};\n\ntype Pipeline = {\n readonly input: Input;\n readonly hydrationTimeMs: number;\n readonly hydrationRowCount: number;\n readonly hydrationReason: PipelineHydrationReason;\n readonly pipelineRunID: string;\n readonly pipelineReadyAtMs: number;\n readonly transformedAst: AST;\n readonly originalAst: AST;\n readonly transformationHash: string;\n readonly queryName?: string | undefined;\n readonly companions: readonly CompanionPipeline[];\n};\n\nexport type QueryInfo = {\n readonly transformedAst: AST;\n readonly originalAst?: AST | undefined;\n readonly transformationHash: string;\n readonly queryName?: string | undefined;\n};\n\ntype QueryLogInfo = {\n readonly queryHash: string;\n readonly transformationHash: string;\n readonly queryName?: string | undefined;\n};\n\ntype QueryPipelineLifecycleEvent =\n | 'query-pipeline-hydrate-start'\n | 'query-pipeline-hydrate-finish'\n | 'query-pipeline-hydrate-failed'\n | 'query-pipeline-hydrate-aborted'\n | 'query-pipeline-stop';\n\nexport type PipelineHydrationReason =\n | 'query-set-sync'\n | 'unchanged-query-rehydrate';\n\ntype PipelineStopReason =\n | 'replace-query'\n | 'remove-query'\n | 'reset'\n | 'destroy';\n\ntype QueryPipelineLifecycleLog = {\n readonly zeroEvent: QueryPipelineLifecycleEvent;\n readonly pipelineRunID: string;\n readonly queryHash: string;\n readonly transformationHash: string;\n readonly queryName?: string | undefined;\n readonly hydrationReason?: PipelineHydrationReason | undefined;\n readonly stopReason?: PipelineStopReason | undefined;\n readonly hydrationTimeMs?: number | undefined;\n readonly hydrationRowCount?: number | undefined;\n readonly pipelineLifetimeMs?: number | undefined;\n};\n\ntype AdvanceContext = {\n readonly timer: Timer;\n readonly totalHydrationTimeMs: number;\n readonly numChanges: number;\n currentChangeStartMs: number | undefined;\n pos: number;\n};\n\ntype HydrateContext = {\n readonly timer: Timer;\n};\n\nexport type Timer = {\n elapsedLap: () => number;\n totalElapsed: () => number;\n};\n\n/**\n * No matter how fast hydration is, advancement is given at least this long to\n * complete before doing a pipeline reset.\n */\nconst MIN_ADVANCEMENT_TIME_LIMIT_MS = 50;\nconst MIN_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES = 8;\nconst PROJECTED_ADVANCEMENT_SAMPLE_FRACTION = 0.25;\nconst MAX_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES = 50;\nconst MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS = 5;\nconst MIN_PROJECTED_ADVANCEMENT_CHANGES = 16;\nconst PROJECTED_ADVANCEMENT_RESET_MULTIPLIER = 1.5;\nconst LATE_ADVANCEMENT_FINISH_PROGRESS = 0.8;\n\nfunction randomID() {\n return randInt(1, Number.MAX_SAFE_INTEGER).toString(36);\n}\n\nfunction projectedAdvancementTimeMs(\n elapsedMs: number,\n processedChanges: number,\n numChanges: number,\n): number | undefined {\n if (processedChanges <= 0 || numChanges <= 0) {\n return undefined;\n }\n return (elapsedMs / processedChanges) * numChanges;\n}\n\nfunction advancementResetTimeLimitMs(totalHydrationTimeMs: number): number {\n return Math.max(totalHydrationTimeMs, 1);\n}\n\nfunction minProjectedAdvancementSampleChanges(numChanges: number): number {\n return Math.max(\n MIN_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES,\n Math.min(\n MAX_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES,\n Math.ceil(numChanges * PROJECTED_ADVANCEMENT_SAMPLE_FRACTION),\n ),\n );\n}\n\nfunction shouldResetProjectedAdvancement(\n elapsedMs: number,\n projectedTotalTimeMs: number | undefined,\n processedChanges: number,\n numChanges: number,\n totalHydrationTimeMs: number,\n): boolean {\n if (\n projectedTotalTimeMs === undefined ||\n numChanges < MIN_PROJECTED_ADVANCEMENT_CHANGES ||\n processedChanges < minProjectedAdvancementSampleChanges(numChanges) ||\n elapsedMs < MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS\n ) {\n return false;\n }\n\n return (\n projectedTotalTimeMs >\n advancementResetTimeLimitMs(totalHydrationTimeMs) *\n PROJECTED_ADVANCEMENT_RESET_MULTIPLIER\n );\n}\n\nfunction shouldFinishLateAdvancement(\n processedChanges: number,\n numChanges: number,\n): boolean {\n return (\n numChanges > 0 &&\n processedChanges / numChanges >= LATE_ADVANCEMENT_FINISH_PROGRESS\n );\n}\n\nfunction shouldResetSlowCurrentChange(\n currentChangeElapsedMs: number,\n totalHydrationTimeMs: number,\n): boolean {\n return (\n currentChangeElapsedMs > MIN_ADVANCEMENT_TIME_LIMIT_MS &&\n currentChangeElapsedMs > advancementResetTimeLimitMs(totalHydrationTimeMs)\n );\n}\n\n/**\n * Manages the state of IVM pipelines for a given ViewSyncer (i.e. client group).\n */\nexport class PipelineDriver {\n readonly #tables = new Map<string, TableSource>();\n // Query id to pipeline\n readonly #pipelines = new Map<string, Pipeline>();\n /**\n * XOR signature of the set of rows currently attached to each active\n * query, maintained as RowChanges are yielded from {@link addQuery} and\n * {@link advance}. ADDs / REMOVEs XOR the row's unit in (XOR is\n * self-inverse, so one op serves both directions); EDITs are no-ops.\n * Hydration implicitly reseeds from `0n` because {@link addQuery} calls\n * {@link removeQuery} first, which deletes the entry.\n */\n readonly #rowSetSignatures = new Map<string, bigint>();\n\n readonly #lc: LogContext;\n readonly #snapshotter: Snapshotter;\n readonly #storage: ClientGroupStorage;\n readonly #shardID: ShardID;\n readonly #logConfig: LogConfig;\n readonly #config: ZeroConfig | undefined;\n readonly #tableSpecs = new Map<string, LiteAndZqlSpec>();\n readonly #allTableNames = new Set<string>();\n readonly #costModels: WeakMap<Database, ConnectionCostModel> | undefined;\n readonly #yieldThresholdMs: () => number;\n #streamer: Streamer | null = null;\n #hydrateContext: HydrateContext | null = null;\n #advanceContext: AdvanceContext | null = null;\n #replicaVersion: string | null = null;\n #primaryKeys: Map<string, PrimaryKey> | null = null;\n #permissions: LoadedPermissions | null = null;\n\n readonly #advanceTime = getOrCreateLatencyHistogram(\n 'sync',\n 'ivm.advance-time',\n 'Time to advance all queries for a given client group in response to a single change.',\n );\n\n readonly #conflictRowsDeleted = getOrCreateCounter(\n 'sync',\n 'ivm.conflict-rows-deleted',\n 'Number of rows deleted because they conflicted with added row',\n );\n\n readonly #inspectorDelegate: InspectorDelegate;\n\n constructor(\n lc: LogContext,\n logConfig: LogConfig,\n snapshotter: Snapshotter,\n shardID: ShardID,\n storage: ClientGroupStorage,\n clientGroupID: string,\n inspectorDelegate: InspectorDelegate,\n yieldThresholdMs: () => number,\n enablePlanner?: boolean,\n config?: ZeroConfig,\n ) {\n this.#lc = lc.withContext('clientGroupID', clientGroupID);\n this.#snapshotter = snapshotter;\n this.#storage = storage;\n this.#shardID = shardID;\n this.#logConfig = logConfig;\n this.#config = config;\n this.#inspectorDelegate = inspectorDelegate;\n this.#costModels = enablePlanner ? new WeakMap() : undefined;\n this.#yieldThresholdMs = yieldThresholdMs;\n }\n\n /**\n * Initializes the PipelineDriver to the current head of the database.\n * Queries can then be added (i.e. hydrated) with {@link addQuery()}.\n *\n * Must only be called once.\n */\n init(clientSchema: ClientSchema) {\n assert(!this.#snapshotter.initialized(), 'Already initialized');\n this.#snapshotter.init();\n this.#initAndResetCommon(clientSchema);\n }\n\n /**\n * @returns Whether the PipelineDriver has been initialized.\n */\n initialized(): boolean {\n return this.#snapshotter.initialized();\n }\n\n /**\n * Clears the current pipelines and TableSources, returning the PipelineDriver\n * to its initial state. This should be called in response to a schema change,\n * as TableSources need to be recomputed.\n */\n reset(clientSchema: ClientSchema) {\n for (const [queryID, pipeline] of this.#pipelines) {\n this.#pipelines.delete(queryID);\n this.#destroyPipeline(queryID, pipeline, 'reset');\n }\n this.#tables.clear();\n this.#allTableNames.clear();\n this.#rowSetSignatures.clear();\n this.#initAndResetCommon(clientSchema);\n }\n\n #initAndResetCommon(clientSchema: ClientSchema) {\n const {db} = this.#snapshotter.current();\n const fullTables = new Map<string, LiteTableSpec>();\n computeZqlSpecs(\n this.#lc,\n db.db,\n {includeBackfillingColumns: false},\n this.#tableSpecs,\n fullTables,\n );\n checkClientSchema(\n this.#shardID,\n clientSchema,\n this.#tableSpecs,\n fullTables,\n );\n this.#allTableNames.clear();\n for (const table of fullTables.keys()) {\n this.#allTableNames.add(table);\n }\n const primaryKeys = this.#primaryKeys ?? new Map<string, PrimaryKey>();\n this.#primaryKeys = primaryKeys;\n primaryKeys.clear();\n for (const [table, spec] of this.#tableSpecs.entries()) {\n primaryKeys.set(table, spec.tableSpec.primaryKey);\n }\n buildPrimaryKeys(clientSchema, primaryKeys);\n const {replicaVersion} = getSubscriptionState(db);\n this.#replicaVersion = replicaVersion;\n }\n\n /** @returns The replica version. The PipelineDriver must have been initialized. */\n get replicaVersion(): string {\n return must(this.#replicaVersion, 'Not yet initialized');\n }\n\n /**\n * Returns the current version of the database. This will reflect the\n * latest version change when calling {@link advance()} once the\n * iteration has begun.\n */\n currentVersion(): string {\n assert(this.initialized(), 'Not yet initialized');\n return this.#snapshotter.current().version;\n }\n\n /**\n * Returns the current upstream {app}.permissions, or `null` if none are defined.\n */\n currentPermissions(): LoadedPermissions | null {\n assert(this.initialized(), 'Not yet initialized');\n const res = reloadPermissionsIfChanged(\n this.#lc,\n this.#snapshotter.current().db,\n this.#shardID.appID,\n this.#permissions,\n this.#config,\n );\n if (res.changed) {\n this.#permissions = res.permissions;\n this.#lc.debug?.(\n 'Reloaded permissions',\n JSON.stringify(this.#permissions),\n );\n }\n return this.#permissions;\n }\n\n /**\n * Advances the snapshot to the head of the database without diffing the\n * change log, in preparation for hydrating queries at head.\n *\n * Throws a {@link ResetPipelinesSignal} if the change log records a\n * schema change since the previous snapshot. The table specs (and any\n * TableSources built from them) were computed at or before that snapshot\n * and are stale with respect to the new head, so the caller must\n * {@link reset()} before hydrating. ({@link advance()} detects this when\n * the diff encounters the RESET op; this path skips the diff and so must\n * check explicitly.)\n */\n advanceWithoutDiff(): string {\n const {prev, curr} = this.#snapshotter.advanceWithoutDiff();\n if (curr.schemaChangedSince(prev.version)) {\n throw new ResetPipelinesSignal(\n `schema changed between ${prev.version} and ${curr.version}`,\n 'schema-change',\n );\n }\n for (const table of this.#tables.values()) {\n table.setDB(curr.db.db);\n }\n return curr.version;\n }\n\n #ensureCostModelExistsIfEnabled(db: Database) {\n let existing = this.#costModels?.get(db);\n if (existing) {\n return existing;\n }\n if (this.#costModels) {\n const costModel = createSQLiteCostModel(db, this.#tableSpecs);\n this.#costModels.set(db, costModel);\n return costModel;\n }\n return undefined;\n }\n\n /**\n * Clears storage used for the pipelines. Call this when the\n * PipelineDriver will no longer be used.\n */\n destroy() {\n for (const [queryID, pipeline] of this.#pipelines) {\n this.#pipelines.delete(queryID);\n this.#destroyPipeline(queryID, pipeline, 'destroy');\n }\n this.#tables.clear();\n this.#rowSetSignatures.clear();\n this.#storage.destroy();\n this.#snapshotter.destroy();\n }\n\n /** @return Map from query ID to PipelineInfo for all added queries. */\n queries(): ReadonlyMap<string, QueryInfo> {\n return this.#pipelines;\n }\n\n totalHydrationTimeMs(): number {\n let total = 0;\n for (const pipeline of this.#pipelines.values()) {\n total += pipeline.hydrationTimeMs;\n }\n return total;\n }\n\n #logQueryPipelineLifecycle({\n zeroEvent,\n pipelineRunID,\n queryHash,\n transformationHash,\n queryName,\n hydrationReason,\n stopReason,\n hydrationTimeMs,\n hydrationRowCount,\n pipelineLifetimeMs,\n }: QueryPipelineLifecycleLog): void {\n let lc = this.#lc\n .withContext('zeroEvent', zeroEvent)\n .withContext('pipelineRunID', pipelineRunID)\n .withContext('queryHash', queryHash)\n .withContext('transformationHash', transformationHash);\n if (queryName !== undefined) {\n lc = lc.withContext('queryName', queryName);\n }\n if (hydrationReason !== undefined) {\n lc = lc.withContext('hydrationReason', hydrationReason);\n }\n if (stopReason !== undefined) {\n lc = lc.withContext('stopReason', stopReason);\n }\n if (hydrationTimeMs !== undefined) {\n lc = lc.withContext('hydrationTimeMs', hydrationTimeMs);\n }\n if (hydrationRowCount !== undefined) {\n lc = lc.withContext('hydrationRowCount', hydrationRowCount);\n }\n if (pipelineLifetimeMs !== undefined) {\n lc = lc.withContext('pipelineLifetimeMs', pipelineLifetimeMs);\n }\n lc.info?.('query pipeline lifecycle');\n }\n\n /**\n * A `{scalar: true}` that cannot be honored degrades silently to a plain\n * EXISTS, so the author gets none of the plan they asked for and no signal\n * that they didn't. Say so, with the unique keys that were actually\n * available — the client schema knows only primary keys, so this is the only\n * place the advice can be correct.\n */\n #warnIgnoredScalarHints(queryID: string, hints: IgnoredScalarHint[]): void {\n for (const {table, uniqueKeys} of hints) {\n const keys = uniqueKeys.map(k => `(${k.join(', ')})`).join(', ');\n this.#lc.warn?.(\n `Ignoring {scalar: true} on the \"${table}\" subquery of query ` +\n `${queryID}: it does not constrain every column of any unique key ` +\n `${keys.length > 0 ? `[${keys}]` : '(none on this table)'} to a ` +\n `literal with \"=\", so it is not provably limited to one row. ` +\n `The gate runs as a plain EXISTS.`,\n );\n }\n }\n\n #disableCorrelatedPredicatePushdown(): boolean {\n return this.#config?.enableCorrelatedPredicatePushdown === false;\n }\n\n #resolveScalarSubqueries(ast: AST): {\n ast: AST;\n companionRows: {table: string; row: Row}[];\n companions: CompanionSubquery[];\n companionInputs: Input[];\n ignoredScalarHints: IgnoredScalarHint[];\n } {\n const companionRows: {table: string; row: Row}[] = [];\n const companionInputs: Input[] = [];\n\n const executor = (\n subqueryAST: AST,\n childField: string,\n ): LiteralValue | null | undefined => {\n const input = buildPipeline(\n subqueryAST,\n {\n disableCorrelatedPredicatePushdown:\n this.#disableCorrelatedPredicatePushdown(),\n getSource: name => this.#getSource(name),\n createStorage: () => this.#createStorage(),\n decorateSourceInput: (input: SourceInput): Input => input,\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n },\n 'scalar-subquery',\n );\n // Tracked before it is fetched so that a failure in this or a later\n // subquery can tear it down below. A companion with no result is kept\n // alive too: it detects a future insert that creates the row.\n companionInputs.push(input);\n // Consume the full stream rather than using first() to avoid\n // triggering early return on Take's #initialFetch assertion.\n // The subquery AST already has limit: 1, so at most one row is produced.\n let node: Node | undefined;\n for (const n of skipYields(input.fetch({}))) {\n node ??= n;\n }\n if (!node) {\n return undefined;\n }\n companionRows.push({table: subqueryAST.table, row: node.row as Row});\n return (node.row[childField] as LiteralValue) ?? null;\n };\n\n let resolved: AST;\n let companions: CompanionSubquery[];\n let ignoredScalarHints: IgnoredScalarHint[];\n try {\n ({\n ast: resolved,\n companions,\n ignoredScalarHints,\n } = resolveSimpleScalarSubqueries(ast, this.#tableSpecs, executor));\n } catch (e) {\n for (const input of companionInputs) {\n input.destroy();\n }\n throw e;\n }\n return {\n ast: resolved,\n companionRows,\n companions,\n companionInputs,\n ignoredScalarHints,\n };\n }\n\n /**\n * Adds a pipeline for the query. The method will hydrate the query using the\n * driver's current snapshot of the database and return a stream of results.\n * Henceforth, updates to the query will be returned when the driver is\n * {@link advance}d. The query and its pipeline can be removed with\n * {@link removeQuery()}.\n *\n * If a query with the same queryID is already added, the existing pipeline\n * will be removed and destroyed before adding the new pipeline.\n *\n * @param timer The caller-controlled {@link Timer} used to determine the\n * final hydration time. (The caller may pause and resume the timer\n * when yielding the thread for time-slicing).\n * @return The rows from the initial hydration of the query.\n */\n addQuery(\n transformationHash: string,\n queryID: string,\n query: AST,\n timer: Timer,\n queryName?: string,\n hydrationReason: PipelineHydrationReason = 'query-set-sync',\n ): Iterable<RowChange | 'yield'> {\n return this.#trackRowSetSignatures(\n this.#addQueryImpl(\n transformationHash,\n queryID,\n query,\n timer,\n queryName,\n hydrationReason,\n ),\n );\n }\n\n *#addQueryImpl(\n transformationHash: string,\n queryID: string,\n query: AST,\n timer: Timer,\n queryName?: string,\n hydrationReason: PipelineHydrationReason = 'query-set-sync',\n ): Iterable<RowChange | 'yield'> {\n assert(\n this.initialized(),\n 'Pipeline driver must be initialized before adding queries',\n );\n this.removeQuery(queryID, 'replace-query');\n const pipelineRunID = randomID();\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-hydrate-start',\n pipelineRunID,\n queryHash: queryID,\n transformationHash,\n queryName,\n hydrationReason,\n });\n const debugDelegate = runtimeDebugFlags.trackRowsVended\n ? new Debug(true)\n : undefined;\n\n const costModel = this.#ensureCostModelExistsIfEnabled(\n this.#snapshotter.current().db.db,\n );\n\n assert(\n this.#advanceContext === null,\n 'Cannot hydrate while advance is in progress',\n );\n this.#hydrateContext = {\n timer,\n };\n let hydrationFinished = false;\n let hydrationFailed = false;\n let hydrationRowCount = 0;\n // The inputs built so far, held outside the try so that a hydration that\n // does not finish (aborted by the consumer or failed) can tear them down.\n // Only a finished hydration hands them over to #pipelines.\n let builtInputs: Input[] = [];\n try {\n const {\n ast: resolvedQuery,\n companionRows,\n companions: companionMeta,\n companionInputs,\n ignoredScalarHints,\n } = this.#resolveScalarSubqueries(query);\n builtInputs = [...companionInputs];\n\n this.#warnIgnoredScalarHints(queryID, ignoredScalarHints);\n\n const input = buildPipeline(\n resolvedQuery,\n {\n debug: debugDelegate,\n enableNotExists: true, // Server-side can handle NOT EXISTS\n disableCorrelatedPredicatePushdown:\n this.#disableCorrelatedPredicatePushdown(),\n enablePlannerAwarePushdown:\n this.#config?.enablePlannerAwarePushdown !== false,\n getSource: name => this.#getSource(name),\n createStorage: () => this.#createStorage(),\n decorateSourceInput: (input: SourceInput, _queryID: string): Input =>\n new MeasurePushOperator(\n new QueryFailureLoggingOperator(\n this.#lc,\n input,\n queryID,\n transformationHash,\n queryName,\n ),\n queryID,\n this.#inspectorDelegate,\n 'query-update-server',\n ),\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n },\n queryID,\n costModel,\n );\n builtInputs.push(input);\n const schema = input.getSchema();\n input.setOutput({\n push: change => {\n const streamer = this.#streamer;\n assert(streamer, 'must #startAccumulating() before pushing changes');\n streamer.accumulate(queryID, schema, [change]);\n return [];\n },\n });\n\n for (const change of hydrateInternal(\n input,\n queryID,\n must(this.#primaryKeys),\n this.#tableSpecs,\n )) {\n if (change !== 'yield') {\n hydrationRowCount++;\n }\n yield change;\n }\n\n for (const {table, row} of companionRows) {\n const primaryKey = mustGetPrimaryKey(this.#primaryKeys, table);\n hydrationRowCount++;\n yield {\n type: ChangeType.ADD,\n queryID,\n table,\n rowKey: getRowKey(primaryKey, row),\n row,\n } as RowChange;\n }\n\n const hydrationTimeMs = timer.totalElapsed();\n if (runtimeDebugFlags.trackRowCountsVended) {\n if (hydrationTimeMs > this.#logConfig.slowHydrateThreshold) {\n let totalRowsConsidered = 0;\n const lc = this.#lc\n .withContext('queryID', queryID)\n .withContext('hydrationTimeMs', hydrationTimeMs);\n for (const tableName of this.#tables.keys()) {\n const entries = Object.entries(\n debugDelegate?.getVendedRowCounts()[tableName] ?? {},\n );\n totalRowsConsidered += entries.reduce(\n (acc, entry) => acc + entry[1],\n 0,\n );\n lc.info?.(tableName + ' VENDED: ', entries);\n }\n lc.info?.(`Total rows considered: ${totalRowsConsidered}`);\n }\n }\n debugDelegate?.reset();\n\n // Set up live companion pipelines for reactive scalar subquery monitoring.\n const liveCompanions: CompanionPipeline[] = [];\n for (let i = 0; i < companionMeta.length; i++) {\n const meta = companionMeta[i];\n const companionInput = companionInputs[i];\n const companionSchema = companionInput.getSchema();\n const {childField, resolvedValue} = meta;\n companionInput.setOutput({\n push: (change: Change) => {\n let newValue: LiteralValue | null | undefined;\n switch (change[ChangeIndex.TYPE]) {\n case ChangeType.ADD:\n case ChangeType.EDIT:\n newValue =\n (change[ChangeIndex.NODE].row[childField] as LiteralValue) ??\n null;\n break;\n case ChangeType.REMOVE:\n newValue = undefined;\n break;\n case ChangeType.CHILD:\n return [];\n }\n if (!scalarValuesEqual(newValue, resolvedValue)) {\n throw new ResetPipelinesSignal(\n `Scalar subquery value changed for ${meta.ast.table}: ` +\n `${String(resolvedValue)} -> ${String(newValue)}`,\n 'scalar-subquery',\n );\n }\n const streamer = this.#streamer;\n assert(\n streamer,\n 'must #startAccumulating() before pushing changes',\n );\n streamer.accumulate(queryID, companionSchema, [change]);\n return [];\n },\n });\n liveCompanions.push({input: companionInput, childField, resolvedValue});\n }\n\n // Note: This hydrationTime is a wall-clock overestimate, as it does\n // not take time slicing into account. The view-syncer resets this\n // to a more precise processing-time measurement with setHydrationTime().\n const pipelineReadyAtMs = Date.now();\n this.#pipelines.set(queryID, {\n input,\n hydrationTimeMs,\n hydrationRowCount,\n hydrationReason,\n pipelineRunID,\n pipelineReadyAtMs,\n transformedAst: resolvedQuery,\n originalAst: query,\n transformationHash,\n ...(queryName !== undefined && {queryName}),\n companions: liveCompanions,\n });\n hydrationFinished = true;\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-hydrate-finish',\n pipelineRunID,\n queryHash: queryID,\n transformationHash,\n queryName,\n hydrationReason,\n hydrationTimeMs,\n hydrationRowCount,\n });\n } catch (e) {\n hydrationFailed = true;\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-hydrate-failed',\n pipelineRunID,\n queryHash: queryID,\n transformationHash,\n queryName,\n hydrationReason,\n hydrationTimeMs: timer.totalElapsed(),\n hydrationRowCount,\n });\n logQueryFailure(\n this.#lc,\n {queryHash: queryID, transformationHash, queryName},\n 'query hydration failed',\n e,\n );\n throw e;\n } finally {\n if (!hydrationFinished && !hydrationFailed) {\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-hydrate-aborted',\n pipelineRunID,\n queryHash: queryID,\n transformationHash,\n queryName,\n hydrationReason,\n hydrationTimeMs: timer.totalElapsed(),\n hydrationRowCount,\n });\n }\n if (!hydrationFinished) {\n for (const input of builtInputs) {\n input.destroy();\n }\n this.#pruneUnusedTables();\n // Rows may already have been yielded through #trackRowSetSignatures,\n // and rowSetSignature() must not report a signature for a query\n // without an active pipeline.\n this.#rowSetSignatures.delete(queryID);\n }\n this.#hydrateContext = null;\n }\n }\n\n /**\n * Removes the pipeline for the query. This is a no-op if the query\n * was not added.\n */\n removeQuery(\n queryID: string,\n stopReason: PipelineStopReason = 'remove-query',\n ) {\n const pipeline = this.#pipelines.get(queryID);\n if (pipeline) {\n this.#pipelines.delete(queryID);\n this.#destroyPipeline(queryID, pipeline, stopReason);\n this.#pruneUnusedTables();\n }\n this.#rowSetSignatures.delete(queryID);\n }\n\n #pruneUnusedTables() {\n for (const [table, source] of this.#tables.entries()) {\n if (!source.hasConnections()) {\n this.#tables.delete(table);\n }\n }\n }\n\n #destroyPipeline(\n queryID: string,\n pipeline: Pipeline,\n stopReason: PipelineStopReason,\n ): void {\n this.#logQueryPipelineLifecycle({\n zeroEvent: 'query-pipeline-stop',\n pipelineRunID: pipeline.pipelineRunID,\n queryHash: queryID,\n transformationHash: pipeline.transformationHash,\n queryName: pipeline.queryName,\n hydrationReason: pipeline.hydrationReason,\n stopReason,\n hydrationTimeMs: pipeline.hydrationTimeMs,\n hydrationRowCount: pipeline.hydrationRowCount,\n pipelineLifetimeMs: Date.now() - pipeline.pipelineReadyAtMs,\n });\n pipeline.input.destroy();\n for (const companion of pipeline.companions) {\n companion.input.destroy();\n }\n }\n\n /**\n * Current XOR signature of the row-set attached to `queryID`, or\n * `undefined` if no pipeline for the query is currently active.\n * Maintained incrementally by {@link addQuery} and {@link advance}.\n */\n rowSetSignature(queryID: string): bigint | undefined {\n return this.#rowSetSignatures.get(queryID);\n }\n\n /**\n * Wraps an iterable of RowChanges, XORing each row's unit hash into the\n * query's signature (ADDs and REMOVEs share the same op; EDITs are no-ops).\n * Used to intercept the yield streams from {@link addQuery} and\n * {@link advance}.\n */\n *#trackRowSetSignatures(\n changes: Iterable<RowChange | 'yield'>,\n ): Iterable<RowChange | 'yield'> {\n for (const change of changes) {\n if (change !== 'yield' && change.type !== ChangeType.EDIT) {\n const cur = this.#rowSetSignatures.get(change.queryID) ?? 0n;\n const unit = rowIDSignatureUnit({\n schema: '',\n table: change.table,\n rowKey: change.rowKey as RowKey,\n });\n this.#rowSetSignatures.set(change.queryID, cur ^ unit);\n }\n yield change;\n }\n }\n\n /**\n * Returns the value of the row with the given primary key `pk`,\n * or `undefined` if there is no such row. The pipeline must have been\n * initialized.\n */\n getRow(table: string, pk: RowKey): Row | undefined {\n assert(this.initialized(), 'Not yet initialized');\n const source = must(this.#tables.get(table));\n return source.getRow(pk as Row);\n }\n\n /**\n * Advances to the new head of the database.\n *\n * @param timer The caller-controlled {@link Timer} that will be used to\n * measure the progress of the advancement and abort with a\n * {@link ResetPipelinesSignal} if it is estimated to take longer\n * than a hydration.\n * @return The resulting row changes for all added queries. Note that the\n * `changes` must be iterated over in their entirety in order to\n * advance the database snapshot.\n */\n advance(timer: Timer): {\n version: string;\n numChanges: number;\n changes: Iterable<RowChange | 'yield'>;\n } {\n assert(\n this.initialized(),\n 'Pipeline driver must be initialized before advancing',\n );\n const diff = this.#snapshotter.advance(\n this.#tableSpecs,\n this.#allTableNames,\n this.#tables,\n );\n const {prev, curr, changes} = diff;\n this.#lc.debug?.(\n `advance ${prev.version} => ${curr.version}: ${changes} changes`,\n );\n\n return {\n version: curr.version,\n numChanges: changes,\n changes: this.#trackRowSetSignatures(this.#advance(diff, timer, changes)),\n };\n }\n\n *#advance(\n diff: SnapshotDiff,\n timer: Timer,\n numChanges: number,\n ): Iterable<RowChange | 'yield'> {\n assert(\n this.#hydrateContext === null,\n 'Cannot advance while hydration is in progress',\n );\n const totalHydrationTimeMs = this.totalHydrationTimeMs();\n this.#advanceContext = {\n timer,\n totalHydrationTimeMs,\n numChanges,\n currentChangeStartMs: undefined,\n pos: 0,\n };\n this.#lc.debug?.(\n `starting pipeline advancement of ${numChanges} changes with an ` +\n `advancement time limited based on total hydration time of ` +\n `${totalHydrationTimeMs} ms.`,\n );\n try {\n for (const {table, prevValues, nextValue} of diff) {\n // Advance progress is checked each time a row is fetched\n // from a TableSource during push processing, but some pushes\n // don't read any rows. Check progress here before processing\n // the next change.\n if (this.#shouldAdvanceYieldMaybeAbortAdvance()) {\n yield 'yield';\n }\n const start = timer.totalElapsed();\n const advanceContext = must(this.#advanceContext);\n advanceContext.currentChangeStartMs = start;\n\n try {\n try {\n const tableSource = this.#tables.get(table);\n if (!tableSource) {\n // no pipelines read from this table, so no need to process the change\n continue;\n }\n const primaryKey = mustGetPrimaryKey(this.#primaryKeys, table);\n let editOldRow: Row | undefined = undefined;\n for (const prevValue of prevValues) {\n if (\n nextValue &&\n deepEqual(\n getRowKey(primaryKey, prevValue as Row) as JSONValue,\n getRowKey(primaryKey, nextValue as Row) as JSONValue,\n )\n ) {\n editOldRow = prevValue;\n } else {\n if (nextValue) {\n this.#conflictRowsDeleted.add(1);\n }\n yield* this.#push(\n tableSource,\n makeSourceChangeRemove(prevValue as Row),\n );\n }\n }\n if (nextValue) {\n if (editOldRow) {\n yield* this.#push(\n tableSource,\n makeSourceChangeEdit(nextValue as Row, editOldRow),\n );\n } else {\n yield* this.#push(\n tableSource,\n makeSourceChangeAdd(nextValue as Row),\n );\n }\n }\n } finally {\n advanceContext.pos++;\n }\n\n this.#shouldAdvanceYieldMaybeAbortAdvance(false);\n } finally {\n advanceContext.currentChangeStartMs = undefined;\n }\n\n const elapsed = timer.totalElapsed() - start;\n this.#advanceTime.recordMs(elapsed, {\n table,\n });\n }\n\n // Set the new snapshot on all TableSources.\n const {curr} = diff;\n for (const table of this.#tables.values()) {\n table.setDB(curr.db.db);\n }\n this.#ensureCostModelExistsIfEnabled(curr.db.db);\n this.#lc.debug?.(`Advanced to ${curr.version}`);\n } finally {\n this.#advanceContext = null;\n }\n }\n\n /** Implements `BuilderDelegate.getSource()` */\n #getSource(tableName: string): Source {\n return getOrInsertComputed(this.#tables, tableName, tableName => {\n const tableSpec = mustGetTableSpec(this.#tableSpecs, tableName);\n const primaryKey = mustGetPrimaryKey(this.#primaryKeys, tableName);\n\n const {db} = this.#snapshotter.current();\n const source = new TableSource(\n this.#lc,\n this.#logConfig,\n db.db,\n tableName,\n tableSpec.zqlSpec,\n primaryKey,\n () => this.#shouldYield(),\n // Pipelines only read tables through their connections, and the\n // sources are moved to the next snapshot after every advancement.\n {skipUnobservableChanges: true},\n );\n this.#lc.debug?.(`created TableSource for ${tableName}`);\n return source;\n });\n }\n\n #shouldYield(): boolean {\n if (this.#hydrateContext) {\n return this.#hydrateContext.timer.elapsedLap() > this.#yieldThresholdMs();\n }\n if (this.#advanceContext) {\n return this.#shouldAdvanceYieldMaybeAbortAdvance();\n }\n throw new Error('shouldYield called outside of hydration or advancement');\n }\n\n /**\n * Cancel advancement processing when either the whole batch projects to be\n * more expensive than hydration, or the current source change alone exceeds\n * the hydration budget. The late-finish exception only applies to batch-level\n * checks; a single pathological push always resets.\n */\n #shouldAdvanceYieldMaybeAbortAdvance(checkYield = true): boolean {\n const {\n currentChangeStartMs,\n pos,\n numChanges,\n timer: advanceTimer,\n totalHydrationTimeMs,\n } = must(this.#advanceContext);\n const elapsed = advanceTimer.totalElapsed();\n const currentChangeElapsedMs =\n currentChangeStartMs === undefined\n ? undefined\n : elapsed - currentChangeStartMs;\n if (\n currentChangeElapsedMs !== undefined &&\n shouldResetSlowCurrentChange(currentChangeElapsedMs, totalHydrationTimeMs)\n ) {\n this.#throwSlowCurrentChangeReset(\n pos,\n numChanges,\n elapsed,\n currentChangeElapsedMs,\n totalHydrationTimeMs,\n );\n }\n const projectedTotalTimeMs = projectedAdvancementTimeMs(\n elapsed,\n pos,\n numChanges,\n );\n const shouldFinish = shouldFinishLateAdvancement(pos, numChanges);\n if (\n !shouldFinish &&\n shouldResetProjectedAdvancement(\n elapsed,\n projectedTotalTimeMs,\n pos,\n numChanges,\n totalHydrationTimeMs,\n )\n ) {\n this.#throwProjectedAdvancementReset(\n pos,\n numChanges,\n elapsed,\n projectedTotalTimeMs,\n totalHydrationTimeMs,\n );\n }\n if (\n !shouldFinish &&\n elapsed > MIN_ADVANCEMENT_TIME_LIMIT_MS &&\n (elapsed > totalHydrationTimeMs ||\n (elapsed > totalHydrationTimeMs / 2 && pos <= numChanges / 2))\n ) {\n throw new ResetPipelinesSignal(\n `Advancement exceeded timeout at ${pos} of ${numChanges} changes ` +\n `after ${elapsed} ms. Advancement time limited based on total ` +\n `hydration time of ${totalHydrationTimeMs} ms.`,\n 'advancement-timeout',\n );\n }\n return checkYield && advanceTimer.elapsedLap() > this.#yieldThresholdMs();\n }\n\n #throwSlowCurrentChangeReset(\n pos: number,\n numChanges: number,\n elapsed: number,\n currentChangeElapsedMs: number,\n totalHydrationTimeMs: number,\n ): never {\n throw new ResetPipelinesSignal(\n `Advancement exceeded timeout processing current change at ${pos} of ` +\n `${numChanges} changes after ${currentChangeElapsedMs} ms ` +\n `(${elapsed} ms total). Advancement time limited based on total ` +\n `hydration time of ${totalHydrationTimeMs} ms.`,\n 'advancement-timeout',\n );\n }\n\n #throwProjectedAdvancementReset(\n pos: number,\n numChanges: number,\n elapsed: number,\n projectedTotalTimeMs: number | undefined,\n totalHydrationTimeMs: number,\n ): never {\n const projection =\n projectedTotalTimeMs === undefined\n ? ''\n : ` Projected total advancement time is ${projectedTotalTimeMs} ms.`;\n throw new ResetPipelinesSignal(\n `Advancement projected to exceed hydration time at ${pos} of ` +\n `${numChanges} changes after ${elapsed} ms.` +\n projection +\n ` Advancement time limited based on total hydration time of ` +\n `${totalHydrationTimeMs} ms.`,\n 'advancement-timeout',\n );\n }\n\n /** Implements `BuilderDelegate.createStorage()` */\n #createStorage(): Storage {\n return this.#storage.createStorage();\n }\n\n *#push(\n source: TableSource,\n change: SourceChange,\n ): Iterable<RowChange | 'yield'> {\n this.#startAccumulating();\n try {\n for (const val of source.genPush(change)) {\n if (val === 'yield') {\n yield 'yield';\n }\n for (const changeOrYield of this.#stopAccumulating().stream()) {\n yield changeOrYield;\n }\n this.#startAccumulating();\n }\n } finally {\n if (this.#streamer !== null) {\n this.#stopAccumulating();\n }\n }\n }\n\n #startAccumulating() {\n assert(this.#streamer === null, 'Streamer already started');\n this.#streamer = new Streamer(\n must(this.#primaryKeys),\n this.#tableSpecs,\n (queryID, error) =>\n this.#logQueryFailure(queryID, 'query pipeline failed', error),\n );\n }\n\n #stopAccumulating(): Streamer {\n const streamer = this.#streamer;\n assert(streamer, 'Streamer not started');\n this.#streamer = null;\n return streamer;\n }\n\n #logQueryFailure(queryID: string, message: string, error: unknown): void {\n const pipeline = this.#pipelines.get(queryID);\n const queryInfo = pipeline\n ? {\n queryHash: queryID,\n transformationHash: pipeline.transformationHash,\n queryName: pipeline.queryName,\n }\n : undefined;\n logQueryFailure(this.#lc, queryInfo, message, error);\n }\n}\n\nclass Streamer {\n readonly #primaryKeys: Map<string, PrimaryKey>;\n readonly #tableSpecs: Map<string, LiteAndZqlSpec>;\n readonly #logQueryFailure:\n | ((queryID: string, error: unknown) => void)\n | undefined;\n\n constructor(\n primaryKeys: Map<string, PrimaryKey>,\n tableSpecs: Map<string, LiteAndZqlSpec>,\n logQueryFailure?: (queryID: string, error: unknown) => void,\n ) {\n this.#primaryKeys = primaryKeys;\n this.#tableSpecs = tableSpecs;\n this.#logQueryFailure = logQueryFailure;\n }\n\n readonly #changes: [\n queryID: string,\n schema: SourceSchema,\n changes: Iterable<Change | 'yield'>,\n ][] = [];\n\n accumulate(\n queryID: string,\n schema: SourceSchema,\n changes: Iterable<Change | 'yield'>,\n ): this {\n this.#changes.push([queryID, schema, changes]);\n return this;\n }\n\n *stream(): Iterable<RowChange | 'yield'> {\n for (const [queryID, schema, changes] of this.#changes) {\n try {\n yield* this.#streamChanges(queryID, schema, changes);\n } catch (e) {\n this.#logQueryFailure?.(queryID, e);\n throw e;\n }\n }\n }\n\n *#streamChanges(\n queryID: string,\n schema: SourceSchema,\n changes: Iterable<Change | 'yield'>,\n ): Iterable<RowChange | 'yield'> {\n // We do not sync rows gathered by the permissions\n // system to the client.\n if (schema.system === 'permissions') {\n return;\n }\n\n for (const change of changes) {\n if (change === 'yield') {\n yield change;\n continue;\n }\n const type = change[ChangeIndex.TYPE];\n switch (type) {\n case ChangeType.REMOVE:\n case ChangeType.ADD: {\n yield* this.#streamNodes(queryID, schema, type, () => [\n change[ChangeIndex.NODE],\n ]);\n break;\n }\n\n case ChangeType.CHILD: {\n const child = change[ChangeIndex.CHILD_DATA];\n const childSchema = must(\n schema.relationships[child.relationshipName],\n );\n\n yield* this.#streamChanges(queryID, childSchema, [child.change]);\n break;\n }\n case ChangeType.EDIT:\n yield* this.#streamNodes(queryID, schema, type, () => [\n {row: change[ChangeIndex.NODE].row, relationships: {}},\n ]);\n break;\n default:\n unreachable(change[ChangeIndex.TYPE]);\n }\n }\n }\n\n *#streamNodes(\n queryID: string,\n schema: SourceSchema,\n op: ChangeType.ADD | ChangeType.REMOVE | ChangeType.EDIT,\n nodes: () => Iterable<Node | 'yield'>,\n ): Iterable<RowChange | 'yield'> {\n const {tableName: table, system} = schema;\n\n const primaryKey = must(this.#primaryKeys.get(table));\n const spec = must(this.#tableSpecs.get(table)).tableSpec;\n\n // We do not sync rows gathered by the permissions\n // system to the client.\n if (system === 'permissions') {\n return;\n }\n\n for (const node of nodes()) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n const {relationships} = node;\n let {row} = node;\n const rowKey = getRowKey(primaryKey, row);\n if (op !== ChangeType.REMOVE) {\n const rowVersion = row[ZERO_VERSION_COLUMN_NAME];\n if (\n typeof rowVersion === 'string' &&\n rowVersion < (spec.minRowVersion ?? '00')\n ) {\n row = {...row, [ZERO_VERSION_COLUMN_NAME]: spec.minRowVersion};\n }\n }\n\n yield {\n type: op,\n queryID,\n table,\n rowKey,\n row: op === ChangeType.REMOVE ? undefined : row,\n } as RowChange;\n\n for (const [relationship, children] of Object.entries(relationships)) {\n const childSchema = must(schema.relationships[relationship]);\n yield* this.#streamNodes(queryID, childSchema, op, children);\n }\n }\n }\n}\n\nclass QueryFailureLoggingOperator implements Input, Output {\n readonly #lc: LogContext;\n readonly #input: Input;\n readonly #queryHash: string;\n readonly #transformationHash: string;\n readonly #queryName: string | undefined;\n #output: Output = throwOutput;\n\n constructor(\n lc: LogContext,\n input: Input,\n queryHash: string,\n transformationHash: string,\n queryName?: string,\n ) {\n this.#lc = lc;\n this.#input = input;\n this.#queryHash = queryHash;\n this.#transformationHash = transformationHash;\n this.#queryName = queryName;\n input.setOutput(this);\n }\n\n setOutput(output: Output): void {\n this.#output = output;\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n fetch(req: FetchRequest): Iterable<Node | 'yield'> {\n return this.#input.fetch(req);\n }\n\n *push(change: Change): Iterable<'yield'> {\n try {\n yield* this.#output.push(change, this);\n } catch (e) {\n logQueryFailure(\n this.#lc,\n {\n queryHash: this.#queryHash,\n transformationHash: this.#transformationHash,\n queryName: this.#queryName,\n },\n 'query pipeline failed',\n e,\n );\n throw e;\n }\n }\n}\n\nfunction logQueryFailure(\n lc: LogContext,\n queryInfo: QueryLogInfo | undefined,\n message: string,\n error: unknown,\n): void {\n if (error instanceof ResetPipelinesSignal) {\n return;\n }\n let queryLC = lc;\n if (queryInfo) {\n queryLC = queryLC\n .withContext('queryHash', queryInfo.queryHash)\n .withContext('transformationHash', queryInfo.transformationHash);\n if (queryInfo.queryName !== undefined) {\n queryLC = queryLC.withContext('queryName', queryInfo.queryName);\n }\n }\n queryLC.error?.(message, error);\n}\n\nfunction* toAdds(nodes: Iterable<Node | 'yield'>): Iterable<Change | 'yield'> {\n for (const node of nodes) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n yield [ChangeType.ADD, node, null];\n }\n}\n\nfunction getRowKey(cols: PrimaryKey, row: Row): RowKey {\n return Object.fromEntries(cols.map(col => [col, must(row[col])]));\n}\n\n/**\n * Core hydration logic used by {@link PipelineDriver#addQuery}, extracted to a\n * function for reuse by the analyze-query RPC path so that analysis hydrates\n * queries the same way the view-syncer does in production.\n */\nexport function hydrate(\n input: Input,\n hash: string,\n clientSchema: ClientSchema,\n tableSpecs: Map<string, LiteAndZqlSpec>,\n): Iterable<RowChange | 'yield'> {\n const res = input.fetch({});\n const streamer = new Streamer(\n buildPrimaryKeys(clientSchema),\n tableSpecs,\n ).accumulate(hash, input.getSchema(), toAdds(res));\n return streamer.stream();\n}\n\nexport function hydrateInternal(\n input: Input,\n hash: string,\n primaryKeys: Map<string, PrimaryKey>,\n tableSpecs: Map<string, LiteAndZqlSpec>,\n): Iterable<RowChange | 'yield'> {\n const res = input.fetch({});\n const streamer = new Streamer(primaryKeys, tableSpecs).accumulate(\n hash,\n input.getSchema(),\n toAdds(res),\n );\n return streamer.stream();\n}\n\nfunction buildPrimaryKeys(\n clientSchema: ClientSchema,\n primaryKeys: Map<string, PrimaryKey> = new Map<string, PrimaryKey>(),\n) {\n for (const [tableName, {primaryKey}] of Object.entries(clientSchema.tables)) {\n primaryKeys.set(tableName, primaryKey as unknown as PrimaryKey);\n }\n return primaryKeys;\n}\n\nfunction mustGetPrimaryKey(\n primaryKeys: Map<string, PrimaryKey> | null,\n table: string,\n): PrimaryKey {\n const pKeys = must(primaryKeys, 'primaryKey map must be non-null');\n\n const rv = pKeys.get(table);\n assert(\n rv,\n () =>\n // oxlint-disable-next-line e18e/prefer-array-to-sorted\n `table '${table}' is not one of: ${JSON.stringify([...pKeys.keys()].sort())}. ` +\n `Check the spelling and ensure that the table has a primary key.`,\n );\n return rv;\n}\n\n/**\n * Compares two scalar subquery resolved values for equality.\n * Unlike `valuesEqual` in data.ts (which treats null != null for join\n * semantics), this uses identity semantics: undefined === undefined\n * (no row matched), null === null (row matched but field was NULL).\n */\nfunction scalarValuesEqual(\n a: LiteralValue | null | undefined,\n b: LiteralValue | null | undefined,\n): boolean {\n return a === b;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"query-covering.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/query-covering.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,GAAG,EAOT,MAAM,sCAAsC,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC,CAAC;AAOF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO,CAErE;AAED,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,GAAG,EACf,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAChD,aAAa,GAAG,SAAS,CAK3B;AAED,qBAAa,kBAAkB;;IAI7B,YAAY,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAM7D;IAED,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAY9C;IAED,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAgB5B;IAED,iBAAiB,CACf,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,GAAG,GACd,aAAa,GAAG,SAAS,CAoB3B;CACF"}
1
+ {"version":3,"file":"query-covering.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/query-covering.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,GAAG,EAOT,MAAM,sCAAsC,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,cAAc,EAAE,GAAG,CAAC;IAC7B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC,CAAC;AAOF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,GAAG,OAAO,CAErE;AAED,wBAAgB,iBAAiB,CAC/B,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,GAAG,EACf,cAAc,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAChD,aAAa,GAAG,SAAS,CAK3B;AAED,qBAAa,kBAAkB;;IAI7B,YAAY,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,EAM7D;IAED,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,IAAI,CAU9C;IAED,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAgB5B;IAED,iBAAiB,CACf,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,GAAG,GACd,aAAa,GAAG,SAAS,CAoB3B;CACF"}
@@ -1,4 +1,5 @@
1
1
  import { deepEqual } from "../../../../shared/src/json.js";
2
+ import { getOrInsertComputed, newMap } from "../../../../shared/src/map.js";
2
3
  import { normalizeAST } from "../../../../zero-protocol/src/ast.js";
3
4
  //#region ../zero-cache/src/services/view-syncer/query-covering.ts
4
5
  var QueryCoveringIndex = class {
@@ -11,12 +12,7 @@ var QueryCoveringIndex = class {
11
12
  this.remove(queryID);
12
13
  const normalizedAst = normalizeAST(query.transformedAst);
13
14
  const root = rootKey(normalizedAst);
14
- let queries = this.#byRoot.get(root);
15
- if (!queries) {
16
- queries = /* @__PURE__ */ new Map();
17
- this.#byRoot.set(root, queries);
18
- }
19
- queries.set(queryID, {
15
+ getOrInsertComputed(this.#byRoot, root, newMap).set(queryID, {
20
16
  ...query,
21
17
  normalizedAst
22
18
  });