@rocicorp/zero 1.11.0-canary.2 → 1.11.0-canary.21

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 (832) hide show
  1. package/out/analyze-query/src/bin-analyze.js +9 -8
  2. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  3. package/out/ast-to-zql/src/ast-to-zql.d.ts +8 -1
  4. package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
  5. package/out/ast-to-zql/src/ast-to-zql.js +25 -25
  6. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  7. package/out/otel/src/log-options.d.ts +16 -0
  8. package/out/otel/src/log-options.d.ts.map +1 -1
  9. package/out/otel/src/log-options.js +54 -1
  10. package/out/otel/src/log-options.js.map +1 -1
  11. package/out/replicache/src/bg-interval.d.ts +2 -1
  12. package/out/replicache/src/bg-interval.d.ts.map +1 -1
  13. package/out/replicache/src/bg-interval.js +13 -4
  14. package/out/replicache/src/bg-interval.js.map +1 -1
  15. package/out/replicache/src/btree/node.d.ts.map +1 -1
  16. package/out/replicache/src/btree/node.js +3 -6
  17. package/out/replicache/src/btree/node.js.map +1 -1
  18. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  19. package/out/replicache/src/dag/gc.js +8 -11
  20. package/out/replicache/src/dag/gc.js.map +1 -1
  21. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
  22. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
  23. package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
  24. package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
  25. package/out/replicache/src/dag/lazy-store.d.ts +17 -4
  26. package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
  27. package/out/replicache/src/dag/lazy-store.js +35 -9
  28. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  29. package/out/replicache/src/dag/store-impl.d.ts +12 -2
  30. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  31. package/out/replicache/src/dag/store-impl.js +29 -9
  32. package/out/replicache/src/dag/store-impl.js.map +1 -1
  33. package/out/replicache/src/db/rebase.d.ts +14 -2
  34. package/out/replicache/src/db/rebase.d.ts.map +1 -1
  35. package/out/replicache/src/db/rebase.js +27 -5
  36. package/out/replicache/src/db/rebase.js.map +1 -1
  37. package/out/replicache/src/get-kv-store-provider.d.ts +1 -1
  38. package/out/replicache/src/get-kv-store-provider.d.ts.map +1 -1
  39. package/out/replicache/src/get-kv-store-provider.js +4 -4
  40. package/out/replicache/src/get-kv-store-provider.js.map +1 -1
  41. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  42. package/out/replicache/src/kv/expo-sqlite/store.js +28 -5
  43. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  44. package/out/replicache/src/kv/idb-store.d.ts +18 -0
  45. package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
  46. package/out/replicache/src/kv/idb-store.js +30 -2
  47. package/out/replicache/src/kv/idb-store.js.map +1 -1
  48. package/out/replicache/src/kv/mem-fallback-store.d.ts +54 -0
  49. package/out/replicache/src/kv/mem-fallback-store.d.ts.map +1 -0
  50. package/out/replicache/src/kv/mem-fallback-store.js +177 -0
  51. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -0
  52. package/out/replicache/src/kv/mem-store.d.ts +1 -0
  53. package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
  54. package/out/replicache/src/kv/mem-store.js +3 -0
  55. package/out/replicache/src/kv/mem-store.js.map +1 -1
  56. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  57. package/out/replicache/src/kv/op-sqlite/store.js +4 -4
  58. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  59. package/out/replicache/src/kv/sqlite-store.d.ts +22 -1
  60. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  61. package/out/replicache/src/kv/sqlite-store.js +159 -14
  62. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  63. package/out/replicache/src/kv/store.d.ts +6 -0
  64. package/out/replicache/src/kv/store.d.ts.map +1 -1
  65. package/out/replicache/src/new-client-channel.js.map +1 -1
  66. package/out/replicache/src/persist/client-gc.d.ts +2 -1
  67. package/out/replicache/src/persist/client-gc.d.ts.map +1 -1
  68. package/out/replicache/src/persist/client-gc.js +2 -2
  69. package/out/replicache/src/persist/client-gc.js.map +1 -1
  70. package/out/replicache/src/persist/client-group-gc.d.ts +2 -1
  71. package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
  72. package/out/replicache/src/persist/client-group-gc.js +2 -2
  73. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  74. package/out/replicache/src/persist/collect-idb-databases.d.ts +28 -8
  75. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  76. package/out/replicache/src/persist/collect-idb-databases.js +97 -20
  77. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  78. package/out/replicache/src/persist/heartbeat.d.ts +2 -1
  79. package/out/replicache/src/persist/heartbeat.d.ts.map +1 -1
  80. package/out/replicache/src/persist/heartbeat.js +2 -2
  81. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  82. package/out/replicache/src/persist/idb-databases-store-db-name.js +1 -1
  83. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
  84. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  85. package/out/replicache/src/persist/persist.js +18 -8
  86. package/out/replicache/src/persist/persist.js.map +1 -1
  87. package/out/replicache/src/persist/refresh.js +6 -2
  88. package/out/replicache/src/persist/refresh.js.map +1 -1
  89. package/out/replicache/src/replicache-impl.d.ts +85 -3
  90. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  91. package/out/replicache/src/replicache-impl.js +321 -29
  92. package/out/replicache/src/replicache-impl.js.map +1 -1
  93. package/out/replicache/src/replicache-options.d.ts +9 -0
  94. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  95. package/out/replicache/src/storage-failure.d.ts +37 -0
  96. package/out/replicache/src/storage-failure.d.ts.map +1 -0
  97. package/out/replicache/src/storage-failure.js +31 -0
  98. package/out/replicache/src/storage-failure.js.map +1 -0
  99. package/out/shared/src/arrays.d.ts +5 -0
  100. package/out/shared/src/arrays.d.ts.map +1 -1
  101. package/out/shared/src/arrays.js +8 -10
  102. package/out/shared/src/arrays.js.map +1 -1
  103. package/out/shared/src/error.d.ts +11 -0
  104. package/out/shared/src/error.d.ts.map +1 -1
  105. package/out/shared/src/error.js +35 -1
  106. package/out/shared/src/error.js.map +1 -1
  107. package/out/shared/src/iterables.d.ts +2 -0
  108. package/out/shared/src/iterables.d.ts.map +1 -1
  109. package/out/shared/src/iterables.js +18 -1
  110. package/out/shared/src/iterables.js.map +1 -1
  111. package/out/shared/src/map.d.ts +24 -2
  112. package/out/shared/src/map.d.ts.map +1 -1
  113. package/out/shared/src/map.js +18 -4
  114. package/out/shared/src/map.js.map +1 -1
  115. package/out/shared/src/random-values.js +12 -1
  116. package/out/shared/src/random-values.js.map +1 -1
  117. package/out/shared/src/ring-buffer.d.ts +10 -0
  118. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  119. package/out/shared/src/ring-buffer.js +26 -1
  120. package/out/shared/src/ring-buffer.js.map +1 -1
  121. package/out/z2s/src/compiler.js +1 -1
  122. package/out/z2s/src/sql.d.ts.map +1 -1
  123. package/out/z2s/src/sql.js +2 -2
  124. package/out/z2s/src/sql.js.map +1 -1
  125. package/out/zero/package.js +3 -4
  126. package/out/zero/package.js.map +1 -1
  127. package/out/zero/src/zero.js +2 -1
  128. package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
  129. package/out/zero-cache/src/auth/write-authorizer.js +1 -0
  130. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  131. package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
  132. package/out/zero-cache/src/config/normalize.js +26 -2
  133. package/out/zero-cache/src/config/normalize.js.map +1 -1
  134. package/out/zero-cache/src/config/zero-config.d.ts +102 -6
  135. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  136. package/out/zero-cache/src/config/zero-config.js +254 -57
  137. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  138. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  139. package/out/zero-cache/src/db/lite-tables.js +3 -4
  140. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  141. package/out/zero-cache/src/observability/events.js +4 -1
  142. package/out/zero-cache/src/observability/events.js.map +1 -1
  143. package/out/zero-cache/src/observability/log-throttle.d.ts +44 -0
  144. package/out/zero-cache/src/observability/log-throttle.d.ts.map +1 -0
  145. package/out/zero-cache/src/observability/log-throttle.js +76 -0
  146. package/out/zero-cache/src/observability/log-throttle.js.map +1 -0
  147. package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
  148. package/out/zero-cache/src/observability/metrics.js +2 -7
  149. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  150. package/out/zero-cache/src/scripts/permissions.d.ts +16 -0
  151. package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
  152. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  153. package/out/zero-cache/src/server/change-streamer.js +27 -10
  154. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  155. package/out/zero-cache/src/server/inspector-delegate.d.ts +28 -2
  156. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  157. package/out/zero-cache/src/server/inspector-delegate.js +37 -17
  158. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  159. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  160. package/out/zero-cache/src/server/main.js +8 -1
  161. package/out/zero-cache/src/server/main.js.map +1 -1
  162. package/out/zero-cache/src/server/mutator.js +2 -0
  163. package/out/zero-cache/src/server/mutator.js.map +1 -1
  164. package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
  165. package/out/zero-cache/src/server/reaper.js +2 -0
  166. package/out/zero-cache/src/server/reaper.js.map +1 -1
  167. package/out/zero-cache/src/server/replicator.d.ts +3 -0
  168. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  169. package/out/zero-cache/src/server/replicator.js +79 -15
  170. package/out/zero-cache/src/server/replicator.js.map +1 -1
  171. package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
  172. package/out/zero-cache/src/server/runner/zero-dispatcher.js +5 -0
  173. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  174. package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
  175. package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
  176. package/out/zero-cache/src/server/syncer-assigner.js +72 -0
  177. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
  178. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  179. package/out/zero-cache/src/server/syncer.js +24 -2
  180. package/out/zero-cache/src/server/syncer.js.map +1 -1
  181. package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
  182. package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
  183. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  184. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  185. package/out/zero-cache/src/services/analyze.js +11 -9
  186. package/out/zero-cache/src/services/analyze.js.map +1 -1
  187. package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
  188. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +198 -24
  189. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  190. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
  191. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +15 -3
  192. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  193. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +1 -0
  194. package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
  195. package/out/zero-cache/src/services/change-source/common/replica-schema.js +15 -3
  196. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  197. package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +9 -0
  198. package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
  199. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +204 -18
  200. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  201. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +25 -0
  202. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
  203. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +202 -0
  204. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
  205. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +14 -16
  206. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  207. package/out/zero-cache/src/services/change-source/pg/change-source.js +64 -143
  208. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  209. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +37 -2
  210. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  211. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +53 -21
  212. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  213. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
  214. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
  215. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
  216. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
  217. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +21 -15
  218. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  219. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +86 -23
  220. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  221. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
  222. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
  223. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  224. package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
  225. package/out/zero-cache/src/services/change-source/pg/schema/init.js +32 -1
  226. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  227. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
  228. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
  229. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
  230. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
  231. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +50 -27
  232. package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
  233. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +100 -34
  234. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  235. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +68 -0
  236. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +1 -0
  237. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +141 -0
  238. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -0
  239. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +43 -0
  240. package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
  241. package/out/zero-cache/src/services/change-source/protocol/current/data.js +10 -1
  242. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  243. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +57 -0
  244. package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
  245. package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +20 -6
  246. package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
  247. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +17 -7
  248. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  249. package/out/zero-cache/src/services/change-source/protocol/current.js +2 -1
  250. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts +66 -0
  251. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts.map +1 -0
  252. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js +154 -0
  253. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -0
  254. package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts +50 -0
  255. package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts.map +1 -0
  256. package/out/zero-cache/src/services/change-streamer/backfill-state.js +268 -0
  257. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -0
  258. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
  259. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +2 -0
  260. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  261. package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
  262. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +58 -7
  263. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  264. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +8 -2
  265. package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
  266. package/out/zero-cache/src/services/change-streamer/broadcast.js +24 -4
  267. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  268. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -4
  269. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
  270. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +28 -8
  271. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
  272. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +48 -6
  273. package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
  274. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +130 -34
  275. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  276. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +11 -0
  277. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  278. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +118 -68
  279. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  280. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +37 -15
  281. package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
  282. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  283. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
  284. package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
  285. package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
  286. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  287. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +51 -0
  288. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts.map +1 -0
  289. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +132 -0
  290. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -0
  291. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +1 -1
  292. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  293. package/out/zero-cache/src/services/change-streamer/schema/tables.js +19 -8
  294. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  295. package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts +92 -0
  296. package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts.map +1 -0
  297. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +42 -0
  298. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -0
  299. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +1 -1
  300. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
  301. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +16 -4
  302. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  303. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +7 -69
  304. package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
  305. package/out/zero-cache/src/services/change-streamer/snapshot.js +21 -53
  306. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  307. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
  308. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
  309. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
  310. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  311. package/out/zero-cache/src/services/change-streamer/storer.d.ts +2 -2
  312. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  313. package/out/zero-cache/src/services/change-streamer/storer.js +9 -6
  314. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  315. package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +446 -0
  316. package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -0
  317. package/out/zero-cache/src/services/change-streamer/subscribe.js +76 -0
  318. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -0
  319. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +33 -1
  320. package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
  321. package/out/zero-cache/src/services/change-streamer/subscriber.js +76 -0
  322. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +17 -1
  324. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +19 -3
  326. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +5 -0
  328. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +35 -5
  330. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -1
  331. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  332. package/out/zero-cache/src/services/life-cycle.js +3 -1
  333. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  334. package/out/zero-cache/src/services/litestream/commands.d.ts +15 -3
  335. package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
  336. package/out/zero-cache/src/services/litestream/commands.js +24 -7
  337. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  338. package/out/zero-cache/src/services/litestream/config-v5.yml +11 -4
  339. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +51 -24
  340. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  341. package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +10 -2
  342. package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +1 -1
  343. package/out/zero-cache/src/services/litestream/litestream-controller.js +3 -2
  344. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  345. package/out/zero-cache/src/services/litestream/restore-progress.d.ts +24 -0
  346. package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +1 -0
  347. package/out/zero-cache/src/services/litestream/restore-progress.js +91 -0
  348. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -0
  349. package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
  350. package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
  351. package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
  352. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  353. package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
  354. package/out/zero-cache/src/services/mutagen/pusher.js +5 -6
  355. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  356. package/out/zero-cache/src/services/plannerz.d.ts +163 -0
  357. package/out/zero-cache/src/services/plannerz.d.ts.map +1 -0
  358. package/out/zero-cache/src/services/plannerz.js +267 -0
  359. package/out/zero-cache/src/services/plannerz.js.map +1 -0
  360. package/out/zero-cache/src/services/profz.d.ts +30 -0
  361. package/out/zero-cache/src/services/profz.d.ts.map +1 -0
  362. package/out/zero-cache/src/services/profz.js +145 -0
  363. package/out/zero-cache/src/services/profz.js.map +1 -0
  364. package/out/zero-cache/src/services/replicator/change-log-cookies.js +1 -1
  365. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  366. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +5 -4
  367. package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -1
  368. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +20 -22
  369. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  370. package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
  371. package/out/zero-cache/src/services/replicator/change-processor.js +49 -5
  372. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  373. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +3 -2
  374. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  375. package/out/zero-cache/src/services/replicator/incremental-sync.js +50 -20
  376. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  377. package/out/zero-cache/src/services/replicator/replication-status.d.ts +35 -1
  378. package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
  379. package/out/zero-cache/src/services/replicator/replication-status.js +96 -6
  380. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  381. package/out/zero-cache/src/services/replicator/replicator.d.ts +2 -1
  382. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  383. package/out/zero-cache/src/services/replicator/replicator.js +2 -2
  384. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  385. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +23 -2
  386. package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -1
  387. package/out/zero-cache/src/services/replicator/schema/backfilling.js +54 -2
  388. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  389. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +6 -6
  390. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
  391. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +19 -14
  392. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  393. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +11 -3
  394. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
  395. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  396. package/out/zero-cache/src/services/replicator/write-worker.js +5 -1
  397. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  398. package/out/zero-cache/src/services/run-ast.d.ts +12 -0
  399. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  400. package/out/zero-cache/src/services/run-ast.js +26 -14
  401. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  402. package/out/zero-cache/src/services/runner.d.ts +2 -1
  403. package/out/zero-cache/src/services/runner.d.ts.map +1 -1
  404. package/out/zero-cache/src/services/runner.js +10 -2
  405. package/out/zero-cache/src/services/runner.js.map +1 -1
  406. package/out/zero-cache/src/services/statz.d.ts +4 -0
  407. package/out/zero-cache/src/services/statz.d.ts.map +1 -1
  408. package/out/zero-cache/src/services/statz.js +22 -5
  409. package/out/zero-cache/src/services/statz.js.map +1 -1
  410. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +19 -2
  411. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  412. package/out/zero-cache/src/services/view-syncer/client-handler.js +42 -30
  413. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  414. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +19 -1
  415. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  416. package/out/zero-cache/src/services/view-syncer/cvr-store.js +34 -11
  417. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  418. package/out/zero-cache/src/services/view-syncer/cvr.d.ts +51 -2
  419. package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
  420. package/out/zero-cache/src/services/view-syncer/cvr.js +142 -6
  421. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  422. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +81 -0
  423. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +1 -0
  424. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +128 -0
  425. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -0
  426. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
  427. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  428. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
  429. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  430. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +33 -0
  431. package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +1 -0
  432. package/out/zero-cache/src/services/view-syncer/hydration-budget.js +62 -0
  433. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -0
  434. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
  435. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
  436. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
  437. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
  438. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
  439. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
  440. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +3 -3
  441. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  442. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +50 -2
  443. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  444. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +466 -62
  445. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  446. package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +7 -0
  447. package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +1 -0
  448. package/out/zero-cache/src/services/view-syncer/plan-warnings.js +35 -0
  449. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -0
  450. package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
  451. package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -6
  452. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  453. package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +25 -0
  454. package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +1 -0
  455. package/out/zero-cache/src/services/view-syncer/query-shape.js +28 -0
  456. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -0
  457. package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +77 -0
  458. package/out/zero-cache/src/services/view-syncer/query-stats.d.ts.map +1 -0
  459. package/out/zero-cache/src/services/view-syncer/query-stats.js +206 -0
  460. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -0
  461. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +95 -0
  462. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +1 -0
  463. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +155 -0
  464. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -0
  465. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +78 -4
  466. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  467. package/out/zero-cache/src/services/view-syncer/snapshotter.js +158 -28
  468. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  469. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +11 -1
  470. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  471. package/out/zero-cache/src/services/view-syncer/view-syncer.js +587 -103
  472. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  473. package/out/zero-cache/src/types/processes.d.ts +39 -0
  474. package/out/zero-cache/src/types/processes.d.ts.map +1 -1
  475. package/out/zero-cache/src/types/processes.js +43 -4
  476. package/out/zero-cache/src/types/processes.js.map +1 -1
  477. package/out/zero-cache/src/types/profiler.d.ts +12 -0
  478. package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
  479. package/out/zero-cache/src/types/profiler.js +46 -1
  480. package/out/zero-cache/src/types/profiler.js.map +1 -1
  481. package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
  482. package/out/zero-cache/src/types/row-key.js +5 -5
  483. package/out/zero-cache/src/types/row-key.js.map +1 -1
  484. package/out/zero-cache/src/types/streams.d.ts +49 -7
  485. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  486. package/out/zero-cache/src/types/streams.js +190 -58
  487. package/out/zero-cache/src/types/streams.js.map +1 -1
  488. package/out/zero-cache/src/types/subscription.d.ts +15 -0
  489. package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
  490. package/out/zero-cache/src/types/subscription.js +123 -31
  491. package/out/zero-cache/src/types/subscription.js.map +1 -1
  492. package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
  493. package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
  494. package/out/zero-cache/src/types/websocket-handoff.js +18 -9
  495. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  496. package/out/zero-cache/src/types/ws.d.ts.map +1 -1
  497. package/out/zero-cache/src/types/ws.js +1 -16
  498. package/out/zero-cache/src/types/ws.js.map +1 -1
  499. package/out/zero-cache/src/workers/connect-params.d.ts +1 -0
  500. package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
  501. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  502. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  503. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
  504. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  505. package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
  506. package/out/zero-cache/src/workers/syncer.js +55 -4
  507. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  508. package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
  509. package/out/zero-client/src/client/active-clients-manager.js +4 -1
  510. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  511. package/out/zero-client/src/client/connection-manager.d.ts +20 -0
  512. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  513. package/out/zero-client/src/client/connection-manager.js +77 -13
  514. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  515. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  516. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  517. package/out/zero-client/src/client/connection-status-enum.js +3 -1
  518. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  519. package/out/zero-client/src/client/connection.d.ts +6 -0
  520. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  521. package/out/zero-client/src/client/connection.js +2 -1
  522. package/out/zero-client/src/client/connection.js.map +1 -1
  523. package/out/zero-client/src/client/context.d.ts +22 -12
  524. package/out/zero-client/src/client/context.d.ts.map +1 -1
  525. package/out/zero-client/src/client/context.js +92 -25
  526. package/out/zero-client/src/client/context.js.map +1 -1
  527. package/out/zero-client/src/client/custom.js +2 -2
  528. package/out/zero-client/src/client/custom.js.map +1 -1
  529. package/out/zero-client/src/client/error.js +1 -1
  530. package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
  531. package/out/zero-client/src/client/ivm-branch.js +20 -3
  532. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  533. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  534. package/out/zero-client/src/client/mutator-proxy.js +5 -2
  535. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  536. package/out/zero-client/src/client/options.d.ts +33 -0
  537. package/out/zero-client/src/client/options.d.ts.map +1 -1
  538. package/out/zero-client/src/client/options.js.map +1 -1
  539. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  540. package/out/zero-client/src/client/query-manager.js +44 -11
  541. package/out/zero-client/src/client/query-manager.js.map +1 -1
  542. package/out/zero-client/src/client/version.js +1 -1
  543. package/out/zero-client/src/client/zero-rep.d.ts +1 -0
  544. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  545. package/out/zero-client/src/client/zero-rep.js +8 -6
  546. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  547. package/out/zero-client/src/client/zero.d.ts +18 -3
  548. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  549. package/out/zero-client/src/client/zero.js +84 -47
  550. package/out/zero-client/src/client/zero.js.map +1 -1
  551. package/out/zero-client/src/mod.d.ts +1 -0
  552. package/out/zero-client/src/mod.d.ts.map +1 -1
  553. package/out/zero-client/src/mod.js +1 -0
  554. package/out/zero-client/src/types/query-result.d.ts +2 -0
  555. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  556. package/out/zero-events/src/status.d.ts +58 -0
  557. package/out/zero-events/src/status.d.ts.map +1 -1
  558. package/out/zero-protocol/src/ast.d.ts.map +1 -1
  559. package/out/zero-protocol/src/ast.js +13 -14
  560. package/out/zero-protocol/src/ast.js.map +1 -1
  561. package/out/zero-protocol/src/down.d.ts +29 -29
  562. package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
  563. package/out/zero-protocol/src/query-hash.js +2 -5
  564. package/out/zero-protocol/src/query-hash.js.map +1 -1
  565. package/out/zero-react/src/use-query.d.ts +5 -4
  566. package/out/zero-react/src/use-query.d.ts.map +1 -1
  567. package/out/zero-react/src/use-query.js +62 -4
  568. package/out/zero-react/src/use-query.js.map +1 -1
  569. package/out/zero-react/src/zero.js +1 -0
  570. package/out/zero-server/src/adapters/drizzle.d.ts +2 -1
  571. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  572. package/out/zero-server/src/adapters/drizzle.js +12 -7
  573. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  574. package/out/zero-server/src/adapters/kysely.d.ts +2 -1
  575. package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
  576. package/out/zero-server/src/adapters/kysely.js +8 -2
  577. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  578. package/out/zero-server/src/adapters/pg.d.ts +1 -0
  579. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  580. package/out/zero-server/src/adapters/pg.js +8 -2
  581. package/out/zero-server/src/adapters/pg.js.map +1 -1
  582. package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
  583. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  584. package/out/zero-server/src/adapters/postgresjs.js +7 -1
  585. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  586. package/out/zero-server/src/adapters/prisma.d.ts +3 -2
  587. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  588. package/out/zero-server/src/adapters/prisma.js +8 -2
  589. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  590. package/out/zero-server/src/custom.d.ts +5 -1
  591. package/out/zero-server/src/custom.d.ts.map +1 -1
  592. package/out/zero-server/src/custom.js +6 -3
  593. package/out/zero-server/src/custom.js.map +1 -1
  594. package/out/zero-server/src/logging.d.ts +2 -2
  595. package/out/zero-server/src/logging.d.ts.map +1 -1
  596. package/out/zero-server/src/logging.js +2 -2
  597. package/out/zero-server/src/logging.js.map +1 -1
  598. package/out/zero-server/src/mod.d.ts +1 -1
  599. package/out/zero-server/src/mod.d.ts.map +1 -1
  600. package/out/zero-server/src/pg-query-executor.d.ts +2 -2
  601. package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
  602. package/out/zero-server/src/pg-query-executor.js +2 -2
  603. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  604. package/out/zero-server/src/process-mutations.d.ts +12 -3
  605. package/out/zero-server/src/process-mutations.d.ts.map +1 -1
  606. package/out/zero-server/src/process-mutations.js +13 -8
  607. package/out/zero-server/src/process-mutations.js.map +1 -1
  608. package/out/zero-server/src/push-processor.d.ts +8 -2
  609. package/out/zero-server/src/push-processor.d.ts.map +1 -1
  610. package/out/zero-server/src/push-processor.js +12 -4
  611. package/out/zero-server/src/push-processor.js.map +1 -1
  612. package/out/zero-server/src/schema.d.ts +2 -2
  613. package/out/zero-server/src/schema.d.ts.map +1 -1
  614. package/out/zero-server/src/schema.js +2 -2
  615. package/out/zero-server/src/schema.js.map +1 -1
  616. package/out/zero-server/src/zql-database.d.ts +21 -1
  617. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  618. package/out/zero-server/src/zql-database.js +33 -2
  619. package/out/zero-server/src/zql-database.js.map +1 -1
  620. package/out/zero-solid/src/solid-view.d.ts +17 -0
  621. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  622. package/out/zero-solid/src/solid-view.js +39 -1
  623. package/out/zero-solid/src/solid-view.js.map +1 -1
  624. package/out/zero-solid/src/use-query.js +1 -2
  625. package/out/zero-solid/src/use-query.js.map +1 -1
  626. package/out/zero-solid/src/zero.js +1 -0
  627. package/out/zql/src/builder/builder.d.ts +25 -0
  628. package/out/zql/src/builder/builder.d.ts.map +1 -1
  629. package/out/zql/src/builder/builder.js +69 -19
  630. package/out/zql/src/builder/builder.js.map +1 -1
  631. package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +43 -0
  632. package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +1 -0
  633. package/out/zql/src/builder/correlated-predicate-pushdown.js +161 -0
  634. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -0
  635. package/out/zql/src/builder/debug-delegate.d.ts +6 -1
  636. package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
  637. package/out/zql/src/builder/debug-delegate.js +14 -2
  638. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  639. package/out/zql/src/ivm/array-view.d.ts +29 -0
  640. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  641. package/out/zql/src/ivm/array-view.js +58 -9
  642. package/out/zql/src/ivm/array-view.js.map +1 -1
  643. package/out/zql/src/ivm/cap.d.ts +2 -1
  644. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  645. package/out/zql/src/ivm/cap.js +14 -4
  646. package/out/zql/src/ivm/cap.js.map +1 -1
  647. package/out/zql/src/ivm/connection-index.d.ts +68 -0
  648. package/out/zql/src/ivm/connection-index.d.ts.map +1 -0
  649. package/out/zql/src/ivm/connection-index.js +149 -0
  650. package/out/zql/src/ivm/connection-index.js.map +1 -0
  651. package/out/zql/src/ivm/data.d.ts.map +1 -1
  652. package/out/zql/src/ivm/data.js +8 -3
  653. package/out/zql/src/ivm/data.js.map +1 -1
  654. package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
  655. package/out/zql/src/ivm/deferred-input.js +3 -2
  656. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  657. package/out/zql/src/ivm/exists.d.ts +3 -1
  658. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  659. package/out/zql/src/ivm/exists.js +4 -1
  660. package/out/zql/src/ivm/exists.js.map +1 -1
  661. package/out/zql/src/ivm/fan-in.d.ts +6 -2
  662. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  663. package/out/zql/src/ivm/fan-in.js +13 -5
  664. package/out/zql/src/ivm/fan-in.js.map +1 -1
  665. package/out/zql/src/ivm/fan-out.d.ts +5 -2
  666. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  667. package/out/zql/src/ivm/fan-out.js +4 -0
  668. package/out/zql/src/ivm/fan-out.js.map +1 -1
  669. package/out/zql/src/ivm/filter-operators.d.ts +8 -6
  670. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  671. package/out/zql/src/ivm/filter-operators.js +19 -8
  672. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  673. package/out/zql/src/ivm/filter.d.ts +5 -2
  674. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  675. package/out/zql/src/ivm/filter.js +10 -4
  676. package/out/zql/src/ivm/filter.js.map +1 -1
  677. package/out/zql/src/ivm/flipped-join.d.ts +9 -4
  678. package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
  679. package/out/zql/src/ivm/flipped-join.js +97 -46
  680. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  681. package/out/zql/src/ivm/join-index-tap.d.ts +33 -0
  682. package/out/zql/src/ivm/join-index-tap.d.ts.map +1 -0
  683. package/out/zql/src/ivm/join-index-tap.js +70 -0
  684. package/out/zql/src/ivm/join-index-tap.js.map +1 -0
  685. package/out/zql/src/ivm/join-index.d.ts +35 -0
  686. package/out/zql/src/ivm/join-index.d.ts.map +1 -0
  687. package/out/zql/src/ivm/join-index.js +141 -0
  688. package/out/zql/src/ivm/join-index.js.map +1 -0
  689. package/out/zql/src/ivm/join-utils.d.ts +6 -0
  690. package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
  691. package/out/zql/src/ivm/join-utils.js +22 -1
  692. package/out/zql/src/ivm/join-utils.js.map +1 -1
  693. package/out/zql/src/ivm/join.d.ts +19 -1
  694. package/out/zql/src/ivm/join.d.ts.map +1 -1
  695. package/out/zql/src/ivm/join.js +107 -15
  696. package/out/zql/src/ivm/join.js.map +1 -1
  697. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  698. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  699. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
  700. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  701. package/out/zql/src/ivm/memory-source.d.ts +28 -3
  702. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  703. package/out/zql/src/ivm/memory-source.js +69 -33
  704. package/out/zql/src/ivm/memory-source.js.map +1 -1
  705. package/out/zql/src/ivm/memory-storage.d.ts +1 -0
  706. package/out/zql/src/ivm/memory-storage.d.ts.map +1 -1
  707. package/out/zql/src/ivm/memory-storage.js +1 -0
  708. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  709. package/out/zql/src/ivm/operator.d.ts +45 -10
  710. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  711. package/out/zql/src/ivm/operator.js +9 -4
  712. package/out/zql/src/ivm/operator.js.map +1 -1
  713. package/out/zql/src/ivm/push-accumulated.d.ts +6 -1
  714. package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
  715. package/out/zql/src/ivm/push-accumulated.js +47 -2
  716. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  717. package/out/zql/src/ivm/skip.d.ts +2 -1
  718. package/out/zql/src/ivm/skip.d.ts.map +1 -1
  719. package/out/zql/src/ivm/skip.js +3 -0
  720. package/out/zql/src/ivm/skip.js.map +1 -1
  721. package/out/zql/src/ivm/take-gate.d.ts +57 -0
  722. package/out/zql/src/ivm/take-gate.d.ts.map +1 -0
  723. package/out/zql/src/ivm/take-gate.js +106 -0
  724. package/out/zql/src/ivm/take-gate.js.map +1 -0
  725. package/out/zql/src/ivm/take.d.ts +8 -2
  726. package/out/zql/src/ivm/take.d.ts.map +1 -1
  727. package/out/zql/src/ivm/take.js +139 -103
  728. package/out/zql/src/ivm/take.js.map +1 -1
  729. package/out/zql/src/ivm/union-fan-in.d.ts +3 -0
  730. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  731. package/out/zql/src/ivm/union-fan-in.js +63 -10
  732. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  733. package/out/zql/src/ivm/union-fan-out.d.ts +2 -1
  734. package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
  735. package/out/zql/src/ivm/union-fan-out.js +5 -0
  736. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  737. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  738. package/out/zql/src/ivm/view-apply-change.js +9 -4
  739. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  740. package/out/zql/src/ivm/view.d.ts +15 -0
  741. package/out/zql/src/ivm/view.d.ts.map +1 -1
  742. package/out/zql/src/mutate/custom.d.ts +24 -1
  743. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  744. package/out/zql/src/mutate/custom.js.map +1 -1
  745. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  746. package/out/zql/src/mutate/mutator-registry.js +2 -2
  747. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  748. package/out/zql/src/planner/planner-builder.d.ts +23 -3
  749. package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
  750. package/out/zql/src/planner/planner-builder.js +34 -17
  751. package/out/zql/src/planner/planner-builder.js.map +1 -1
  752. package/out/zql/src/planner/planner-connection.d.ts +58 -2
  753. package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
  754. package/out/zql/src/planner/planner-connection.js +103 -11
  755. package/out/zql/src/planner/planner-connection.js.map +1 -1
  756. package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
  757. package/out/zql/src/planner/planner-debug.js +3 -8
  758. package/out/zql/src/planner/planner-debug.js.map +1 -1
  759. package/out/zql/src/planner/planner-graph.d.ts +10 -0
  760. package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
  761. package/out/zql/src/planner/planner-graph.js +14 -0
  762. package/out/zql/src/planner/planner-graph.js.map +1 -1
  763. package/out/zql/src/planner/planner-source.d.ts +2 -2
  764. package/out/zql/src/planner/planner-source.d.ts.map +1 -1
  765. package/out/zql/src/planner/planner-source.js +2 -2
  766. package/out/zql/src/planner/planner-source.js.map +1 -1
  767. package/out/zql/src/planner/planner-warnings.d.ts +83 -0
  768. package/out/zql/src/planner/planner-warnings.d.ts.map +1 -0
  769. package/out/zql/src/planner/planner-warnings.js +78 -0
  770. package/out/zql/src/planner/planner-warnings.js.map +1 -0
  771. package/out/zql/src/query/measure-push-operator.d.ts +2 -1
  772. package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
  773. package/out/zql/src/query/measure-push-operator.js +33 -4
  774. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  775. package/out/zql/src/query/query-delegate-base.d.ts +4 -2
  776. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  777. package/out/zql/src/query/query-delegate-base.js +66 -33
  778. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  779. package/out/zql/src/query/query-delegate.d.ts +33 -6
  780. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  781. package/out/zql/src/query/query-impl.d.ts +1 -0
  782. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  783. package/out/zql/src/query/query-impl.js +6 -23
  784. package/out/zql/src/query/query-impl.js.map +1 -1
  785. package/out/zql/src/query/query-transitions.d.ts.map +1 -1
  786. package/out/zql/src/query/query-transitions.js +2 -5
  787. package/out/zql/src/query/query-transitions.js.map +1 -1
  788. package/out/zql/src/query/query.d.ts +11 -2
  789. package/out/zql/src/query/query.d.ts.map +1 -1
  790. package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
  791. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  792. package/out/zql/src/query/runnable-query-impl.js +2 -10
  793. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  794. package/out/zql/src/query/typed-view.d.ts +1 -1
  795. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  796. package/out/zqlite/src/database-storage.d.ts.map +1 -1
  797. package/out/zqlite/src/database-storage.js +9 -1
  798. package/out/zqlite/src/database-storage.js.map +1 -1
  799. package/out/zqlite/src/db.d.ts +9 -1
  800. package/out/zqlite/src/db.d.ts.map +1 -1
  801. package/out/zqlite/src/db.js +31 -27
  802. package/out/zqlite/src/db.js.map +1 -1
  803. package/out/zqlite/src/pending-delta.d.ts +110 -0
  804. package/out/zqlite/src/pending-delta.d.ts.map +1 -0
  805. package/out/zqlite/src/pending-delta.js +278 -0
  806. package/out/zqlite/src/pending-delta.js.map +1 -0
  807. package/out/zqlite/src/query-builder.d.ts +17 -1
  808. package/out/zqlite/src/query-builder.d.ts.map +1 -1
  809. package/out/zqlite/src/query-builder.js +111 -20
  810. package/out/zqlite/src/query-builder.js.map +1 -1
  811. package/out/zqlite/src/query-delegate.d.ts.map +1 -1
  812. package/out/zqlite/src/query-delegate.js +10 -7
  813. package/out/zqlite/src/query-delegate.js.map +1 -1
  814. package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
  815. package/out/zqlite/src/sqlite-cost-model.js +52 -1
  816. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  817. package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
  818. package/out/zqlite/src/sqlite-stat-fanout.js +5 -31
  819. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  820. package/out/zqlite/src/sqlite-stat4-sample.d.ts +37 -0
  821. package/out/zqlite/src/sqlite-stat4-sample.d.ts.map +1 -0
  822. package/out/zqlite/src/sqlite-stat4-sample.js +61 -0
  823. package/out/zqlite/src/sqlite-stat4-sample.js.map +1 -0
  824. package/out/zqlite/src/table-source.d.ts +82 -2
  825. package/out/zqlite/src/table-source.d.ts.map +1 -1
  826. package/out/zqlite/src/table-source.js +261 -38
  827. package/out/zqlite/src/table-source.js.map +1 -1
  828. package/package.json +3 -4
  829. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +0 -25
  830. package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +0 -1
  831. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +0 -83
  832. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +0 -1
@@ -0,0 +1,25 @@
1
+ import type { AST } from '../../../../zero-protocol/src/ast.ts';
2
+ /**
3
+ * A query with its literal values redacted, for logging.
4
+ */
5
+ export type QueryShape = {
6
+ /**
7
+ * The query as ZQL with every literal (and the `start` row) rendered as
8
+ * `?`, so it can be logged without leaking row data, query arguments, or
9
+ * auth data substituted in by permissions.
10
+ */
11
+ readonly zql: string;
12
+ /**
13
+ * A hash of {@link zql}. Queries that differ only in their literal values,
14
+ * e.g. the same named query called with different arguments, share a hash,
15
+ * which makes it a key for grouping and throttling logs.
16
+ */
17
+ readonly hash: string;
18
+ };
19
+ /**
20
+ * Never throws: it is computed for every hydration, and a query that cannot be
21
+ * rendered as ZQL (e.g. a subquery without an alias) must still hydrate. Such
22
+ * a query is shaped by its AST with the literal values redacted instead.
23
+ */
24
+ export declare function queryShape(ast: AST): QueryShape;
25
+ //# sourceMappingURL=query-shape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-shape.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/query-shape.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,sCAAsC,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB;;;;OAIG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,CAQ/C"}
@@ -0,0 +1,28 @@
1
+ import { h64 } from "../../../../shared/src/hash.js";
2
+ import { astToZQL } from "../../../../ast-to-zql/src/ast-to-zql.js";
3
+ //#region ../zero-cache/src/services/view-syncer/query-shape.ts
4
+ /**
5
+ * Never throws: it is computed for every hydration, and a query that cannot be
6
+ * rendered as ZQL (e.g. a subquery without an alias) must still hydrate. Such
7
+ * a query is shaped by its AST with the literal values redacted instead.
8
+ */
9
+ function queryShape(ast) {
10
+ let zql;
11
+ try {
12
+ zql = ast.table + astToZQL(ast, { redactLiterals: true });
13
+ } catch {
14
+ zql = JSON.stringify(ast, redactLiterals);
15
+ }
16
+ return {
17
+ zql,
18
+ hash: h64(zql).toString(36)
19
+ };
20
+ }
21
+ function redactLiterals(key, value) {
22
+ if (key === "value" && this.type === "literal" || key === "start") return "?";
23
+ return value;
24
+ }
25
+ //#endregion
26
+ export { queryShape };
27
+
28
+ //# sourceMappingURL=query-shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-shape.js","names":[],"sources":["../../../../../../zero-cache/src/services/view-syncer/query-shape.ts"],"sourcesContent":["// @circular-dep-ignore\nimport {astToZQL} from '../../../../ast-to-zql/src/ast-to-zql.ts';\nimport {h64} from '../../../../shared/src/hash.ts';\nimport type {AST} from '../../../../zero-protocol/src/ast.ts';\n\n/**\n * A query with its literal values redacted, for logging.\n */\nexport type QueryShape = {\n /**\n * The query as ZQL with every literal (and the `start` row) rendered as\n * `?`, so it can be logged without leaking row data, query arguments, or\n * auth data substituted in by permissions.\n */\n readonly zql: string;\n\n /**\n * A hash of {@link zql}. Queries that differ only in their literal values,\n * e.g. the same named query called with different arguments, share a hash,\n * which makes it a key for grouping and throttling logs.\n */\n readonly hash: string;\n};\n\n/**\n * Never throws: it is computed for every hydration, and a query that cannot be\n * rendered as ZQL (e.g. a subquery without an alias) must still hydrate. Such\n * a query is shaped by its AST with the literal values redacted instead.\n */\nexport function queryShape(ast: AST): QueryShape {\n let zql: string;\n try {\n zql = ast.table + astToZQL(ast, {redactLiterals: true});\n } catch {\n zql = JSON.stringify(ast, redactLiterals);\n }\n return {zql, hash: h64(zql).toString(36)};\n}\n\nfunction redactLiterals(this: unknown, key: string, value: unknown) {\n if (\n (key === 'value' && (this as {type?: unknown}).type === 'literal') ||\n key === 'start'\n ) {\n return '?';\n }\n return value;\n}\n"],"mappings":";;;;;;;;AA6BA,SAAgB,WAAW,KAAsB;CAC/C,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,QAAQ,SAAS,KAAK,EAAC,gBAAgB,KAAI,CAAC;CACxD,QAAQ;EACN,MAAM,KAAK,UAAU,KAAK,cAAc;CAC1C;CACA,OAAO;EAAC;EAAK,MAAM,IAAI,GAAG,EAAE,SAAS,EAAE;CAAC;AAC1C;AAEA,SAAS,eAA8B,KAAa,OAAgB;CAClE,IACG,QAAQ,WAAY,KAA0B,SAAS,aACxD,QAAQ,SAER,OAAO;CAET,OAAO;AACT"}
@@ -0,0 +1,77 @@
1
+ import type { LogContext } from '@rocicorp/logger';
2
+ import type { PlanWarning } from '../../../../zql/src/planner/planner-warnings.ts';
3
+ import type { QueryShape } from './query-shape.ts';
4
+ /** The query that work is accounted to. */
5
+ export type QueryIdentity = {
6
+ readonly queryName?: string | undefined;
7
+ readonly shape: QueryShape;
8
+ };
9
+ export type HydrationOutcome = 'finished' | 'aborted' | 'failed';
10
+ export type HydrationRecord = {
11
+ readonly outcome: HydrationOutcome;
12
+ readonly timeMs: number;
13
+ /** Only for a finished hydration. */
14
+ readonly rowCount?: number | undefined;
15
+ /** Only for a finished hydration. */
16
+ readonly rowsRead?: number | undefined;
17
+ readonly planWarnings?: readonly PlanWarning[] | undefined;
18
+ };
19
+ export type AdvanceRecord = {
20
+ /** The time spent processing the pushes to the query. */
21
+ readonly timeMs: number;
22
+ /** The number of changes pushed to the query. */
23
+ readonly changes: number;
24
+ /** Whether the advancement timed out and reset the pipelines. */
25
+ readonly timedOut: boolean;
26
+ };
27
+ export type QueryStatsOptions = {
28
+ /**
29
+ * The most query shapes tracked per interval. Work on shapes beyond this is
30
+ * accounted to the interval's totals only, which bounds memory when the
31
+ * shape space is unbounded (e.g. dynamically built queries).
32
+ */
33
+ readonly maxShapes?: number | undefined;
34
+ /**
35
+ * The most query shapes logged per interval, those that took the most
36
+ * time. The rest are included in the interval's totals.
37
+ */
38
+ readonly maxReported?: number | undefined;
39
+ readonly now?: (() => number) | undefined;
40
+ };
41
+ /**
42
+ * Aggregates the work done for each query shape (the query with its values
43
+ * redacted, see {@link QueryShape}) on a worker, and periodically logs it,
44
+ * like `pg_stat_statements` does for Postgres.
45
+ *
46
+ * Unlike the slow query logs, which are throttled and only written above a
47
+ * threshold, every hydration and advancement is counted, so the logs can be
48
+ * summed over any time range and across workers to rank queries by the time
49
+ * they take.
50
+ *
51
+ * Each {@link flush} logs the interval since the previous one:
52
+ *
53
+ * - a `query-stats` event per query shape, for the {@link
54
+ * QueryStatsOptions.maxReported} shapes that took the most time, and
55
+ * - a `query-stats-summary` event with the totals of all shapes, including
56
+ * those not reported individually.
57
+ *
58
+ * The events carry counts, sums, minimums and maximums, which compose across
59
+ * intervals and workers.
60
+ */
61
+ export declare class QueryStats {
62
+ #private;
63
+ constructor({ maxShapes, maxReported, now, }?: QueryStatsOptions);
64
+ recordHydration(query: QueryIdentity, record: HydrationRecord): void;
65
+ recordAdvance(query: QueryIdentity, record: AdvanceRecord): void;
66
+ /**
67
+ * Logs the stats of the interval since the previous flush, and starts a
68
+ * new interval. Nothing is logged for an interval without any work.
69
+ */
70
+ flush(lc: LogContext): void;
71
+ /**
72
+ * Flushes every `intervalMs` until the returned function is called, which
73
+ * flushes one last time.
74
+ */
75
+ start(lc: LogContext, intervalMs: number): () => void;
76
+ }
77
+ //# sourceMappingURL=query-stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-stats.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/query-stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,iDAAiD,CAAC;AACjF,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,2CAA2C;AAC3C,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEjE,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,GAAG,SAAS,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,yDAAyD;IACzD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAExC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE1C,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;CAC3C,CAAC;AA+GF;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,UAAU;;IAUrB,YAAY,EACV,SAAgB,EAChB,WAAiB,EACjB,GAAc,GACf,GAAE,iBAAsB,EAOxB;IAED,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CASnE;IAED,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAG/D;IAgBD;;;OAGG;IACH,KAAK,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CAqC1B;IAED;;;OAGG;IACH,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,IAAI,CAOpD;CACF"}
@@ -0,0 +1,206 @@
1
+ import { assert } from "../../../../shared/src/asserts.js";
2
+ //#region ../zero-cache/src/services/view-syncer/query-stats.ts
3
+ var Distribution = class {
4
+ count = 0;
5
+ sumMs = 0;
6
+ minMs = Infinity;
7
+ maxMs = 0;
8
+ add(ms) {
9
+ this.count++;
10
+ this.sumMs += ms;
11
+ this.minMs = Math.min(this.minMs, ms);
12
+ this.maxMs = Math.max(this.maxMs, ms);
13
+ }
14
+ toJSON() {
15
+ return {
16
+ count: this.count,
17
+ sumMs: round(this.sumMs),
18
+ minMs: round(this.count === 0 ? 0 : this.minMs),
19
+ maxMs: round(this.maxMs)
20
+ };
21
+ }
22
+ };
23
+ var Totals = class {
24
+ hydrations = new Distribution();
25
+ hydrationsAborted = 0;
26
+ hydrationsFailed = 0;
27
+ hydrationRowCount = 0;
28
+ hydrationRowsRead = 0;
29
+ advances = new Distribution();
30
+ advanceChanges = 0;
31
+ advanceTimeouts = 0;
32
+ get timeMs() {
33
+ return this.hydrations.sumMs + this.advances.sumMs;
34
+ }
35
+ addHydration({ outcome, timeMs, rowCount, rowsRead }) {
36
+ this.hydrations.add(timeMs);
37
+ if (outcome === "aborted") this.hydrationsAborted++;
38
+ else if (outcome === "failed") this.hydrationsFailed++;
39
+ this.hydrationRowCount += rowCount ?? 0;
40
+ this.hydrationRowsRead += rowsRead ?? 0;
41
+ }
42
+ addAdvance({ timeMs, changes, timedOut }) {
43
+ this.advances.add(timeMs);
44
+ this.advanceChanges += changes;
45
+ if (timedOut) this.advanceTimeouts++;
46
+ }
47
+ toJSON() {
48
+ return {
49
+ timeMs: round(this.timeMs),
50
+ hydrations: this.hydrations.toJSON(),
51
+ hydrationsAborted: this.hydrationsAborted,
52
+ hydrationsFailed: this.hydrationsFailed,
53
+ hydrationRowCount: this.hydrationRowCount,
54
+ hydrationRowsRead: this.hydrationRowsRead,
55
+ advances: this.advances.toJSON(),
56
+ advanceChanges: this.advanceChanges,
57
+ advanceTimeouts: this.advanceTimeouts
58
+ };
59
+ }
60
+ };
61
+ var ShapeStats = class extends Totals {
62
+ query;
63
+ planWarnings;
64
+ constructor(query) {
65
+ super();
66
+ this.query = query;
67
+ }
68
+ };
69
+ /** A fixed-size linear-counting sketch for shapes beyond the tracking limit. */
70
+ var OverflowShapeCounter = class {
71
+ #buckets = new Uint8Array(4096);
72
+ #occupied = 0;
73
+ add(key) {
74
+ let hash = 2166136261;
75
+ for (let i = 0; i < key.length; i++) hash = Math.imul(hash ^ key.charCodeAt(i), 16777619);
76
+ const bucket = (hash >>> 0) % this.#buckets.length;
77
+ if (this.#buckets[bucket] === 0) {
78
+ this.#buckets[bucket] = 1;
79
+ this.#occupied++;
80
+ }
81
+ }
82
+ get estimatedCount() {
83
+ const empty = this.#buckets.length - this.#occupied;
84
+ return empty === 0 ? this.#buckets.length : Math.round(-this.#buckets.length * Math.log(empty / this.#buckets.length));
85
+ }
86
+ };
87
+ /**
88
+ * Aggregates the work done for each query shape (the query with its values
89
+ * redacted, see {@link QueryShape}) on a worker, and periodically logs it,
90
+ * like `pg_stat_statements` does for Postgres.
91
+ *
92
+ * Unlike the slow query logs, which are throttled and only written above a
93
+ * threshold, every hydration and advancement is counted, so the logs can be
94
+ * summed over any time range and across workers to rank queries by the time
95
+ * they take.
96
+ *
97
+ * Each {@link flush} logs the interval since the previous one:
98
+ *
99
+ * - a `query-stats` event per query shape, for the {@link
100
+ * QueryStatsOptions.maxReported} shapes that took the most time, and
101
+ * - a `query-stats-summary` event with the totals of all shapes, including
102
+ * those not reported individually.
103
+ *
104
+ * The events carry counts, sums, minimums and maximums, which compose across
105
+ * intervals and workers.
106
+ */
107
+ var QueryStats = class {
108
+ #maxShapes;
109
+ #maxReported;
110
+ #now;
111
+ #shapes = /* @__PURE__ */ new Map();
112
+ #totals = new Totals();
113
+ #overflowShapes = new OverflowShapeCounter();
114
+ #intervalStart;
115
+ constructor({ maxShapes = 1e3, maxReported = 100, now = Date.now } = {}) {
116
+ assert(maxShapes > 0, "maxShapes must be positive");
117
+ assert(maxReported > 0, "maxReported must be positive");
118
+ this.#maxShapes = maxShapes;
119
+ this.#maxReported = maxReported;
120
+ this.#now = now;
121
+ this.#intervalStart = now();
122
+ }
123
+ recordHydration(query, record) {
124
+ this.#totals.addHydration(record);
125
+ const stats = this.#stats(query);
126
+ if (stats) {
127
+ stats.addHydration(record);
128
+ if (record.planWarnings !== void 0) stats.planWarnings = record.planWarnings;
129
+ }
130
+ }
131
+ recordAdvance(query, record) {
132
+ this.#totals.addAdvance(record);
133
+ this.#stats(query)?.addAdvance(record);
134
+ }
135
+ #stats(query) {
136
+ const key = `${query.queryName ?? ""}:${query.shape.hash}`;
137
+ let stats = this.#shapes.get(key);
138
+ if (stats === void 0) {
139
+ if (this.#shapes.size >= this.#maxShapes) {
140
+ this.#overflowShapes.add(key);
141
+ return;
142
+ }
143
+ stats = new ShapeStats({
144
+ queryName: query.queryName,
145
+ shape: query.shape
146
+ });
147
+ this.#shapes.set(key, stats);
148
+ }
149
+ return stats;
150
+ }
151
+ /**
152
+ * Logs the stats of the interval since the previous flush, and starts a
153
+ * new interval. Nothing is logged for an interval without any work.
154
+ */
155
+ flush(lc) {
156
+ const now = this.#now();
157
+ const intervalMs = now - this.#intervalStart;
158
+ const shapes = this.#shapes;
159
+ const totals = this.#totals;
160
+ const overflowShapes = this.#overflowShapes.estimatedCount;
161
+ this.#shapes = /* @__PURE__ */ new Map();
162
+ this.#totals = new Totals();
163
+ this.#overflowShapes = new OverflowShapeCounter();
164
+ this.#intervalStart = now;
165
+ if (shapes.size === 0 && overflowShapes === 0) return;
166
+ const reported = [...shapes.values()].toSorted((a, b) => b.timeMs - a.timeMs).slice(0, this.#maxReported);
167
+ for (const stats of reported) {
168
+ const { queryName, shape } = stats.query;
169
+ lc.info?.("query stats", {
170
+ zeroEvent: "query-stats",
171
+ intervalMs,
172
+ ...queryName !== void 0 && { queryName },
173
+ queryShape: shape.hash,
174
+ ...stats.toJSON(),
175
+ ...stats.planWarnings !== void 0 && stats.planWarnings.length > 0 && { planWarnings: stats.planWarnings },
176
+ zql: shape.zql
177
+ });
178
+ }
179
+ lc.info?.("query stats summary", {
180
+ zeroEvent: "query-stats-summary",
181
+ intervalMs,
182
+ shapes: shapes.size + overflowShapes,
183
+ shapesReported: reported.length,
184
+ ...totals.toJSON()
185
+ });
186
+ }
187
+ /**
188
+ * Flushes every `intervalMs` until the returned function is called, which
189
+ * flushes one last time.
190
+ */
191
+ start(lc, intervalMs) {
192
+ const timer = setInterval(() => this.flush(lc), intervalMs);
193
+ timer.unref?.();
194
+ return () => {
195
+ clearInterval(timer);
196
+ this.flush(lc);
197
+ };
198
+ }
199
+ };
200
+ function round(ms) {
201
+ return Math.round(ms * 100) / 100;
202
+ }
203
+ //#endregion
204
+ export { QueryStats };
205
+
206
+ //# sourceMappingURL=query-stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-stats.js","names":["#buckets","#occupied","#maxShapes","#maxReported","#now","#intervalStart","#totals","#stats","#shapes","#overflowShapes"],"sources":["../../../../../../zero-cache/src/services/view-syncer/query-stats.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../../shared/src/asserts.ts';\nimport type {PlanWarning} from '../../../../zql/src/planner/planner-warnings.ts';\nimport type {QueryShape} from './query-shape.ts';\n\n/** The query that work is accounted to. */\nexport type QueryIdentity = {\n readonly queryName?: string | undefined;\n readonly shape: QueryShape;\n};\n\nexport type HydrationOutcome = 'finished' | 'aborted' | 'failed';\n\nexport type HydrationRecord = {\n readonly outcome: HydrationOutcome;\n readonly timeMs: number;\n /** Only for a finished hydration. */\n readonly rowCount?: number | undefined;\n /** Only for a finished hydration. */\n readonly rowsRead?: number | undefined;\n readonly planWarnings?: readonly PlanWarning[] | undefined;\n};\n\nexport type AdvanceRecord = {\n /** The time spent processing the pushes to the query. */\n readonly timeMs: number;\n /** The number of changes pushed to the query. */\n readonly changes: number;\n /** Whether the advancement timed out and reset the pipelines. */\n readonly timedOut: boolean;\n};\n\nexport type QueryStatsOptions = {\n /**\n * The most query shapes tracked per interval. Work on shapes beyond this is\n * accounted to the interval's totals only, which bounds memory when the\n * shape space is unbounded (e.g. dynamically built queries).\n */\n readonly maxShapes?: number | undefined;\n\n /**\n * The most query shapes logged per interval, those that took the most\n * time. The rest are included in the interval's totals.\n */\n readonly maxReported?: number | undefined;\n\n readonly now?: (() => number) | undefined;\n};\n\nclass Distribution {\n count = 0;\n sumMs = 0;\n minMs = Infinity;\n maxMs = 0;\n\n add(ms: number) {\n this.count++;\n this.sumMs += ms;\n this.minMs = Math.min(this.minMs, ms);\n this.maxMs = Math.max(this.maxMs, ms);\n }\n\n toJSON() {\n return {\n count: this.count,\n sumMs: round(this.sumMs),\n minMs: round(this.count === 0 ? 0 : this.minMs),\n maxMs: round(this.maxMs),\n };\n }\n}\n\nclass Totals {\n readonly hydrations = new Distribution();\n hydrationsAborted = 0;\n hydrationsFailed = 0;\n hydrationRowCount = 0;\n hydrationRowsRead = 0;\n readonly advances = new Distribution();\n advanceChanges = 0;\n advanceTimeouts = 0;\n\n get timeMs() {\n return this.hydrations.sumMs + this.advances.sumMs;\n }\n\n addHydration({outcome, timeMs, rowCount, rowsRead}: HydrationRecord) {\n this.hydrations.add(timeMs);\n if (outcome === 'aborted') {\n this.hydrationsAborted++;\n } else if (outcome === 'failed') {\n this.hydrationsFailed++;\n }\n this.hydrationRowCount += rowCount ?? 0;\n this.hydrationRowsRead += rowsRead ?? 0;\n }\n\n addAdvance({timeMs, changes, timedOut}: AdvanceRecord) {\n this.advances.add(timeMs);\n this.advanceChanges += changes;\n if (timedOut) {\n this.advanceTimeouts++;\n }\n }\n\n toJSON() {\n return {\n timeMs: round(this.timeMs),\n hydrations: this.hydrations.toJSON(),\n hydrationsAborted: this.hydrationsAborted,\n hydrationsFailed: this.hydrationsFailed,\n hydrationRowCount: this.hydrationRowCount,\n hydrationRowsRead: this.hydrationRowsRead,\n advances: this.advances.toJSON(),\n advanceChanges: this.advanceChanges,\n advanceTimeouts: this.advanceTimeouts,\n };\n }\n}\n\nclass ShapeStats extends Totals {\n readonly query: QueryIdentity;\n planWarnings: readonly PlanWarning[] | undefined;\n\n constructor(query: QueryIdentity) {\n super();\n this.query = query;\n }\n}\n\n/** A fixed-size linear-counting sketch for shapes beyond the tracking limit. */\nclass OverflowShapeCounter {\n readonly #buckets = new Uint8Array(4096);\n #occupied = 0;\n\n add(key: string): void {\n // FNV-1a gives a stable bucket without retaining the key.\n let hash = 0x811c9dc5;\n for (let i = 0; i < key.length; i++) {\n hash = Math.imul(hash ^ key.charCodeAt(i), 0x01000193);\n }\n const bucket = (hash >>> 0) % this.#buckets.length;\n if (this.#buckets[bucket] === 0) {\n this.#buckets[bucket] = 1;\n this.#occupied++;\n }\n }\n\n get estimatedCount(): number {\n const empty = this.#buckets.length - this.#occupied;\n return empty === 0\n ? this.#buckets.length\n : Math.round(\n -this.#buckets.length * Math.log(empty / this.#buckets.length),\n );\n }\n}\n\n/**\n * Aggregates the work done for each query shape (the query with its values\n * redacted, see {@link QueryShape}) on a worker, and periodically logs it,\n * like `pg_stat_statements` does for Postgres.\n *\n * Unlike the slow query logs, which are throttled and only written above a\n * threshold, every hydration and advancement is counted, so the logs can be\n * summed over any time range and across workers to rank queries by the time\n * they take.\n *\n * Each {@link flush} logs the interval since the previous one:\n *\n * - a `query-stats` event per query shape, for the {@link\n * QueryStatsOptions.maxReported} shapes that took the most time, and\n * - a `query-stats-summary` event with the totals of all shapes, including\n * those not reported individually.\n *\n * The events carry counts, sums, minimums and maximums, which compose across\n * intervals and workers.\n */\nexport class QueryStats {\n readonly #maxShapes: number;\n readonly #maxReported: number;\n readonly #now: () => number;\n\n #shapes = new Map<string, ShapeStats>();\n #totals = new Totals();\n #overflowShapes = new OverflowShapeCounter();\n #intervalStart: number;\n\n constructor({\n maxShapes = 1000,\n maxReported = 100,\n now = Date.now,\n }: QueryStatsOptions = {}) {\n assert(maxShapes > 0, 'maxShapes must be positive');\n assert(maxReported > 0, 'maxReported must be positive');\n this.#maxShapes = maxShapes;\n this.#maxReported = maxReported;\n this.#now = now;\n this.#intervalStart = now();\n }\n\n recordHydration(query: QueryIdentity, record: HydrationRecord): void {\n this.#totals.addHydration(record);\n const stats = this.#stats(query);\n if (stats) {\n stats.addHydration(record);\n if (record.planWarnings !== undefined) {\n stats.planWarnings = record.planWarnings;\n }\n }\n }\n\n recordAdvance(query: QueryIdentity, record: AdvanceRecord): void {\n this.#totals.addAdvance(record);\n this.#stats(query)?.addAdvance(record);\n }\n\n #stats(query: QueryIdentity): ShapeStats | undefined {\n const key = `${query.queryName ?? ''}:${query.shape.hash}`;\n let stats = this.#shapes.get(key);\n if (stats === undefined) {\n if (this.#shapes.size >= this.#maxShapes) {\n this.#overflowShapes.add(key);\n return undefined;\n }\n stats = new ShapeStats({queryName: query.queryName, shape: query.shape});\n this.#shapes.set(key, stats);\n }\n return stats;\n }\n\n /**\n * Logs the stats of the interval since the previous flush, and starts a\n * new interval. Nothing is logged for an interval without any work.\n */\n flush(lc: LogContext): void {\n const now = this.#now();\n const intervalMs = now - this.#intervalStart;\n const shapes = this.#shapes;\n const totals = this.#totals;\n const overflowShapes = this.#overflowShapes.estimatedCount;\n this.#shapes = new Map();\n this.#totals = new Totals();\n this.#overflowShapes = new OverflowShapeCounter();\n this.#intervalStart = now;\n\n if (shapes.size === 0 && overflowShapes === 0) {\n return;\n }\n const reported = [...shapes.values()]\n .toSorted((a, b) => b.timeMs - a.timeMs)\n .slice(0, this.#maxReported);\n for (const stats of reported) {\n const {queryName, shape} = stats.query;\n lc.info?.('query stats', {\n zeroEvent: 'query-stats',\n intervalMs,\n ...(queryName !== undefined && {queryName}),\n queryShape: shape.hash,\n ...stats.toJSON(),\n ...(stats.planWarnings !== undefined &&\n stats.planWarnings.length > 0 && {planWarnings: stats.planWarnings}),\n zql: shape.zql,\n });\n }\n lc.info?.('query stats summary', {\n zeroEvent: 'query-stats-summary',\n intervalMs,\n shapes: shapes.size + overflowShapes,\n shapesReported: reported.length,\n ...totals.toJSON(),\n });\n }\n\n /**\n * Flushes every `intervalMs` until the returned function is called, which\n * flushes one last time.\n */\n start(lc: LogContext, intervalMs: number): () => void {\n const timer = setInterval(() => this.flush(lc), intervalMs);\n timer.unref?.();\n return () => {\n clearInterval(timer);\n this.flush(lc);\n };\n }\n}\n\nfunction round(ms: number) {\n return Math.round(ms * 100) / 100;\n}\n"],"mappings":";;AAiDA,IAAM,eAAN,MAAmB;CACjB,QAAQ;CACR,QAAQ;CACR,QAAQ;CACR,QAAQ;CAER,IAAI,IAAY;EACd,KAAK;EACL,KAAK,SAAS;EACd,KAAK,QAAQ,KAAK,IAAI,KAAK,OAAO,EAAE;EACpC,KAAK,QAAQ,KAAK,IAAI,KAAK,OAAO,EAAE;CACtC;CAEA,SAAS;EACP,OAAO;GACL,OAAO,KAAK;GACZ,OAAO,MAAM,KAAK,KAAK;GACvB,OAAO,MAAM,KAAK,UAAU,IAAI,IAAI,KAAK,KAAK;GAC9C,OAAO,MAAM,KAAK,KAAK;EACzB;CACF;AACF;AAEA,IAAM,SAAN,MAAa;CACX,aAAsB,IAAI,aAAa;CACvC,oBAAoB;CACpB,mBAAmB;CACnB,oBAAoB;CACpB,oBAAoB;CACpB,WAAoB,IAAI,aAAa;CACrC,iBAAiB;CACjB,kBAAkB;CAElB,IAAI,SAAS;EACX,OAAO,KAAK,WAAW,QAAQ,KAAK,SAAS;CAC/C;CAEA,aAAa,EAAC,SAAS,QAAQ,UAAU,YAA4B;EACnE,KAAK,WAAW,IAAI,MAAM;EAC1B,IAAI,YAAY,WACd,KAAK;OACA,IAAI,YAAY,UACrB,KAAK;EAEP,KAAK,qBAAqB,YAAY;EACtC,KAAK,qBAAqB,YAAY;CACxC;CAEA,WAAW,EAAC,QAAQ,SAAS,YAA0B;EACrD,KAAK,SAAS,IAAI,MAAM;EACxB,KAAK,kBAAkB;EACvB,IAAI,UACF,KAAK;CAET;CAEA,SAAS;EACP,OAAO;GACL,QAAQ,MAAM,KAAK,MAAM;GACzB,YAAY,KAAK,WAAW,OAAO;GACnC,mBAAmB,KAAK;GACxB,kBAAkB,KAAK;GACvB,mBAAmB,KAAK;GACxB,mBAAmB,KAAK;GACxB,UAAU,KAAK,SAAS,OAAO;GAC/B,gBAAgB,KAAK;GACrB,iBAAiB,KAAK;EACxB;CACF;AACF;AAEA,IAAM,aAAN,cAAyB,OAAO;CAC9B;CACA;CAEA,YAAY,OAAsB;EAChC,MAAM;EACN,KAAK,QAAQ;CACf;AACF;;AAGA,IAAM,uBAAN,MAA2B;CACzB,WAAoB,IAAI,WAAW,IAAI;CACvC,YAAY;CAEZ,IAAI,KAAmB;EAErB,IAAI,OAAO;EACX,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAC9B,OAAO,KAAK,KAAK,OAAO,IAAI,WAAW,CAAC,GAAG,QAAU;EAEvD,MAAM,UAAU,SAAS,KAAK,KAAKA,SAAS;EAC5C,IAAI,KAAKA,SAAS,YAAY,GAAG;GAC/B,KAAKA,SAAS,UAAU;GACxB,KAAKC;EACP;CACF;CAEA,IAAI,iBAAyB;EAC3B,MAAM,QAAQ,KAAKD,SAAS,SAAS,KAAKC;EAC1C,OAAO,UAAU,IACb,KAAKD,SAAS,SACd,KAAK,MACH,CAAC,KAAKA,SAAS,SAAS,KAAK,IAAI,QAAQ,KAAKA,SAAS,MAAM,CAC/D;CACN;AACF;;;;;;;;;;;;;;;;;;;;;AAsBA,IAAa,aAAb,MAAwB;CACtB;CACA;CACA;CAEA,0BAAU,IAAI,IAAwB;CACtC,UAAU,IAAI,OAAO;CACrB,kBAAkB,IAAI,qBAAqB;CAC3C;CAEA,YAAY,EACV,YAAY,KACZ,cAAc,KACd,MAAM,KAAK,QACU,CAAC,GAAG;EACzB,OAAO,YAAY,GAAG,4BAA4B;EAClD,OAAO,cAAc,GAAG,8BAA8B;EACtD,KAAKE,aAAa;EAClB,KAAKC,eAAe;EACpB,KAAKC,OAAO;EACZ,KAAKC,iBAAiB,IAAI;CAC5B;CAEA,gBAAgB,OAAsB,QAA+B;EACnE,KAAKC,QAAQ,aAAa,MAAM;EAChC,MAAM,QAAQ,KAAKC,OAAO,KAAK;EAC/B,IAAI,OAAO;GACT,MAAM,aAAa,MAAM;GACzB,IAAI,OAAO,iBAAiB,KAAA,GAC1B,MAAM,eAAe,OAAO;EAEhC;CACF;CAEA,cAAc,OAAsB,QAA6B;EAC/D,KAAKD,QAAQ,WAAW,MAAM;EAC9B,KAAKC,OAAO,KAAK,GAAG,WAAW,MAAM;CACvC;CAEA,OAAO,OAA8C;EACnD,MAAM,MAAM,GAAG,MAAM,aAAa,GAAG,GAAG,MAAM,MAAM;EACpD,IAAI,QAAQ,KAAKC,QAAQ,IAAI,GAAG;EAChC,IAAI,UAAU,KAAA,GAAW;GACvB,IAAI,KAAKA,QAAQ,QAAQ,KAAKN,YAAY;IACxC,KAAKO,gBAAgB,IAAI,GAAG;IAC5B;GACF;GACA,QAAQ,IAAI,WAAW;IAAC,WAAW,MAAM;IAAW,OAAO,MAAM;GAAK,CAAC;GACvE,KAAKD,QAAQ,IAAI,KAAK,KAAK;EAC7B;EACA,OAAO;CACT;;;;;CAMA,MAAM,IAAsB;EAC1B,MAAM,MAAM,KAAKJ,KAAK;EACtB,MAAM,aAAa,MAAM,KAAKC;EAC9B,MAAM,SAAS,KAAKG;EACpB,MAAM,SAAS,KAAKF;EACpB,MAAM,iBAAiB,KAAKG,gBAAgB;EAC5C,KAAKD,0BAAU,IAAI,IAAI;EACvB,KAAKF,UAAU,IAAI,OAAO;EAC1B,KAAKG,kBAAkB,IAAI,qBAAqB;EAChD,KAAKJ,iBAAiB;EAEtB,IAAI,OAAO,SAAS,KAAK,mBAAmB,GAC1C;EAEF,MAAM,WAAW,CAAC,GAAG,OAAO,OAAO,CAAC,EACjC,UAAU,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,EACtC,MAAM,GAAG,KAAKF,YAAY;EAC7B,KAAK,MAAM,SAAS,UAAU;GAC5B,MAAM,EAAC,WAAW,UAAS,MAAM;GACjC,GAAG,OAAO,eAAe;IACvB,WAAW;IACX;IACA,GAAI,cAAc,KAAA,KAAa,EAAC,UAAS;IACzC,YAAY,MAAM;IAClB,GAAG,MAAM,OAAO;IAChB,GAAI,MAAM,iBAAiB,KAAA,KACzB,MAAM,aAAa,SAAS,KAAK,EAAC,cAAc,MAAM,aAAY;IACpE,KAAK,MAAM;GACb,CAAC;EACH;EACA,GAAG,OAAO,uBAAuB;GAC/B,WAAW;GACX;GACA,QAAQ,OAAO,OAAO;GACtB,gBAAgB,SAAS;GACzB,GAAG,OAAO,OAAO;EACnB,CAAC;CACH;;;;;CAMA,MAAM,IAAgB,YAAgC;EACpD,MAAM,QAAQ,kBAAkB,KAAK,MAAM,EAAE,GAAG,UAAU;EAC1D,MAAM,QAAQ;EACd,aAAa;GACX,cAAc,KAAK;GACnB,KAAK,MAAM,EAAE;EACf;CACF;AACF;AAEA,SAAS,MAAM,IAAY;CACzB,OAAO,KAAK,MAAM,KAAK,GAAG,IAAI;AAChC"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * The default maximum number of entries retained by a {@link SnapshotRowCache}.
3
+ *
4
+ * Each entry is a raw SQLite row (or the list of rows conflicting with
5
+ * a row on its unique keys) read while computing a snapshot diff. A
6
+ * replicated transaction of N rows produces up to 2N entries (the new value
7
+ * and the previous value(s) of each row), so the cache should be large enough
8
+ * to hold the largest transactions that are commonly replicated in order for
9
+ * all of the client groups on a worker to share the reads.
10
+ */
11
+ export declare const DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES = 50000;
12
+ /**
13
+ * How a statement's results are read: a single row (`Statement.get()`) or
14
+ * all rows (`Statement.all()`).
15
+ */
16
+ export type ReadMode = 'get' | 'all';
17
+ /**
18
+ * The maximum number of distinct SQL statements interned by a
19
+ * {@link SnapshotRowCache} before it is cleared. There is one per table and
20
+ * lookup shape, so this is only reached after many schema changes.
21
+ */
22
+ export declare const MAX_INTERNED_STATEMENTS = 10000;
23
+ /**
24
+ * A worker-wide, bounded cache of the rows that a `Snapshotter` reads from
25
+ * replica snapshots when computing the diff between two versions of the
26
+ * replica.
27
+ *
28
+ * Every client group (i.e. view-syncer) on a sync worker computes its own
29
+ * diff from the shared `_zero.changeLog2`, and each change in the diff costs
30
+ * two SQLite reads: the new value of the row (from the `curr` snapshot) and
31
+ * the previous value(s) that it replaces (from the `prev` snapshot). The
32
+ * reads for a given change are identical for every client group that
33
+ * traverses it, so a replicated transaction of N rows costs N × 2 × (client
34
+ * groups) reads per worker, most of which are redundant. This cache lets the
35
+ * client groups on a worker share those reads.
36
+ *
37
+ * ### Keys
38
+ *
39
+ * Entries are keyed by the exact SQL statement and arguments of the read
40
+ * (which encodes the table, the selected columns and the lookup keys), plus
41
+ * a `tag` supplied by the caller that pins the result to a version of the
42
+ * replica:
43
+ *
44
+ * - The new value of a row is the row as of the `stateVersion` recorded in
45
+ * its change log entry (its `_0_version` is asserted to equal that
46
+ * version), and is tagged with that `stateVersion`. It is thus shareable
47
+ * by all client groups regardless of the snapshots they are advancing
48
+ * between.
49
+ * - Previous values are read from the `prev` snapshot at its version, and
50
+ * are tagged with that version (and, when the result can depend on the
51
+ * changes applied to the snapshot before the read, the `curr` version
52
+ * as well). See `Diff` in `snapshotter.ts` for the details.
53
+ *
54
+ * Because every key includes the version(s) that the result depends on,
55
+ * entries never go stale and are never invalidated; they are only evicted.
56
+ *
57
+ * ### Eviction
58
+ *
59
+ * The cache is bounded by entry count and evicts in insertion (FIFO) order
60
+ * rather than by recency. Diffs are traversed in change log order by every
61
+ * client group, so the entries that will not be needed again are those that
62
+ * were inserted the earliest (all groups have moved past them), while the
63
+ * most recently inserted entries are the ones that the trailing groups have
64
+ * yet to reach. Refreshing an entry on a hit would evict exactly the wrong
65
+ * entries when a trailing group catches up.
66
+ *
67
+ * ### Sharing
68
+ *
69
+ * Cached values are shared by reference across client groups and must
70
+ * therefore never be mutated by callers.
71
+ */
72
+ export declare class SnapshotRowCache {
73
+ #private;
74
+ constructor(maxEntries?: number);
75
+ get size(): number;
76
+ get maxEntries(): number;
77
+ stats(): {
78
+ hits: number;
79
+ misses: number;
80
+ size: number;
81
+ };
82
+ /**
83
+ * Returns the cached result of the read identified by `tag`, `sql`, `mode`
84
+ * and `args`, or performs the read via `read()`, caching and returning its
85
+ * result. `undefined` results (i.e. a missing row) are not cached.
86
+ *
87
+ * `mode` is part of the key because the same statement can be read both
88
+ * ways: for a table whose only unique key is its primary key, `getRow()`
89
+ * and `getRows()` produce identical SQL, args and tags, but the former
90
+ * caches a row and the latter an array of rows.
91
+ */
92
+ getOrRead<T>(tag: string, sql: string, mode: ReadMode, args: unknown[], read: () => T): T;
93
+ clear(): void;
94
+ }
95
+ //# sourceMappingURL=snapshot-row-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-row-cache.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/snapshot-row-cache.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,eAAO,MAAM,sCAAsC,QAAS,CAAC;AAwB7D;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAK9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,qBAAa,gBAAgB;;IAmB3B,YAAY,UAAU,SAAyC,EAE9D;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,KAAK,IAAI;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,CAEpD;IAED;;;;;;;;;OASG;IACH,SAAS,CAAC,CAAC,EACT,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,OAAO,EAAE,EACf,IAAI,EAAE,MAAM,CAAC,GACZ,CAAC,CAoBH;IAED,KAAK,IAAI,IAAI,CAIZ;CAsBF"}
@@ -0,0 +1,155 @@
1
+ import { getOrInsert } from "../../../../shared/src/map.js";
2
+ import { must } from "../../../../shared/src/must.js";
3
+ import { stringify } from "../../../../shared/src/bigint-json.js";
4
+ import { getOrCreateCounter } from "../../observability/metrics.js";
5
+ import { RingBuffer } from "../../../../shared/src/ring-buffer.js";
6
+ //#region ../zero-cache/src/services/view-syncer/snapshot-row-cache.ts
7
+ /**
8
+ * The default maximum number of entries retained by a {@link SnapshotRowCache}.
9
+ *
10
+ * Each entry is a raw SQLite row (or the list of rows conflicting with
11
+ * a row on its unique keys) read while computing a snapshot diff. A
12
+ * replicated transaction of N rows produces up to 2N entries (the new value
13
+ * and the previous value(s) of each row), so the cache should be large enough
14
+ * to hold the largest transactions that are commonly replicated in order for
15
+ * all of the client groups on a worker to share the reads.
16
+ */
17
+ var DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES = 5e4;
18
+ /**
19
+ * Serializes a lookup key value (i.e. a SQLite-bound parameter). Numbers and
20
+ * bigints serialize identically, as row keys parsed from the change log are
21
+ * JSON numbers whereas the values read from SQLite are bigints; both address
22
+ * the same row. Strings are prefixed to distinguish them from numbers.
23
+ */
24
+ function serialize(v) {
25
+ switch (typeof v) {
26
+ case "string": return "s" + v;
27
+ case "number":
28
+ case "bigint": return String(v);
29
+ case "boolean": return v ? "true" : "false";
30
+ case "object": return v === null ? "null" : "o" + stringify(v);
31
+ default: return "u" + String(v);
32
+ }
33
+ }
34
+ var HIT = { result: "hit" };
35
+ var MISS = { result: "miss" };
36
+ /**
37
+ * A worker-wide, bounded cache of the rows that a `Snapshotter` reads from
38
+ * replica snapshots when computing the diff between two versions of the
39
+ * replica.
40
+ *
41
+ * Every client group (i.e. view-syncer) on a sync worker computes its own
42
+ * diff from the shared `_zero.changeLog2`, and each change in the diff costs
43
+ * two SQLite reads: the new value of the row (from the `curr` snapshot) and
44
+ * the previous value(s) that it replaces (from the `prev` snapshot). The
45
+ * reads for a given change are identical for every client group that
46
+ * traverses it, so a replicated transaction of N rows costs N × 2 × (client
47
+ * groups) reads per worker, most of which are redundant. This cache lets the
48
+ * client groups on a worker share those reads.
49
+ *
50
+ * ### Keys
51
+ *
52
+ * Entries are keyed by the exact SQL statement and arguments of the read
53
+ * (which encodes the table, the selected columns and the lookup keys), plus
54
+ * a `tag` supplied by the caller that pins the result to a version of the
55
+ * replica:
56
+ *
57
+ * - The new value of a row is the row as of the `stateVersion` recorded in
58
+ * its change log entry (its `_0_version` is asserted to equal that
59
+ * version), and is tagged with that `stateVersion`. It is thus shareable
60
+ * by all client groups regardless of the snapshots they are advancing
61
+ * between.
62
+ * - Previous values are read from the `prev` snapshot at its version, and
63
+ * are tagged with that version (and, when the result can depend on the
64
+ * changes applied to the snapshot before the read, the `curr` version
65
+ * as well). See `Diff` in `snapshotter.ts` for the details.
66
+ *
67
+ * Because every key includes the version(s) that the result depends on,
68
+ * entries never go stale and are never invalidated; they are only evicted.
69
+ *
70
+ * ### Eviction
71
+ *
72
+ * The cache is bounded by entry count and evicts in insertion (FIFO) order
73
+ * rather than by recency. Diffs are traversed in change log order by every
74
+ * client group, so the entries that will not be needed again are those that
75
+ * were inserted the earliest (all groups have moved past them), while the
76
+ * most recently inserted entries are the ones that the trailing groups have
77
+ * yet to reach. Refreshing an entry on a hit would evict exactly the wrong
78
+ * entries when a trailing group catches up.
79
+ *
80
+ * ### Sharing
81
+ *
82
+ * Cached values are shared by reference across client groups and must
83
+ * therefore never be mutated by callers.
84
+ */
85
+ var SnapshotRowCache = class {
86
+ #maxEntries;
87
+ #entries = /* @__PURE__ */ new Map();
88
+ #keys = new RingBuffer();
89
+ #sqlIDs = /* @__PURE__ */ new Map();
90
+ #reads = getOrCreateCounter("sync", "ivm.snapshot-row-reads", "Row reads performed while computing snapshot diffs for IVM, labeled by whether the read was served by the worker-wide snapshot row cache.");
91
+ #hits = 0;
92
+ #misses = 0;
93
+ constructor(maxEntries = DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES) {
94
+ this.#maxEntries = Math.max(0, maxEntries);
95
+ }
96
+ get size() {
97
+ return this.#entries.size;
98
+ }
99
+ get maxEntries() {
100
+ return this.#maxEntries;
101
+ }
102
+ stats() {
103
+ return {
104
+ hits: this.#hits,
105
+ misses: this.#misses,
106
+ size: this.#entries.size
107
+ };
108
+ }
109
+ /**
110
+ * Returns the cached result of the read identified by `tag`, `sql`, `mode`
111
+ * and `args`, or performs the read via `read()`, caching and returning its
112
+ * result. `undefined` results (i.e. a missing row) are not cached.
113
+ *
114
+ * `mode` is part of the key because the same statement can be read both
115
+ * ways: for a table whose only unique key is its primary key, `getRow()`
116
+ * and `getRows()` produce identical SQL, args and tags, but the former
117
+ * caches a row and the latter an array of rows.
118
+ */
119
+ getOrRead(tag, sql, mode, args, read) {
120
+ const key = this.#key(tag, sql, mode, args);
121
+ const cached = this.#entries.get(key);
122
+ if (cached !== void 0) {
123
+ this.#hits++;
124
+ this.#reads.add(1, HIT);
125
+ return cached;
126
+ }
127
+ this.#misses++;
128
+ this.#reads.add(1, MISS);
129
+ const value = read();
130
+ if (value !== void 0 && this.#maxEntries > 0) {
131
+ this.#entries.set(key, value);
132
+ this.#keys.push(key);
133
+ if (this.#keys.size > this.#maxEntries) this.#entries.delete(must(this.#keys.shift()));
134
+ }
135
+ return value;
136
+ }
137
+ clear() {
138
+ this.#entries.clear();
139
+ this.#keys.clear();
140
+ this.#sqlIDs.clear();
141
+ }
142
+ #key(tag, sql, mode, args) {
143
+ if (this.#sqlIDs.size >= 1e4 && !this.#sqlIDs.has(sql)) this.clear();
144
+ let key = `${tag}\0${mode}${getOrInsert(this.#sqlIDs, sql, this.#sqlIDs.size)}`;
145
+ for (const arg of args) {
146
+ const serialized = serialize(arg);
147
+ key += `\0${serialized.length}:${serialized}`;
148
+ }
149
+ return key;
150
+ }
151
+ };
152
+ //#endregion
153
+ export { SnapshotRowCache };
154
+
155
+ //# sourceMappingURL=snapshot-row-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshot-row-cache.js","names":["#maxEntries","#entries","#keys","#sqlIDs","#reads","#hits","#misses","#key"],"sources":["../../../../../../zero-cache/src/services/view-syncer/snapshot-row-cache.ts"],"sourcesContent":["import {stringify} from '../../../../shared/src/bigint-json.ts';\nimport {getOrInsert} from '../../../../shared/src/map.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport {RingBuffer} from '../../../../shared/src/ring-buffer.ts';\nimport {getOrCreateCounter} from '../../observability/metrics.ts';\n\n/**\n * The default maximum number of entries retained by a {@link SnapshotRowCache}.\n *\n * Each entry is a raw SQLite row (or the list of rows conflicting with\n * a row on its unique keys) read while computing a snapshot diff. A\n * replicated transaction of N rows produces up to 2N entries (the new value\n * and the previous value(s) of each row), so the cache should be large enough\n * to hold the largest transactions that are commonly replicated in order for\n * all of the client groups on a worker to share the reads.\n */\nexport const DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES = 50_000;\n\n/**\n * Serializes a lookup key value (i.e. a SQLite-bound parameter). Numbers and\n * bigints serialize identically, as row keys parsed from the change log are\n * JSON numbers whereas the values read from SQLite are bigints; both address\n * the same row. Strings are prefixed to distinguish them from numbers.\n */\nfunction serialize(v: unknown): string {\n switch (typeof v) {\n case 'string':\n return 's' + v;\n case 'number':\n case 'bigint':\n return String(v);\n case 'boolean':\n return v ? 'true' : 'false';\n case 'object':\n return v === null ? 'null' : 'o' + stringify(v);\n default:\n return 'u' + String(v);\n }\n}\n\n/**\n * How a statement's results are read: a single row (`Statement.get()`) or\n * all rows (`Statement.all()`).\n */\nexport type ReadMode = 'get' | 'all';\n\n/**\n * The maximum number of distinct SQL statements interned by a\n * {@link SnapshotRowCache} before it is cleared. There is one per table and\n * lookup shape, so this is only reached after many schema changes.\n */\nexport const MAX_INTERNED_STATEMENTS = 10_000;\n\nconst HIT = {result: 'hit'} as const;\nconst MISS = {result: 'miss'} as const;\n\n/**\n * A worker-wide, bounded cache of the rows that a `Snapshotter` reads from\n * replica snapshots when computing the diff between two versions of the\n * replica.\n *\n * Every client group (i.e. view-syncer) on a sync worker computes its own\n * diff from the shared `_zero.changeLog2`, and each change in the diff costs\n * two SQLite reads: the new value of the row (from the `curr` snapshot) and\n * the previous value(s) that it replaces (from the `prev` snapshot). The\n * reads for a given change are identical for every client group that\n * traverses it, so a replicated transaction of N rows costs N × 2 × (client\n * groups) reads per worker, most of which are redundant. This cache lets the\n * client groups on a worker share those reads.\n *\n * ### Keys\n *\n * Entries are keyed by the exact SQL statement and arguments of the read\n * (which encodes the table, the selected columns and the lookup keys), plus\n * a `tag` supplied by the caller that pins the result to a version of the\n * replica:\n *\n * - The new value of a row is the row as of the `stateVersion` recorded in\n * its change log entry (its `_0_version` is asserted to equal that\n * version), and is tagged with that `stateVersion`. It is thus shareable\n * by all client groups regardless of the snapshots they are advancing\n * between.\n * - Previous values are read from the `prev` snapshot at its version, and\n * are tagged with that version (and, when the result can depend on the\n * changes applied to the snapshot before the read, the `curr` version\n * as well). See `Diff` in `snapshotter.ts` for the details.\n *\n * Because every key includes the version(s) that the result depends on,\n * entries never go stale and are never invalidated; they are only evicted.\n *\n * ### Eviction\n *\n * The cache is bounded by entry count and evicts in insertion (FIFO) order\n * rather than by recency. Diffs are traversed in change log order by every\n * client group, so the entries that will not be needed again are those that\n * were inserted the earliest (all groups have moved past them), while the\n * most recently inserted entries are the ones that the trailing groups have\n * yet to reach. Refreshing an entry on a hit would evict exactly the wrong\n * entries when a trailing group catches up.\n *\n * ### Sharing\n *\n * Cached values are shared by reference across client groups and must\n * therefore never be mutated by callers.\n */\nexport class SnapshotRowCache {\n readonly #maxEntries: number;\n readonly #entries = new Map<string, unknown>();\n // The keys of #entries in insertion order, so that the oldest can be\n // evicted in O(1). (Finding the oldest key with a fresh Map iterator\n // instead costs O(evictions) per insert, as V8 leaves deleted entries in\n // the table until it is compacted and every new iterator walks over them.)\n readonly #keys = new RingBuffer<string>();\n // Interns the SQL text of each distinct read so that entry keys\n // do not repeat the (long) column list of every statement.\n readonly #sqlIDs = new Map<string, number>();\n readonly #reads = getOrCreateCounter(\n 'sync',\n 'ivm.snapshot-row-reads',\n 'Row reads performed while computing snapshot diffs for IVM, labeled by whether the read was served by the worker-wide snapshot row cache.',\n );\n #hits = 0;\n #misses = 0;\n\n constructor(maxEntries = DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES) {\n this.#maxEntries = Math.max(0, maxEntries);\n }\n\n get size(): number {\n return this.#entries.size;\n }\n\n get maxEntries(): number {\n return this.#maxEntries;\n }\n\n stats(): {hits: number; misses: number; size: number} {\n return {hits: this.#hits, misses: this.#misses, size: this.#entries.size};\n }\n\n /**\n * Returns the cached result of the read identified by `tag`, `sql`, `mode`\n * and `args`, or performs the read via `read()`, caching and returning its\n * result. `undefined` results (i.e. a missing row) are not cached.\n *\n * `mode` is part of the key because the same statement can be read both\n * ways: for a table whose only unique key is its primary key, `getRow()`\n * and `getRows()` produce identical SQL, args and tags, but the former\n * caches a row and the latter an array of rows.\n */\n getOrRead<T>(\n tag: string,\n sql: string,\n mode: ReadMode,\n args: unknown[],\n read: () => T,\n ): T {\n const key = this.#key(tag, sql, mode, args);\n const cached = this.#entries.get(key);\n if (cached !== undefined) {\n this.#hits++;\n this.#reads.add(1, HIT);\n return cached as T;\n }\n this.#misses++;\n this.#reads.add(1, MISS);\n const value = read();\n if (value !== undefined && this.#maxEntries > 0) {\n // `key` is not in #entries (this is a miss), so it is always added.\n this.#entries.set(key, value);\n this.#keys.push(key);\n if (this.#keys.size > this.#maxEntries) {\n this.#entries.delete(must(this.#keys.shift()));\n }\n }\n return value;\n }\n\n clear(): void {\n this.#entries.clear();\n this.#keys.clear();\n this.#sqlIDs.clear();\n }\n\n #key(tag: string, sql: string, mode: ReadMode, args: unknown[]): string {\n if (\n this.#sqlIDs.size >= MAX_INTERNED_STATEMENTS &&\n !this.#sqlIDs.has(sql)\n ) {\n // Statements are only added (e.g. when schema changes produce new\n // column lists), so bound them by starting over. The entries refer to\n // statements by ID and are cleared with them.\n this.clear();\n }\n const sqlID = getOrInsert(this.#sqlIDs, sql, this.#sqlIDs.size);\n let key = `${tag}\\0${mode}${sqlID}`;\n // Include each value's length so separators inside string values cannot\n // make different argument arrays produce the same key.\n for (const arg of args) {\n const serialized = serialize(arg);\n key += `\\0${serialized.length}:${serialized}`;\n }\n return key;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAa,yCAAyC;;;;;;;AAQtD,SAAS,UAAU,GAAoB;CACrC,QAAQ,OAAO,GAAf;EACE,KAAK,UACH,OAAO,MAAM;EACf,KAAK;EACL,KAAK,UACH,OAAO,OAAO,CAAC;EACjB,KAAK,WACH,OAAO,IAAI,SAAS;EACtB,KAAK,UACH,OAAO,MAAM,OAAO,SAAS,MAAM,UAAU,CAAC;EAChD,SACE,OAAO,MAAM,OAAO,CAAC;CACzB;AACF;AAeA,IAAM,MAAM,EAAC,QAAQ,MAAK;AAC1B,IAAM,OAAO,EAAC,QAAQ,OAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmD5B,IAAa,mBAAb,MAA8B;CAC5B;CACA,2BAAoB,IAAI,IAAqB;CAK7C,QAAiB,IAAI,WAAmB;CAGxC,0BAAmB,IAAI,IAAoB;CAC3C,SAAkB,mBAChB,QACA,0BACA,2IACF;CACA,QAAQ;CACR,UAAU;CAEV,YAAY,aAAa,wCAAwC;EAC/D,KAAKA,cAAc,KAAK,IAAI,GAAG,UAAU;CAC3C;CAEA,IAAI,OAAe;EACjB,OAAO,KAAKC,SAAS;CACvB;CAEA,IAAI,aAAqB;EACvB,OAAO,KAAKD;CACd;CAEA,QAAsD;EACpD,OAAO;GAAC,MAAM,KAAKK;GAAO,QAAQ,KAAKC;GAAS,MAAM,KAAKL,SAAS;EAAI;CAC1E;;;;;;;;;;;CAYA,UACE,KACA,KACA,MACA,MACA,MACG;EACH,MAAM,MAAM,KAAKM,KAAK,KAAK,KAAK,MAAM,IAAI;EAC1C,MAAM,SAAS,KAAKN,SAAS,IAAI,GAAG;EACpC,IAAI,WAAW,KAAA,GAAW;GACxB,KAAKI;GACL,KAAKD,OAAO,IAAI,GAAG,GAAG;GACtB,OAAO;EACT;EACA,KAAKE;EACL,KAAKF,OAAO,IAAI,GAAG,IAAI;EACvB,MAAM,QAAQ,KAAK;EACnB,IAAI,UAAU,KAAA,KAAa,KAAKJ,cAAc,GAAG;GAE/C,KAAKC,SAAS,IAAI,KAAK,KAAK;GAC5B,KAAKC,MAAM,KAAK,GAAG;GACnB,IAAI,KAAKA,MAAM,OAAO,KAAKF,aACzB,KAAKC,SAAS,OAAO,KAAK,KAAKC,MAAM,MAAM,CAAC,CAAC;EAEjD;EACA,OAAO;CACT;CAEA,QAAc;EACZ,KAAKD,SAAS,MAAM;EACpB,KAAKC,MAAM,MAAM;EACjB,KAAKC,QAAQ,MAAM;CACrB;CAEA,KAAK,KAAa,KAAa,MAAgB,MAAyB;EACtE,IACE,KAAKA,QAAQ,QAAA,OACb,CAAC,KAAKA,QAAQ,IAAI,GAAG,GAKrB,KAAK,MAAM;EAGb,IAAI,MAAM,GAAG,IAAI,IAAI,OADP,YAAY,KAAKA,SAAS,KAAK,KAAKA,QAAQ,IAC9B;EAG5B,KAAK,MAAM,OAAO,MAAM;GACtB,MAAM,aAAa,UAAU,GAAG;GAChC,OAAO,KAAK,WAAW,OAAO,GAAG;EACnC;EACA,OAAO;CACT;AACF"}