@rocicorp/zero 1.11.0-canary.3 → 1.11.0-canary.30

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 (988) hide show
  1. package/out/analyze-query/src/analyze-cli.js +4 -4
  2. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  3. package/out/analyze-query/src/bin-analyze.js +13 -12
  4. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  5. package/out/analyze-query/src/bin-transform.js +1 -1
  6. package/out/analyze-query/src/bin-transform.js.map +1 -1
  7. package/out/ast-to-zql/src/ast-to-zql.d.ts +8 -1
  8. package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
  9. package/out/ast-to-zql/src/ast-to-zql.js +25 -25
  10. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  11. package/out/otel/src/log-options.d.ts +16 -0
  12. package/out/otel/src/log-options.d.ts.map +1 -1
  13. package/out/otel/src/log-options.js +60 -6
  14. package/out/otel/src/log-options.js.map +1 -1
  15. package/out/replicache/src/bg-interval.d.ts +2 -1
  16. package/out/replicache/src/bg-interval.d.ts.map +1 -1
  17. package/out/replicache/src/bg-interval.js +13 -4
  18. package/out/replicache/src/bg-interval.js.map +1 -1
  19. package/out/replicache/src/btree/node.d.ts.map +1 -1
  20. package/out/replicache/src/btree/node.js +3 -6
  21. package/out/replicache/src/btree/node.js.map +1 -1
  22. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  23. package/out/replicache/src/dag/gc.js +8 -11
  24. package/out/replicache/src/dag/gc.js.map +1 -1
  25. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
  26. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
  27. package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
  28. package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
  29. package/out/replicache/src/dag/lazy-store.d.ts +17 -4
  30. package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
  31. package/out/replicache/src/dag/lazy-store.js +35 -9
  32. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  33. package/out/replicache/src/dag/store-impl.d.ts +12 -2
  34. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  35. package/out/replicache/src/dag/store-impl.js +29 -9
  36. package/out/replicache/src/dag/store-impl.js.map +1 -1
  37. package/out/replicache/src/db/rebase.d.ts +14 -2
  38. package/out/replicache/src/db/rebase.d.ts.map +1 -1
  39. package/out/replicache/src/db/rebase.js +27 -5
  40. package/out/replicache/src/db/rebase.js.map +1 -1
  41. package/out/replicache/src/get-kv-store-provider.d.ts +1 -1
  42. package/out/replicache/src/get-kv-store-provider.d.ts.map +1 -1
  43. package/out/replicache/src/get-kv-store-provider.js +4 -4
  44. package/out/replicache/src/get-kv-store-provider.js.map +1 -1
  45. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  46. package/out/replicache/src/kv/expo-sqlite/store.js +28 -5
  47. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  48. package/out/replicache/src/kv/idb-store.d.ts +18 -0
  49. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  50. package/out/replicache/src/kv/idb-store.js +30 -2
  51. package/out/replicache/src/kv/idb-store.js.map +1 -1
  52. package/out/replicache/src/kv/mem-fallback-store.d.ts +54 -0
  53. package/out/replicache/src/kv/mem-fallback-store.d.ts.map +1 -0
  54. package/out/replicache/src/kv/mem-fallback-store.js +177 -0
  55. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -0
  56. package/out/replicache/src/kv/mem-store.d.ts +1 -0
  57. package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
  58. package/out/replicache/src/kv/mem-store.js +3 -0
  59. package/out/replicache/src/kv/mem-store.js.map +1 -1
  60. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  61. package/out/replicache/src/kv/op-sqlite/store.js +4 -4
  62. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  63. package/out/replicache/src/kv/sqlite-store.d.ts +22 -1
  64. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  65. package/out/replicache/src/kv/sqlite-store.js +159 -14
  66. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  67. package/out/replicache/src/kv/store.d.ts +6 -0
  68. package/out/replicache/src/kv/store.d.ts.map +1 -1
  69. package/out/replicache/src/new-client-channel.js.map +1 -1
  70. package/out/replicache/src/persist/client-gc.d.ts +2 -1
  71. package/out/replicache/src/persist/client-gc.d.ts.map +1 -1
  72. package/out/replicache/src/persist/client-gc.js +2 -2
  73. package/out/replicache/src/persist/client-gc.js.map +1 -1
  74. package/out/replicache/src/persist/client-group-gc.d.ts +2 -1
  75. package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
  76. package/out/replicache/src/persist/client-group-gc.js +2 -2
  77. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  78. package/out/replicache/src/persist/clients.d.ts +2 -2
  79. package/out/replicache/src/persist/collect-idb-databases.d.ts +28 -8
  80. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  81. package/out/replicache/src/persist/collect-idb-databases.js +97 -20
  82. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  83. package/out/replicache/src/persist/heartbeat.d.ts +2 -1
  84. package/out/replicache/src/persist/heartbeat.d.ts.map +1 -1
  85. package/out/replicache/src/persist/heartbeat.js +2 -2
  86. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  87. package/out/replicache/src/persist/idb-databases-store-db-name.js +1 -1
  88. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
  89. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  90. package/out/replicache/src/persist/persist.js +18 -8
  91. package/out/replicache/src/persist/persist.js.map +1 -1
  92. package/out/replicache/src/persist/refresh.js +6 -2
  93. package/out/replicache/src/persist/refresh.js.map +1 -1
  94. package/out/replicache/src/replicache-impl.d.ts +85 -3
  95. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  96. package/out/replicache/src/replicache-impl.js +321 -29
  97. package/out/replicache/src/replicache-impl.js.map +1 -1
  98. package/out/replicache/src/replicache-options.d.ts +9 -0
  99. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  100. package/out/replicache/src/storage-failure.d.ts +37 -0
  101. package/out/replicache/src/storage-failure.d.ts.map +1 -0
  102. package/out/replicache/src/storage-failure.js +31 -0
  103. package/out/replicache/src/storage-failure.js.map +1 -0
  104. package/out/shared/src/arrays.d.ts +5 -0
  105. package/out/shared/src/arrays.d.ts.map +1 -1
  106. package/out/shared/src/arrays.js +8 -10
  107. package/out/shared/src/arrays.js.map +1 -1
  108. package/out/shared/src/base64.d.ts +19 -0
  109. package/out/shared/src/base64.d.ts.map +1 -0
  110. package/out/shared/src/base64.js +40 -0
  111. package/out/shared/src/base64.js.map +1 -0
  112. package/out/shared/src/centroid.d.ts +0 -1
  113. package/out/shared/src/centroid.d.ts.map +1 -1
  114. package/out/shared/src/centroid.js +1 -4
  115. package/out/shared/src/centroid.js.map +1 -1
  116. package/out/shared/src/error.d.ts +11 -0
  117. package/out/shared/src/error.d.ts.map +1 -1
  118. package/out/shared/src/error.js +35 -1
  119. package/out/shared/src/error.js.map +1 -1
  120. package/out/shared/src/hash.d.ts.map +1 -1
  121. package/out/shared/src/hash.js +32 -7
  122. package/out/shared/src/hash.js.map +1 -1
  123. package/out/shared/src/iterables.d.ts +2 -0
  124. package/out/shared/src/iterables.d.ts.map +1 -1
  125. package/out/shared/src/iterables.js +18 -1
  126. package/out/shared/src/iterables.js.map +1 -1
  127. package/out/shared/src/map.d.ts +24 -2
  128. package/out/shared/src/map.d.ts.map +1 -1
  129. package/out/shared/src/map.js +18 -4
  130. package/out/shared/src/map.js.map +1 -1
  131. package/out/shared/src/options-types.d.ts +2 -2
  132. package/out/shared/src/options.d.ts.map +1 -1
  133. package/out/shared/src/options.js +10 -7
  134. package/out/shared/src/options.js.map +1 -1
  135. package/out/shared/src/packed-boolean-map.d.ts +7 -0
  136. package/out/shared/src/packed-boolean-map.d.ts.map +1 -0
  137. package/out/shared/src/packed-boolean-map.js +36 -0
  138. package/out/shared/src/packed-boolean-map.js.map +1 -0
  139. package/out/shared/src/random-values.js +12 -1
  140. package/out/shared/src/random-values.js.map +1 -1
  141. package/out/shared/src/ring-buffer.d.ts +10 -0
  142. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  143. package/out/shared/src/ring-buffer.js +26 -1
  144. package/out/shared/src/ring-buffer.js.map +1 -1
  145. package/out/shared/src/tdigest.d.ts +10 -0
  146. package/out/shared/src/tdigest.d.ts.map +1 -1
  147. package/out/shared/src/tdigest.js +147 -63
  148. package/out/shared/src/tdigest.js.map +1 -1
  149. package/out/shared/src/valita.d.ts +13 -0
  150. package/out/shared/src/valita.d.ts.map +1 -1
  151. package/out/shared/src/valita.js +23 -23
  152. package/out/shared/src/valita.js.map +1 -1
  153. package/out/z2s/src/compiler.d.ts.map +1 -1
  154. package/out/z2s/src/compiler.js +10 -6
  155. package/out/z2s/src/compiler.js.map +1 -1
  156. package/out/z2s/src/sql.d.ts.map +1 -1
  157. package/out/z2s/src/sql.js +9 -5
  158. package/out/z2s/src/sql.js.map +1 -1
  159. package/out/zero/package.js +4 -5
  160. package/out/zero/package.js.map +1 -1
  161. package/out/zero/src/zero.js +2 -1
  162. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  163. package/out/zero-cache/src/auth/write-authorizer.js +1 -0
  164. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  165. package/out/zero-cache/src/config/normalize.d.ts +1 -0
  166. package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
  167. package/out/zero-cache/src/config/normalize.js +46 -4
  168. package/out/zero-cache/src/config/normalize.js.map +1 -1
  169. package/out/zero-cache/src/config/zero-config.d.ts +116 -24
  170. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  171. package/out/zero-cache/src/config/zero-config.js +409 -157
  172. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  173. package/out/zero-cache/src/custom/fetch.d.ts +1 -1
  174. package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
  175. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  176. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  177. package/out/zero-cache/src/db/lite-tables.js +3 -4
  178. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  179. package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
  180. package/out/zero-cache/src/db/migration-lite.js +5 -3
  181. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  182. package/out/zero-cache/src/observability/events.js +4 -1
  183. package/out/zero-cache/src/observability/events.js.map +1 -1
  184. package/out/zero-cache/src/observability/log-throttle.d.ts +44 -0
  185. package/out/zero-cache/src/observability/log-throttle.d.ts.map +1 -0
  186. package/out/zero-cache/src/observability/log-throttle.js +76 -0
  187. package/out/zero-cache/src/observability/log-throttle.js.map +1 -0
  188. package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
  189. package/out/zero-cache/src/observability/metrics.js +2 -7
  190. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  191. package/out/zero-cache/src/scripts/permissions.d.ts +16 -0
  192. package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
  193. package/out/zero-cache/src/scripts/permissions.js +3 -3
  194. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  195. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  196. package/out/zero-cache/src/server/change-streamer.js +117 -77
  197. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  198. package/out/zero-cache/src/server/inspector-delegate.d.ts +28 -2
  199. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  200. package/out/zero-cache/src/server/inspector-delegate.js +37 -17
  201. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  202. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  203. package/out/zero-cache/src/server/main.js +8 -1
  204. package/out/zero-cache/src/server/main.js.map +1 -1
  205. package/out/zero-cache/src/server/mutator.js +2 -0
  206. package/out/zero-cache/src/server/mutator.js.map +1 -1
  207. package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
  208. package/out/zero-cache/src/server/reaper.js +2 -0
  209. package/out/zero-cache/src/server/reaper.js.map +1 -1
  210. package/out/zero-cache/src/server/replicator.d.ts +3 -0
  211. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  212. package/out/zero-cache/src/server/replicator.js +95 -21
  213. package/out/zero-cache/src/server/replicator.js.map +1 -1
  214. package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
  215. package/out/zero-cache/src/server/runner/zero-dispatcher.js +5 -0
  216. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  217. package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
  218. package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
  219. package/out/zero-cache/src/server/syncer-assigner.js +72 -0
  220. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
  221. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  222. package/out/zero-cache/src/server/syncer.js +24 -2
  223. package/out/zero-cache/src/server/syncer.js.map +1 -1
  224. package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
  225. package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
  226. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  227. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  228. package/out/zero-cache/src/services/analyze.js +11 -9
  229. package/out/zero-cache/src/services/analyze.js.map +1 -1
  230. package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
  231. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +198 -24
  232. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  233. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
  234. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +16 -4
  235. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  236. package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts +24 -0
  237. package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts.map +1 -0
  238. package/out/zero-cache/src/services/change-source/common/init-cleanup.js +44 -0
  239. package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -0
  240. package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +92 -2
  241. package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -1
  242. package/out/zero-cache/src/services/change-source/common/replica-restore.js +27 -10
  243. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  244. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +1 -0
  245. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  246. package/out/zero-cache/src/services/change-source/common/replica-schema.js +15 -3
  247. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  248. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +1 -1
  249. package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
  250. package/out/zero-cache/src/services/change-source/custom/change-source.js +7 -3
  251. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  252. package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +9 -0
  253. package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
  254. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +206 -19
  255. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  256. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +55 -0
  257. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
  258. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +305 -0
  259. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
  260. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +31 -18
  261. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  262. package/out/zero-cache/src/services/change-source/pg/change-source.js +130 -157
  263. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  264. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +38 -2
  265. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  266. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +55 -21
  267. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  268. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +31 -0
  269. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
  270. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +102 -3
  271. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  272. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
  273. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
  274. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
  275. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
  276. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +40 -15
  277. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  278. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +149 -27
  279. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  280. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
  281. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
  282. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  283. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  284. package/out/zero-cache/src/services/change-source/pg/schema/init.js +32 -1
  285. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  286. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
  287. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
  288. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
  289. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
  290. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +50 -27
  291. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  292. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +98 -34
  293. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  294. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +68 -0
  295. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +1 -0
  296. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +141 -0
  297. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -0
  298. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +45 -2
  299. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
  300. package/out/zero-cache/src/services/change-source/protocol/current/data.js +10 -1
  301. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  302. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +60 -3
  303. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
  304. package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +23 -10
  305. package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
  306. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +17 -7
  307. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  308. package/out/zero-cache/src/services/change-source/protocol/current.js +2 -1
  309. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts +72 -0
  310. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts.map +1 -0
  311. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js +162 -0
  312. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -0
  313. package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts +50 -0
  314. package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts.map +1 -0
  315. package/out/zero-cache/src/services/change-streamer/backfill-state.js +268 -0
  316. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -0
  317. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
  318. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +6 -17
  319. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  320. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  321. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +59 -8
  322. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +8 -2
  324. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/broadcast.js +24 -4
  326. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -4
  328. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +28 -8
  330. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
  331. package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +17 -0
  332. package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +1 -1
  333. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +44 -1
  334. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
  335. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +48 -6
  336. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  337. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +131 -34
  338. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  339. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +22 -0
  340. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  341. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +149 -78
  342. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  343. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +38 -16
  344. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  345. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  346. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
  347. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
  348. package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
  349. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  350. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +53 -0
  351. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts.map +1 -0
  352. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +156 -0
  353. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -0
  354. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +58 -1
  355. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  356. package/out/zero-cache/src/services/change-streamer/schema/tables.js +107 -16
  357. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  358. package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts +92 -0
  359. package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts.map +1 -0
  360. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +42 -0
  361. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -0
  362. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +1 -1
  363. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
  364. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +16 -4
  365. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  366. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +7 -69
  367. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
  368. package/out/zero-cache/src/services/change-streamer/snapshot.js +21 -53
  369. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  370. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
  371. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
  372. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
  373. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  374. package/out/zero-cache/src/services/change-streamer/storer.d.ts +95 -4
  375. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  376. package/out/zero-cache/src/services/change-streamer/storer.js +293 -83
  377. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  378. package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +446 -0
  379. package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -0
  380. package/out/zero-cache/src/services/change-streamer/subscribe.js +76 -0
  381. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -0
  382. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +58 -1
  383. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
  384. package/out/zero-cache/src/services/change-streamer/subscriber.js +123 -12
  385. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  386. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +19 -1
  387. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
  388. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +23 -3
  389. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  390. package/out/zero-cache/src/services/http-service.d.ts +1 -1
  391. package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
  392. package/out/zero-cache/src/services/http-service.js.map +1 -1
  393. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  394. package/out/zero-cache/src/services/life-cycle.js +3 -1
  395. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  396. package/out/zero-cache/src/services/litestream/commands.d.ts +34 -3
  397. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  398. package/out/zero-cache/src/services/litestream/commands.js +121 -35
  399. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  400. package/out/zero-cache/src/services/litestream/config-v5.yml +6 -7
  401. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +51 -24
  402. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  403. package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +10 -2
  404. package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +1 -1
  405. package/out/zero-cache/src/services/litestream/litestream-controller.js +3 -2
  406. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  407. package/out/zero-cache/src/services/litestream/restore-progress.d.ts +24 -0
  408. package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +1 -0
  409. package/out/zero-cache/src/services/litestream/restore-progress.js +91 -0
  410. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -0
  411. package/out/zero-cache/src/services/litestream/wal-keeper.d.ts +33 -0
  412. package/out/zero-cache/src/services/litestream/wal-keeper.d.ts.map +1 -0
  413. package/out/zero-cache/src/services/litestream/wal-keeper.js +49 -0
  414. package/out/zero-cache/src/services/litestream/wal-keeper.js.map +1 -0
  415. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
  416. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  417. package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
  418. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  419. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  420. package/out/zero-cache/src/services/mutagen/pusher.js +5 -6
  421. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  422. package/out/zero-cache/src/services/plannerz.d.ts +163 -0
  423. package/out/zero-cache/src/services/plannerz.d.ts.map +1 -0
  424. package/out/zero-cache/src/services/plannerz.js +267 -0
  425. package/out/zero-cache/src/services/plannerz.js.map +1 -0
  426. package/out/zero-cache/src/services/profz.d.ts +30 -0
  427. package/out/zero-cache/src/services/profz.d.ts.map +1 -0
  428. package/out/zero-cache/src/services/profz.js +163 -0
  429. package/out/zero-cache/src/services/profz.js.map +1 -0
  430. package/out/zero-cache/src/services/replicator/change-log-cookies.js +1 -1
  431. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  432. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +5 -4
  433. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -1
  434. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +20 -22
  435. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  436. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  437. package/out/zero-cache/src/services/replicator/change-processor.js +51 -5
  438. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  439. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +5 -2
  440. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  441. package/out/zero-cache/src/services/replicator/incremental-sync.js +54 -21
  442. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  443. package/out/zero-cache/src/services/replicator/replication-status.d.ts +35 -1
  444. package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
  445. package/out/zero-cache/src/services/replicator/replication-status.js +99 -8
  446. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  447. package/out/zero-cache/src/services/replicator/replicator.d.ts +4 -1
  448. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  449. package/out/zero-cache/src/services/replicator/replicator.js +5 -2
  450. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  451. package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +16 -1
  452. package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +1 -1
  453. package/out/zero-cache/src/services/replicator/reporter/recorder.js +70 -27
  454. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  455. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +23 -2
  456. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -1
  457. package/out/zero-cache/src/services/replicator/schema/backfilling.js +54 -2
  458. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  459. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +6 -6
  460. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
  461. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +19 -14
  462. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  463. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +11 -3
  464. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
  465. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  466. package/out/zero-cache/src/services/replicator/write-worker.js +5 -1
  467. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  468. package/out/zero-cache/src/services/run-ast.d.ts +12 -0
  469. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  470. package/out/zero-cache/src/services/run-ast.js +42 -22
  471. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  472. package/out/zero-cache/src/services/runner.d.ts +2 -1
  473. package/out/zero-cache/src/services/runner.d.ts.map +1 -1
  474. package/out/zero-cache/src/services/runner.js +10 -2
  475. package/out/zero-cache/src/services/runner.js.map +1 -1
  476. package/out/zero-cache/src/services/statz.d.ts +4 -0
  477. package/out/zero-cache/src/services/statz.d.ts.map +1 -1
  478. package/out/zero-cache/src/services/statz.js +22 -5
  479. package/out/zero-cache/src/services/statz.js.map +1 -1
  480. package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts +26 -0
  481. package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts.map +1 -0
  482. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js +26 -0
  483. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -0
  484. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +19 -2
  485. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  486. package/out/zero-cache/src/services/view-syncer/client-handler.js +42 -30
  487. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  488. package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts +2 -1
  489. package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts.map +1 -1
  490. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js +1 -0
  491. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  492. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +27 -2
  493. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  494. package/out/zero-cache/src/services/view-syncer/cvr-store.js +85 -20
  495. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  496. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +76 -11
  497. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  498. package/out/zero-cache/src/services/view-syncer/cvr.js +214 -40
  499. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  500. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +81 -0
  501. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +1 -0
  502. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +128 -0
  503. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -0
  504. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
  505. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  506. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
  507. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  508. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +33 -0
  509. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +1 -0
  510. package/out/zero-cache/src/services/view-syncer/hydration-budget.js +62 -0
  511. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -0
  512. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
  513. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
  514. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
  515. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
  516. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +10 -1
  517. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
  518. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +18 -4
  519. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  520. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +80 -6
  521. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  522. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +658 -195
  523. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  524. package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +7 -0
  525. package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +1 -0
  526. package/out/zero-cache/src/services/view-syncer/plan-warnings.js +35 -0
  527. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -0
  528. package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
  529. package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -6
  530. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  531. package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +25 -0
  532. package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +1 -0
  533. package/out/zero-cache/src/services/view-syncer/query-shape.js +28 -0
  534. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -0
  535. package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +82 -0
  536. package/out/zero-cache/src/services/view-syncer/query-stats.d.ts.map +1 -0
  537. package/out/zero-cache/src/services/view-syncer/query-stats.js +214 -0
  538. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -0
  539. package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +2 -107
  540. package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
  541. package/out/zero-cache/src/services/view-syncer/schema/types.js +5 -20
  542. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  543. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +95 -0
  544. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +1 -0
  545. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +155 -0
  546. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -0
  547. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +96 -14
  548. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  549. package/out/zero-cache/src/services/view-syncer/snapshotter.js +214 -30
  550. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  551. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +11 -1
  552. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  553. package/out/zero-cache/src/services/view-syncer/view-syncer.js +566 -107
  554. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  555. package/out/zero-cache/src/types/pg-data-type.d.ts +2 -0
  556. package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
  557. package/out/zero-cache/src/types/pg-data-type.js +6 -1
  558. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  559. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  560. package/out/zero-cache/src/types/pg.js +1 -1
  561. package/out/zero-cache/src/types/pg.js.map +1 -1
  562. package/out/zero-cache/src/types/processes.d.ts +39 -0
  563. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  564. package/out/zero-cache/src/types/processes.js +43 -4
  565. package/out/zero-cache/src/types/processes.js.map +1 -1
  566. package/out/zero-cache/src/types/profiler.d.ts +12 -0
  567. package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
  568. package/out/zero-cache/src/types/profiler.js +46 -1
  569. package/out/zero-cache/src/types/profiler.js.map +1 -1
  570. package/out/zero-cache/src/types/row-key.d.ts +1 -15
  571. package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
  572. package/out/zero-cache/src/types/row-key.js +6 -8
  573. package/out/zero-cache/src/types/row-key.js.map +1 -1
  574. package/out/zero-cache/src/types/streams.d.ts +49 -7
  575. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  576. package/out/zero-cache/src/types/streams.js +190 -58
  577. package/out/zero-cache/src/types/streams.js.map +1 -1
  578. package/out/zero-cache/src/types/subscription.d.ts +15 -0
  579. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  580. package/out/zero-cache/src/types/subscription.js +123 -31
  581. package/out/zero-cache/src/types/subscription.js.map +1 -1
  582. package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
  583. package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
  584. package/out/zero-cache/src/types/websocket-handoff.js +18 -9
  585. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  586. package/out/zero-cache/src/types/ws.d.ts.map +1 -1
  587. package/out/zero-cache/src/types/ws.js +1 -16
  588. package/out/zero-cache/src/types/ws.js.map +1 -1
  589. package/out/zero-cache/src/workers/connect-params.d.ts +18 -1
  590. package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
  591. package/out/zero-cache/src/workers/connect-params.js +25 -1
  592. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  593. package/out/zero-cache/src/workers/connection.d.ts +4 -4
  594. package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
  595. package/out/zero-cache/src/workers/connection.js +8 -8
  596. package/out/zero-cache/src/workers/connection.js.map +1 -1
  597. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  598. package/out/zero-cache/src/workers/replicator.js +15 -7
  599. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  600. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  601. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
  602. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  603. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  604. package/out/zero-cache/src/workers/syncer.js +55 -4
  605. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  606. package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
  607. package/out/zero-client/src/client/active-clients-manager.js +4 -1
  608. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  609. package/out/zero-client/src/client/connection-manager.d.ts +20 -0
  610. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  611. package/out/zero-client/src/client/connection-manager.js +77 -13
  612. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  613. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  614. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  615. package/out/zero-client/src/client/connection-status-enum.js +3 -1
  616. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  617. package/out/zero-client/src/client/connection.d.ts +6 -0
  618. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  619. package/out/zero-client/src/client/connection.js +2 -1
  620. package/out/zero-client/src/client/connection.js.map +1 -1
  621. package/out/zero-client/src/client/context.d.ts +23 -13
  622. package/out/zero-client/src/client/context.d.ts.map +1 -1
  623. package/out/zero-client/src/client/context.js +94 -26
  624. package/out/zero-client/src/client/context.js.map +1 -1
  625. package/out/zero-client/src/client/crud-impl.d.ts.map +1 -1
  626. package/out/zero-client/src/client/crud-impl.js +1 -1
  627. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  628. package/out/zero-client/src/client/custom.d.ts +5 -4
  629. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  630. package/out/zero-client/src/client/custom.js +3 -3
  631. package/out/zero-client/src/client/custom.js.map +1 -1
  632. package/out/zero-client/src/client/inspector/lazy-inspector.js +1 -1
  633. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  634. package/out/zero-client/src/client/ivm-branch.js +20 -3
  635. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  636. package/out/zero-client/src/client/keys.d.ts.map +1 -1
  637. package/out/zero-client/src/client/keys.js +19 -1
  638. package/out/zero-client/src/client/keys.js.map +1 -1
  639. package/out/zero-client/src/client/make-mutate-property.d.ts +1 -1
  640. package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
  641. package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
  642. package/out/zero-client/src/client/make-replicache-mutators.d.ts.map +1 -1
  643. package/out/zero-client/src/client/make-replicache-mutators.js +1 -1
  644. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  645. package/out/zero-client/src/client/mutation-tracker.d.ts +2 -2
  646. package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
  647. package/out/zero-client/src/client/mutation-tracker.js +3 -7
  648. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  649. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  650. package/out/zero-client/src/client/mutator-proxy.js +9 -4
  651. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  652. package/out/zero-client/src/client/options.d.ts +33 -0
  653. package/out/zero-client/src/client/options.d.ts.map +1 -1
  654. package/out/zero-client/src/client/options.js.map +1 -1
  655. package/out/zero-client/src/client/query-manager.d.ts +9 -0
  656. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  657. package/out/zero-client/src/client/query-manager.js +47 -14
  658. package/out/zero-client/src/client/query-manager.js.map +1 -1
  659. package/out/zero-client/src/client/reload-error-handler.js +2 -2
  660. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  661. package/out/zero-client/src/client/version.js +1 -1
  662. package/out/zero-client/src/client/zero-rep.d.ts +1 -0
  663. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  664. package/out/zero-client/src/client/zero-rep.js +8 -6
  665. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  666. package/out/zero-client/src/client/zero.d.ts +18 -3
  667. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  668. package/out/zero-client/src/client/zero.js +89 -50
  669. package/out/zero-client/src/client/zero.js.map +1 -1
  670. package/out/zero-client/src/mod.d.ts +2 -1
  671. package/out/zero-client/src/mod.d.ts.map +1 -1
  672. package/out/zero-client/src/mod.js +1 -0
  673. package/out/zero-client/src/types/query-result.d.ts +2 -0
  674. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  675. package/out/zero-events/src/status.d.ts +64 -0
  676. package/out/zero-events/src/status.d.ts.map +1 -1
  677. package/out/zero-protocol/src/analyze-query-result.d.ts +5 -0
  678. package/out/zero-protocol/src/analyze-query-result.d.ts.map +1 -1
  679. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  680. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  681. package/out/zero-protocol/src/ast.js +13 -14
  682. package/out/zero-protocol/src/ast.js.map +1 -1
  683. package/out/zero-protocol/src/connect.d.ts +16 -0
  684. package/out/zero-protocol/src/connect.d.ts.map +1 -1
  685. package/out/zero-protocol/src/connect.js +27 -1
  686. package/out/zero-protocol/src/connect.js.map +1 -1
  687. package/out/zero-protocol/src/down.d.ts +31 -31
  688. package/out/zero-protocol/src/feature-flag-enum.d.ts +14 -0
  689. package/out/zero-protocol/src/feature-flag-enum.d.ts.map +1 -0
  690. package/out/zero-protocol/src/feature-flag-enum.js +10 -0
  691. package/out/zero-protocol/src/feature-flag-enum.js.map +1 -0
  692. package/out/zero-protocol/src/feature-flag.d.ts +5 -0
  693. package/out/zero-protocol/src/feature-flag.d.ts.map +1 -0
  694. package/out/zero-protocol/src/inspect-down.d.ts +16 -16
  695. package/out/zero-protocol/src/poke.d.ts +17 -10
  696. package/out/zero-protocol/src/poke.d.ts.map +1 -1
  697. package/out/zero-protocol/src/poke.js +3 -2
  698. package/out/zero-protocol/src/poke.js.map +1 -1
  699. package/out/zero-protocol/src/protocol-version.d.ts +30 -6
  700. package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
  701. package/out/zero-protocol/src/protocol-version.js +1 -1
  702. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  703. package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
  704. package/out/zero-protocol/src/query-hash.js +2 -5
  705. package/out/zero-protocol/src/query-hash.js.map +1 -1
  706. package/out/zero-react/src/use-query.d.ts +5 -4
  707. package/out/zero-react/src/use-query.d.ts.map +1 -1
  708. package/out/zero-react/src/use-query.js +74 -7
  709. package/out/zero-react/src/use-query.js.map +1 -1
  710. package/out/zero-react/src/zero.js +1 -0
  711. package/out/zero-server/src/adapters/drizzle.d.ts +2 -1
  712. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  713. package/out/zero-server/src/adapters/drizzle.js +12 -7
  714. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  715. package/out/zero-server/src/adapters/kysely.d.ts +2 -1
  716. package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
  717. package/out/zero-server/src/adapters/kysely.js +8 -2
  718. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  719. package/out/zero-server/src/adapters/pg.d.ts +5 -1
  720. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  721. package/out/zero-server/src/adapters/pg.js +28 -7
  722. package/out/zero-server/src/adapters/pg.js.map +1 -1
  723. package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
  724. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  725. package/out/zero-server/src/adapters/postgresjs.js +7 -1
  726. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  727. package/out/zero-server/src/adapters/prisma.d.ts +3 -2
  728. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  729. package/out/zero-server/src/adapters/prisma.js +8 -2
  730. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  731. package/out/zero-server/src/closable-db-transaction.d.ts +16 -0
  732. package/out/zero-server/src/closable-db-transaction.d.ts.map +1 -0
  733. package/out/zero-server/src/closable-db-transaction.js +31 -0
  734. package/out/zero-server/src/closable-db-transaction.js.map +1 -0
  735. package/out/zero-server/src/custom.d.ts +10 -4
  736. package/out/zero-server/src/custom.d.ts.map +1 -1
  737. package/out/zero-server/src/custom.js +15 -6
  738. package/out/zero-server/src/custom.js.map +1 -1
  739. package/out/zero-server/src/logging.d.ts +2 -2
  740. package/out/zero-server/src/logging.d.ts.map +1 -1
  741. package/out/zero-server/src/logging.js +2 -2
  742. package/out/zero-server/src/logging.js.map +1 -1
  743. package/out/zero-server/src/mod.d.ts +1 -1
  744. package/out/zero-server/src/mod.d.ts.map +1 -1
  745. package/out/zero-server/src/pg-query-executor.d.ts +2 -2
  746. package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
  747. package/out/zero-server/src/pg-query-executor.js +2 -2
  748. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  749. package/out/zero-server/src/process-mutations.d.ts +25 -4
  750. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  751. package/out/zero-server/src/process-mutations.js +103 -52
  752. package/out/zero-server/src/process-mutations.js.map +1 -1
  753. package/out/zero-server/src/push-processor.d.ts +8 -2
  754. package/out/zero-server/src/push-processor.d.ts.map +1 -1
  755. package/out/zero-server/src/push-processor.js +12 -4
  756. package/out/zero-server/src/push-processor.js.map +1 -1
  757. package/out/zero-server/src/schema.d.ts +2 -2
  758. package/out/zero-server/src/schema.d.ts.map +1 -1
  759. package/out/zero-server/src/schema.js +3 -2
  760. package/out/zero-server/src/schema.js.map +1 -1
  761. package/out/zero-server/src/zql-database.d.ts +21 -1
  762. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  763. package/out/zero-server/src/zql-database.js +61 -24
  764. package/out/zero-server/src/zql-database.js.map +1 -1
  765. package/out/zero-solid/src/solid-view.d.ts +17 -0
  766. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  767. package/out/zero-solid/src/solid-view.js +39 -1
  768. package/out/zero-solid/src/solid-view.js.map +1 -1
  769. package/out/zero-solid/src/use-query.js +1 -2
  770. package/out/zero-solid/src/use-query.js.map +1 -1
  771. package/out/zero-solid/src/zero.js +1 -0
  772. package/out/zql/src/builder/builder.d.ts +25 -0
  773. package/out/zql/src/builder/builder.d.ts.map +1 -1
  774. package/out/zql/src/builder/builder.js +69 -19
  775. package/out/zql/src/builder/builder.js.map +1 -1
  776. package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +43 -0
  777. package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +1 -0
  778. package/out/zql/src/builder/correlated-predicate-pushdown.js +161 -0
  779. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -0
  780. package/out/zql/src/builder/debug-delegate.d.ts +6 -1
  781. package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
  782. package/out/zql/src/builder/debug-delegate.js +14 -2
  783. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  784. package/out/zql/src/ivm/array-view.d.ts +29 -0
  785. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  786. package/out/zql/src/ivm/array-view.js +74 -16
  787. package/out/zql/src/ivm/array-view.js.map +1 -1
  788. package/out/zql/src/ivm/cap.d.ts +2 -1
  789. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  790. package/out/zql/src/ivm/cap.js +14 -4
  791. package/out/zql/src/ivm/cap.js.map +1 -1
  792. package/out/zql/src/ivm/data.d.ts.map +1 -1
  793. package/out/zql/src/ivm/data.js +8 -3
  794. package/out/zql/src/ivm/data.js.map +1 -1
  795. package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
  796. package/out/zql/src/ivm/deferred-input.js +3 -2
  797. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  798. package/out/zql/src/ivm/exists.d.ts +3 -1
  799. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  800. package/out/zql/src/ivm/exists.js +4 -1
  801. package/out/zql/src/ivm/exists.js.map +1 -1
  802. package/out/zql/src/ivm/fan-in.d.ts +6 -2
  803. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  804. package/out/zql/src/ivm/fan-in.js +13 -5
  805. package/out/zql/src/ivm/fan-in.js.map +1 -1
  806. package/out/zql/src/ivm/fan-out.d.ts +5 -2
  807. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  808. package/out/zql/src/ivm/fan-out.js +4 -0
  809. package/out/zql/src/ivm/fan-out.js.map +1 -1
  810. package/out/zql/src/ivm/filter-operators.d.ts +8 -6
  811. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  812. package/out/zql/src/ivm/filter-operators.js +19 -8
  813. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  814. package/out/zql/src/ivm/filter.d.ts +5 -2
  815. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  816. package/out/zql/src/ivm/filter.js +10 -4
  817. package/out/zql/src/ivm/filter.js.map +1 -1
  818. package/out/zql/src/ivm/flipped-join.d.ts +9 -4
  819. package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
  820. package/out/zql/src/ivm/flipped-join.js +97 -46
  821. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  822. package/out/zql/src/ivm/join-index-tap.d.ts +33 -0
  823. package/out/zql/src/ivm/join-index-tap.d.ts.map +1 -0
  824. package/out/zql/src/ivm/join-index-tap.js +70 -0
  825. package/out/zql/src/ivm/join-index-tap.js.map +1 -0
  826. package/out/zql/src/ivm/join-index.d.ts +35 -0
  827. package/out/zql/src/ivm/join-index.d.ts.map +1 -0
  828. package/out/zql/src/ivm/join-index.js +141 -0
  829. package/out/zql/src/ivm/join-index.js.map +1 -0
  830. package/out/zql/src/ivm/join-utils.d.ts +6 -0
  831. package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
  832. package/out/zql/src/ivm/join-utils.js +22 -1
  833. package/out/zql/src/ivm/join-utils.js.map +1 -1
  834. package/out/zql/src/ivm/join.d.ts +19 -1
  835. package/out/zql/src/ivm/join.d.ts.map +1 -1
  836. package/out/zql/src/ivm/join.js +107 -15
  837. package/out/zql/src/ivm/join.js.map +1 -1
  838. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  839. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  840. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
  841. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  842. package/out/zql/src/ivm/memory-source.d.ts +29 -4
  843. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  844. package/out/zql/src/ivm/memory-source.js +70 -34
  845. package/out/zql/src/ivm/memory-source.js.map +1 -1
  846. package/out/zql/src/ivm/memory-storage.d.ts +1 -0
  847. package/out/zql/src/ivm/memory-storage.d.ts.map +1 -1
  848. package/out/zql/src/ivm/memory-storage.js +1 -0
  849. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  850. package/out/zql/src/ivm/operator.d.ts +45 -10
  851. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  852. package/out/zql/src/ivm/operator.js +9 -4
  853. package/out/zql/src/ivm/operator.js.map +1 -1
  854. package/out/zql/src/ivm/push-accumulated.d.ts +6 -1
  855. package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
  856. package/out/zql/src/ivm/push-accumulated.js +47 -2
  857. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  858. package/out/zql/src/ivm/skip.d.ts +2 -1
  859. package/out/zql/src/ivm/skip.d.ts.map +1 -1
  860. package/out/zql/src/ivm/skip.js +3 -0
  861. package/out/zql/src/ivm/skip.js.map +1 -1
  862. package/out/zql/src/ivm/take-gate.d.ts +57 -0
  863. package/out/zql/src/ivm/take-gate.d.ts.map +1 -0
  864. package/out/zql/src/ivm/take-gate.js +106 -0
  865. package/out/zql/src/ivm/take-gate.js.map +1 -0
  866. package/out/zql/src/ivm/take.d.ts +8 -2
  867. package/out/zql/src/ivm/take.d.ts.map +1 -1
  868. package/out/zql/src/ivm/take.js +139 -103
  869. package/out/zql/src/ivm/take.js.map +1 -1
  870. package/out/zql/src/ivm/union-fan-in.d.ts +3 -0
  871. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  872. package/out/zql/src/ivm/union-fan-in.js +63 -10
  873. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  874. package/out/zql/src/ivm/union-fan-out.d.ts +2 -1
  875. package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
  876. package/out/zql/src/ivm/union-fan-out.js +5 -0
  877. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  878. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  879. package/out/zql/src/ivm/view-apply-change.js +9 -4
  880. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  881. package/out/zql/src/ivm/view.d.ts +15 -0
  882. package/out/zql/src/ivm/view.d.ts.map +1 -1
  883. package/out/zql/src/mutate/custom.d.ts +53 -1
  884. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  885. package/out/zql/src/mutate/custom.js.map +1 -1
  886. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  887. package/out/zql/src/mutate/mutator-registry.js +3 -3
  888. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  889. package/out/zql/src/mutate/mutator.d.ts +2 -2
  890. package/out/zql/src/mutate/mutator.d.ts.map +1 -1
  891. package/out/zql/src/mutate/mutator.js.map +1 -1
  892. package/out/zql/src/planner/planner-builder.d.ts +23 -3
  893. package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
  894. package/out/zql/src/planner/planner-builder.js +34 -17
  895. package/out/zql/src/planner/planner-builder.js.map +1 -1
  896. package/out/zql/src/planner/planner-connection.d.ts +58 -2
  897. package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
  898. package/out/zql/src/planner/planner-connection.js +103 -11
  899. package/out/zql/src/planner/planner-connection.js.map +1 -1
  900. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  901. package/out/zql/src/planner/planner-debug.js +3 -8
  902. package/out/zql/src/planner/planner-debug.js.map +1 -1
  903. package/out/zql/src/planner/planner-graph.d.ts +10 -0
  904. package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
  905. package/out/zql/src/planner/planner-graph.js +14 -0
  906. package/out/zql/src/planner/planner-graph.js.map +1 -1
  907. package/out/zql/src/planner/planner-source.d.ts +2 -2
  908. package/out/zql/src/planner/planner-source.d.ts.map +1 -1
  909. package/out/zql/src/planner/planner-source.js +2 -2
  910. package/out/zql/src/planner/planner-source.js.map +1 -1
  911. package/out/zql/src/planner/planner-warnings.d.ts +83 -0
  912. package/out/zql/src/planner/planner-warnings.d.ts.map +1 -0
  913. package/out/zql/src/planner/planner-warnings.js +78 -0
  914. package/out/zql/src/planner/planner-warnings.js.map +1 -0
  915. package/out/zql/src/query/measure-push-operator.d.ts +9 -2
  916. package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
  917. package/out/zql/src/query/measure-push-operator.js +52 -5
  918. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  919. package/out/zql/src/query/query-delegate-base.d.ts +4 -2
  920. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  921. package/out/zql/src/query/query-delegate-base.js +66 -33
  922. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  923. package/out/zql/src/query/query-delegate.d.ts +33 -6
  924. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  925. package/out/zql/src/query/query-impl.d.ts +1 -0
  926. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  927. package/out/zql/src/query/query-impl.js +6 -23
  928. package/out/zql/src/query/query-impl.js.map +1 -1
  929. package/out/zql/src/query/query-transitions.d.ts.map +1 -1
  930. package/out/zql/src/query/query-transitions.js +2 -5
  931. package/out/zql/src/query/query-transitions.js.map +1 -1
  932. package/out/zql/src/query/query.d.ts +22 -5
  933. package/out/zql/src/query/query.d.ts.map +1 -1
  934. package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
  935. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  936. package/out/zql/src/query/runnable-query-impl.js +2 -10
  937. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  938. package/out/zql/src/query/typed-view.d.ts +1 -1
  939. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  940. package/out/zqlite/src/database-storage.d.ts.map +1 -1
  941. package/out/zqlite/src/database-storage.js +9 -1
  942. package/out/zqlite/src/database-storage.js.map +1 -1
  943. package/out/zqlite/src/db.d.ts +9 -1
  944. package/out/zqlite/src/db.d.ts.map +1 -1
  945. package/out/zqlite/src/db.js +62 -30
  946. package/out/zqlite/src/db.js.map +1 -1
  947. package/out/zqlite/src/index-usage.d.ts +19 -0
  948. package/out/zqlite/src/index-usage.d.ts.map +1 -0
  949. package/out/zqlite/src/index-usage.js +49 -0
  950. package/out/zqlite/src/index-usage.js.map +1 -0
  951. package/out/zqlite/src/pending-delta.d.ts +110 -0
  952. package/out/zqlite/src/pending-delta.d.ts.map +1 -0
  953. package/out/zqlite/src/pending-delta.js +278 -0
  954. package/out/zqlite/src/pending-delta.js.map +1 -0
  955. package/out/zqlite/src/query-builder.d.ts +17 -1
  956. package/out/zqlite/src/query-builder.d.ts.map +1 -1
  957. package/out/zqlite/src/query-builder.js +111 -20
  958. package/out/zqlite/src/query-builder.js.map +1 -1
  959. package/out/zqlite/src/query-delegate.d.ts.map +1 -1
  960. package/out/zqlite/src/query-delegate.js +10 -7
  961. package/out/zqlite/src/query-delegate.js.map +1 -1
  962. package/out/zqlite/src/resolve-scalar-subqueries.d.ts +3 -1
  963. package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
  964. package/out/zqlite/src/resolve-scalar-subqueries.js +1 -0
  965. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  966. package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
  967. package/out/zqlite/src/sqlite-cost-model.js +52 -1
  968. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  969. package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
  970. package/out/zqlite/src/sqlite-stat-fanout.js +5 -31
  971. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  972. package/out/zqlite/src/sqlite-stat4-sample.d.ts +37 -0
  973. package/out/zqlite/src/sqlite-stat4-sample.d.ts.map +1 -0
  974. package/out/zqlite/src/sqlite-stat4-sample.js +61 -0
  975. package/out/zqlite/src/sqlite-stat4-sample.js.map +1 -0
  976. package/out/zqlite/src/table-source.d.ts +87 -2
  977. package/out/zqlite/src/table-source.d.ts.map +1 -1
  978. package/out/zqlite/src/table-source.js +276 -42
  979. package/out/zqlite/src/table-source.js.map +1 -1
  980. package/package.json +4 -5
  981. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +0 -25
  982. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +0 -1
  983. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +0 -83
  984. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +0 -1
  985. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +0 -29
  986. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +0 -1
  987. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +0 -154
  988. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"change-log-cookies.js","names":["#upsertMetadata","#upsertBackfill","#renameMetadataTable","#renameBackfillTable","#deleteMetadataTable","#deleteBackfillTable","#renameBackfillColumn","#deleteBackfillColumn","#run"],"sources":["../../../../../../zero-cache/src/services/replicator/change-log-cookies.ts"],"sourcesContent":["/**\n * The change log's *second* job.\n *\n * A change log is a buffer **and** a cookie jar. The buffer catches a\n * reconnecting subscriber up to the head; the cookie jar holds the backfill\n * progress state that the change-streamer hands the change-source on every\n * `startStream`, so that the change source never has to persist backfill state\n * upstream. See `change-log-db.ts` for the buffer.\n *\n * There are two cookies, mirroring the two `cdc` tables the Postgres change log\n * has always carried (`change-streamer/schema/tables.ts`):\n *\n * - **table metadata**, the most current {@link TableMetadata} of a table, which\n * a {@link BackfillRequest} has to carry; and\n * - **backfilling columns**, the opaque {@link BackfillID} of every column whose\n * backfill has not completed.\n *\n * Both are a *fold over the change stream*: the cookie set is only meaningful\n * paired with the watermark it was folded up to. {@link cookieOps} is that fold,\n * expressed transport-free so that the Postgres change log and the SQLite change\n * log cannot drift from each other — they must agree on all eight transitions\n * forever, and the failure mode if they disagree is a backfill that is silently\n * never re-requested. The two interpreters are {@link ChangeLogCookieWriter}\n * here and `Storer.#trackBackfillMetadata()` in\n * `change-streamer/storer.ts`.\n *\n * The tables live in the change-log database rather than in the replica: the\n * replicator is a subscriber *downstream* of the change-streamer's write loop,\n * so its state version trails the log's head, and pairing its cookies with the\n * log's resume watermark would lose every backfill that completed in between.\n * The replica's own copies (`_zero.tableMetadata`, `_zero.column_metadata`) are\n * the *seed* source; these are the *working* set.\n */\n\nimport {unreachable} from '../../../../shared/src/asserts.ts';\nimport {BigIntJSON} from '../../../../shared/src/bigint-json.ts';\nimport * as v from '../../../../shared/src/valita.ts';\nimport type {Database, Statement} from '../../../../zqlite/src/db.ts';\nimport type {\n BackfillID,\n Identifier,\n SchemaChange,\n TableMetadata,\n} from '../change-source/protocol/current/data.ts';\nimport {\n backfillRequestSchema,\n type BackfillRequest,\n} from '../change-source/protocol/current/upstream.ts';\n\nexport const CHANGE_LOG_TABLE_METADATA_TABLE = '_zero.changeLogTableMetadata';\nexport const CHANGE_LOG_BACKFILLING_TABLE = '_zero.changeLogBackfilling';\n\n// The names follow the file's existing convention, beside\n// \"_zero.changeLogStream\" and \"_zero.changeLogMeta\".\n//\n// `metadata` and `backfill` hold the JSON that the `cdc` tables hold as JSONB.\n// SQLite has no JSONB, and nothing here queries into the documents: they are\n// stored to be handed back to the change source verbatim.\nexport const CREATE_CHANGE_LOG_COOKIE_SCHEMA = /*sql*/ `\n CREATE TABLE \"${CHANGE_LOG_TABLE_METADATA_TABLE}\" (\n \"schema\" TEXT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"metadata\" TEXT NOT NULL,\n PRIMARY KEY (\"schema\", \"table\")\n );\n\n CREATE TABLE \"${CHANGE_LOG_BACKFILLING_TABLE}\" (\n \"schema\" TEXT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"column\" TEXT NOT NULL,\n \"backfill\" TEXT NOT NULL,\n PRIMARY KEY (\"schema\", \"table\", \"column\")\n );\n`;\n\nexport const DROP_CHANGE_LOG_COOKIE_TABLES = /*sql*/ `\n DROP TABLE IF EXISTS \"${CHANGE_LOG_TABLE_METADATA_TABLE}\";\n DROP TABLE IF EXISTS \"${CHANGE_LOG_BACKFILLING_TABLE}\";\n`;\n\nexport type TableMetadataCookie = {\n readonly schema: string;\n readonly table: string;\n readonly metadata: TableMetadata;\n};\n\nexport type BackfillCookie = {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n readonly backfill: BackfillID;\n};\n\n/**\n * The whole cookie set, as of the log's head. Both lists are ordered by their\n * primary key so that two stores' sets can be compared directly.\n */\nexport type CookieSet = {\n readonly tableMetadata: readonly TableMetadataCookie[];\n readonly backfilling: readonly BackfillCookie[];\n};\n\nexport const EMPTY_COOKIE_SET: CookieSet = {\n tableMetadata: [],\n backfilling: [],\n};\n\n/**\n * A transport-free description of a cookie mutation. This is the whole of what\n * a {@link SchemaChange} means to the cookie jar; everything else about the\n * change belongs to the buffer.\n */\nexport type CookieOp =\n | {op: 'upsert-metadata'; table: Identifier; metadata: TableMetadata}\n | {\n op: 'upsert-backfill';\n table: Identifier;\n column: string;\n backfill: BackfillID;\n }\n | {op: 'rename-table'; old: Identifier; new: Identifier}\n | {op: 'drop-table'; table: Identifier}\n | {op: 'rename-column'; table: Identifier; old: string; new: string}\n | {op: 'drop-column'; table: Identifier; column: string}\n | {op: 'complete-backfill'; table: Identifier; columns: readonly string[]};\n\nexport type CookieOpTag = CookieOp['op'];\n\n/**\n * The fold, and the only place either store decides what a schema change means\n * for the cookie set. Both interpreters are mechanical translations of what this\n * returns, in the order it returns them.\n *\n * Changes that carry no cookie state — index changes, and the `create-table` /\n * `add-column` variants whose optional `metadata` and `backfill` fields are\n * absent — produce no ops.\n */\nexport function cookieOps(change: SchemaChange): CookieOp[] {\n switch (change.tag) {\n case 'update-table-metadata':\n return [\n {op: 'upsert-metadata', table: change.table, metadata: change.new},\n ];\n\n case 'create-table': {\n const {spec, metadata, backfill} = change;\n const table = {schema: spec.schema, name: spec.name};\n const ops: CookieOp[] = [];\n if (metadata) {\n ops.push({op: 'upsert-metadata', table, metadata});\n }\n if (backfill) {\n for (const [column, id] of Object.entries(backfill)) {\n ops.push({op: 'upsert-backfill', table, column, backfill: id});\n }\n }\n return ops;\n }\n\n case 'rename-table':\n return [{op: 'rename-table', old: change.old, new: change.new}];\n\n case 'drop-table':\n return [{op: 'drop-table', table: change.id}];\n\n case 'add-column': {\n const {table, tableMetadata, column, backfill} = change;\n const ops: CookieOp[] = [];\n if (tableMetadata) {\n ops.push({op: 'upsert-metadata', table, metadata: tableMetadata});\n }\n if (backfill) {\n ops.push({\n op: 'upsert-backfill',\n table,\n column: column.name,\n backfill,\n });\n }\n return ops;\n }\n\n case 'update-column': {\n // Only a rename moves the cookie; the rest of a column update does not\n // affect whether or how it is being backfilled.\n const {table, old, new: updated} = change;\n return old.name === updated.name\n ? []\n : [{op: 'rename-column', table, old: old.name, new: updated.name}];\n }\n\n case 'drop-column':\n return [{op: 'drop-column', table: change.table, column: change.column}];\n\n case 'backfill-completed': {\n const {relation, columns} = change;\n // The rowKey columns are excluded from `columns` but are backfilled with\n // them, so both are cleared.\n const cleared = [...relation.rowKey.columns, ...columns];\n return cleared.length === 0\n ? []\n : [\n {\n op: 'complete-backfill',\n table: {schema: relation.schema, name: relation.name},\n columns: cleared,\n },\n ];\n }\n\n case 'create-index':\n case 'drop-index':\n return [];\n\n default:\n // Unreachable: `isSchemaChange()` gates on the same tag set this switch\n // covers. It is exhaustive so that a new schema-change tag is a compile\n // error here rather than a silently dropped backfill.\n unreachable(change);\n }\n}\n\n/**\n * The SQLite interpreter of {@link cookieOps}, over prepared statements on the\n * change-log database.\n *\n * The statements run inside the log's transaction, in stream order, at the point\n * the schema change is appended (see `ChangeLogStreamWriter`). That is what\n * makes the cookie set atomic with the head — a crash cannot leave cookies ahead\n * of or behind the rows they were folded from — and what makes an aborted\n * transaction discard its cookies with its rows, for free.\n *\n * Statements are prepared against the tables as they exist now, so an instance\n * does not survive a reconcile that drops and recreates them.\n */\nexport class ChangeLogCookieWriter {\n readonly #upsertMetadata: Statement;\n readonly #upsertBackfill: Statement;\n readonly #renameMetadataTable: Statement;\n readonly #renameBackfillTable: Statement;\n readonly #deleteMetadataTable: Statement;\n readonly #deleteBackfillTable: Statement;\n readonly #renameBackfillColumn: Statement;\n readonly #deleteBackfillColumn: Statement;\n\n constructor(db: Database) {\n this.#upsertMetadata = db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n (\"schema\", \"table\", \"metadata\") VALUES (?, ?, ?)\n ON CONFLICT (\"schema\", \"table\")\n DO UPDATE SET \"metadata\" = excluded.\"metadata\"\n `);\n this.#upsertBackfill = db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n (\"schema\", \"table\", \"column\", \"backfill\") VALUES (?, ?, ?, ?)\n ON CONFLICT (\"schema\", \"table\", \"column\")\n DO UPDATE SET \"backfill\" = excluded.\"backfill\"\n `);\n this.#renameMetadataTable = db.prepare(/*sql*/ `\n UPDATE \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n SET \"schema\" = ?, \"table\" = ? WHERE \"schema\" = ? AND \"table\" = ?\n `);\n this.#renameBackfillTable = db.prepare(/*sql*/ `\n UPDATE \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n SET \"schema\" = ?, \"table\" = ? WHERE \"schema\" = ? AND \"table\" = ?\n `);\n this.#deleteMetadataTable = db.prepare(/*sql*/ `\n DELETE FROM \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n WHERE \"schema\" = ? AND \"table\" = ?\n `);\n this.#deleteBackfillTable = db.prepare(/*sql*/ `\n DELETE FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n WHERE \"schema\" = ? AND \"table\" = ?\n `);\n this.#renameBackfillColumn = db.prepare(/*sql*/ `\n UPDATE \"${CHANGE_LOG_BACKFILLING_TABLE}\" SET \"column\" = ?\n WHERE \"schema\" = ? AND \"table\" = ? AND \"column\" = ?\n `);\n this.#deleteBackfillColumn = db.prepare(/*sql*/ `\n DELETE FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n WHERE \"schema\" = ? AND \"table\" = ? AND \"column\" = ?\n `);\n }\n\n /** Applies the change's cookie ops, returning the ops that were applied. */\n apply(change: SchemaChange): CookieOp[] {\n const ops = cookieOps(change);\n for (const op of ops) {\n this.#run(op);\n }\n return ops;\n }\n\n #run(op: CookieOp): void {\n switch (op.op) {\n case 'upsert-metadata':\n this.#upsertMetadata.run(\n op.table.schema,\n op.table.name,\n BigIntJSON.stringify(op.metadata),\n );\n break;\n\n case 'upsert-backfill':\n this.#upsertBackfill.run(\n op.table.schema,\n op.table.name,\n op.column,\n BigIntJSON.stringify(op.backfill),\n );\n break;\n\n case 'rename-table':\n this.#renameMetadataTable.run(\n op.new.schema,\n op.new.name,\n op.old.schema,\n op.old.name,\n );\n this.#renameBackfillTable.run(\n op.new.schema,\n op.new.name,\n op.old.schema,\n op.old.name,\n );\n break;\n\n case 'drop-table':\n this.#deleteMetadataTable.run(op.table.schema, op.table.name);\n this.#deleteBackfillTable.run(op.table.schema, op.table.name);\n break;\n\n case 'rename-column':\n this.#renameBackfillColumn.run(\n op.new,\n op.table.schema,\n op.table.name,\n op.old,\n );\n break;\n\n case 'drop-column':\n this.#deleteBackfillColumn.run(\n op.table.schema,\n op.table.name,\n op.column,\n );\n break;\n\n case 'complete-backfill':\n // A per-column delete rather than an `IN` list, which cannot be a\n // single prepared statement across arities. The columns of one\n // completed backfill are few, and this runs only on schema changes.\n for (const column of op.columns) {\n this.#deleteBackfillColumn.run(\n op.table.schema,\n op.table.name,\n column,\n );\n }\n break;\n\n default:\n unreachable(op);\n }\n }\n}\n\nconst tableKey = (schema: string, table: string) =>\n JSON.stringify([schema, table]);\n\nconst columnKey = (schema: string, table: string, column: string) =>\n JSON.stringify([schema, table, column]);\n\nconst cmp = (a: string, b: string) => (a < b ? -1 : a > b ? 1 : 0);\n\n/**\n * The in-memory interpreter of {@link cookieOps}: the third one, and the only\n * one that is not a store.\n *\n * A replica-derived cookie set is a snapshot at the replica's state version,\n * which trails the change log's head, so it cannot be compared with a\n * Postgres-derived set directly. This carries it forward over the schema changes\n * the log holds in between, which turns \"the two stores disagree, but they are\n * also at different positions\" into an exact equality — and makes a\n * disagreement between any two of the three interpreters visible as an\n * inequality that neither store would have noticed on its own.\n *\n * `changes` must be the log's schema changes over `(from, to]` in stream order.\n * Anything else produces a set that belongs to no watermark.\n */\nexport function foldCookies(\n cookies: CookieSet,\n changes: Iterable<SchemaChange>,\n): CookieSet {\n const metadata = new Map<string, TableMetadataCookie>(\n cookies.tableMetadata.map(c => [tableKey(c.schema, c.table), c]),\n );\n const backfilling = new Map<string, BackfillCookie>(\n cookies.backfilling.map(c => [columnKey(c.schema, c.table, c.column), c]),\n );\n const dropColumn = ({schema, name}: Identifier, column: string) =>\n backfilling.delete(columnKey(schema, name, column));\n\n for (const change of changes) {\n for (const op of cookieOps(change)) {\n switch (op.op) {\n case 'upsert-metadata':\n metadata.set(tableKey(op.table.schema, op.table.name), {\n schema: op.table.schema,\n table: op.table.name,\n metadata: op.metadata,\n });\n break;\n\n case 'upsert-backfill':\n backfilling.set(\n columnKey(op.table.schema, op.table.name, op.column),\n {\n schema: op.table.schema,\n table: op.table.name,\n column: op.column,\n backfill: op.backfill,\n },\n );\n break;\n\n case 'rename-table': {\n const {old, new: renamed} = op;\n const moved = metadata.get(tableKey(old.schema, old.name));\n if (moved) {\n metadata.delete(tableKey(old.schema, old.name));\n metadata.set(tableKey(renamed.schema, renamed.name), {\n ...moved,\n schema: renamed.schema,\n table: renamed.name,\n });\n }\n // Snapshotted before mutating, since the rename both deletes and\n // inserts into the map being scanned.\n for (const [key, cookie] of [...backfilling]) {\n if (cookie.schema === old.schema && cookie.table === old.name) {\n backfilling.delete(key);\n backfilling.set(\n columnKey(renamed.schema, renamed.name, cookie.column),\n {...cookie, schema: renamed.schema, table: renamed.name},\n );\n }\n }\n break;\n }\n\n case 'drop-table': {\n const {schema, name} = op.table;\n metadata.delete(tableKey(schema, name));\n for (const [key, cookie] of [...backfilling]) {\n if (cookie.schema === schema && cookie.table === name) {\n backfilling.delete(key);\n }\n }\n break;\n }\n\n case 'rename-column': {\n const {schema, name} = op.table;\n const moved = backfilling.get(columnKey(schema, name, op.old));\n if (moved) {\n backfilling.delete(columnKey(schema, name, op.old));\n backfilling.set(columnKey(schema, name, op.new), {\n ...moved,\n column: op.new,\n });\n }\n break;\n }\n\n case 'drop-column':\n dropColumn(op.table, op.column);\n break;\n\n case 'complete-backfill':\n for (const column of op.columns) {\n dropColumn(op.table, column);\n }\n break;\n\n default:\n unreachable(op);\n }\n }\n }\n\n return {\n tableMetadata: [...metadata.values()].toSorted(\n (a, b) => cmp(a.schema, b.schema) || cmp(a.table, b.table),\n ),\n backfilling: [...backfilling.values()].toSorted(\n (a, b) =>\n cmp(a.schema, b.schema) ||\n cmp(a.table, b.table) ||\n cmp(a.column, b.column),\n ),\n };\n}\n\nconst backfillRequestsSchema = v.array(backfillRequestSchema);\n\n/**\n * Returns one {@link BackfillRequest} for each table with an active backfill.\n * Each request contains the stored table metadata, if available.\n */\nexport function backfillRequestsFrom(cookies: CookieSet): BackfillRequest[] {\n const metadata = new Map(\n cookies.tableMetadata.map(c => [tableKey(c.schema, c.table), c.metadata]),\n );\n const requests: BackfillRequest[] = [];\n let curr: BackfillRequest | undefined;\n for (const {schema, table, column, backfill} of cookies.backfilling) {\n if (curr?.table.schema !== schema || curr.table.name !== table) {\n curr = {\n table: {\n schema,\n name: table,\n // Use `null` when a backfilling table has no metadata. This matches\n // the result of the Postgres left join.\n metadata: metadata.get(tableKey(schema, table)) ?? null,\n },\n columns: {},\n };\n requests.push(curr);\n }\n curr.columns[column] = backfill;\n }\n return v.parse(requests, backfillRequestsSchema);\n}\n\n/**\n * Reads the whole cookie set, ordered by primary key. This is what a\n * change-streamer would hand `startStream`, and what the Postgres-derived and\n * replica-derived sets are compared against.\n */\nexport function readCookies(db: Database): CookieSet {\n const tableMetadata = db\n .prepare(/*sql*/ `\n SELECT \"schema\", \"table\", \"metadata\"\n FROM \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n ORDER BY \"schema\", \"table\"\n `)\n .all<{schema: string; table: string; metadata: string}>()\n .map(({schema, table, metadata}) => ({\n schema,\n table,\n metadata: BigIntJSON.parse(metadata) as TableMetadata,\n }));\n\n const backfilling = db\n .prepare(/*sql*/ `\n SELECT \"schema\", \"table\", \"column\", \"backfill\"\n FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n ORDER BY \"schema\", \"table\", \"column\"\n `)\n .all<{schema: string; table: string; column: string; backfill: string}>()\n .map(({schema, table, column, backfill}) => ({\n schema,\n table,\n column,\n backfill: BigIntJSON.parse(backfill) as BackfillID,\n }));\n\n return {tableMetadata, backfilling};\n}\n\n/**\n * Replaces the cookie set wholesale.\n *\n * The cookies are unversioned point-in-time state, so a reconciliation that\n * moves the head invalidates them: truncating the stream above `W` does not roll\n * the cookie set back to `W`, and the truncated transactions can contain\n * `create-table`, `add-column`, and `backfill-completed`. The caller must run\n * this in the same transaction as the reconciliation that invalidated them.\n */\nexport function replaceCookies(db: Database, cookies: CookieSet): void {\n db.prepare(/*sql*/ `DELETE FROM \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"`).run();\n db.prepare(/*sql*/ `DELETE FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\"`).run();\n\n if (cookies.tableMetadata.length > 0) {\n const insert = db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n (\"schema\", \"table\", \"metadata\") VALUES (?, ?, ?)\n `);\n for (const {schema, table, metadata} of cookies.tableMetadata) {\n insert.run(schema, table, BigIntJSON.stringify(metadata));\n }\n }\n if (cookies.backfilling.length > 0) {\n const insert = db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n (\"schema\", \"table\", \"column\", \"backfill\") VALUES (?, ?, ?, ?)\n `);\n for (const {schema, table, column, backfill} of cookies.backfilling) {\n insert.run(schema, table, column, BigIntJSON.stringify(backfill));\n }\n }\n}\n\n/** Retained cookie rows, by table. Both are normally zero. */\nexport type CookieRowCounts = {\n readonly tableMetadata: number;\n readonly backfilling: number;\n};\n\nexport function readCookieRowCounts(db: Database): CookieRowCounts {\n return db\n .prepare(/*sql*/ `\n SELECT\n (SELECT count(*) FROM \"${CHANGE_LOG_TABLE_METADATA_TABLE}\")\n AS \"tableMetadata\",\n (SELECT count(*) FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\")\n AS \"backfilling\"\n `)\n .get<CookieRowCounts>();\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"change-log-cookies.js","names":["#upsertMetadata","#upsertBackfill","#renameMetadataTable","#renameBackfillTable","#deleteMetadataTable","#deleteBackfillTable","#renameBackfillColumn","#deleteBackfillColumn","#run"],"sources":["../../../../../../zero-cache/src/services/replicator/change-log-cookies.ts"],"sourcesContent":["/**\n * The change log's *second* job.\n *\n * A change log is a buffer **and** a cookie jar. The buffer catches a\n * reconnecting subscriber up to the head; the cookie jar holds the backfill\n * progress state that the change-streamer hands the change-source on every\n * `startStream`, so that the change source never has to persist backfill state\n * upstream. See `change-log-db.ts` for the buffer.\n *\n * There are two cookies, mirroring the two `cdc` tables the Postgres change log\n * has always carried (`change-streamer/schema/tables.ts`):\n *\n * - **table metadata**, the most current {@link TableMetadata} of a table, which\n * a {@link BackfillRequest} has to carry; and\n * - **backfilling columns**, the opaque {@link BackfillID} of every column whose\n * backfill has not completed.\n *\n * Both are a *fold over the change stream*: the cookie set is only meaningful\n * paired with the watermark it was folded up to. {@link cookieOps} is that fold,\n * expressed transport-free so that the Postgres change log and the SQLite change\n * log cannot drift from each other — they must agree on all eight transitions\n * forever, and the failure mode if they disagree is a backfill that is silently\n * never re-requested. The two interpreters are {@link ChangeLogCookieWriter}\n * here and `Storer.#trackBackfillMetadata()` in\n * `change-streamer/storer.ts`.\n *\n * The tables live in the change-log database rather than in the replica: the\n * replicator is a subscriber *downstream* of the change-streamer's write loop,\n * so its state version trails the log's head, and pairing its cookies with the\n * log's resume watermark would lose every backfill that completed in between.\n * The replica's own copies (`_zero.tableMetadata`, `_zero.column_metadata`) are\n * the *seed* source; these are the *working* set.\n */\n\nimport {unreachable} from '../../../../shared/src/asserts.ts';\nimport {BigIntJSON} from '../../../../shared/src/bigint-json.ts';\nimport * as v from '../../../../shared/src/valita.ts';\nimport type {Database, Statement} from '../../../../zqlite/src/db.ts';\nimport type {\n BackfillID,\n Identifier,\n SchemaChange,\n TableMetadata,\n} from '../change-source/protocol/current/data.ts';\nimport {\n backfillRequestSchema,\n type BackfillRequest,\n} from '../change-source/protocol/current/upstream.ts';\n\nexport const CHANGE_LOG_TABLE_METADATA_TABLE = '_zero.changeLogTableMetadata';\nexport const CHANGE_LOG_BACKFILLING_TABLE = '_zero.changeLogBackfilling';\n\n// The names follow the file's existing convention, beside\n// \"_zero.changeLogStream\" and \"_zero.changeLogMeta\".\n//\n// `metadata` and `backfill` hold the JSON that the `cdc` tables hold as JSONB.\n// SQLite has no JSONB, and nothing here queries into the documents: they are\n// stored to be handed back to the change source verbatim.\nexport const CREATE_CHANGE_LOG_COOKIE_SCHEMA = /*sql*/ `\n CREATE TABLE \"${CHANGE_LOG_TABLE_METADATA_TABLE}\" (\n \"schema\" TEXT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"metadata\" TEXT NOT NULL,\n PRIMARY KEY (\"schema\", \"table\")\n );\n\n CREATE TABLE \"${CHANGE_LOG_BACKFILLING_TABLE}\" (\n \"schema\" TEXT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"column\" TEXT NOT NULL,\n \"backfill\" TEXT NOT NULL,\n PRIMARY KEY (\"schema\", \"table\", \"column\")\n );\n`;\n\nexport const DROP_CHANGE_LOG_COOKIE_TABLES = /*sql*/ `\n DROP TABLE IF EXISTS \"${CHANGE_LOG_TABLE_METADATA_TABLE}\";\n DROP TABLE IF EXISTS \"${CHANGE_LOG_BACKFILLING_TABLE}\";\n`;\n\nexport type TableMetadataCookie = {\n readonly schema: string;\n readonly table: string;\n readonly metadata: TableMetadata;\n};\n\nexport type BackfillCookie = {\n readonly schema: string;\n readonly table: string;\n readonly column: string;\n readonly backfill: BackfillID;\n};\n\n/**\n * The whole cookie set, as of the log's head. Both lists are ordered by their\n * primary key so that two stores' sets can be compared directly.\n */\nexport type CookieSet = {\n readonly tableMetadata: readonly TableMetadataCookie[];\n readonly backfilling: readonly BackfillCookie[];\n};\n\nexport const EMPTY_COOKIE_SET: CookieSet = {\n tableMetadata: [],\n backfilling: [],\n};\n\n/**\n * A transport-free description of a cookie mutation. This is the whole of what\n * a {@link SchemaChange} means to the cookie jar; everything else about the\n * change belongs to the buffer.\n */\nexport type CookieOp =\n | {op: 'upsert-metadata'; table: Identifier; metadata: TableMetadata}\n | {\n op: 'upsert-backfill';\n table: Identifier;\n column: string;\n backfill: BackfillID;\n }\n | {op: 'rename-table'; old: Identifier; new: Identifier}\n | {op: 'drop-table'; table: Identifier}\n | {op: 'rename-column'; table: Identifier; old: string; new: string}\n | {op: 'drop-column'; table: Identifier; column: string}\n | {op: 'complete-backfill'; table: Identifier; columns: readonly string[]};\n\nexport type CookieOpTag = CookieOp['op'];\n\n/**\n * The fold, and the only place either store decides what a schema change means\n * for the cookie set. Both interpreters are mechanical translations of what this\n * returns, in the order it returns them.\n *\n * Changes that carry no cookie state — index changes, and the `create-table` /\n * `add-column` variants whose optional `metadata` and `backfill` fields are\n * absent — produce no ops.\n */\nexport function cookieOps(change: SchemaChange): CookieOp[] {\n switch (change.tag) {\n case 'update-table-metadata':\n return [\n {op: 'upsert-metadata', table: change.table, metadata: change.new},\n ];\n\n case 'create-table': {\n const {spec, metadata, backfill} = change;\n const table = {schema: spec.schema, name: spec.name};\n const ops: CookieOp[] = [];\n if (metadata) {\n ops.push({op: 'upsert-metadata', table, metadata});\n }\n if (backfill) {\n for (const [column, id] of Object.entries(backfill)) {\n ops.push({op: 'upsert-backfill', table, column, backfill: id});\n }\n }\n return ops;\n }\n\n case 'rename-table':\n return [{op: 'rename-table', old: change.old, new: change.new}];\n\n case 'drop-table':\n return [{op: 'drop-table', table: change.id}];\n\n case 'add-column': {\n const {table, tableMetadata, column, backfill} = change;\n const ops: CookieOp[] = [];\n if (tableMetadata) {\n ops.push({op: 'upsert-metadata', table, metadata: tableMetadata});\n }\n if (backfill) {\n ops.push({\n op: 'upsert-backfill',\n table,\n column: column.name,\n backfill,\n });\n }\n return ops;\n }\n\n case 'update-column': {\n // Only a rename moves the cookie; the rest of a column update does not\n // affect whether or how it is being backfilled.\n const {table, old, new: updated} = change;\n return old.name === updated.name\n ? []\n : [{op: 'rename-column', table, old: old.name, new: updated.name}];\n }\n\n case 'drop-column':\n return [{op: 'drop-column', table: change.table, column: change.column}];\n\n case 'backfill-completed': {\n const {relation, columns} = change;\n // The rowKey columns are excluded from `columns` but are backfilled with\n // them, so both are cleared.\n const cleared = [...relation.rowKey.columns, ...columns];\n return cleared.length === 0\n ? []\n : [\n {\n op: 'complete-backfill',\n table: {schema: relation.schema, name: relation.name},\n columns: cleared,\n },\n ];\n }\n\n case 'create-index':\n case 'drop-index':\n return [];\n\n default:\n // Unreachable: `isSchemaChange()` gates on the same tag set this switch\n // covers. It is exhaustive so that a new schema-change tag is a compile\n // error here rather than a silently dropped backfill.\n unreachable(change);\n }\n}\n\n/**\n * The SQLite interpreter of {@link cookieOps}, over prepared statements on the\n * change-log database.\n *\n * The statements run inside the log's transaction, in stream order, at the point\n * the schema change is appended (see `ChangeLogStreamWriter`). That is what\n * makes the cookie set atomic with the head — a crash cannot leave cookies ahead\n * of or behind the rows they were folded from — and what makes an aborted\n * transaction discard its cookies with its rows, for free.\n *\n * Statements are prepared against the tables as they exist now, so an instance\n * does not survive a reconcile that drops and recreates them.\n */\nexport class ChangeLogCookieWriter {\n readonly #upsertMetadata: Statement;\n readonly #upsertBackfill: Statement;\n readonly #renameMetadataTable: Statement;\n readonly #renameBackfillTable: Statement;\n readonly #deleteMetadataTable: Statement;\n readonly #deleteBackfillTable: Statement;\n readonly #renameBackfillColumn: Statement;\n readonly #deleteBackfillColumn: Statement;\n\n constructor(db: Database) {\n this.#upsertMetadata = db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n (\"schema\", \"table\", \"metadata\") VALUES (?, ?, ?)\n ON CONFLICT (\"schema\", \"table\")\n DO UPDATE SET \"metadata\" = excluded.\"metadata\"\n `);\n this.#upsertBackfill = db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n (\"schema\", \"table\", \"column\", \"backfill\") VALUES (?, ?, ?, ?)\n ON CONFLICT (\"schema\", \"table\", \"column\")\n DO UPDATE SET \"backfill\" = excluded.\"backfill\"\n `);\n this.#renameMetadataTable = db.prepare(/*sql*/ `\n UPDATE \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n SET \"schema\" = ?, \"table\" = ? WHERE \"schema\" = ? AND \"table\" = ?\n `);\n this.#renameBackfillTable = db.prepare(/*sql*/ `\n UPDATE \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n SET \"schema\" = ?, \"table\" = ? WHERE \"schema\" = ? AND \"table\" = ?\n `);\n this.#deleteMetadataTable = db.prepare(/*sql*/ `\n DELETE FROM \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n WHERE \"schema\" = ? AND \"table\" = ?\n `);\n this.#deleteBackfillTable = db.prepare(/*sql*/ `\n DELETE FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n WHERE \"schema\" = ? AND \"table\" = ?\n `);\n this.#renameBackfillColumn = db.prepare(/*sql*/ `\n UPDATE \"${CHANGE_LOG_BACKFILLING_TABLE}\" SET \"column\" = ?\n WHERE \"schema\" = ? AND \"table\" = ? AND \"column\" = ?\n `);\n this.#deleteBackfillColumn = db.prepare(/*sql*/ `\n DELETE FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n WHERE \"schema\" = ? AND \"table\" = ? AND \"column\" = ?\n `);\n }\n\n /** Applies the change's cookie ops, returning the ops that were applied. */\n apply(change: SchemaChange): CookieOp[] {\n const ops = cookieOps(change);\n for (const op of ops) {\n this.#run(op);\n }\n return ops;\n }\n\n #run(op: CookieOp): void {\n switch (op.op) {\n case 'upsert-metadata':\n this.#upsertMetadata.run(\n op.table.schema,\n op.table.name,\n BigIntJSON.stringify(op.metadata),\n );\n break;\n\n case 'upsert-backfill':\n this.#upsertBackfill.run(\n op.table.schema,\n op.table.name,\n op.column,\n BigIntJSON.stringify(op.backfill),\n );\n break;\n\n case 'rename-table':\n this.#renameMetadataTable.run(\n op.new.schema,\n op.new.name,\n op.old.schema,\n op.old.name,\n );\n this.#renameBackfillTable.run(\n op.new.schema,\n op.new.name,\n op.old.schema,\n op.old.name,\n );\n break;\n\n case 'drop-table':\n this.#deleteMetadataTable.run(op.table.schema, op.table.name);\n this.#deleteBackfillTable.run(op.table.schema, op.table.name);\n break;\n\n case 'rename-column':\n this.#renameBackfillColumn.run(\n op.new,\n op.table.schema,\n op.table.name,\n op.old,\n );\n break;\n\n case 'drop-column':\n this.#deleteBackfillColumn.run(\n op.table.schema,\n op.table.name,\n op.column,\n );\n break;\n\n case 'complete-backfill':\n // A per-column delete rather than an `IN` list, which cannot be a\n // single prepared statement across arities. The columns of one\n // completed backfill are few, and this runs only on schema changes.\n for (const column of op.columns) {\n this.#deleteBackfillColumn.run(\n op.table.schema,\n op.table.name,\n column,\n );\n }\n break;\n\n default:\n unreachable(op);\n }\n }\n}\n\nconst tableKey = (schema: string, table: string) =>\n JSON.stringify([schema, table]);\n\nconst columnKey = (schema: string, table: string, column: string) =>\n JSON.stringify([schema, table, column]);\n\nconst cmp = (a: string, b: string) => (a < b ? -1 : a > b ? 1 : 0);\n\n/**\n * The in-memory interpreter of {@link cookieOps}: the third one, and the only\n * one that is not a store.\n *\n * A replica-derived cookie set is a snapshot at the replica's state version,\n * which trails the change log's head, so it cannot be compared with a\n * Postgres-derived set directly. This carries it forward over the schema changes\n * the log holds in between, which turns \"the two stores disagree, but they are\n * also at different positions\" into an exact equality — and makes a\n * disagreement between any two of the three interpreters visible as an\n * inequality that neither store would have noticed on its own.\n *\n * `changes` must be the log's schema changes over `(from, to]` in stream order.\n * Anything else produces a set that belongs to no watermark.\n */\nexport function foldCookies(\n cookies: CookieSet,\n changes: Iterable<SchemaChange>,\n): CookieSet {\n const metadata = new Map<string, TableMetadataCookie>(\n cookies.tableMetadata.map(c => [tableKey(c.schema, c.table), c]),\n );\n const backfilling = new Map<string, BackfillCookie>(\n cookies.backfilling.map(c => [columnKey(c.schema, c.table, c.column), c]),\n );\n const dropColumn = ({schema, name}: Identifier, column: string) =>\n backfilling.delete(columnKey(schema, name, column));\n\n for (const change of changes) {\n for (const op of cookieOps(change)) {\n switch (op.op) {\n case 'upsert-metadata':\n metadata.set(tableKey(op.table.schema, op.table.name), {\n schema: op.table.schema,\n table: op.table.name,\n metadata: op.metadata,\n });\n break;\n\n case 'upsert-backfill':\n backfilling.set(\n columnKey(op.table.schema, op.table.name, op.column),\n {\n schema: op.table.schema,\n table: op.table.name,\n column: op.column,\n backfill: op.backfill,\n },\n );\n break;\n\n case 'rename-table': {\n const {old, new: renamed} = op;\n const moved = metadata.get(tableKey(old.schema, old.name));\n if (moved) {\n metadata.delete(tableKey(old.schema, old.name));\n metadata.set(tableKey(renamed.schema, renamed.name), {\n ...moved,\n schema: renamed.schema,\n table: renamed.name,\n });\n }\n // Snapshotted before mutating, since the rename both deletes and\n // inserts into the map being scanned.\n for (const [key, cookie] of [...backfilling]) {\n if (cookie.schema === old.schema && cookie.table === old.name) {\n backfilling.delete(key);\n backfilling.set(\n columnKey(renamed.schema, renamed.name, cookie.column),\n {...cookie, schema: renamed.schema, table: renamed.name},\n );\n }\n }\n break;\n }\n\n case 'drop-table': {\n const {schema, name} = op.table;\n metadata.delete(tableKey(schema, name));\n for (const [key, cookie] of [...backfilling]) {\n if (cookie.schema === schema && cookie.table === name) {\n backfilling.delete(key);\n }\n }\n break;\n }\n\n case 'rename-column': {\n const {schema, name} = op.table;\n const moved = backfilling.get(columnKey(schema, name, op.old));\n if (moved) {\n backfilling.delete(columnKey(schema, name, op.old));\n backfilling.set(columnKey(schema, name, op.new), {\n ...moved,\n column: op.new,\n });\n }\n break;\n }\n\n case 'drop-column':\n dropColumn(op.table, op.column);\n break;\n\n case 'complete-backfill':\n for (const column of op.columns) {\n dropColumn(op.table, column);\n }\n break;\n\n default:\n unreachable(op);\n }\n }\n }\n\n return {\n tableMetadata: [...metadata.values()].toSorted(\n (a, b) => cmp(a.schema, b.schema) || cmp(a.table, b.table),\n ),\n backfilling: [...backfilling.values()].toSorted(\n (a, b) =>\n cmp(a.schema, b.schema) ||\n cmp(a.table, b.table) ||\n cmp(a.column, b.column),\n ),\n };\n}\n\nconst backfillRequestsSchema = v.array(backfillRequestSchema);\n\n/**\n * Returns one {@link BackfillRequest} for each table with an active backfill.\n * Each request contains the stored table metadata, if available.\n */\nexport function backfillRequestsFrom(cookies: CookieSet): BackfillRequest[] {\n const metadata = new Map(\n cookies.tableMetadata.map(c => [tableKey(c.schema, c.table), c.metadata]),\n );\n const requests: BackfillRequest[] = [];\n let curr: BackfillRequest | undefined;\n for (const {schema, table, column, backfill} of cookies.backfilling) {\n if (curr?.table.schema !== schema || curr.table.name !== table) {\n curr = {\n table: {\n schema,\n name: table,\n // Use `null` when a backfilling table has no metadata. This matches\n // the result of the Postgres left join.\n metadata: metadata.get(tableKey(schema, table)) ?? null,\n },\n columns: {},\n };\n requests.push(curr);\n }\n curr.columns[column] = {id: backfill};\n }\n return v.parse(requests, backfillRequestsSchema);\n}\n\n/**\n * Reads the whole cookie set, ordered by primary key. This is what a\n * change-streamer would hand `startStream`, and what the Postgres-derived and\n * replica-derived sets are compared against.\n */\nexport function readCookies(db: Database): CookieSet {\n const tableMetadata = db\n .prepare(/*sql*/ `\n SELECT \"schema\", \"table\", \"metadata\"\n FROM \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n ORDER BY \"schema\", \"table\"\n `)\n .all<{schema: string; table: string; metadata: string}>()\n .map(({schema, table, metadata}) => ({\n schema,\n table,\n metadata: BigIntJSON.parse(metadata) as TableMetadata,\n }));\n\n const backfilling = db\n .prepare(/*sql*/ `\n SELECT \"schema\", \"table\", \"column\", \"backfill\"\n FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n ORDER BY \"schema\", \"table\", \"column\"\n `)\n .all<{schema: string; table: string; column: string; backfill: string}>()\n .map(({schema, table, column, backfill}) => ({\n schema,\n table,\n column,\n backfill: BigIntJSON.parse(backfill) as BackfillID,\n }));\n\n return {tableMetadata, backfilling};\n}\n\n/**\n * Replaces the cookie set wholesale.\n *\n * The cookies are unversioned point-in-time state, so a reconciliation that\n * moves the head invalidates them: truncating the stream above `W` does not roll\n * the cookie set back to `W`, and the truncated transactions can contain\n * `create-table`, `add-column`, and `backfill-completed`. The caller must run\n * this in the same transaction as the reconciliation that invalidated them.\n */\nexport function replaceCookies(db: Database, cookies: CookieSet): void {\n db.prepare(/*sql*/ `DELETE FROM \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"`).run();\n db.prepare(/*sql*/ `DELETE FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\"`).run();\n\n if (cookies.tableMetadata.length > 0) {\n const insert = db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_TABLE_METADATA_TABLE}\"\n (\"schema\", \"table\", \"metadata\") VALUES (?, ?, ?)\n `);\n for (const {schema, table, metadata} of cookies.tableMetadata) {\n insert.run(schema, table, BigIntJSON.stringify(metadata));\n }\n }\n if (cookies.backfilling.length > 0) {\n const insert = db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_BACKFILLING_TABLE}\"\n (\"schema\", \"table\", \"column\", \"backfill\") VALUES (?, ?, ?, ?)\n `);\n for (const {schema, table, column, backfill} of cookies.backfilling) {\n insert.run(schema, table, column, BigIntJSON.stringify(backfill));\n }\n }\n}\n\n/** Retained cookie rows, by table. Both are normally zero. */\nexport type CookieRowCounts = {\n readonly tableMetadata: number;\n readonly backfilling: number;\n};\n\nexport function readCookieRowCounts(db: Database): CookieRowCounts {\n return db\n .prepare(/*sql*/ `\n SELECT\n (SELECT count(*) FROM \"${CHANGE_LOG_TABLE_METADATA_TABLE}\")\n AS \"tableMetadata\",\n (SELECT count(*) FROM \"${CHANGE_LOG_BACKFILLING_TABLE}\")\n AS \"backfilling\"\n `)\n .get<CookieRowCounts>();\n}\n"],"mappings":"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"}
@@ -4,7 +4,8 @@ import { type CookieOpTag } from './change-log-cookies.ts';
4
4
  export type ChangeLogStreamTransactionStats = {
5
5
  readonly rows: number;
6
6
  readonly estimatedBytes: number;
7
- readonly hash: string;
7
+ /** Present only for transactions selected for shadow-write validation. */
8
+ readonly hash?: string | undefined;
8
9
  /**
9
10
  * The cookie mutations this transaction's schema changes folded in, in stream
10
11
  * order. Empty for the overwhelming majority of transactions.
@@ -32,7 +33,7 @@ export declare class ChangeLogStreamInvariantError extends Error {
32
33
  export declare class ChangeLogStreamWriter {
33
34
  #private;
34
35
  constructor(db: StatementRunner);
35
- begin(watermark: string, json: string): void;
36
+ begin(watermark: string, json: string, storedChange?: string, hash?: boolean): void;
36
37
  /**
37
38
  * Appends one data or schema change. The parsed message is taken rather than
38
39
  * just its tag because a schema change also mutates the cookie jar, and the
@@ -43,8 +44,8 @@ export declare class ChangeLogStreamWriter {
43
44
  * has to flush its buffered batch to get the same ordering
44
45
  * (`Storer.#processQueue()`); SQLite gets it from statement order.
45
46
  */
46
- append(json: string, change: DataOrSchemaChange): void;
47
- commit(watermark: string, json: string, writeTimeMs: number): ChangeLogStreamTransactionStats;
47
+ append(json: string, change: DataOrSchemaChange, storedChange?: string): void;
48
+ commit(watermark: string, json: string, writeTimeMs: number, storedChange?: string): ChangeLogStreamTransactionStats;
48
49
  /**
49
50
  * Discards the open transaction, if any. Safe to call when none is open — the
50
51
  * caller rolls back on an interrupted change stream, which can arrive between
@@ -1 +1 @@
1
- {"version":3,"file":"change-log-stream-writer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/replicator/change-log-stream-writer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,2CAA2C,CAAC;AAGnD,OAAO,EAAwB,KAAK,WAAW,EAAC,MAAM,yBAAyB,CAAC;AAMhF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,eAAe,EAAE,SAAS,WAAW,EAAE,CAAC;CAClD,CAAC;AAEF,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,SAAkB,IAAI,mCAAmC;CAC1D;AAWD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,qBAAqB;;IAYhC,YAAY,EAAE,EAAE,eAAe,EAc9B;IAED,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAiC3C;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAwBrD;IAED,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,GAClB,+BAA+B,CA2CjC;IAED;;;;OAIG;IACH,QAAQ,IAAI,IAAI,CAMf;CA2BF"}
1
+ {"version":3,"file":"change-log-stream-writer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/replicator/change-log-stream-writer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,2CAA2C,CAAC;AAGnD,OAAO,EAAwB,KAAK,WAAW,EAAC,MAAM,yBAAyB,CAAC;AAMhF,MAAM,MAAM,+BAA+B,GAAG;IAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC;;;OAGG;IACH,QAAQ,CAAC,eAAe,EAAE,SAAS,WAAW,EAAE,CAAC;CAClD,CAAC;AAEF,qBAAa,6BAA8B,SAAQ,KAAK;IACtD,SAAkB,IAAI,mCAAmC;CAC1D;AAWD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,qBAAqB;;IAYhC,YAAY,EAAE,EAAE,eAAe,EAc9B;IAED,KAAK,CACH,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,YAAY,SAAwC,EACpD,IAAI,UAAO,GACV,IAAI,CAmCN;IAED;;;;;;;;;OASG;IACH,MAAM,CACJ,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,kBAAkB,EAC1B,YAAY,SAA2C,GACtD,IAAI,CAwBN;IAED,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,YAAY,SAAyC,GACpD,+BAA+B,CA2CjC;IAED;;;;OAIG;IACH,QAAQ,IAAI,IAAI,CAMf;CAmBF"}
@@ -50,22 +50,24 @@ var ChangeLogStreamWriter = class {
50
50
  `);
51
51
  this.#cookies = new ChangeLogCookieWriter(db.db);
52
52
  }
53
- begin(watermark, json) {
53
+ begin(watermark, json, storedChange = extractChangeSubstring(json, "begin"), hash = true) {
54
54
  assertInvariant(this.#watermark === void 0, `change-log stream transaction already open at ${this.#watermark}`);
55
55
  this.#db.beginImmediate();
56
56
  this.#watermark = watermark;
57
57
  this.#pos = 0;
58
- const change = extractChangeSubstring(json, "begin");
58
+ const change = storedChange;
59
59
  const estimatedBytes = estimateChangeLogStreamRowBytes(watermark, "begin", change);
60
60
  this.#insertChange.run(watermark, this.#pos, "begin", estimatedBytes, change);
61
- this.#hasher = new ChangeLogTransactionHasher();
62
- this.#hasher.add({
63
- watermark,
64
- pos: this.#pos,
65
- tag: "begin",
66
- change,
67
- precommit: null
68
- });
61
+ if (hash) {
62
+ this.#hasher = new ChangeLogTransactionHasher();
63
+ this.#hasher.add({
64
+ watermark,
65
+ pos: this.#pos,
66
+ tag: "begin",
67
+ change,
68
+ precommit: null
69
+ });
70
+ }
69
71
  this.#estimatedBytes = estimatedBytes;
70
72
  }
71
73
  /**
@@ -78,13 +80,13 @@ var ChangeLogStreamWriter = class {
78
80
  * has to flush its buffered batch to get the same ordering
79
81
  * (`Storer.#processQueue()`); SQLite gets it from statement order.
80
82
  */
81
- append(json, change) {
83
+ append(json, change, storedChange = extractChangeSubstring(json, change.tag)) {
82
84
  const watermark = this.#requireWatermark();
83
85
  const { tag } = change;
84
- const stored = extractChangeSubstring(json, tag);
86
+ const stored = storedChange;
85
87
  const estimatedBytes = estimateChangeLogStreamRowBytes(watermark, tag, stored);
86
88
  this.#insertChange.run(watermark, ++this.#pos, tag, estimatedBytes, stored);
87
- this.#requireHasher().add({
89
+ this.#hasher?.add({
88
90
  watermark,
89
91
  pos: this.#pos,
90
92
  tag,
@@ -94,14 +96,14 @@ var ChangeLogStreamWriter = class {
94
96
  this.#estimatedBytes += estimatedBytes;
95
97
  if (isSchemaChange(change)) for (const op of this.#cookies.apply(change)) this.#cookieMutations.push(op.op);
96
98
  }
97
- commit(watermark, json, writeTimeMs) {
99
+ commit(watermark, json, writeTimeMs, storedChange = extractChangeSubstring(json, "commit")) {
98
100
  const precommit = this.#requireWatermark();
99
101
  assertInvariant(watermark === precommit, `change-log stream commit ${watermark} does not match begin ${precommit}`);
100
- const change = extractChangeSubstring(json, "commit");
102
+ const change = storedChange;
101
103
  const estimatedBytes = estimateChangeLogStreamRowBytes(watermark, "commit", change, precommit, true);
102
104
  this.#insertCommit.run(watermark, ++this.#pos, estimatedBytes, change, precommit, writeTimeMs);
103
- const hasher = this.#requireHasher();
104
- hasher.add({
105
+ const hasher = this.#hasher;
106
+ hasher?.add({
105
107
  watermark,
106
108
  pos: this.#pos,
107
109
  tag: "commit",
@@ -111,7 +113,7 @@ var ChangeLogStreamWriter = class {
111
113
  const stats = {
112
114
  rows: this.#pos + 1,
113
115
  estimatedBytes: this.#estimatedBytes + estimatedBytes,
114
- hash: hasher.digest(),
116
+ hash: hasher?.digest(),
115
117
  cookieMutations: this.#cookieMutations
116
118
  };
117
119
  this.#db.commit();
@@ -139,10 +141,6 @@ var ChangeLogStreamWriter = class {
139
141
  assertInvariant(this.#watermark !== void 0, "change-log stream message received outside of a transaction");
140
142
  return this.#watermark;
141
143
  }
142
- #requireHasher() {
143
- assertInvariant(this.#hasher !== void 0, "change-log stream hash received outside of a transaction");
144
- return this.#hasher;
145
- }
146
144
  };
147
145
  //#endregion
148
146
  export { ChangeLogStreamWriter };
@@ -1 +1 @@
1
- {"version":3,"file":"change-log-stream-writer.js","names":["#db","#insertChange","#insertCommit","#cookies","#watermark","#pos","#hasher","#estimatedBytes","#requireWatermark","#requireHasher","#cookieMutations","#reset"],"sources":["../../../../../../zero-cache/src/services/replicator/change-log-stream-writer.ts"],"sourcesContent":["import type {Statement} from '../../../../zqlite/src/db.ts';\nimport type {StatementRunner} from '../../db/statements.ts';\nimport {\n isSchemaChange,\n type DataOrSchemaChange,\n} from '../change-source/protocol/current/data.ts';\nimport {extractChangeSubstring} from '../change-streamer/change-log-codec.ts';\nimport {ChangeLogTransactionHasher} from '../change-streamer/change-log-transaction-hash.ts';\nimport {ChangeLogCookieWriter, type CookieOpTag} from './change-log-cookies.ts';\nimport {\n CHANGE_LOG_STREAM_TABLE,\n estimateChangeLogStreamRowBytes,\n} from './change-log-db.ts';\n\nexport type ChangeLogStreamTransactionStats = {\n readonly rows: number;\n readonly estimatedBytes: number;\n readonly hash: string;\n /**\n * The cookie mutations this transaction's schema changes folded in, in stream\n * order. Empty for the overwhelming majority of transactions.\n */\n readonly cookieMutations: readonly CookieOpTag[];\n};\n\nexport class ChangeLogStreamInvariantError extends Error {\n override readonly name = 'ChangeLogStreamInvariantError';\n}\n\nfunction assertInvariant(\n condition: unknown,\n message: string,\n): asserts condition {\n if (!condition) {\n throw new ChangeLogStreamInvariantError(message);\n }\n}\n\n/**\n * Appends the canonical downstream stream to the change-log database, which is\n * a separate file from the replica, and folds its schema changes into the log's\n * cookie jar (`change-log-cookies.ts`) as it goes.\n *\n * This class owns the change log's transaction, and its transaction alone. It is\n * driven from the change-streamer's stream loop, which commits it before\n * forwarding a transaction's `commit` message; see `SQLiteChangeLogWriter` in\n * `change-streamer/sqlite-change-log-writer.ts` for the ordering that makes a\n * hole unreachable, and for the fail-soft policy that wraps every call here.\n *\n * Because the cookies are written in that same transaction, they are atomic with\n * the head and {@link rollback} discards them with the rows they were folded\n * from. Neither needs any handling of its own.\n */\nexport class ChangeLogStreamWriter {\n readonly #db: StatementRunner;\n readonly #insertChange: Statement;\n readonly #insertCommit: Statement;\n readonly #cookies: ChangeLogCookieWriter;\n\n #watermark: string | undefined;\n #pos = 0;\n #estimatedBytes = 0;\n #hasher: ChangeLogTransactionHasher | undefined;\n #cookieMutations: CookieOpTag[] = [];\n\n constructor(db: StatementRunner) {\n this.#db = db;\n this.#insertChange = db.db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_STREAM_TABLE}\"\n (\"watermark\", \"pos\", \"tag\", \"estimatedBytes\", \"change\")\n VALUES (?, ?, ?, ?, ?)\n `);\n this.#insertCommit = db.db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_STREAM_TABLE}\"\n (\"watermark\", \"pos\", \"tag\", \"estimatedBytes\", \"change\", \"precommit\",\n \"writeTimeMs\")\n VALUES (?, ?, 'commit', ?, ?, ?, ?)\n `);\n this.#cookies = new ChangeLogCookieWriter(db.db);\n }\n\n begin(watermark: string, json: string): void {\n assertInvariant(\n this.#watermark === undefined,\n `change-log stream transaction already open at ${this.#watermark}`,\n );\n // This process is the sole writer of the change-log database, so the write\n // lock is taken up front rather than risking a failed upgrade from a\n // deferred transaction partway through the append.\n this.#db.beginImmediate();\n this.#watermark = watermark;\n this.#pos = 0;\n const change = extractChangeSubstring(json, 'begin');\n const estimatedBytes = estimateChangeLogStreamRowBytes(\n watermark,\n 'begin',\n change,\n );\n this.#insertChange.run(\n watermark,\n this.#pos,\n 'begin',\n estimatedBytes,\n change,\n );\n this.#hasher = new ChangeLogTransactionHasher();\n this.#hasher.add({\n watermark,\n pos: this.#pos,\n tag: 'begin',\n change,\n precommit: null,\n });\n this.#estimatedBytes = estimatedBytes;\n }\n\n /**\n * Appends one data or schema change. The parsed message is taken rather than\n * just its tag because a schema change also mutates the cookie jar, and the\n * caller already holds it — so the fold costs no re-parse.\n *\n * The cookie statements run here, i.e. inside this transaction and in stream\n * order relative to the rows they were folded from. The Postgres change log\n * has to flush its buffered batch to get the same ordering\n * (`Storer.#processQueue()`); SQLite gets it from statement order.\n */\n append(json: string, change: DataOrSchemaChange): void {\n const watermark = this.#requireWatermark();\n const {tag} = change;\n const stored = extractChangeSubstring(json, tag);\n const estimatedBytes = estimateChangeLogStreamRowBytes(\n watermark,\n tag,\n stored,\n );\n this.#insertChange.run(watermark, ++this.#pos, tag, estimatedBytes, stored);\n this.#requireHasher().add({\n watermark,\n pos: this.#pos,\n tag,\n change: stored,\n precommit: null,\n });\n this.#estimatedBytes += estimatedBytes;\n\n if (isSchemaChange(change)) {\n for (const op of this.#cookies.apply(change)) {\n this.#cookieMutations.push(op.op);\n }\n }\n }\n\n commit(\n watermark: string,\n json: string,\n writeTimeMs: number,\n ): ChangeLogStreamTransactionStats {\n const precommit = this.#requireWatermark();\n assertInvariant(\n watermark === precommit,\n `change-log stream commit ${watermark} does not match begin ${precommit}`,\n );\n const change = extractChangeSubstring(json, 'commit');\n const estimatedBytes = estimateChangeLogStreamRowBytes(\n watermark,\n 'commit',\n change,\n precommit,\n true,\n );\n this.#insertCommit.run(\n watermark,\n ++this.#pos,\n estimatedBytes,\n change,\n precommit,\n writeTimeMs,\n );\n const hasher = this.#requireHasher();\n hasher.add({\n watermark,\n pos: this.#pos,\n tag: 'commit',\n change,\n precommit,\n });\n const stats = {\n rows: this.#pos + 1,\n estimatedBytes: this.#estimatedBytes + estimatedBytes,\n hash: hasher.digest(),\n cookieMutations: this.#cookieMutations,\n };\n // The log is durable at `watermark` from here on, and nothing that can\n // advance the watermark the stream would resume from has run yet. A crash in\n // that window leaves a transaction the resumed stream re-delivers, which\n // reconciliation truncates.\n this.#db.commit();\n this.#reset();\n return stats;\n }\n\n /**\n * Discards the open transaction, if any. Safe to call when none is open — the\n * caller rolls back on an interrupted change stream, which can arrive between\n * transactions as well as inside one.\n */\n rollback(): void {\n const {inTransaction} = this.#db.db;\n this.#reset();\n if (inTransaction) {\n this.#db.rollback();\n }\n }\n\n #reset(): void {\n this.#watermark = undefined;\n this.#pos = 0;\n this.#estimatedBytes = 0;\n this.#hasher = undefined;\n // A fresh array rather than a truncation: the committed stats hold a\n // reference to the previous one.\n this.#cookieMutations = [];\n }\n\n #requireWatermark(): string {\n assertInvariant(\n this.#watermark !== undefined,\n 'change-log stream message received outside of a transaction',\n );\n return this.#watermark;\n }\n\n #requireHasher(): ChangeLogTransactionHasher {\n assertInvariant(\n this.#hasher !== undefined,\n 'change-log stream hash received outside of a transaction',\n );\n return this.#hasher;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"change-log-stream-writer.js","names":["#db","#insertChange","#insertCommit","#cookies","#watermark","#pos","#hasher","#estimatedBytes","#requireWatermark","#cookieMutations","#reset"],"sources":["../../../../../../zero-cache/src/services/replicator/change-log-stream-writer.ts"],"sourcesContent":["import type {Statement} from '../../../../zqlite/src/db.ts';\nimport type {StatementRunner} from '../../db/statements.ts';\nimport {\n isSchemaChange,\n type DataOrSchemaChange,\n} from '../change-source/protocol/current/data.ts';\nimport {extractChangeSubstring} from '../change-streamer/change-log-codec.ts';\nimport {ChangeLogTransactionHasher} from '../change-streamer/change-log-transaction-hash.ts';\nimport {ChangeLogCookieWriter, type CookieOpTag} from './change-log-cookies.ts';\nimport {\n CHANGE_LOG_STREAM_TABLE,\n estimateChangeLogStreamRowBytes,\n} from './change-log-db.ts';\n\nexport type ChangeLogStreamTransactionStats = {\n readonly rows: number;\n readonly estimatedBytes: number;\n /** Present only for transactions selected for shadow-write validation. */\n readonly hash?: string | undefined;\n /**\n * The cookie mutations this transaction's schema changes folded in, in stream\n * order. Empty for the overwhelming majority of transactions.\n */\n readonly cookieMutations: readonly CookieOpTag[];\n};\n\nexport class ChangeLogStreamInvariantError extends Error {\n override readonly name = 'ChangeLogStreamInvariantError';\n}\n\nfunction assertInvariant(\n condition: unknown,\n message: string,\n): asserts condition {\n if (!condition) {\n throw new ChangeLogStreamInvariantError(message);\n }\n}\n\n/**\n * Appends the canonical downstream stream to the change-log database, which is\n * a separate file from the replica, and folds its schema changes into the log's\n * cookie jar (`change-log-cookies.ts`) as it goes.\n *\n * This class owns the change log's transaction, and its transaction alone. It is\n * driven from the change-streamer's stream loop, which commits it before\n * forwarding a transaction's `commit` message; see `SQLiteChangeLogWriter` in\n * `change-streamer/sqlite-change-log-writer.ts` for the ordering that makes a\n * hole unreachable, and for the fail-soft policy that wraps every call here.\n *\n * Because the cookies are written in that same transaction, they are atomic with\n * the head and {@link rollback} discards them with the rows they were folded\n * from. Neither needs any handling of its own.\n */\nexport class ChangeLogStreamWriter {\n readonly #db: StatementRunner;\n readonly #insertChange: Statement;\n readonly #insertCommit: Statement;\n readonly #cookies: ChangeLogCookieWriter;\n\n #watermark: string | undefined;\n #pos = 0;\n #estimatedBytes = 0;\n #hasher: ChangeLogTransactionHasher | undefined;\n #cookieMutations: CookieOpTag[] = [];\n\n constructor(db: StatementRunner) {\n this.#db = db;\n this.#insertChange = db.db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_STREAM_TABLE}\"\n (\"watermark\", \"pos\", \"tag\", \"estimatedBytes\", \"change\")\n VALUES (?, ?, ?, ?, ?)\n `);\n this.#insertCommit = db.db.prepare(/*sql*/ `\n INSERT INTO \"${CHANGE_LOG_STREAM_TABLE}\"\n (\"watermark\", \"pos\", \"tag\", \"estimatedBytes\", \"change\", \"precommit\",\n \"writeTimeMs\")\n VALUES (?, ?, 'commit', ?, ?, ?, ?)\n `);\n this.#cookies = new ChangeLogCookieWriter(db.db);\n }\n\n begin(\n watermark: string,\n json: string,\n storedChange = extractChangeSubstring(json, 'begin'),\n hash = true,\n ): void {\n assertInvariant(\n this.#watermark === undefined,\n `change-log stream transaction already open at ${this.#watermark}`,\n );\n // This process is the sole writer of the change-log database, so the write\n // lock is taken up front rather than risking a failed upgrade from a\n // deferred transaction partway through the append.\n this.#db.beginImmediate();\n this.#watermark = watermark;\n this.#pos = 0;\n const change = storedChange;\n const estimatedBytes = estimateChangeLogStreamRowBytes(\n watermark,\n 'begin',\n change,\n );\n this.#insertChange.run(\n watermark,\n this.#pos,\n 'begin',\n estimatedBytes,\n change,\n );\n if (hash) {\n this.#hasher = new ChangeLogTransactionHasher();\n this.#hasher.add({\n watermark,\n pos: this.#pos,\n tag: 'begin',\n change,\n precommit: null,\n });\n }\n this.#estimatedBytes = estimatedBytes;\n }\n\n /**\n * Appends one data or schema change. The parsed message is taken rather than\n * just its tag because a schema change also mutates the cookie jar, and the\n * caller already holds it — so the fold costs no re-parse.\n *\n * The cookie statements run here, i.e. inside this transaction and in stream\n * order relative to the rows they were folded from. The Postgres change log\n * has to flush its buffered batch to get the same ordering\n * (`Storer.#processQueue()`); SQLite gets it from statement order.\n */\n append(\n json: string,\n change: DataOrSchemaChange,\n storedChange = extractChangeSubstring(json, change.tag),\n ): void {\n const watermark = this.#requireWatermark();\n const {tag} = change;\n const stored = storedChange;\n const estimatedBytes = estimateChangeLogStreamRowBytes(\n watermark,\n tag,\n stored,\n );\n this.#insertChange.run(watermark, ++this.#pos, tag, estimatedBytes, stored);\n this.#hasher?.add({\n watermark,\n pos: this.#pos,\n tag,\n change: stored,\n precommit: null,\n });\n this.#estimatedBytes += estimatedBytes;\n\n if (isSchemaChange(change)) {\n for (const op of this.#cookies.apply(change)) {\n this.#cookieMutations.push(op.op);\n }\n }\n }\n\n commit(\n watermark: string,\n json: string,\n writeTimeMs: number,\n storedChange = extractChangeSubstring(json, 'commit'),\n ): ChangeLogStreamTransactionStats {\n const precommit = this.#requireWatermark();\n assertInvariant(\n watermark === precommit,\n `change-log stream commit ${watermark} does not match begin ${precommit}`,\n );\n const change = storedChange;\n const estimatedBytes = estimateChangeLogStreamRowBytes(\n watermark,\n 'commit',\n change,\n precommit,\n true,\n );\n this.#insertCommit.run(\n watermark,\n ++this.#pos,\n estimatedBytes,\n change,\n precommit,\n writeTimeMs,\n );\n const hasher = this.#hasher;\n hasher?.add({\n watermark,\n pos: this.#pos,\n tag: 'commit',\n change,\n precommit,\n });\n const stats = {\n rows: this.#pos + 1,\n estimatedBytes: this.#estimatedBytes + estimatedBytes,\n hash: hasher?.digest(),\n cookieMutations: this.#cookieMutations,\n };\n // The log is durable at `watermark` from here on, and nothing that can\n // advance the watermark the stream would resume from has run yet. A crash in\n // that window leaves a transaction the resumed stream re-delivers, which\n // reconciliation truncates.\n this.#db.commit();\n this.#reset();\n return stats;\n }\n\n /**\n * Discards the open transaction, if any. Safe to call when none is open — the\n * caller rolls back on an interrupted change stream, which can arrive between\n * transactions as well as inside one.\n */\n rollback(): void {\n const {inTransaction} = this.#db.db;\n this.#reset();\n if (inTransaction) {\n this.#db.rollback();\n }\n }\n\n #reset(): void {\n this.#watermark = undefined;\n this.#pos = 0;\n this.#estimatedBytes = 0;\n this.#hasher = undefined;\n // A fresh array rather than a truncation: the committed stats hold a\n // reference to the previous one.\n this.#cookieMutations = [];\n }\n\n #requireWatermark(): string {\n assertInvariant(\n this.#watermark !== undefined,\n 'change-log stream message received outside of a transaction',\n );\n return this.#watermark;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"change-processor.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/replicator/change-processor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAOjD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAmB1E,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,wBAAwB,CAAC;AAiC5D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,iDAAiD,CAAC;AACtF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAUpD,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,cAAc,CAAC;AASlE,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,cAAc,GAAG,SAAS,CAAC;IAC9C,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;;IAiB1B,YACE,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,mBAAmB,EACzB,WAAW,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,EAQpD;IA2BD,KAAK,CAAC,EAAE,EAAE,UAAU,QAEnB;IAED,8CAA8C;IAC9C,cAAc,CACZ,EAAE,EAAE,UAAU,EACd,UAAU,EAAE,gBAAgB,GAC3B,YAAY,GAAG,IAAI,CAkBrB;CAyIF"}
1
+ {"version":3,"file":"change-processor.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/replicator/change-processor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAQjD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,uCAAuC,CAAC;AAmB1E,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,wBAAwB,CAAC;AAsC5D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,iDAAiD,CAAC;AACtF,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,iBAAiB,CAAC;AAUpD,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG,cAAc,CAAC;AASlE,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,cAAc,GAAG,SAAS,CAAC;IAC9C,aAAa,EAAE,OAAO,CAAC;IACvB,gBAAgB,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;;IAiB1B,YACE,EAAE,EAAE,eAAe,EACnB,IAAI,EAAE,mBAAmB,EACzB,WAAW,EAAE,CAAC,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,KAAK,IAAI,EAQpD;IA2BD,KAAK,CAAC,EAAE,EAAE,UAAU,QAEnB;IAED,8CAA8C;IAC9C,cAAc,CACZ,EAAE,EAAE,UAAU,EACd,UAAU,EAAE,gBAAgB,GAC3B,YAAY,GAAG,IAAI,CAkBrB;CAyIF"}
@@ -1,4 +1,5 @@
1
1
  import { assert, unreachable } from "../../../../shared/src/asserts.js";
2
+ import { deepEqual } from "../../../../shared/src/json.js";
2
3
  import { AbortError } from "../../../../shared/src/abort-error.js";
3
4
  import { must } from "../../../../shared/src/must.js";
4
5
  import { mapEntries } from "../../../../shared/src/objects.js";
@@ -15,6 +16,7 @@ import { ChangeLog } from "./schema/change-log.js";
15
16
  import { updateReplicationWatermark } from "./schema/replication-state.js";
16
17
  import { id } from "../../types/sql.js";
17
18
  import { createLiteIndexStatement, createLiteTableStatement, liteColumnDef } from "../../db/create.js";
19
+ import { acceptBackfill } from "../change-source/protocol/backfill-progress.js";
18
20
  import { SqliteError } from "@rocicorp/zero-sqlite3";
19
21
  import { constants } from "node:buffer";
20
22
  //#region ../zero-cache/src/services/replicator/change-processor.ts
@@ -424,7 +426,9 @@ var TransactionProcessor = class {
424
426
  }
425
427
  processDropIndex(drop) {
426
428
  const name = liteTableName(drop.id);
429
+ const indexExisted = this.#db.db.prepare(`SELECT tbl_name as tableName FROM sqlite_master WHERE type = 'index' AND name = ?`).get(name);
427
430
  this.#db.db.exec(`DROP INDEX IF EXISTS ${id(name)}`);
431
+ if (indexExisted) this.#logResetOp(indexExisted.tableName);
428
432
  this.#lc.info?.(drop.tag, name);
429
433
  }
430
434
  #bumpVersions(table) {
@@ -460,11 +464,18 @@ var TransactionProcessor = class {
460
464
  }
461
465
  this.#reloadTableSpecs();
462
466
  }
463
- processBackfill({ relation, watermark, columns, rowValues }) {
467
+ processBackfill({ relation, watermark, columns, rowValues, progressMarks }) {
464
468
  const tableName = liteTableName(relation);
465
469
  const tableSpec = must(this.#tableSpecs.get(tableName));
466
470
  const rowKeyCols = relation.rowKey.columns;
467
471
  const cols = [...rowKeyCols, ...columns];
472
+ const { accepted, ignored } = this.#trackBackfillProgress(relation, cols, (own) => acceptBackfill(own, progressMarks));
473
+ if (accepted.length === 0) {
474
+ this.#lc.debug?.(ignored.length ? `skipping backfill of ${rowValues.length} rows into ${tableName}: not contiguous with the progress of columns [${ignored.join(",")}]` : `skipping redundant backfill of ${rowValues.length} rows into ${tableName} (all columns already published)`, progressMarks);
475
+ return;
476
+ }
477
+ if (ignored.length) this.#lc.debug?.(`backfill of ${tableName} is not contiguous with the progress of columns [${ignored.join(",")}]`, progressMarks);
478
+ const acceptedSet = new Set(accepted);
468
479
  const insertColsStr = [...cols, ZERO_VERSION_COLUMN_NAME].map(id).join(",");
469
480
  const qMarks = Array.from({ length: cols.length + 1 }).fill("?").join(",");
470
481
  const rowKeyColsStr = rowKeyCols.map(id).join(",");
@@ -478,7 +489,7 @@ var TransactionProcessor = class {
478
489
  skipped++;
479
490
  continue;
480
491
  }
481
- const updates = rowOp?.op === "s" ? cols.filter((c) => (rowOp.backfillingColumnVersions[c] ?? "") <= watermark) : cols;
492
+ const updates = (rowOp?.op === "s" ? cols.filter((c) => (rowOp.backfillingColumnVersions[c] ?? "") <= watermark) : cols).filter((c) => acceptedSet.has(c));
482
493
  if (updates.length === 0) {
483
494
  skipped++;
484
495
  continue;
@@ -494,13 +505,47 @@ var TransactionProcessor = class {
494
505
  this.#lc.debug?.(`backfilled ${backfilled} rows (skipped ${skipped}) into ${tableName}`);
495
506
  }
496
507
  #completedBackfill;
508
+ /**
509
+ * Applies `accept` to the tracked progress of each of the `cols` that are
510
+ * still backfilling on this replica, updating the progress of the accepted
511
+ * ones. Columns that are not backfilling (e.g. already published) are
512
+ * neither accepted nor ignored.
513
+ */
514
+ #trackBackfillProgress(relation, cols, accept) {
515
+ const tracked = this.#backfilling.getProgress(relation);
516
+ const accepted = [];
517
+ const ignored = [];
518
+ for (const col of cols) {
519
+ if (!tracked.has(col)) continue;
520
+ const progress = tracked.get(col);
521
+ const result = accept(progress);
522
+ if (!result.accept) {
523
+ ignored.push(col);
524
+ continue;
525
+ }
526
+ accepted.push(col);
527
+ if (!deepEqual(result.progress, progress)) this.#backfilling.setProgress(relation, col, result.progress);
528
+ }
529
+ return {
530
+ accepted,
531
+ ignored
532
+ };
533
+ }
497
534
  processBackfillCompleted(msg) {
498
- const { relation, columns, status } = msg;
535
+ const { relation, columns, status, progressMarks } = msg;
499
536
  const tableName = liteTableName(relation);
500
- const cols = [...relation.rowKey.columns, ...columns];
537
+ const rowKeyCols = relation.rowKey.columns;
538
+ const { accepted, ignored } = this.#trackBackfillProgress(relation, [...rowKeyCols, ...columns], (own) => acceptBackfill(own, progressMarks ? { previous: progressMarks.previous } : void 0));
539
+ if (ignored.length) this.#lc.info?.(`ignoring backfill-completed of ${tableName} for columns [${ignored.join(",")}], which have not received all of the data`, progressMarks);
540
+ if (accepted.length === 0) {
541
+ if (ignored.length === 0) this.#lc.debug?.(`skipping redundant backfill-completed for ${tableName} (all columns already published)`);
542
+ return;
543
+ }
544
+ const ignoredSet = new Set(ignored);
545
+ const cols = [...rowKeyCols.filter((c) => !ignoredSet.has(c)), ...columns.filter((c) => !ignoredSet.has(c))];
501
546
  const columnMetadata = must(ColumnMetadataStore.getInstance(this.#db.db));
502
547
  for (const col of cols) columnMetadata.clearBackfilling(tableName, col);
503
- this.#backfilling.apply(msg);
548
+ this.#backfilling.complete(relation, cols);
504
549
  this.#bumpVersions(relation);
505
550
  if (status) this.#completedBackfill = {
506
551
  table: tableName,
@@ -531,6 +576,7 @@ var TransactionProcessor = class {
531
576
  abort(lc) {
532
577
  lc.info?.(`aborting transaction ${this.#version}`);
533
578
  this.#db.rollback();
579
+ this.#tableSpecs.clear();
534
580
  }
535
581
  };
536
582
  function differentStorageTypes(oldSpec, newSpec) {