@rocicorp/zero 1.12.0-canary.3 → 1.12.0-canary.5

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 (819) hide show
  1. package/out/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.154.0/helpers/esm}/usingCtx.js +2 -2
  2. package/out/analyze-query/src/analyze-cli.d.ts.map +1 -1
  3. package/out/analyze-query/src/analyze-cli.js +6 -4
  4. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  5. package/out/analyze-query/src/bin-transform.js +4 -3
  6. package/out/analyze-query/src/bin-transform.js.map +1 -1
  7. package/out/analyze-query/src/zql-chain.d.ts +23 -0
  8. package/out/analyze-query/src/zql-chain.d.ts.map +1 -0
  9. package/out/analyze-query/src/zql-chain.js +162 -0
  10. package/out/analyze-query/src/zql-chain.js.map +1 -0
  11. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  12. package/out/ast-to-zql/src/bin.js +4 -3
  13. package/out/ast-to-zql/src/bin.js.map +1 -1
  14. package/out/ast-to-zql/src/format.js.map +1 -1
  15. package/out/datadog/src/datadog-log-sink.js +5 -4
  16. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  17. package/out/otel/src/log-options.js.map +1 -1
  18. package/out/replicache/src/btree/node.js +13 -11
  19. package/out/replicache/src/btree/node.js.map +1 -1
  20. package/out/replicache/src/btree/read.js +4 -2
  21. package/out/replicache/src/btree/read.js.map +1 -1
  22. package/out/replicache/src/btree/splice.js.map +1 -1
  23. package/out/replicache/src/btree/write.js +9 -5
  24. package/out/replicache/src/btree/write.js.map +1 -1
  25. package/out/replicache/src/config.js +1 -2
  26. package/out/replicache/src/connection-loop.js.map +1 -1
  27. package/out/replicache/src/dag/chunk.js +1 -1
  28. package/out/replicache/src/dag/gc.js.map +1 -1
  29. package/out/replicache/src/dag/lazy-store.js +8 -7
  30. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  31. package/out/replicache/src/dag/store-impl.js +1 -1
  32. package/out/replicache/src/dag/store-impl.js.map +1 -1
  33. package/out/replicache/src/dag/visitor.js.map +1 -1
  34. package/out/replicache/src/db/commit.js +5 -3
  35. package/out/replicache/src/db/commit.js.map +1 -1
  36. package/out/replicache/src/db/read.js +1 -1
  37. package/out/replicache/src/db/read.js.map +1 -1
  38. package/out/replicache/src/db/rebase.js.map +1 -1
  39. package/out/replicache/src/db/write.js +5 -2
  40. package/out/replicache/src/db/write.js.map +1 -1
  41. package/out/replicache/src/deleted-clients.js +3 -2
  42. package/out/replicache/src/deleted-clients.js.map +1 -1
  43. package/out/replicache/src/expo-sqlite.js +1 -2
  44. package/out/replicache/src/frozen-json.js +1 -1
  45. package/out/replicache/src/frozen-json.js.map +1 -1
  46. package/out/replicache/src/get-default-puller.js +1 -1
  47. package/out/replicache/src/hash.js +1 -1
  48. package/out/replicache/src/hash.js.map +1 -1
  49. package/out/replicache/src/impl.js +1 -2
  50. package/out/replicache/src/index-defs.js +5 -3
  51. package/out/replicache/src/index-defs.js.map +1 -1
  52. package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
  53. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  54. package/out/replicache/src/kv/idb-store.js +1 -1
  55. package/out/replicache/src/kv/idb-store.js.map +1 -1
  56. package/out/replicache/src/kv/mem-fallback-store.js +1 -1
  57. package/out/replicache/src/kv/mem-fallback-store.js.map +1 -1
  58. package/out/replicache/src/kv/mem-store.js.map +1 -1
  59. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  60. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  61. package/out/replicache/src/kv/read-impl.js.map +1 -1
  62. package/out/replicache/src/kv/sqlite-store.js +1 -1
  63. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  64. package/out/replicache/src/kv/write-impl-base.js +4 -1
  65. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  66. package/out/replicache/src/kv/write-impl.js.map +1 -1
  67. package/out/replicache/src/log-options.js +2 -1
  68. package/out/replicache/src/log-options.js.map +1 -1
  69. package/out/replicache/src/make-idb-name.js +1 -1
  70. package/out/replicache/src/new-client-channel.js +9 -7
  71. package/out/replicache/src/new-client-channel.js.map +1 -1
  72. package/out/replicache/src/on-persist-channel.js +1 -1
  73. package/out/replicache/src/on-persist-channel.js.map +1 -1
  74. package/out/replicache/src/op-sqlite.js +1 -2
  75. package/out/replicache/src/pending-mutations.js +2 -1
  76. package/out/replicache/src/pending-mutations.js.map +1 -1
  77. package/out/replicache/src/persist/client-gc.js +2 -2
  78. package/out/replicache/src/persist/client-gc.js.map +1 -1
  79. package/out/replicache/src/persist/client-group-gc.js +2 -2
  80. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  81. package/out/replicache/src/persist/client-groups.js +1 -1
  82. package/out/replicache/src/persist/client-groups.js.map +1 -1
  83. package/out/replicache/src/persist/clients.js +1 -1
  84. package/out/replicache/src/persist/clients.js.map +1 -1
  85. package/out/replicache/src/persist/collect-idb-databases.js +5 -4
  86. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  87. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  88. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  89. package/out/replicache/src/persist/heartbeat.js +2 -2
  90. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  91. package/out/replicache/src/persist/idb-databases-store.js +1 -1
  92. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  93. package/out/replicache/src/persist/make-client-id.js +1 -1
  94. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  95. package/out/replicache/src/persist/persist.js +3 -2
  96. package/out/replicache/src/persist/persist.js.map +1 -1
  97. package/out/replicache/src/persist/refresh.js +8 -5
  98. package/out/replicache/src/persist/refresh.js.map +1 -1
  99. package/out/replicache/src/process-scheduler.js.map +1 -1
  100. package/out/replicache/src/replicache-impl.js +3 -3
  101. package/out/replicache/src/replicache-impl.js.map +1 -1
  102. package/out/replicache/src/scan-iterator.js.map +1 -1
  103. package/out/replicache/src/scan-options.js +7 -6
  104. package/out/replicache/src/scan-options.js.map +1 -1
  105. package/out/replicache/src/sqlite.js +1 -2
  106. package/out/replicache/src/subscriptions.js +1 -1
  107. package/out/replicache/src/subscriptions.js.map +1 -1
  108. package/out/replicache/src/sync/diff.js +3 -1
  109. package/out/replicache/src/sync/diff.js.map +1 -1
  110. package/out/replicache/src/sync/ids.js.map +1 -1
  111. package/out/replicache/src/sync/patch.js +2 -4
  112. package/out/replicache/src/sync/patch.js.map +1 -1
  113. package/out/replicache/src/sync/pull.js +3 -1
  114. package/out/replicache/src/sync/pull.js.map +1 -1
  115. package/out/replicache/src/sync/push.js.map +1 -1
  116. package/out/replicache/src/sync/request-id.js +1 -1
  117. package/out/replicache/src/sync/request-id.js.map +1 -1
  118. package/out/replicache/src/transactions.js +1 -1
  119. package/out/replicache/src/transactions.js.map +1 -1
  120. package/out/shared/src/arrays.js +4 -1
  121. package/out/shared/src/arrays.js.map +1 -1
  122. package/out/shared/src/asserts.js +1 -1
  123. package/out/shared/src/bigint-json.d.ts +9 -0
  124. package/out/shared/src/bigint-json.d.ts.map +1 -1
  125. package/out/shared/src/bigint-json.js +27 -2
  126. package/out/shared/src/bigint-json.js.map +1 -1
  127. package/out/shared/src/broadcast-channel.js +1 -1
  128. package/out/shared/src/btree-set.js +11 -8
  129. package/out/shared/src/btree-set.js.map +1 -1
  130. package/out/shared/src/cache.js.map +1 -1
  131. package/out/shared/src/config.js +1 -1
  132. package/out/shared/src/custom-key-map.js.map +1 -1
  133. package/out/shared/src/custom-key-set.js.map +1 -1
  134. package/out/shared/src/deep-clone.js +1 -1
  135. package/out/shared/src/document-visible.js.map +1 -1
  136. package/out/shared/src/dotenv.js.map +1 -1
  137. package/out/shared/src/error.js +1 -1
  138. package/out/shared/src/error.js.map +1 -1
  139. package/out/shared/src/hash.js +2 -2
  140. package/out/shared/src/hash.js.map +1 -1
  141. package/out/shared/src/iterables.js.map +1 -1
  142. package/out/shared/src/json-schema.js.map +1 -1
  143. package/out/shared/src/json.js.map +1 -1
  144. package/out/shared/src/logging-test-utils.js +1 -1
  145. package/out/shared/src/logging.js +1 -1
  146. package/out/shared/src/logging.js.map +1 -1
  147. package/out/shared/src/navigator.js +1 -1
  148. package/out/shared/src/options.js +9 -12
  149. package/out/shared/src/options.js.map +1 -1
  150. package/out/shared/src/promise-race.js.map +1 -1
  151. package/out/shared/src/queue.js.map +1 -1
  152. package/out/shared/src/record-proxy.js.map +1 -1
  153. package/out/shared/src/ring-buffer.js.map +1 -1
  154. package/out/shared/src/size-of-value.js +7 -10
  155. package/out/shared/src/size-of-value.js.map +1 -1
  156. package/out/shared/src/sorted-entries.js.map +1 -1
  157. package/out/shared/src/tdigest-schema.js.map +1 -1
  158. package/out/shared/src/tdigest.js.map +1 -1
  159. package/out/shared/src/valita.js +1 -1
  160. package/out/shared/src/valita.js.map +1 -1
  161. package/out/z2s/src/compiler.js +2 -4
  162. package/out/z2s/src/compiler.js.map +1 -1
  163. package/out/z2s/src/sql.js +1 -1
  164. package/out/z2s/src/sql.js.map +1 -1
  165. package/out/zero/package.js +211 -189
  166. package/out/zero/package.js.map +1 -1
  167. package/out/zero/src/adapters/drizzle.js +1 -2
  168. package/out/zero/src/adapters/kysely.js +1 -2
  169. package/out/zero/src/adapters/pg.js +1 -2
  170. package/out/zero/src/adapters/postgresjs.js +1 -2
  171. package/out/zero/src/adapters/prisma.js +1 -2
  172. package/out/zero/src/analyze.js +1 -2
  173. package/out/zero/src/change-protocol/v0.js +1 -2
  174. package/out/zero/src/expo-sqlite.js +1 -2
  175. package/out/zero/src/op-sqlite.js +1 -2
  176. package/out/zero/src/react-native.js.map +1 -1
  177. package/out/zero/src/sqlite.js +1 -2
  178. package/out/zero/src/zero-cache-dev.js +10 -9
  179. package/out/zero/src/zero-cache-dev.js.map +1 -1
  180. package/out/zero/src/zero-out.js +2 -1
  181. package/out/zero/src/zero-out.js.map +1 -1
  182. package/out/zero-cache/src/auth/auth.js +1 -1
  183. package/out/zero-cache/src/auth/auth.js.map +1 -1
  184. package/out/zero-cache/src/auth/jwt.js +4 -1
  185. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  186. package/out/zero-cache/src/auth/load-permissions.js +1 -1
  187. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  188. package/out/zero-cache/src/auth/read-authorizer.js +3 -2
  189. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  190. package/out/zero-cache/src/auth/write-authorizer.js +6 -17
  191. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  192. package/out/zero-cache/src/config/network.js +1 -1
  193. package/out/zero-cache/src/config/network.js.map +1 -1
  194. package/out/zero-cache/src/config/server-context.js.map +1 -1
  195. package/out/zero-cache/src/config/zero-config.d.ts +5 -0
  196. package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
  197. package/out/zero-cache/src/config/zero-config.js +13 -2
  198. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  199. package/out/zero-cache/src/custom/fetch.js +1 -1
  200. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  201. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  202. package/out/zero-cache/src/db/create.js.map +1 -1
  203. package/out/zero-cache/src/db/index-predicate.js.map +1 -1
  204. package/out/zero-cache/src/db/lite-tables.d.ts +2 -2
  205. package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
  206. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  207. package/out/zero-cache/src/db/migration-lite.js +1 -1
  208. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  209. package/out/zero-cache/src/db/migration.js +5 -3
  210. package/out/zero-cache/src/db/migration.js.map +1 -1
  211. package/out/zero-cache/src/db/pg-copy-binary.js +4 -3
  212. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  213. package/out/zero-cache/src/db/pg-copy.js +0 -1
  214. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  215. package/out/zero-cache/src/db/pg-to-lite.js +1 -1
  216. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  217. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  218. package/out/zero-cache/src/db/specs.js +7 -5
  219. package/out/zero-cache/src/db/specs.js.map +1 -1
  220. package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
  221. package/out/zero-cache/src/db/statements.d.ts.map +1 -1
  222. package/out/zero-cache/src/db/statements.js +9 -2
  223. package/out/zero-cache/src/db/statements.js.map +1 -1
  224. package/out/zero-cache/src/db/transaction-pool.js +5 -3
  225. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  226. package/out/zero-cache/src/db/warmup.js.map +1 -1
  227. package/out/zero-cache/src/observability/events.js.map +1 -1
  228. package/out/zero-cache/src/observability/log-throttle.js.map +1 -1
  229. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  230. package/out/zero-cache/src/scripts/decommission.js +1 -1
  231. package/out/zero-cache/src/scripts/deploy-permissions.js +5 -3
  232. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  233. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  234. package/out/zero-cache/src/server/anonymous-otel-start.js +2 -1
  235. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  236. package/out/zero-cache/src/server/change-streamer.js +1 -1
  237. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  238. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  239. package/out/zero-cache/src/server/logging.js +1 -1
  240. package/out/zero-cache/src/server/logging.js.map +1 -1
  241. package/out/zero-cache/src/server/main.js.map +1 -1
  242. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  243. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  244. package/out/zero-cache/src/server/reaper.js +2 -2
  245. package/out/zero-cache/src/server/reaper.js.map +1 -1
  246. package/out/zero-cache/src/server/replicator.js +1 -1
  247. package/out/zero-cache/src/server/replicator.js.map +1 -1
  248. package/out/zero-cache/src/server/runner/run-worker.js +2 -1
  249. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  250. package/out/zero-cache/src/server/runner/runtime.js +2 -1
  251. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  252. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  253. package/out/zero-cache/src/server/shadow-syncer.js +1 -1
  254. package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
  255. package/out/zero-cache/src/server/slot-keeper.js.map +1 -1
  256. package/out/zero-cache/src/server/syncer-assigner.js.map +1 -1
  257. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  258. package/out/zero-cache/src/server/syncer.js +9 -4
  259. package/out/zero-cache/src/server/syncer.js.map +1 -1
  260. package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
  261. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  262. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  263. package/out/zero-cache/src/services/analyze.js +2 -2
  264. package/out/zero-cache/src/services/analyze.js.map +1 -1
  265. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +2 -2
  266. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  267. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  268. package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -1
  269. package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
  270. package/out/zero-cache/src/services/change-source/common/replica-schema.js +4 -4
  271. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  272. package/out/zero-cache/src/services/change-source/custom/change-source.js +4 -4
  273. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  274. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  275. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +4 -4
  276. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  277. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +3 -3
  278. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
  279. package/out/zero-cache/src/services/change-source/pg/change-source.js +6 -8
  280. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  281. package/out/zero-cache/src/services/change-source/pg/decommission.js +2 -1
  282. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  283. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +9 -7
  284. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  285. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  286. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  287. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +5 -4
  288. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  289. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  290. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +2 -2
  291. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -1
  292. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js +1 -1
  293. package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js.map +1 -1
  294. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +3 -3
  295. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  296. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +2 -2
  297. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  298. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +13 -12
  299. package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
  300. package/out/zero-cache/src/services/change-source/pg/schema/init.js +1 -1
  301. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  302. package/out/zero-cache/src/services/change-source/pg/schema/published.js +2 -2
  303. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  304. package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -1
  305. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +10 -7
  306. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  307. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -1
  308. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  309. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +1 -1
  310. package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -1
  311. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  312. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  313. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  314. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  315. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  316. package/out/zero-cache/src/services/change-source/protocol/current.js +1 -1
  317. package/out/zero-cache/src/services/change-source/protocol/mod.js +1 -2
  318. package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -1
  319. package/out/zero-cache/src/services/change-streamer/backfill-state.js +1 -1
  320. package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -1
  321. package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
  322. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  323. package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
  324. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  325. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +1 -1
  326. package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
  327. package/out/zero-cache/src/services/change-streamer/change-log-codec.js +2 -3
  328. package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
  329. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +3 -3
  330. package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
  331. package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -1
  332. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +5 -3
  333. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  334. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +21 -21
  335. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  336. package/out/zero-cache/src/services/change-streamer/change-streamer.js +1 -1
  337. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  338. package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
  339. package/out/zero-cache/src/services/change-streamer/forwarder.js +11 -10
  340. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  341. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +1 -1
  342. package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -1
  343. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +3 -3
  344. package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
  345. package/out/zero-cache/src/services/change-streamer/replica-poller.js +2 -2
  346. package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -1
  347. package/out/zero-cache/src/services/change-streamer/restore-admission.js +12 -1
  348. package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
  349. package/out/zero-cache/src/services/change-streamer/schema/init.js +1 -1
  350. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  351. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  352. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  353. package/out/zero-cache/src/services/change-streamer/snapshot-message.js +1 -1
  354. package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
  355. package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
  356. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +1 -1
  357. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
  358. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +2 -2
  359. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -1
  360. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -1
  361. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
  362. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +1 -1
  363. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +4 -6
  364. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
  365. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +3 -5
  366. package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
  367. package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
  368. package/out/zero-cache/src/services/change-streamer/storer.js +3 -3
  369. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  370. package/out/zero-cache/src/services/change-streamer/subscribe.js +1 -1
  371. package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
  372. package/out/zero-cache/src/services/change-streamer/subscriber.js +2 -2
  373. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  374. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +0 -1
  375. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  376. package/out/zero-cache/src/services/heapz.js +2 -1
  377. package/out/zero-cache/src/services/heapz.js.map +1 -1
  378. package/out/zero-cache/src/services/http-service.js.map +1 -1
  379. package/out/zero-cache/src/services/life-cycle.js +2 -2
  380. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  381. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +4 -2
  382. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  383. package/out/zero-cache/src/services/litestream/commands.js +3 -3
  384. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  385. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +2 -2
  386. package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
  387. package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
  388. package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
  389. package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -1
  390. package/out/zero-cache/src/services/mutagen/mutagen.js +1 -1
  391. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  392. package/out/zero-cache/src/services/mutagen/pusher.js +3 -2
  393. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  394. package/out/zero-cache/src/services/plannerz.js +6 -5
  395. package/out/zero-cache/src/services/plannerz.js.map +1 -1
  396. package/out/zero-cache/src/services/profz.js +5 -3
  397. package/out/zero-cache/src/services/profz.js.map +1 -1
  398. package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
  399. package/out/zero-cache/src/services/replicator/change-log-db.js +4 -3
  400. package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
  401. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +1 -1
  402. package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
  403. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  404. package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
  405. package/out/zero-cache/src/services/replicator/incremental-sync.js +4 -4
  406. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  407. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  408. package/out/zero-cache/src/services/replicator/replication-status.js +4 -3
  409. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  410. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  411. package/out/zero-cache/src/services/replicator/reporter/recorder.js +1 -1
  412. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  413. package/out/zero-cache/src/services/replicator/reporter/report-schema.js +1 -1
  414. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  415. package/out/zero-cache/src/services/replicator/schema/backfilling.js +2 -2
  416. package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
  417. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +19 -7
  418. package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
  419. package/out/zero-cache/src/services/replicator/schema/change-log.js +31 -15
  420. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  421. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
  422. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  423. package/out/zero-cache/src/services/replicator/schema/replication-state.js +10 -7
  424. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  425. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  426. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +1 -1
  427. package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
  428. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +1 -1
  429. package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -1
  430. package/out/zero-cache/src/services/replicator/write-worker-client.js +1 -1
  431. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  432. package/out/zero-cache/src/services/replicator/write-worker.js +3 -3
  433. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  434. package/out/zero-cache/src/services/run-ast.js +1 -1
  435. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  436. package/out/zero-cache/src/services/runner.js.map +1 -1
  437. package/out/zero-cache/src/services/running-state.js.map +1 -1
  438. package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
  439. package/out/zero-cache/src/services/statz.js +4 -3
  440. package/out/zero-cache/src/services/statz.js.map +1 -1
  441. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +2 -2
  442. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  443. package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -1
  444. package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -1
  445. package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
  446. package/out/zero-cache/src/services/view-syncer/client-handler.js +24 -3
  447. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  448. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts +15 -2
  449. package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +1 -1
  450. package/out/zero-cache/src/services/view-syncer/client-schema.js +46 -6
  451. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  452. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  453. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -2
  454. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  455. package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
  456. package/out/zero-cache/src/services/view-syncer/cvr-store.js +11 -6
  457. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  458. package/out/zero-cache/src/services/view-syncer/cvr.js +12 -4
  459. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  460. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +1 -1
  461. package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -1
  462. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  463. package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -1
  464. package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -1
  465. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +2 -2
  466. package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -1
  467. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +6 -4
  468. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  469. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  470. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +13 -10
  471. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  472. package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -1
  473. package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -1
  474. package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -1
  475. package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
  476. package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -1
  477. package/out/zero-cache/src/services/view-syncer/query-stats.js +1 -1
  478. package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
  479. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +1 -1
  480. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  481. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
  482. package/out/zero-cache/src/services/view-syncer/schema/types.js +1 -1
  483. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  484. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +7 -1
  485. package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -1
  486. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +8 -1
  487. package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
  488. package/out/zero-cache/src/services/view-syncer/snapshotter.js +7 -6
  489. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  490. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  491. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  492. package/out/zero-cache/src/services/view-syncer/view-syncer.js +19 -15
  493. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  494. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  495. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  496. package/out/zero-cache/src/types/lite.js +1 -1
  497. package/out/zero-cache/src/types/lite.js.map +1 -1
  498. package/out/zero-cache/src/types/pg-data-type.js +1 -1
  499. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  500. package/out/zero-cache/src/types/pg.js +6 -4
  501. package/out/zero-cache/src/types/pg.js.map +1 -1
  502. package/out/zero-cache/src/types/poke-chunk.js +2 -2
  503. package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
  504. package/out/zero-cache/src/types/processes.js +1 -1
  505. package/out/zero-cache/src/types/processes.js.map +1 -1
  506. package/out/zero-cache/src/types/profiler.js +1 -1
  507. package/out/zero-cache/src/types/profiler.js.map +1 -1
  508. package/out/zero-cache/src/types/row-key.js.map +1 -1
  509. package/out/zero-cache/src/types/sql.js.map +1 -1
  510. package/out/zero-cache/src/types/streams.js +10 -9
  511. package/out/zero-cache/src/types/streams.js.map +1 -1
  512. package/out/zero-cache/src/types/strings.js.map +1 -1
  513. package/out/zero-cache/src/types/subscription.js.map +1 -1
  514. package/out/zero-cache/src/types/timeout.js +1 -1
  515. package/out/zero-cache/src/types/websocket-handoff.js +1 -1
  516. package/out/zero-cache/src/types/ws.js +1 -1
  517. package/out/zero-cache/src/workers/connection.js +5 -6
  518. package/out/zero-cache/src/workers/connection.js.map +1 -1
  519. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  520. package/out/zero-cache/src/workers/replicator.js +5 -4
  521. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  522. package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
  523. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +9 -1
  524. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  525. package/out/zero-cache/src/workers/syncer.js +4 -4
  526. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  527. package/out/zero-client/src/client/active-clients-manager.js +1 -1
  528. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  529. package/out/zero-client/src/client/bindings.js +11 -11
  530. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  531. package/out/zero-client/src/client/connection.js +1 -1
  532. package/out/zero-client/src/client/connection.js.map +1 -1
  533. package/out/zero-client/src/client/context.js.map +1 -1
  534. package/out/zero-client/src/client/crud-impl.js +1 -1
  535. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  536. package/out/zero-client/src/client/crud.js +1 -1
  537. package/out/zero-client/src/client/crud.js.map +1 -1
  538. package/out/zero-client/src/client/custom.js +1 -1
  539. package/out/zero-client/src/client/custom.js.map +1 -1
  540. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  541. package/out/zero-client/src/client/enable-analytics.js +1 -1
  542. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  543. package/out/zero-client/src/client/error.js.map +1 -1
  544. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  545. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  546. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +1 -1
  547. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  548. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  549. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  550. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  551. package/out/zero-client/src/client/ivm-branch.js +1 -3
  552. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  553. package/out/zero-client/src/client/keys.js +2 -1
  554. package/out/zero-client/src/client/keys.js.map +1 -1
  555. package/out/zero-client/src/client/log-options.js.map +1 -1
  556. package/out/zero-client/src/client/make-replicache-mutators.js +5 -3
  557. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  558. package/out/zero-client/src/client/metrics.js +3 -5
  559. package/out/zero-client/src/client/metrics.js.map +1 -1
  560. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  561. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  562. package/out/zero-client/src/client/options.js.map +1 -1
  563. package/out/zero-client/src/client/query-manager.js +2 -2
  564. package/out/zero-client/src/client/query-manager.js.map +1 -1
  565. package/out/zero-client/src/client/reload-error-handler.js +4 -3
  566. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  567. package/out/zero-client/src/client/version.js +1 -1
  568. package/out/zero-client/src/client/zero-poke-handler.js +1 -1
  569. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  570. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  571. package/out/zero-client/src/client/zero.js +19 -11
  572. package/out/zero-client/src/client/zero.js.map +1 -1
  573. package/out/zero-client/src/mod.js +23 -23
  574. package/out/zero-client/src/util/nanoid.js.map +1 -1
  575. package/out/zero-permissions/src/permissions.js +3 -2
  576. package/out/zero-permissions/src/permissions.js.map +1 -1
  577. package/out/zero-pg/src/mod.js +9 -9
  578. package/out/zero-protocol/src/analyze-query-result.js +1 -1
  579. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  580. package/out/zero-protocol/src/application-error.js.map +1 -1
  581. package/out/zero-protocol/src/ast.js +19 -9
  582. package/out/zero-protocol/src/ast.js.map +1 -1
  583. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  584. package/out/zero-protocol/src/client-schema.js +1 -1
  585. package/out/zero-protocol/src/client-schema.js.map +1 -1
  586. package/out/zero-protocol/src/close-connection.js +1 -1
  587. package/out/zero-protocol/src/close-connection.js.map +1 -1
  588. package/out/zero-protocol/src/connect.js +1 -1
  589. package/out/zero-protocol/src/connect.js.map +1 -1
  590. package/out/zero-protocol/src/custom-queries.js +1 -1
  591. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  592. package/out/zero-protocol/src/data.js +4 -2
  593. package/out/zero-protocol/src/data.js.map +1 -1
  594. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  595. package/out/zero-protocol/src/down.d.ts +27 -27
  596. package/out/zero-protocol/src/down.js.map +1 -1
  597. package/out/zero-protocol/src/error.js.map +1 -1
  598. package/out/zero-protocol/src/inspect-down.d.ts +81 -81
  599. package/out/zero-protocol/src/inspect-down.js +1 -1
  600. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  601. package/out/zero-protocol/src/inspect-up.js +1 -1
  602. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  603. package/out/zero-protocol/src/mutate-server.js +1 -1
  604. package/out/zero-protocol/src/mutate-server.js.map +1 -1
  605. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  606. package/out/zero-protocol/src/mutation.js +1 -1
  607. package/out/zero-protocol/src/mutation.js.map +1 -1
  608. package/out/zero-protocol/src/mutations-patch.js +1 -1
  609. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  610. package/out/zero-protocol/src/ping.js +1 -1
  611. package/out/zero-protocol/src/ping.js.map +1 -1
  612. package/out/zero-protocol/src/poke.d.ts +6 -6
  613. package/out/zero-protocol/src/poke.js +1 -1
  614. package/out/zero-protocol/src/poke.js.map +1 -1
  615. package/out/zero-protocol/src/pong.js +1 -1
  616. package/out/zero-protocol/src/pong.js.map +1 -1
  617. package/out/zero-protocol/src/primary-key.js.map +1 -1
  618. package/out/zero-protocol/src/protocol-version.js +1 -0
  619. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  620. package/out/zero-protocol/src/pull.js +1 -1
  621. package/out/zero-protocol/src/pull.js.map +1 -1
  622. package/out/zero-protocol/src/push.js +1 -1
  623. package/out/zero-protocol/src/push.js.map +1 -1
  624. package/out/zero-protocol/src/queries-patch.js +1 -1
  625. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  626. package/out/zero-protocol/src/query-hash-visitor.js.map +1 -1
  627. package/out/zero-protocol/src/query-hash.js +2 -2
  628. package/out/zero-protocol/src/query-server.js +1 -1
  629. package/out/zero-protocol/src/query-server.js.map +1 -1
  630. package/out/zero-protocol/src/row-patch.js.map +1 -1
  631. package/out/zero-protocol/src/up.d.ts +60 -60
  632. package/out/zero-protocol/src/up.js.map +1 -1
  633. package/out/zero-protocol/src/update-auth.js.map +1 -1
  634. package/out/zero-protocol/src/version.js.map +1 -1
  635. package/out/zero-react/src/bindings.js +11 -11
  636. package/out/zero-react/src/mod.js +5 -5
  637. package/out/zero-react/src/use-query.js +1 -1
  638. package/out/zero-react/src/use-query.js.map +1 -1
  639. package/out/zero-react/src/zero-provider.d.ts +1 -1
  640. package/out/zero-react/src/zero-provider.d.ts.map +1 -1
  641. package/out/zero-react/src/zero-provider.js +2 -1
  642. package/out/zero-react/src/zero-provider.js.map +1 -1
  643. package/out/zero-react/src/zero.js +23 -23
  644. package/out/zero-schema/src/builder/schema-builder.js +3 -2
  645. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  646. package/out/zero-schema/src/builder/table-builder.js +1 -1
  647. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  648. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  649. package/out/zero-schema/src/name-mapper.js +7 -5
  650. package/out/zero-schema/src/name-mapper.js.map +1 -1
  651. package/out/zero-schema/src/schema-config.js +1 -1
  652. package/out/zero-schema/src/schema-config.js.map +1 -1
  653. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  654. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  655. package/out/zero-server/src/adapters/pg.js.map +1 -1
  656. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  657. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  658. package/out/zero-server/src/closable-db-transaction.js.map +1 -1
  659. package/out/zero-server/src/custom.js +1 -1
  660. package/out/zero-server/src/custom.js.map +1 -1
  661. package/out/zero-server/src/mod.js +8 -8
  662. package/out/zero-server/src/process-mutations.js.map +1 -1
  663. package/out/zero-server/src/push-processor.js.map +1 -1
  664. package/out/zero-server/src/queries/process-queries.js +2 -1
  665. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  666. package/out/zero-server/src/schema.js +7 -7
  667. package/out/zero-server/src/schema.js.map +1 -1
  668. package/out/zero-server/src/zql-database.js.map +1 -1
  669. package/out/zero-solid/src/bindings.js +11 -11
  670. package/out/zero-solid/src/mod.js +5 -5
  671. package/out/zero-solid/src/solid-view.js +1 -1
  672. package/out/zero-solid/src/solid-view.js.map +1 -1
  673. package/out/zero-solid/src/use-connection-state.js +2 -1
  674. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  675. package/out/zero-solid/src/use-query.js.map +1 -1
  676. package/out/zero-solid/src/use-zero-online.js +2 -1
  677. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  678. package/out/zero-solid/src/use-zero.js +3 -2
  679. package/out/zero-solid/src/use-zero.js.map +1 -1
  680. package/out/zero-solid/src/zero.js +23 -23
  681. package/out/zero-types/src/name-mapper.js.map +1 -1
  682. package/out/zql/src/builder/builder.js +15 -13
  683. package/out/zql/src/builder/builder.js.map +1 -1
  684. package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -1
  685. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  686. package/out/zql/src/builder/like.js +0 -1
  687. package/out/zql/src/builder/like.js.map +1 -1
  688. package/out/zql/src/ivm/array-view.js.map +1 -1
  689. package/out/zql/src/ivm/cap.d.ts +1 -1
  690. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  691. package/out/zql/src/ivm/cap.js +10 -0
  692. package/out/zql/src/ivm/cap.js.map +1 -1
  693. package/out/zql/src/ivm/constraint.js +1 -1
  694. package/out/zql/src/ivm/constraint.js.map +1 -1
  695. package/out/zql/src/ivm/data.d.ts +15 -1
  696. package/out/zql/src/ivm/data.d.ts.map +1 -1
  697. package/out/zql/src/ivm/data.js +15 -1
  698. package/out/zql/src/ivm/data.js.map +1 -1
  699. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  700. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  701. package/out/zql/src/ivm/exists.js +32 -22
  702. package/out/zql/src/ivm/exists.js.map +1 -1
  703. package/out/zql/src/ivm/fan-in.js.map +1 -1
  704. package/out/zql/src/ivm/fan-out.js.map +1 -1
  705. package/out/zql/src/ivm/filter-operators.d.ts +5 -0
  706. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  707. package/out/zql/src/ivm/filter-operators.js +1 -1
  708. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  709. package/out/zql/src/ivm/filter-push.js.map +1 -1
  710. package/out/zql/src/ivm/filter.js.map +1 -1
  711. package/out/zql/src/ivm/flipped-join.js +1 -3
  712. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  713. package/out/zql/src/ivm/join-index-tap.js.map +1 -1
  714. package/out/zql/src/ivm/join-index.js.map +1 -1
  715. package/out/zql/src/ivm/join-utils.js +11 -13
  716. package/out/zql/src/ivm/join-utils.js.map +1 -1
  717. package/out/zql/src/ivm/join.d.ts.map +1 -1
  718. package/out/zql/src/ivm/join.js +6 -3
  719. package/out/zql/src/ivm/join.js.map +1 -1
  720. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  721. package/out/zql/src/ivm/memory-source.js +27 -23
  722. package/out/zql/src/ivm/memory-source.js.map +1 -1
  723. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  724. package/out/zql/src/ivm/operator.d.ts +6 -0
  725. package/out/zql/src/ivm/operator.d.ts.map +1 -1
  726. package/out/zql/src/ivm/operator.js +2 -2
  727. package/out/zql/src/ivm/operator.js.map +1 -1
  728. package/out/zql/src/ivm/push-accumulated.js +0 -1
  729. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  730. package/out/zql/src/ivm/skip-yields.js.map +1 -1
  731. package/out/zql/src/ivm/skip.js.map +1 -1
  732. package/out/zql/src/ivm/take-gate.js.map +1 -1
  733. package/out/zql/src/ivm/take.d.ts.map +1 -1
  734. package/out/zql/src/ivm/take.js +5 -4
  735. package/out/zql/src/ivm/take.js.map +1 -1
  736. package/out/zql/src/ivm/union-fan-in.js +1 -1
  737. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  738. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  739. package/out/zql/src/ivm/view-apply-change.js +1 -1
  740. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  741. package/out/zql/src/mutate/crud.js +3 -2
  742. package/out/zql/src/mutate/crud.js.map +1 -1
  743. package/out/zql/src/planner/planner-builder.js +1 -1
  744. package/out/zql/src/planner/planner-builder.js.map +1 -1
  745. package/out/zql/src/planner/planner-connection.js.map +1 -1
  746. package/out/zql/src/planner/planner-debug.js.map +1 -1
  747. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  748. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  749. package/out/zql/src/planner/planner-filter.js.map +1 -1
  750. package/out/zql/src/planner/planner-graph.js +1 -5
  751. package/out/zql/src/planner/planner-graph.js.map +1 -1
  752. package/out/zql/src/planner/planner-join.js +1 -1
  753. package/out/zql/src/planner/planner-join.js.map +1 -1
  754. package/out/zql/src/planner/planner-source.js.map +1 -1
  755. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  756. package/out/zql/src/query/create-builder.js +2 -1
  757. package/out/zql/src/query/create-builder.js.map +1 -1
  758. package/out/zql/src/query/expression.js +1 -1
  759. package/out/zql/src/query/expression.js.map +1 -1
  760. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  761. package/out/zql/src/query/named.js +2 -1
  762. package/out/zql/src/query/named.js.map +1 -1
  763. package/out/zql/src/query/query-delegate-base.js +1 -1
  764. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  765. package/out/zql/src/query/query-impl.js +3 -2
  766. package/out/zql/src/query/query-impl.js.map +1 -1
  767. package/out/zql/src/query/query-registry.js +1 -1
  768. package/out/zql/src/query/query-registry.js.map +1 -1
  769. package/out/zql/src/query/query-transitions.js +1 -1
  770. package/out/zql/src/query/query-transitions.js.map +1 -1
  771. package/out/zql/src/query/runnable-query-impl.js +3 -2
  772. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  773. package/out/zql/src/query/static-query.js.map +1 -1
  774. package/out/zql/src/query/ttl.js +8 -8
  775. package/out/zql/src/query/ttl.js.map +1 -1
  776. package/out/zql/src/query/validate-input.js.map +1 -1
  777. package/out/zqlite/src/database-storage.d.ts +27 -8
  778. package/out/zqlite/src/database-storage.d.ts.map +1 -1
  779. package/out/zqlite/src/database-storage.js +190 -53
  780. package/out/zqlite/src/database-storage.js.map +1 -1
  781. package/out/zqlite/src/db.d.ts +47 -1
  782. package/out/zqlite/src/db.d.ts.map +1 -1
  783. package/out/zqlite/src/db.js +121 -21
  784. package/out/zqlite/src/db.js.map +1 -1
  785. package/out/zqlite/src/explain-queries.js.map +1 -1
  786. package/out/zqlite/src/fetch-sql.js.map +1 -1
  787. package/out/zqlite/src/index-usage.js.map +1 -1
  788. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  789. package/out/zqlite/src/internal/sql.js.map +1 -1
  790. package/out/zqlite/src/internal/statement-cache.d.ts +7 -0
  791. package/out/zqlite/src/internal/statement-cache.d.ts.map +1 -1
  792. package/out/zqlite/src/internal/statement-cache.js +11 -4
  793. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  794. package/out/zqlite/src/mod.js +5 -5
  795. package/out/zqlite/src/pending-delta.js.map +1 -1
  796. package/out/zqlite/src/query-builder.js +1 -1
  797. package/out/zqlite/src/query-builder.js.map +1 -1
  798. package/out/zqlite/src/query-delegate.js.map +1 -1
  799. package/out/zqlite/src/resolve-scalar-subqueries.js +2 -5
  800. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  801. package/out/zqlite/src/sqlite-cost-model.js +3 -2
  802. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  803. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  804. package/out/zqlite/src/table-source.d.ts +11 -0
  805. package/out/zqlite/src/table-source.d.ts.map +1 -1
  806. package/out/zqlite/src/table-source.js +63 -26
  807. package/out/zqlite/src/table-source.js.map +1 -1
  808. package/package.json +37 -36
  809. package/out/analyze-query/src/bin-analyze.d.ts +0 -2
  810. package/out/analyze-query/src/bin-analyze.d.ts.map +0 -1
  811. package/out/analyze-query/src/bin-analyze.js +0 -283
  812. package/out/analyze-query/src/bin-analyze.js.map +0 -1
  813. package/out/otel/src/maybe-time.d.ts +0 -3
  814. package/out/otel/src/maybe-time.d.ts.map +0 -1
  815. package/out/otel/src/maybe-time.js +0 -15
  816. package/out/otel/src/maybe-time.js.map +0 -1
  817. package/out/zero/src/analyze-query.d.ts +0 -3
  818. package/out/zero/src/analyze-query.d.ts.map +0 -1
  819. package/out/zero/src/analyze-query.js +0 -3
@@ -10,7 +10,7 @@ import { startOtelAuto } from "./otel-start.js";
10
10
  import { ShadowSyncService } from "../services/shadow-sync/shadow-sync-service.js";
11
11
  import { LogContext, consoleLogSink } from "@rocicorp/logger";
12
12
  //#region ../zero-cache/src/server/shadow-syncer.ts
13
- var MS_PER_HOUR = 1e3 * 60 * 60;
13
+ var MS_PER_HOUR = 36e5;
14
14
  var lc = new LogContext("info", {}, consoleLogSink);
15
15
  function runWorker(parent, env, ...argv) {
16
16
  const config = getNormalizedZeroConfig({
@@ -1 +1 @@
1
- {"version":3,"file":"shadow-syncer.js","names":[],"sources":["../../../../../zero-cache/src/server/shadow-syncer.ts"],"sourcesContent":["import {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {must} from '../../../shared/src/must.ts';\nimport {getServerContext} from '../config/server-context.ts';\nimport {getNormalizedZeroConfig} from '../config/zero-config.ts';\nimport {initEventSink} from '../observability/events.ts';\nimport {exitAfter, runUntilKilled} from '../services/life-cycle.ts';\nimport {ShadowSyncService} from '../services/shadow-sync/shadow-sync-service.ts';\nimport {\n parentWorker,\n singleProcessMode,\n type Worker,\n} from '../types/processes.ts';\nimport {getShardConfig} from '../types/shards.ts';\nimport {createLogContext} from './logging.ts';\nimport {startOtelAuto} from './otel-start.ts';\n\nconst MS_PER_HOUR = 1000 * 60 * 60;\n\n// Default LogContext, overridden in runWorker\nlet lc = new LogContext('info', {}, consoleLogSink);\n\nexport default function runWorker(\n parent: Worker,\n env: NodeJS.ProcessEnv,\n ...argv: string[]\n): Promise<void> {\n const config = getNormalizedZeroConfig({env, argv});\n\n startOtelAuto(\n createLogContext(config, 'shadow-syncer', 0, false),\n 'shadow-syncer',\n 0,\n );\n lc = createLogContext(config, 'shadow-syncer');\n initEventSink(lc, config);\n\n const {shadowSync, upstream, initialSync} = config;\n const shard = getShardConfig(config);\n const service = new ShadowSyncService(\n lc,\n shard,\n upstream.db,\n getServerContext(config),\n {\n intervalMs: shadowSync.intervalHours * MS_PER_HOUR,\n sampleRate: shadowSync.sampleRate,\n maxRowsPerTable: shadowSync.maxRowsPerTable,\n textCopy: initialSync.textCopy,\n },\n );\n\n parent.send(['ready', {ready: true}]);\n\n return runUntilKilled(lc, parent, service);\n}\n\n// fork()\nif (!singleProcessMode()) {\n void exitAfter(\n () => lc,\n () => runWorker(must(parentWorker), process.env, ...process.argv.slice(2)),\n );\n}\n"],"mappings":";;;;;;;;;;;;AAgBA,IAAM,cAAc,MAAO,KAAK;AAGhC,IAAI,KAAK,IAAI,WAAW,QAAQ,CAAC,GAAG,cAAc;AAElD,SAAwB,UACtB,QACA,KACA,GAAG,MACY;CACf,MAAM,SAAS,wBAAwB;EAAC;EAAK;CAAI,CAAC;CAElD,cACE,iBAAiB,QAAQ,iBAAiB,GAAG,KAAK,GAClD,iBACA,CACF;CACA,KAAK,iBAAiB,QAAQ,eAAe;CAC7C,cAAc,IAAI,MAAM;CAExB,MAAM,EAAC,YAAY,UAAU,gBAAe;CAC5C,MAAM,QAAQ,eAAe,MAAM;CACnC,MAAM,UAAU,IAAI,kBAClB,IACA,OACA,SAAS,IACT,iBAAiB,MAAM,GACvB;EACE,YAAY,WAAW,gBAAgB;EACvC,YAAY,WAAW;EACvB,iBAAiB,WAAW;EAC5B,UAAU,YAAY;CACxB,CACF;CAEA,OAAO,KAAK,CAAC,SAAS,EAAC,OAAO,KAAI,CAAC,CAAC;CAEpC,OAAO,eAAe,IAAI,QAAQ,OAAO;AAC3C;AAGA,IAAI,CAAC,kBAAkB,GACrB,gBACQ,UACA,UAAU,KAAK,YAAY,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,CAC3E"}
1
+ {"version":3,"file":"shadow-syncer.js","names":[],"sources":["../../../../../zero-cache/src/server/shadow-syncer.ts"],"sourcesContent":["import {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {must} from '../../../shared/src/must.ts';\nimport {getServerContext} from '../config/server-context.ts';\nimport {getNormalizedZeroConfig} from '../config/zero-config.ts';\nimport {initEventSink} from '../observability/events.ts';\nimport {exitAfter, runUntilKilled} from '../services/life-cycle.ts';\nimport {ShadowSyncService} from '../services/shadow-sync/shadow-sync-service.ts';\nimport {\n parentWorker,\n singleProcessMode,\n type Worker,\n} from '../types/processes.ts';\nimport {getShardConfig} from '../types/shards.ts';\nimport {createLogContext} from './logging.ts';\nimport {startOtelAuto} from './otel-start.ts';\n\nconst MS_PER_HOUR = 1000 * 60 * 60;\n\n// Default LogContext, overridden in runWorker\nlet lc = new LogContext('info', {}, consoleLogSink);\n\nexport default function runWorker(\n parent: Worker,\n env: NodeJS.ProcessEnv,\n ...argv: string[]\n): Promise<void> {\n const config = getNormalizedZeroConfig({env, argv});\n\n startOtelAuto(\n createLogContext(config, 'shadow-syncer', 0, false),\n 'shadow-syncer',\n 0,\n );\n lc = createLogContext(config, 'shadow-syncer');\n initEventSink(lc, config);\n\n const {shadowSync, upstream, initialSync} = config;\n const shard = getShardConfig(config);\n const service = new ShadowSyncService(\n lc,\n shard,\n upstream.db,\n getServerContext(config),\n {\n intervalMs: shadowSync.intervalHours * MS_PER_HOUR,\n sampleRate: shadowSync.sampleRate,\n maxRowsPerTable: shadowSync.maxRowsPerTable,\n textCopy: initialSync.textCopy,\n },\n );\n\n parent.send(['ready', {ready: true}]);\n\n return runUntilKilled(lc, parent, service);\n}\n\n// fork()\nif (!singleProcessMode()) {\n void exitAfter(\n () => lc,\n () => runWorker(must(parentWorker), process.env, ...process.argv.slice(2)),\n );\n}\n"],"mappings":";;;;;;;;;;;;AAgBA,IAAM,cAAc;AAGpB,IAAI,KAAK,IAAI,WAAW,QAAQ,CAAC,GAAG,cAAc;AAElD,SAAwB,UACtB,QACA,KACA,GAAG,MACY;CACf,MAAM,SAAS,wBAAwB;EAAC;EAAK;CAAI,CAAC;CAElD,cACE,iBAAiB,QAAQ,iBAAiB,GAAG,KAAK,GAClD,iBACA,CACF;CACA,KAAK,iBAAiB,QAAQ,eAAe;CAC7C,cAAc,IAAI,MAAM;CAExB,MAAM,EAAC,YAAY,UAAU,gBAAe;CAC5C,MAAM,QAAQ,eAAe,MAAM;CACnC,MAAM,UAAU,IAAI,kBAClB,IACA,OACA,SAAS,IACT,iBAAiB,MAAM,GACvB;EACE,YAAY,WAAW,gBAAgB;EACvC,YAAY,WAAW;EACvB,iBAAiB,WAAW;EAC5B,UAAU,YAAY;CACxB,CACF;CAEA,OAAO,KAAK,CAAC,SAAS,EAAC,OAAO,KAAI,CAAC,CAAC;CAEpC,OAAO,eAAe,IAAI,QAAQ,OAAO;AAC3C;AAGA,IAAI,CAAC,kBAAkB,GACrB,gBACQ,UACA,UAAU,KAAK,YAAY,GAAG,QAAQ,KAAK,GAAG,QAAQ,KAAK,MAAM,CAAC,CAAC,CAC3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"slot-keeper.js","names":[],"sources":["../../../../../zero-cache/src/server/slot-keeper.ts"],"sourcesContent":["import {resolve} from 'node:path';\nimport type {Readable} from 'node:stream';\nimport {fileURLToPath} from 'node:url';\nimport {PG_ADMIN_SHUTDOWN} from '@drdgvhbh/postgres-error-codes';\nimport {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {defu} from 'defu';\nimport postgres, {type Options, type PostgresType} from 'postgres';\nimport {sleep} from '../../../shared/src/sleep.ts';\nimport {getLogConfig} from '../config/zero-config.ts';\nimport {\n DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE,\n makeAck,\n startReplicationStream,\n type PgConnectionConfig,\n} from '../services/change-source/pg/logical-replication/stream.ts';\nimport {toBigInt} from '../services/change-source/pg/lsn.ts';\nimport {exitAfter} from '../services/life-cycle.ts';\nimport {inactivityTimeoutSocket, isPostgresError} from '../types/pg.ts';\nimport {\n parentWorker,\n singleProcessMode,\n type Worker,\n} from '../types/processes.ts';\nimport {createLogContext} from './logging.ts';\n\nexport type SlotKeeperConfig = {\n db: PgConnectionConfig;\n slot: string;\n dummyPublication: string;\n lsn: string;\n ackIntervalMs?: number | undefined;\n};\n\nexport function parseLsn(lsn: string): bigint {\n return lsn.includes('/') ? toBigInt(lsn) : BigInt(lsn);\n}\n\nexport function waitForStartConfig(parent: Worker): Promise<SlotKeeperConfig> {\n return new Promise<SlotKeeperConfig>((resolve, reject) => {\n const cleanup = () => {\n parent.off('disconnect', onDisconnect);\n parent.off('close', onClose);\n if (process.send) {\n process.off('disconnect', onDisconnect);\n }\n };\n const onDisconnect = () => {\n cleanup();\n reject(new Error('Parent disconnected before sending start config'));\n };\n const onClose = () => {\n cleanup();\n reject(new Error('Parent closed before sending start config'));\n };\n parent.once('disconnect', onDisconnect);\n parent.once('close', onClose);\n if (process.send) {\n process.once('disconnect', onDisconnect);\n }\n parent.onceMessageType<['start', SlotKeeperConfig]>('start', cfg => {\n cleanup();\n resolve(cfg);\n });\n parent.send(['init', {}]);\n });\n}\n\nexport type SlotKeeperDependencies = {\n createSession?: (\n config: SlotKeeperConfig,\n lc: LogContext,\n ) => postgres.Sql | {end: (opts?: {timeout?: number}) => Promise<void>};\n startStream?: (\n lc: LogContext,\n session: postgres.Sql,\n slot: string,\n publications: string[],\n startLsn: bigint,\n maxAttempts?: number,\n ) => Promise<[Readable, NodeJS.WritableStream]>;\n sleepFn?: (ms: number) => Promise<void>;\n logContext?: LogContext;\n};\n\nlet lc = new LogContext('info', {}, consoleLogSink);\n\nexport default async function runWorker(\n parent: Worker,\n env: NodeJS.ProcessEnv,\n depsOrArg?: string | SlotKeeperDependencies,\n ...argv: string[]\n): Promise<void> {\n // Only logging config is needed; avoid requiring the full (normalized) config.\n const logConfig = getLogConfig({env, argv});\n const deps: SlotKeeperDependencies =\n typeof depsOrArg === 'object' && depsOrArg !== null ? depsOrArg : {};\n const createSession =\n deps.createSession ??\n ((cfg: SlotKeeperConfig, log: LogContext) =>\n postgres(\n defu(\n {\n max: 1,\n fetch_types: false,\n idle_timeout: null,\n max_lifetime: null as unknown as number,\n connection: {\n application_name: `slot-keeper-${cfg.slot}`,\n replication: 'database',\n },\n socket: inactivityTimeoutSocket(log, 0, 60_000),\n },\n cfg.db as Options<Record<string, PostgresType>>,\n ),\n ));\n const startStream = deps.startStream ?? startReplicationStream;\n const sleepFn = deps.sleepFn ?? sleep;\n\n const config = await waitForStartConfig(parent);\n\n lc = (\n deps.logContext ?? createLogContext(logConfig, 'slot-keeper')\n ).withContext('slot', config.slot);\n lc.info?.(`starting slot-keeper for ${config.slot}`);\n\n let stopped = false;\n let stopResolve: (() => void) | null = null;\n let currentReadable: Readable | null = null;\n let currentSession:\n | postgres.Sql\n | {end: (opts?: {timeout?: number}) => Promise<void>}\n | null = null;\n const lsn = parseLsn(config.lsn);\n const ackIntervalMs = config.ackIntervalMs ?? 5_000;\n\n const closeCurrent = async () => {\n if (currentReadable) {\n try {\n currentReadable.destroy();\n } catch {}\n currentReadable = null;\n }\n if (currentSession) {\n try {\n await currentSession.end({timeout: 0});\n lc.info?.(`ended slot-keeper replication session for ${config.slot}`);\n } catch (e) {\n lc.warn?.(`error ending slot-keeper session`, e);\n }\n currentSession = null;\n }\n };\n\n const stop = async () => {\n if (stopped) {\n return;\n }\n stopped = true;\n lc.info?.(`stopping slot-keeper for ${config.slot}`);\n stopResolve?.();\n await closeCurrent();\n };\n\n parent.onceMessageType('stop', () => void stop());\n parent.on('SIGTERM', () => void stop());\n parent.on('SIGINT', () => void stop());\n parent.once('disconnect', () => void stop());\n parent.once('close', () => void stop());\n process.once('SIGTERM', () => void stop());\n process.once('SIGINT', () => void stop());\n if (process.send) {\n process.once('disconnect', () => void stop());\n }\n\n let firstAttempt = true;\n let delayMs = 1000;\n\n while (!stopped) {\n try {\n lc.info?.(`connecting replication session for slot ${config.slot}`);\n const session = createSession(config, lc);\n currentSession = session;\n\n const [readable, writeable] = await startStream(\n lc,\n session as postgres.Sql,\n config.slot,\n [config.dummyPublication],\n lsn,\n DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE + 1,\n );\n currentReadable = readable;\n // Discard the streamed messages. Otherwise the paused socket backs up the\n // wal_sender (e.g. with keepalives and logical messages) for the duration\n // of the initial sync / restore, and a wal_sender blocked on writing to the\n // client does not exit (and release the slot) when it is terminated by the\n // takeover; it instead blocks on sending the termination error to the\n // client, until signaled again.\n readable.resume();\n\n if (stopped) {\n await closeCurrent();\n break;\n }\n\n lc.info?.(`slot-keeper active for ${config.slot} at lsn ${config.lsn}`);\n if (firstAttempt) {\n firstAttempt = false;\n parent.send(['ready', {ready: true}]);\n }\n\n // Reset backoff delay on successful connection\n delayMs = 1000;\n\n const ackInterval = setInterval(() => {\n if (stopped) {\n clearInterval(ackInterval);\n return;\n }\n try {\n writeable.write(makeAck(lsn));\n } catch (e) {\n lc.warn?.(`error writing ACK to replication stream`, e);\n }\n }, ackIntervalMs);\n\n // Wait until stream closes or errors, or worker is stopped\n await new Promise<void>((resolve, reject) => {\n const onStop = () => {\n cleanup();\n resolve();\n };\n const onClose = () => {\n cleanup();\n resolve();\n };\n const onError = (err: unknown) => {\n cleanup();\n reject(err);\n };\n function cleanup() {\n clearInterval(ackInterval);\n readable.off('close', onClose);\n readable.off('error', onError);\n }\n stopResolve = onStop;\n readable.once('close', onClose);\n readable.once('error', onError);\n });\n\n await closeCurrent();\n\n if (stopped) {\n break;\n }\n } catch (e) {\n await closeCurrent();\n\n if (stopped) {\n break;\n }\n\n if (\n isPostgresError(e, PG_ADMIN_SHUTDOWN) ||\n (e instanceof Error &&\n (e.message.includes('57P01') ||\n e.message.includes(\n 'terminating connection due to administrator command',\n )))\n ) {\n lc.info?.(\n `slot ${config.slot} was taken over (admin shutdown / pg_terminate_backend)`,\n );\n break;\n }\n\n lc.warn?.(\n `slot-keeper stream error for ${config.slot}, will reconnect in ${delayMs}ms`,\n e,\n );\n\n if (firstAttempt) {\n throw e;\n }\n\n await Promise.race([\n sleepFn(delayMs),\n new Promise<void>(resolve => {\n stopResolve = resolve;\n }),\n ]);\n delayMs = Math.min(delayMs * 2, 10_000);\n }\n }\n\n lc.info?.(`slot-keeper finished for ${config.slot}`);\n}\n\n// fork()\nconst isMain =\n typeof process.argv[1] === 'string' &&\n fileURLToPath(import.meta.url) === resolve(process.argv[1]);\n\nconst parent = parentWorker;\nif (isMain && parent !== null && !singleProcessMode()) {\n void exitAfter(\n () => lc,\n () => runWorker(parent, process.env, ...process.argv.slice(2)),\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"slot-keeper.js","names":[],"sources":["../../../../../zero-cache/src/server/slot-keeper.ts"],"sourcesContent":["import {resolve} from 'node:path';\nimport type {Readable} from 'node:stream';\nimport {fileURLToPath} from 'node:url';\nimport {PG_ADMIN_SHUTDOWN} from '@drdgvhbh/postgres-error-codes';\nimport {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {defu} from 'defu';\nimport postgres, {type Options, type PostgresType} from 'postgres';\nimport {sleep} from '../../../shared/src/sleep.ts';\nimport {getLogConfig} from '../config/zero-config.ts';\nimport {\n DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE,\n makeAck,\n startReplicationStream,\n type PgConnectionConfig,\n} from '../services/change-source/pg/logical-replication/stream.ts';\nimport {toBigInt} from '../services/change-source/pg/lsn.ts';\nimport {exitAfter} from '../services/life-cycle.ts';\nimport {inactivityTimeoutSocket, isPostgresError} from '../types/pg.ts';\nimport {\n parentWorker,\n singleProcessMode,\n type Worker,\n} from '../types/processes.ts';\nimport {createLogContext} from './logging.ts';\n\nexport type SlotKeeperConfig = {\n db: PgConnectionConfig;\n slot: string;\n dummyPublication: string;\n lsn: string;\n ackIntervalMs?: number | undefined;\n};\n\nexport function parseLsn(lsn: string): bigint {\n return lsn.includes('/') ? toBigInt(lsn) : BigInt(lsn);\n}\n\nexport function waitForStartConfig(parent: Worker): Promise<SlotKeeperConfig> {\n return new Promise<SlotKeeperConfig>((resolve, reject) => {\n const cleanup = () => {\n parent.off('disconnect', onDisconnect);\n parent.off('close', onClose);\n if (process.send) {\n process.off('disconnect', onDisconnect);\n }\n };\n const onDisconnect = () => {\n cleanup();\n reject(new Error('Parent disconnected before sending start config'));\n };\n const onClose = () => {\n cleanup();\n reject(new Error('Parent closed before sending start config'));\n };\n parent.once('disconnect', onDisconnect);\n parent.once('close', onClose);\n if (process.send) {\n process.once('disconnect', onDisconnect);\n }\n parent.onceMessageType<['start', SlotKeeperConfig]>('start', cfg => {\n cleanup();\n resolve(cfg);\n });\n parent.send(['init', {}]);\n });\n}\n\nexport type SlotKeeperDependencies = {\n createSession?: (\n config: SlotKeeperConfig,\n lc: LogContext,\n ) => postgres.Sql | {end: (opts?: {timeout?: number}) => Promise<void>};\n startStream?: (\n lc: LogContext,\n session: postgres.Sql,\n slot: string,\n publications: string[],\n startLsn: bigint,\n maxAttempts?: number,\n ) => Promise<[Readable, NodeJS.WritableStream]>;\n sleepFn?: (ms: number) => Promise<void>;\n logContext?: LogContext;\n};\n\nlet lc = new LogContext('info', {}, consoleLogSink);\n\nexport default async function runWorker(\n parent: Worker,\n env: NodeJS.ProcessEnv,\n depsOrArg?: string | SlotKeeperDependencies,\n ...argv: string[]\n): Promise<void> {\n // Only logging config is needed; avoid requiring the full (normalized) config.\n const logConfig = getLogConfig({env, argv});\n const deps: SlotKeeperDependencies =\n typeof depsOrArg === 'object' && depsOrArg !== null ? depsOrArg : {};\n const createSession =\n deps.createSession ??\n ((cfg: SlotKeeperConfig, log: LogContext) =>\n postgres(\n defu(\n {\n max: 1,\n fetch_types: false,\n idle_timeout: null,\n max_lifetime: null as unknown as number,\n connection: {\n application_name: `slot-keeper-${cfg.slot}`,\n replication: 'database',\n },\n socket: inactivityTimeoutSocket(log, 0, 60_000),\n },\n cfg.db as Options<Record<string, PostgresType>>,\n ),\n ));\n const startStream = deps.startStream ?? startReplicationStream;\n const sleepFn = deps.sleepFn ?? sleep;\n\n const config = await waitForStartConfig(parent);\n\n lc = (\n deps.logContext ?? createLogContext(logConfig, 'slot-keeper')\n ).withContext('slot', config.slot);\n lc.info?.(`starting slot-keeper for ${config.slot}`);\n\n let stopped = false;\n let stopResolve: (() => void) | null = null;\n let currentReadable: Readable | null = null;\n let currentSession:\n | postgres.Sql\n | {end: (opts?: {timeout?: number}) => Promise<void>}\n | null = null;\n const lsn = parseLsn(config.lsn);\n const ackIntervalMs = config.ackIntervalMs ?? 5_000;\n\n const closeCurrent = async () => {\n if (currentReadable) {\n try {\n currentReadable.destroy();\n } catch {}\n currentReadable = null;\n }\n if (currentSession) {\n try {\n await currentSession.end({timeout: 0});\n lc.info?.(`ended slot-keeper replication session for ${config.slot}`);\n } catch (e) {\n lc.warn?.(`error ending slot-keeper session`, e);\n }\n currentSession = null;\n }\n };\n\n const stop = async () => {\n if (stopped) {\n return;\n }\n stopped = true;\n lc.info?.(`stopping slot-keeper for ${config.slot}`);\n stopResolve?.();\n await closeCurrent();\n };\n\n parent.onceMessageType('stop', () => void stop());\n parent.on('SIGTERM', () => void stop());\n parent.on('SIGINT', () => void stop());\n parent.once('disconnect', () => void stop());\n parent.once('close', () => void stop());\n process.once('SIGTERM', () => void stop());\n process.once('SIGINT', () => void stop());\n if (process.send) {\n process.once('disconnect', () => void stop());\n }\n\n let firstAttempt = true;\n let delayMs = 1000;\n\n while (!stopped) {\n try {\n lc.info?.(`connecting replication session for slot ${config.slot}`);\n const session = createSession(config, lc);\n currentSession = session;\n\n const [readable, writeable] = await startStream(\n lc,\n session as postgres.Sql,\n config.slot,\n [config.dummyPublication],\n lsn,\n DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE + 1,\n );\n currentReadable = readable;\n // Discard the streamed messages. Otherwise the paused socket backs up the\n // wal_sender (e.g. with keepalives and logical messages) for the duration\n // of the initial sync / restore, and a wal_sender blocked on writing to the\n // client does not exit (and release the slot) when it is terminated by the\n // takeover; it instead blocks on sending the termination error to the\n // client, until signaled again.\n readable.resume();\n\n if (stopped) {\n await closeCurrent();\n break;\n }\n\n lc.info?.(`slot-keeper active for ${config.slot} at lsn ${config.lsn}`);\n if (firstAttempt) {\n firstAttempt = false;\n parent.send(['ready', {ready: true}]);\n }\n\n // Reset backoff delay on successful connection\n delayMs = 1000;\n\n const ackInterval = setInterval(() => {\n if (stopped) {\n clearInterval(ackInterval);\n return;\n }\n try {\n writeable.write(makeAck(lsn));\n } catch (e) {\n lc.warn?.(`error writing ACK to replication stream`, e);\n }\n }, ackIntervalMs);\n\n // Wait until stream closes or errors, or worker is stopped\n await new Promise<void>((resolve, reject) => {\n const onStop = () => {\n cleanup();\n resolve();\n };\n const onClose = () => {\n cleanup();\n resolve();\n };\n const onError = (err: unknown) => {\n cleanup();\n reject(err);\n };\n function cleanup() {\n clearInterval(ackInterval);\n readable.off('close', onClose);\n readable.off('error', onError);\n }\n stopResolve = onStop;\n readable.once('close', onClose);\n readable.once('error', onError);\n });\n\n await closeCurrent();\n\n if (stopped) {\n break;\n }\n } catch (e) {\n await closeCurrent();\n\n if (stopped) {\n break;\n }\n\n if (\n isPostgresError(e, PG_ADMIN_SHUTDOWN) ||\n (e instanceof Error &&\n (e.message.includes('57P01') ||\n e.message.includes(\n 'terminating connection due to administrator command',\n )))\n ) {\n lc.info?.(\n `slot ${config.slot} was taken over (admin shutdown / pg_terminate_backend)`,\n );\n break;\n }\n\n lc.warn?.(\n `slot-keeper stream error for ${config.slot}, will reconnect in ${delayMs}ms`,\n e,\n );\n\n if (firstAttempt) {\n throw e;\n }\n\n await Promise.race([\n sleepFn(delayMs),\n new Promise<void>(resolve => {\n stopResolve = resolve;\n }),\n ]);\n delayMs = Math.min(delayMs * 2, 10_000);\n }\n }\n\n lc.info?.(`slot-keeper finished for ${config.slot}`);\n}\n\n// fork()\nconst isMain =\n typeof process.argv[1] === 'string' &&\n fileURLToPath(import.meta.url) === resolve(process.argv[1]);\n\nconst parent = parentWorker;\nif (isMain && parent !== null && !singleProcessMode()) {\n void exitAfter(\n () => lc,\n () => runWorker(parent, process.env, ...process.argv.slice(2)),\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"syncer-assigner.js","names":["#taskID","#numWorkers","#assignments","#workerLoads","#nextGeneration","#decrementLoad"],"sources":["../../../../../zero-cache/src/server/syncer-assigner.ts"],"sourcesContent":["import {h32} from '../../../shared/src/hash.ts';\n\nexport type Assignment = {\n readonly worker: number;\n readonly generation: number;\n};\n\nexport class SyncerAssigner {\n readonly #taskID: string;\n readonly #numWorkers: number;\n readonly #assignments = new Map<string, Assignment>();\n readonly #workerLoads: number[];\n #nextGeneration = 0;\n\n constructor(taskID: string, numWorkers: number) {\n this.#taskID = taskID;\n this.#numWorkers = numWorkers;\n this.#workerLoads = new Array<number>(numWorkers).fill(0);\n }\n\n assign(clientGroupID: string): Assignment {\n if (this.#numWorkers <= 0) {\n return {worker: 0, generation: 0};\n }\n\n const generation = ++this.#nextGeneration;\n const existing = this.#assignments.get(clientGroupID);\n if (existing !== undefined) {\n const updated: Assignment = {worker: existing.worker, generation};\n this.#assignments.set(clientGroupID, updated);\n return updated;\n }\n\n // Find worker(s) with minimum active load\n let minLoad = Infinity;\n const tied: number[] = [];\n for (let i = 0; i < this.#numWorkers; i++) {\n const load = this.#workerLoads[i];\n if (load < minLoad) {\n minLoad = load;\n tied.length = 0;\n tied.push(i);\n } else if (load === minLoad) {\n tied.push(i);\n }\n }\n\n const chosen =\n tied.length === 1\n ? tied[0]\n : tied[h32(this.#taskID + '/' + clientGroupID) % tied.length];\n\n this.#workerLoads[chosen]++;\n const assignment: Assignment = {worker: chosen, generation};\n this.#assignments.set(clientGroupID, assignment);\n return assignment;\n }\n\n release(\n clientGroupID: string,\n workerIndex: number,\n generation?: number,\n ): void {\n const existing = this.#assignments.get(clientGroupID);\n if (existing === undefined || existing.worker !== workerIndex) {\n return;\n }\n if (generation !== undefined && existing.generation !== generation) {\n return;\n }\n this.#decrementLoad(workerIndex);\n this.#assignments.delete(clientGroupID);\n }\n\n getWorkerLoad(workerIndex: number): number {\n return this.#workerLoads[workerIndex] ?? 0;\n }\n\n getAssignment(clientGroupID: string): number | undefined {\n return this.#assignments.get(clientGroupID)?.worker;\n }\n\n #decrementLoad(worker: number): void {\n if (this.#workerLoads[worker] > 0) {\n this.#workerLoads[worker]--;\n }\n }\n\n destroy(): void {\n this.#assignments.clear();\n this.#workerLoads.fill(0);\n }\n}\n"],"mappings":";;AAOA,IAAa,iBAAb,MAA4B;CAC1B;CACA;CACA,+BAAwB,IAAI,IAAwB;CACpD;CACA,kBAAkB;CAElB,YAAY,QAAgB,YAAoB;EAC9C,KAAKA,UAAU;EACf,KAAKC,cAAc;EACnB,KAAKE,eAAe,IAAI,MAAc,UAAU,EAAE,KAAK,CAAC;CAC1D;CAEA,OAAO,eAAmC;EACxC,IAAI,KAAKF,eAAe,GACtB,OAAO;GAAC,QAAQ;GAAG,YAAY;EAAC;EAGlC,MAAM,aAAa,EAAE,KAAKG;EAC1B,MAAM,WAAW,KAAKF,aAAa,IAAI,aAAa;EACpD,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,UAAsB;IAAC,QAAQ,SAAS;IAAQ;GAAU;GAChE,KAAKA,aAAa,IAAI,eAAe,OAAO;GAC5C,OAAO;EACT;EAGA,IAAI,UAAU;EACd,MAAM,OAAiB,CAAC;EACxB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAKD,aAAa,KAAK;GACzC,MAAM,OAAO,KAAKE,aAAa;GAC/B,IAAI,OAAO,SAAS;IAClB,UAAU;IACV,KAAK,SAAS;IACd,KAAK,KAAK,CAAC;GACb,OAAO,IAAI,SAAS,SAClB,KAAK,KAAK,CAAC;EAEf;EAEA,MAAM,SACJ,KAAK,WAAW,IACZ,KAAK,KACL,KAAK,IAAI,KAAKH,UAAU,MAAM,aAAa,IAAI,KAAK;EAE1D,KAAKG,aAAa;EAClB,MAAM,aAAyB;GAAC,QAAQ;GAAQ;EAAU;EAC1D,KAAKD,aAAa,IAAI,eAAe,UAAU;EAC/C,OAAO;CACT;CAEA,QACE,eACA,aACA,YACM;EACN,MAAM,WAAW,KAAKA,aAAa,IAAI,aAAa;EACpD,IAAI,aAAa,KAAA,KAAa,SAAS,WAAW,aAChD;EAEF,IAAI,eAAe,KAAA,KAAa,SAAS,eAAe,YACtD;EAEF,KAAKG,eAAe,WAAW;EAC/B,KAAKH,aAAa,OAAO,aAAa;CACxC;CAEA,cAAc,aAA6B;EACzC,OAAO,KAAKC,aAAa,gBAAgB;CAC3C;CAEA,cAAc,eAA2C;EACvD,OAAO,KAAKD,aAAa,IAAI,aAAa,GAAG;CAC/C;CAEA,eAAe,QAAsB;EACnC,IAAI,KAAKC,aAAa,UAAU,GAC9B,KAAKA,aAAa;CAEtB;CAEA,UAAgB;EACd,KAAKD,aAAa,MAAM;EACxB,KAAKC,aAAa,KAAK,CAAC;CAC1B;AACF"}
1
+ {"version":3,"file":"syncer-assigner.js","names":[],"sources":["../../../../../zero-cache/src/server/syncer-assigner.ts"],"sourcesContent":["import {h32} from '../../../shared/src/hash.ts';\n\nexport type Assignment = {\n readonly worker: number;\n readonly generation: number;\n};\n\nexport class SyncerAssigner {\n readonly #taskID: string;\n readonly #numWorkers: number;\n readonly #assignments = new Map<string, Assignment>();\n readonly #workerLoads: number[];\n #nextGeneration = 0;\n\n constructor(taskID: string, numWorkers: number) {\n this.#taskID = taskID;\n this.#numWorkers = numWorkers;\n this.#workerLoads = new Array<number>(numWorkers).fill(0);\n }\n\n assign(clientGroupID: string): Assignment {\n if (this.#numWorkers <= 0) {\n return {worker: 0, generation: 0};\n }\n\n const generation = ++this.#nextGeneration;\n const existing = this.#assignments.get(clientGroupID);\n if (existing !== undefined) {\n const updated: Assignment = {worker: existing.worker, generation};\n this.#assignments.set(clientGroupID, updated);\n return updated;\n }\n\n // Find worker(s) with minimum active load\n let minLoad = Infinity;\n const tied: number[] = [];\n for (let i = 0; i < this.#numWorkers; i++) {\n const load = this.#workerLoads[i];\n if (load < minLoad) {\n minLoad = load;\n tied.length = 0;\n tied.push(i);\n } else if (load === minLoad) {\n tied.push(i);\n }\n }\n\n const chosen =\n tied.length === 1\n ? tied[0]\n : tied[h32(this.#taskID + '/' + clientGroupID) % tied.length];\n\n this.#workerLoads[chosen]++;\n const assignment: Assignment = {worker: chosen, generation};\n this.#assignments.set(clientGroupID, assignment);\n return assignment;\n }\n\n release(\n clientGroupID: string,\n workerIndex: number,\n generation?: number,\n ): void {\n const existing = this.#assignments.get(clientGroupID);\n if (existing === undefined || existing.worker !== workerIndex) {\n return;\n }\n if (generation !== undefined && existing.generation !== generation) {\n return;\n }\n this.#decrementLoad(workerIndex);\n this.#assignments.delete(clientGroupID);\n }\n\n getWorkerLoad(workerIndex: number): number {\n return this.#workerLoads[workerIndex] ?? 0;\n }\n\n getAssignment(clientGroupID: string): number | undefined {\n return this.#assignments.get(clientGroupID)?.worker;\n }\n\n #decrementLoad(worker: number): void {\n if (this.#workerLoads[worker] > 0) {\n this.#workerLoads[worker]--;\n }\n }\n\n destroy(): void {\n this.#assignments.clear();\n this.#workerLoads.fill(0);\n }\n}\n"],"mappings":";;AAOA,IAAa,iBAAb,MAA4B;CAC1B;CACA;CACA,+BAAwB,IAAI,IAAwB;CACpD;CACA,kBAAkB;CAElB,YAAY,QAAgB,YAAoB;EAC9C,KAAK,UAAU;EACf,KAAK,cAAc;EACnB,KAAK,eAAe,IAAI,MAAc,UAAU,CAAC,CAAC,KAAK,CAAC;CAC1D;CAEA,OAAO,eAAmC;EACxC,IAAI,KAAK,eAAe,GACtB,OAAO;GAAC,QAAQ;GAAG,YAAY;EAAC;EAGlC,MAAM,aAAa,EAAE,KAAK;EAC1B,MAAM,WAAW,KAAK,aAAa,IAAI,aAAa;EACpD,IAAI,aAAa,KAAA,GAAW;GAC1B,MAAM,UAAsB;IAAC,QAAQ,SAAS;IAAQ;GAAU;GAChE,KAAK,aAAa,IAAI,eAAe,OAAO;GAC5C,OAAO;EACT;EAGA,IAAI,UAAU;EACd,MAAM,OAAiB,CAAC;EACxB,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,aAAa,KAAK;GACzC,MAAM,OAAO,KAAK,aAAa;GAC/B,IAAI,OAAO,SAAS;IAClB,UAAU;IACV,KAAK,SAAS;IACd,KAAK,KAAK,CAAC;GACb,OAAO,IAAI,SAAS,SAClB,KAAK,KAAK,CAAC;EAEf;EAEA,MAAM,SACJ,KAAK,WAAW,IACZ,KAAK,KACL,KAAK,IAAI,KAAK,UAAU,MAAM,aAAa,IAAI,KAAK;EAE1D,KAAK,aAAa,OAAO;EACzB,MAAM,aAAyB;GAAC,QAAQ;GAAQ;EAAU;EAC1D,KAAK,aAAa,IAAI,eAAe,UAAU;EAC/C,OAAO;CACT;CAEA,QACE,eACA,aACA,YACM;EACN,MAAM,WAAW,KAAK,aAAa,IAAI,aAAa;EACpD,IAAI,aAAa,KAAA,KAAa,SAAS,WAAW,aAChD;EAEF,IAAI,eAAe,KAAA,KAAa,SAAS,eAAe,YACtD;EAEF,KAAK,eAAe,WAAW;EAC/B,KAAK,aAAa,OAAO,aAAa;CACxC;CAEA,cAAc,aAA6B;EACzC,OAAO,KAAK,aAAa,gBAAgB;CAC3C;CAEA,cAAc,eAA2C;EACvD,OAAO,KAAK,aAAa,IAAI,aAAa,CAAC,EAAE;CAC/C;CAEA,eAAe,QAAsB;EACnC,IAAI,KAAK,aAAa,UAAU,GAC9B,KAAK,aAAa,OAAO;CAE7B;CAEA,UAAgB;EACd,KAAK,aAAa,MAAM;EACxB,KAAK,aAAa,KAAK,CAAC;CAC1B;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/server/syncer.ts"],"names":[],"mappings":"AAsCA,OAAO,EAGL,KAAK,MAAM,EACZ,MAAM,uBAAuB,CAAC;AAqC/B,wBAA8B,SAAS,CACrC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,GAAG,IAAI,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CA0Sf"}
1
+ {"version":3,"file":"syncer.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/server/syncer.ts"],"names":[],"mappings":"AAuCA,OAAO,EAGL,KAAK,MAAM,EACZ,MAAM,uBAAuB,CAAC;AAqC/B,wBAA8B,SAAS,CACrC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,GAAG,IAAI,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC,CAsTf"}
@@ -6,11 +6,9 @@ import { parentWorker, singleProcessMode } from "../types/processes.js";
6
6
  import { getShardID } from "../types/shards.js";
7
7
  import { getNormalizedZeroConfig } from "../config/zero-config.js";
8
8
  import { randInt } from "../../../shared/src/rand.js";
9
- import { getOrCreateGauge } from "../observability/metrics.js";
10
- import { Snapshotter } from "../services/view-syncer/snapshotter.js";
11
- import { PipelineDriver } from "../services/view-syncer/pipeline-driver.js";
12
9
  import { connectPgClient } from "../types/pg.js";
13
10
  import { registerSQLiteCorruptionDiagnosticTarget } from "../db/sqlite-corruption.js";
11
+ import { getOrCreateGauge } from "../observability/metrics.js";
14
12
  import { exitAfter, runUntilKilled } from "../services/life-cycle.js";
15
13
  import { createLogContext } from "./logging.js";
16
14
  import { installProfileHandler } from "../types/profiler.js";
@@ -28,6 +26,8 @@ import { PusherService } from "../services/mutagen/pusher.js";
28
26
  import { BatchPacer } from "../services/view-syncer/batch-pacer.js";
29
27
  import { ConnectionContextManagerImpl } from "../services/view-syncer/connection-context-manager.js";
30
28
  import { DeferredWritesBudget } from "../services/view-syncer/deferred-writes-budget.js";
29
+ import { Snapshotter } from "../services/view-syncer/snapshotter.js";
30
+ import { PipelineDriver } from "../services/view-syncer/pipeline-driver.js";
31
31
  import { QueryStats } from "../services/view-syncer/query-stats.js";
32
32
  import { SnapshotRowCache } from "../services/view-syncer/snapshot-row-cache.js";
33
33
  import { ViewSyncerService } from "../services/view-syncer/view-syncer.js";
@@ -39,6 +39,7 @@ import { pid } from "node:process";
39
39
  import { randomUUID } from "node:crypto";
40
40
  import { tmpdir } from "node:os";
41
41
  import path from "node:path";
42
+ import { getHeapStatistics } from "node:v8";
42
43
  //#region ../zero-cache/src/server/syncer.ts
43
44
  function randomID() {
44
45
  return randInt(1, Number.MAX_SAFE_INTEGER).toString(36);
@@ -78,7 +79,11 @@ async function runWorker(parent, env, ...args) {
78
79
  const upstreamDB = enableCrudMutations && upstream.type === "pg" ? await connectPgClient(lc, upstream.db, `sync-worker-${pid}-upstream`, { max: must(upstream.maxConnsPerWorker, "upstream.maxConnsPerWorker must be set") }) : void 0;
79
80
  const dbWarmup = Promise.allSettled([warmupConnections(lc, cvrDB, "cvr"), upstreamDB ? warmupConnections(lc, upstreamDB, "upstream") : promiseVoid]);
80
81
  const tmpDir = config.storageDBTmpDir ?? tmpdir();
81
- const operatorStorage = DatabaseStorage.create(lc, path.join(tmpDir, `sync-worker-${randomUUID()}`));
82
+ const operatorStorage = DatabaseStorage.create(lc, path.join(tmpDir, `sync-worker-${randomUUID()}`), { maxMemoryBytes: Math.floor(getHeapStatistics().heap_size_limit * config.operatorStorageHeapProportion) });
83
+ getOrCreateGauge("sync", "ivm.operator-storage-memory-bytes", {
84
+ description: "Estimated bytes of IVM operator state that the client groups of a sync worker keep in memory rather than in SQLite",
85
+ unit: "By"
86
+ }).addCallback((o) => o.observe(operatorStorage.memoryBytes));
82
87
  const writeAuthzStorage = DatabaseStorage.create(lc, path.join(tmpDir, `mutagen-${randomUUID()}`));
83
88
  const shard = getShardID(config);
84
89
  const customQueryConfig = getCustomQueryConfig(config);
@@ -1 +1 @@
1
- {"version":3,"file":"syncer.js","names":[],"sources":["../../../../../zero-cache/src/server/syncer.ts"],"sourcesContent":["import {randomUUID} from 'node:crypto';\nimport {tmpdir} from 'node:os';\nimport path from 'node:path';\nimport {pid} from 'node:process';\nimport {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {randInt} from '../../../shared/src/rand.ts';\nimport {promiseVoid} from '../../../shared/src/resolved-promises.ts';\nimport * as v from '../../../shared/src/valita.ts';\nimport {DatabaseStorage} from '../../../zqlite/src/database-storage.ts';\nimport type {ValidateLegacyJWT} from '../auth/auth.ts';\nimport {tokenConfigOptions, verifyToken} from '../auth/jwt.ts';\nimport type {NormalizedZeroConfig} from '../config/normalize.ts';\nimport {getNormalizedZeroConfig} from '../config/zero-config.ts';\nimport {CustomQueryTransformer} from '../custom-queries/transform-query.ts';\nimport {registerSQLiteCorruptionDiagnosticTarget} from '../db/sqlite-corruption.ts';\nimport {warmupConnections} from '../db/warmup.ts';\nimport {initEventSink} from '../observability/events.ts';\nimport {getOrCreateGauge} from '../observability/metrics.ts';\nimport {exitAfter, runUntilKilled} from '../services/life-cycle.ts';\nimport {MutagenService} from '../services/mutagen/mutagen.ts';\nimport {PusherService} from '../services/mutagen/pusher.ts';\nimport type {ReplicaState} from '../services/replicator/replicator.ts';\nimport {BatchPacer} from '../services/view-syncer/batch-pacer.ts';\nimport {\n type ConnectionContextManager,\n ConnectionContextManagerImpl,\n} from '../services/view-syncer/connection-context-manager.ts';\nimport {DeferredWritesBudget} from '../services/view-syncer/deferred-writes-budget.ts';\nimport type {DrainCoordinator} from '../services/view-syncer/drain-coordinator.ts';\nimport {PipelineDriver} from '../services/view-syncer/pipeline-driver.ts';\nimport {QueryStats} from '../services/view-syncer/query-stats.ts';\nimport {SnapshotRowCache} from '../services/view-syncer/snapshot-row-cache.ts';\nimport {Snapshotter} from '../services/view-syncer/snapshotter.ts';\nimport {ViewSyncerService} from '../services/view-syncer/view-syncer.ts';\nimport {ProtocolErrorWithLevel} from '../types/error-with-level.ts';\nimport {connectPgClient} from '../types/pg.ts';\nimport {\n parentWorker,\n singleProcessMode,\n type Worker,\n} from '../types/processes.ts';\nimport {installProfileHandler} from '../types/profiler.ts';\nimport {getShardID} from '../types/shards.ts';\nimport type {Subscription} from '../types/subscription.ts';\nimport {replicaFileModeSchema, replicaFileName} from '../workers/replicator.ts';\nimport {Syncer} from '../workers/syncer.ts';\nimport {startAnonymousTelemetry} from './anonymous-otel-start.ts';\nimport {InspectorDelegate} from './inspector-delegate.ts';\nimport {createLogContext} from './logging.ts';\nimport {startOtelAuto} from './otel-start.ts';\nimport {isPriorityOpRunning, runPriorityOp} from './priority-op.ts';\n\nfunction randomID() {\n return randInt(1, Number.MAX_SAFE_INTEGER).toString(36);\n}\n\nfunction getCustomQueryConfig(\n config: Pick<NormalizedZeroConfig, 'query' | 'getQueries'>,\n) {\n const queryConfig = config.query?.url ? config.query : config.getQueries;\n\n if (!queryConfig?.url) {\n return undefined;\n }\n\n return {\n url: queryConfig.url,\n apiKey: queryConfig.apiKey,\n allowedClientHeaders: queryConfig.allowedClientHeaders,\n allowedRequestHeaders: queryConfig.allowedRequestHeaders,\n forwardCookies: queryConfig.forwardCookies ?? false,\n };\n}\n\n// Default LogContext, overridden in runWorker\nlet lc = new LogContext('info', {}, consoleLogSink);\n\nexport default async function runWorker(\n parent: Worker,\n env: NodeJS.ProcessEnv,\n ...args: string[]\n): Promise<void> {\n assert(args.length >= 2, `expected [fileMode, workerIndex, ...flags]`);\n const fileMode = v.parse(args[0], replicaFileModeSchema);\n const workerIndex = Number(args[1]);\n installProfileHandler(parent, `syncer-${workerIndex}`, workerIndex);\n const config = getNormalizedZeroConfig({env, argv: args.slice(2)});\n\n startOtelAuto(\n createLogContext(config, 'syncer', workerIndex, false),\n 'syncer',\n workerIndex,\n );\n lc = createLogContext(config, 'syncer', workerIndex);\n initEventSink(lc, config);\n\n const {cvr, upstream, enableCrudMutations} = config;\n\n const replicaFile = replicaFileName(config.replica.file, fileMode);\n registerSQLiteCorruptionDiagnosticTarget(\n {\n debugName: 'syncer replica',\n dbPath: replicaFile,\n },\n config.sqliteCorruptionChecks,\n );\n lc.debug?.(`running view-syncer on ${replicaFile}`);\n\n const cvrDB = await connectPgClient(lc, cvr.db, `sync-worker-${pid}-cvr`, {\n max: must(cvr.maxConnsPerWorker, 'cvr.maxConnsPerWorker must be set'),\n });\n\n const upstreamDB =\n enableCrudMutations && upstream.type === 'pg'\n ? await connectPgClient(lc, upstream.db, `sync-worker-${pid}-upstream`, {\n max: must(\n upstream.maxConnsPerWorker,\n 'upstream.maxConnsPerWorker must be set',\n ),\n })\n : undefined;\n\n const dbWarmup = Promise.allSettled([\n warmupConnections(lc, cvrDB, 'cvr'),\n upstreamDB ? warmupConnections(lc, upstreamDB, 'upstream') : promiseVoid,\n ]);\n\n const tmpDir = config.storageDBTmpDir ?? tmpdir();\n const operatorStorage = DatabaseStorage.create(\n lc,\n path.join(tmpDir, `sync-worker-${randomUUID()}`),\n );\n const writeAuthzStorage = DatabaseStorage.create(\n lc,\n path.join(tmpDir, `mutagen-${randomUUID()}`),\n );\n\n const shard = getShardID(config);\n const customQueryConfig = getCustomQueryConfig(config);\n const pushConfig =\n config.push.url === undefined && config.mutate.url === undefined\n ? undefined\n : {\n ...config.push,\n ...config.mutate,\n url: must(\n config.push.url ?? config.mutate.url,\n 'No push or mutate URL configured',\n ),\n };\n\n /** @deprecated used in JWT validation */\n let validateLegacyJWT: ValidateLegacyJWT | undefined = undefined;\n\n const tokenOptions = tokenConfigOptions(config.auth ?? {});\n if (tokenOptions.length === 1) {\n validateLegacyJWT = async (token, {userID}) => {\n if (!userID) {\n throw new ProtocolErrorWithLevel(\n {\n kind: 'Unauthorized',\n message: 'UserID is required for JWT validation.',\n origin: 'zeroCache',\n },\n 'warn',\n );\n }\n\n const decoded = await verifyToken(config.auth, token, {\n subject: userID,\n ...(config.auth?.issuer && {issuer: config.auth.issuer}),\n ...(config.auth?.audience && {\n audience: config.auth.audience,\n }),\n });\n return {\n type: 'jwt',\n raw: token,\n decoded,\n };\n };\n }\n\n // Shared by all of the view-syncers on this worker so that the row reads\n // performed when advancing their pipelines are done once per worker rather\n // than once per client group.\n const snapshotRowCache =\n config.snapshotRowCacheSize > 0\n ? new SnapshotRowCache(config.snapshotRowCacheSize)\n : undefined;\n\n // Shared by all of the view-syncers on this worker, which each hold their\n // own copy of the changes they are advancing through.\n const deferredWritesBudget = config.deferIvmWrites\n ? DeferredWritesBudget.forHeapProportion(\n config.deferIvmWritesHeapProportion,\n )\n : undefined;\n if (deferredWritesBudget) {\n lc.info?.(\n `Deferred IVM writes may hold up to ${deferredWritesBudget.maxRows} ` +\n `rows (~${(deferredWritesBudget.maxBytes / 1024 ** 2).toFixed(2)} MB) ` +\n `across client groups`,\n );\n getOrCreateGauge(\n 'sync',\n 'ivm.deferred-writes-reserved-rows',\n 'Rows reserved by the client groups of a sync worker to hold IVM ' +\n 'changes in memory (deferIvmWrites)',\n ).addCallback(o => o.observe(deferredWritesBudget.reservedRows));\n getOrCreateGauge('sync', 'ivm.deferred-writes-held-bytes', {\n description:\n 'Estimated bytes of the IVM changes that the client groups of a sync ' +\n 'worker hold in memory (deferIvmWrites)',\n unit: 'By',\n }).addCallback(o => o.observe(deferredWritesBudget.heldBytes));\n }\n\n // Shared by all of the view-syncers on this worker, whose batches of\n // changes together are held to a share of the worker's time.\n const batchPacer = config.costBasedSyncEnabled\n ? new BatchPacer({\n shareTarget: config.syncUpdateShareTarget,\n maxIntervalMs: config.syncMaxBatchIntervalMs,\n lc,\n })\n : undefined;\n if (batchPacer) {\n getOrCreateGauge('sync', 'worker-busy-share', {\n description:\n 'Share of its time that a sync worker was busy over the last few ' +\n 'seconds, which the pacing of its client groups holds to a target',\n unit: '1',\n }).addCallback(o => o.observe(batchPacer.share));\n getOrCreateGauge('sync', 'batch-wait-multiplier', {\n description:\n 'How many times the processing time of a batch of changes the ' +\n 'client groups of a sync worker wait before their next batch',\n unit: '1',\n }).addCallback(o => o.observe(batchPacer.multiplier));\n }\n\n // Shared by all of the view-syncers on this worker, so that the work done\n // for each query shape is logged once per worker per interval.\n const queryStats =\n config.log.queryStatsIntervalSeconds > 0 ? new QueryStats() : undefined;\n const stopQueryStats = queryStats?.start(\n lc\n .withContext('taskID', config.taskID)\n .withContext('component', 'view-syncer'),\n config.log.queryStatsIntervalSeconds * 1000,\n );\n\n const viewSyncerFactory = (\n id: string,\n sub: Subscription<ReplicaState>,\n drainCoordinator: DrainCoordinator,\n ) => {\n const logger = lc\n .withContext('taskID', config.taskID)\n .withContext('component', 'view-syncer')\n .withContext('appID', shard.appID)\n .withContext('shardNum', shard.shardNum)\n .withContext('clientGroupID', id)\n .withContext('instance', randomID());\n\n const customQueryTransformer =\n customQueryConfig && new CustomQueryTransformer(logger, shard);\n const connContextManager = new ConnectionContextManagerImpl(\n logger,\n config.auth.revalidateIntervalSeconds,\n config.auth.retransformIntervalSeconds,\n customQueryConfig,\n pushConfig,\n validateLegacyJWT,\n );\n\n lc.debug?.(\n `creating view syncer. Query Planner Enabled: ${config.enableQueryPlanner}`,\n );\n\n const inspectorDelegate = new InspectorDelegate(customQueryTransformer);\n\n const priorityOpRunningYieldThresholdMs = Math.max(\n config.yieldThresholdMs / 4,\n 2,\n );\n const normalYieldThresholdMs = Math.max(config.yieldThresholdMs, 2);\n\n return new ViewSyncerService(\n config,\n logger,\n shard,\n config.taskID,\n id,\n cvrDB,\n new PipelineDriver(\n logger,\n config.log,\n new Snapshotter(\n logger,\n replicaFile,\n shard,\n undefined,\n snapshotRowCache,\n ),\n shard,\n operatorStorage.createClientGroupStorage(id),\n id,\n inspectorDelegate,\n () =>\n isPriorityOpRunning()\n ? priorityOpRunningYieldThresholdMs\n : normalYieldThresholdMs,\n config.enableQueryPlanner,\n config,\n deferredWritesBudget,\n queryStats,\n ),\n sub,\n drainCoordinator,\n config.log.slowHydrateThreshold,\n inspectorDelegate,\n connContextManager,\n customQueryTransformer,\n runPriorityOp,\n undefined,\n undefined,\n undefined,\n undefined,\n batchPacer,\n );\n };\n\n const mutagenFactory = upstreamDB\n ? (id: string) =>\n new MutagenService(\n lc\n .withContext('component', 'mutagen')\n .withContext('clientGroupID', id),\n shard,\n id,\n upstreamDB,\n config,\n writeAuthzStorage,\n )\n : undefined;\n\n const pusherFactory =\n pushConfig === undefined\n ? undefined\n : (id: string, connContextManager: ConnectionContextManager) =>\n new PusherService(\n config,\n lc.withContext('clientGroupID', id),\n id,\n connContextManager,\n );\n\n const syncer = new Syncer(\n lc,\n config,\n viewSyncerFactory,\n mutagenFactory,\n pusherFactory,\n parent,\n validateLegacyJWT,\n );\n\n startAnonymousTelemetry(lc, config);\n\n void dbWarmup.then(() => parent.send(['ready', {ready: true}]));\n\n try {\n return await runUntilKilled(lc, parent, syncer);\n } finally {\n // Logs the work done since the last interval.\n stopQueryStats?.();\n }\n}\n\n// fork()\nif (!singleProcessMode()) {\n void exitAfter(\n () => lc,\n () => runWorker(must(parentWorker), process.env, ...process.argv.slice(2)),\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"syncer.js","names":["v.parse"],"sources":["../../../../../zero-cache/src/server/syncer.ts"],"sourcesContent":["import {randomUUID} from 'node:crypto';\nimport {tmpdir} from 'node:os';\nimport path from 'node:path';\nimport {pid} from 'node:process';\nimport {getHeapStatistics} from 'node:v8';\nimport {consoleLogSink, LogContext} from '@rocicorp/logger';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {randInt} from '../../../shared/src/rand.ts';\nimport {promiseVoid} from '../../../shared/src/resolved-promises.ts';\nimport * as v from '../../../shared/src/valita.ts';\nimport {DatabaseStorage} from '../../../zqlite/src/database-storage.ts';\nimport type {ValidateLegacyJWT} from '../auth/auth.ts';\nimport {tokenConfigOptions, verifyToken} from '../auth/jwt.ts';\nimport type {NormalizedZeroConfig} from '../config/normalize.ts';\nimport {getNormalizedZeroConfig} from '../config/zero-config.ts';\nimport {CustomQueryTransformer} from '../custom-queries/transform-query.ts';\nimport {registerSQLiteCorruptionDiagnosticTarget} from '../db/sqlite-corruption.ts';\nimport {warmupConnections} from '../db/warmup.ts';\nimport {initEventSink} from '../observability/events.ts';\nimport {getOrCreateGauge} from '../observability/metrics.ts';\nimport {exitAfter, runUntilKilled} from '../services/life-cycle.ts';\nimport {MutagenService} from '../services/mutagen/mutagen.ts';\nimport {PusherService} from '../services/mutagen/pusher.ts';\nimport type {ReplicaState} from '../services/replicator/replicator.ts';\nimport {BatchPacer} from '../services/view-syncer/batch-pacer.ts';\nimport {\n type ConnectionContextManager,\n ConnectionContextManagerImpl,\n} from '../services/view-syncer/connection-context-manager.ts';\nimport {DeferredWritesBudget} from '../services/view-syncer/deferred-writes-budget.ts';\nimport type {DrainCoordinator} from '../services/view-syncer/drain-coordinator.ts';\nimport {PipelineDriver} from '../services/view-syncer/pipeline-driver.ts';\nimport {QueryStats} from '../services/view-syncer/query-stats.ts';\nimport {SnapshotRowCache} from '../services/view-syncer/snapshot-row-cache.ts';\nimport {Snapshotter} from '../services/view-syncer/snapshotter.ts';\nimport {ViewSyncerService} from '../services/view-syncer/view-syncer.ts';\nimport {ProtocolErrorWithLevel} from '../types/error-with-level.ts';\nimport {connectPgClient} from '../types/pg.ts';\nimport {\n parentWorker,\n singleProcessMode,\n type Worker,\n} from '../types/processes.ts';\nimport {installProfileHandler} from '../types/profiler.ts';\nimport {getShardID} from '../types/shards.ts';\nimport type {Subscription} from '../types/subscription.ts';\nimport {replicaFileModeSchema, replicaFileName} from '../workers/replicator.ts';\nimport {Syncer} from '../workers/syncer.ts';\nimport {startAnonymousTelemetry} from './anonymous-otel-start.ts';\nimport {InspectorDelegate} from './inspector-delegate.ts';\nimport {createLogContext} from './logging.ts';\nimport {startOtelAuto} from './otel-start.ts';\nimport {isPriorityOpRunning, runPriorityOp} from './priority-op.ts';\n\nfunction randomID() {\n return randInt(1, Number.MAX_SAFE_INTEGER).toString(36);\n}\n\nfunction getCustomQueryConfig(\n config: Pick<NormalizedZeroConfig, 'query' | 'getQueries'>,\n) {\n const queryConfig = config.query?.url ? config.query : config.getQueries;\n\n if (!queryConfig?.url) {\n return undefined;\n }\n\n return {\n url: queryConfig.url,\n apiKey: queryConfig.apiKey,\n allowedClientHeaders: queryConfig.allowedClientHeaders,\n allowedRequestHeaders: queryConfig.allowedRequestHeaders,\n forwardCookies: queryConfig.forwardCookies ?? false,\n };\n}\n\n// Default LogContext, overridden in runWorker\nlet lc = new LogContext('info', {}, consoleLogSink);\n\nexport default async function runWorker(\n parent: Worker,\n env: NodeJS.ProcessEnv,\n ...args: string[]\n): Promise<void> {\n assert(args.length >= 2, `expected [fileMode, workerIndex, ...flags]`);\n const fileMode = v.parse(args[0], replicaFileModeSchema);\n const workerIndex = Number(args[1]);\n installProfileHandler(parent, `syncer-${workerIndex}`, workerIndex);\n const config = getNormalizedZeroConfig({env, argv: args.slice(2)});\n\n startOtelAuto(\n createLogContext(config, 'syncer', workerIndex, false),\n 'syncer',\n workerIndex,\n );\n lc = createLogContext(config, 'syncer', workerIndex);\n initEventSink(lc, config);\n\n const {cvr, upstream, enableCrudMutations} = config;\n\n const replicaFile = replicaFileName(config.replica.file, fileMode);\n registerSQLiteCorruptionDiagnosticTarget(\n {\n debugName: 'syncer replica',\n dbPath: replicaFile,\n },\n config.sqliteCorruptionChecks,\n );\n lc.debug?.(`running view-syncer on ${replicaFile}`);\n\n const cvrDB = await connectPgClient(lc, cvr.db, `sync-worker-${pid}-cvr`, {\n max: must(cvr.maxConnsPerWorker, 'cvr.maxConnsPerWorker must be set'),\n });\n\n const upstreamDB =\n enableCrudMutations && upstream.type === 'pg'\n ? await connectPgClient(lc, upstream.db, `sync-worker-${pid}-upstream`, {\n max: must(\n upstream.maxConnsPerWorker,\n 'upstream.maxConnsPerWorker must be set',\n ),\n })\n : undefined;\n\n const dbWarmup = Promise.allSettled([\n warmupConnections(lc, cvrDB, 'cvr'),\n upstreamDB ? warmupConnections(lc, upstreamDB, 'upstream') : promiseVoid,\n ]);\n\n const tmpDir = config.storageDBTmpDir ?? tmpdir();\n const operatorStorage = DatabaseStorage.create(\n lc,\n path.join(tmpDir, `sync-worker-${randomUUID()}`),\n {\n maxMemoryBytes: Math.floor(\n getHeapStatistics().heap_size_limit *\n config.operatorStorageHeapProportion,\n ),\n },\n );\n getOrCreateGauge('sync', 'ivm.operator-storage-memory-bytes', {\n description:\n 'Estimated bytes of IVM operator state that the client groups of a ' +\n 'sync worker keep in memory rather than in SQLite',\n unit: 'By',\n }).addCallback(o => o.observe(operatorStorage.memoryBytes));\n const writeAuthzStorage = DatabaseStorage.create(\n lc,\n path.join(tmpDir, `mutagen-${randomUUID()}`),\n );\n\n const shard = getShardID(config);\n const customQueryConfig = getCustomQueryConfig(config);\n const pushConfig =\n config.push.url === undefined && config.mutate.url === undefined\n ? undefined\n : {\n ...config.push,\n ...config.mutate,\n url: must(\n config.push.url ?? config.mutate.url,\n 'No push or mutate URL configured',\n ),\n };\n\n /** @deprecated used in JWT validation */\n let validateLegacyJWT: ValidateLegacyJWT | undefined = undefined;\n\n const tokenOptions = tokenConfigOptions(config.auth ?? {});\n if (tokenOptions.length === 1) {\n validateLegacyJWT = async (token, {userID}) => {\n if (!userID) {\n throw new ProtocolErrorWithLevel(\n {\n kind: 'Unauthorized',\n message: 'UserID is required for JWT validation.',\n origin: 'zeroCache',\n },\n 'warn',\n );\n }\n\n const decoded = await verifyToken(config.auth, token, {\n subject: userID,\n ...(config.auth?.issuer && {issuer: config.auth.issuer}),\n ...(config.auth?.audience && {\n audience: config.auth.audience,\n }),\n });\n return {\n type: 'jwt',\n raw: token,\n decoded,\n };\n };\n }\n\n // Shared by all of the view-syncers on this worker so that the row reads\n // performed when advancing their pipelines are done once per worker rather\n // than once per client group.\n const snapshotRowCache =\n config.snapshotRowCacheSize > 0\n ? new SnapshotRowCache(config.snapshotRowCacheSize)\n : undefined;\n\n // Shared by all of the view-syncers on this worker, which each hold their\n // own copy of the changes they are advancing through.\n const deferredWritesBudget = config.deferIvmWrites\n ? DeferredWritesBudget.forHeapProportion(\n config.deferIvmWritesHeapProportion,\n )\n : undefined;\n if (deferredWritesBudget) {\n lc.info?.(\n `Deferred IVM writes may hold up to ${deferredWritesBudget.maxRows} ` +\n `rows (~${(deferredWritesBudget.maxBytes / 1024 ** 2).toFixed(2)} MB) ` +\n `across client groups`,\n );\n getOrCreateGauge(\n 'sync',\n 'ivm.deferred-writes-reserved-rows',\n 'Rows reserved by the client groups of a sync worker to hold IVM ' +\n 'changes in memory (deferIvmWrites)',\n ).addCallback(o => o.observe(deferredWritesBudget.reservedRows));\n getOrCreateGauge('sync', 'ivm.deferred-writes-held-bytes', {\n description:\n 'Estimated bytes of the IVM changes that the client groups of a sync ' +\n 'worker hold in memory (deferIvmWrites)',\n unit: 'By',\n }).addCallback(o => o.observe(deferredWritesBudget.heldBytes));\n }\n\n // Shared by all of the view-syncers on this worker, whose batches of\n // changes together are held to a share of the worker's time.\n const batchPacer = config.costBasedSyncEnabled\n ? new BatchPacer({\n shareTarget: config.syncUpdateShareTarget,\n maxIntervalMs: config.syncMaxBatchIntervalMs,\n lc,\n })\n : undefined;\n if (batchPacer) {\n getOrCreateGauge('sync', 'worker-busy-share', {\n description:\n 'Share of its time that a sync worker was busy over the last few ' +\n 'seconds, which the pacing of its client groups holds to a target',\n unit: '1',\n }).addCallback(o => o.observe(batchPacer.share));\n getOrCreateGauge('sync', 'batch-wait-multiplier', {\n description:\n 'How many times the processing time of a batch of changes the ' +\n 'client groups of a sync worker wait before their next batch',\n unit: '1',\n }).addCallback(o => o.observe(batchPacer.multiplier));\n }\n\n // Shared by all of the view-syncers on this worker, so that the work done\n // for each query shape is logged once per worker per interval.\n const queryStats =\n config.log.queryStatsIntervalSeconds > 0 ? new QueryStats() : undefined;\n const stopQueryStats = queryStats?.start(\n lc\n .withContext('taskID', config.taskID)\n .withContext('component', 'view-syncer'),\n config.log.queryStatsIntervalSeconds * 1000,\n );\n\n const viewSyncerFactory = (\n id: string,\n sub: Subscription<ReplicaState>,\n drainCoordinator: DrainCoordinator,\n ) => {\n const logger = lc\n .withContext('taskID', config.taskID)\n .withContext('component', 'view-syncer')\n .withContext('appID', shard.appID)\n .withContext('shardNum', shard.shardNum)\n .withContext('clientGroupID', id)\n .withContext('instance', randomID());\n\n const customQueryTransformer =\n customQueryConfig && new CustomQueryTransformer(logger, shard);\n const connContextManager = new ConnectionContextManagerImpl(\n logger,\n config.auth.revalidateIntervalSeconds,\n config.auth.retransformIntervalSeconds,\n customQueryConfig,\n pushConfig,\n validateLegacyJWT,\n );\n\n lc.debug?.(\n `creating view syncer. Query Planner Enabled: ${config.enableQueryPlanner}`,\n );\n\n const inspectorDelegate = new InspectorDelegate(customQueryTransformer);\n\n const priorityOpRunningYieldThresholdMs = Math.max(\n config.yieldThresholdMs / 4,\n 2,\n );\n const normalYieldThresholdMs = Math.max(config.yieldThresholdMs, 2);\n\n return new ViewSyncerService(\n config,\n logger,\n shard,\n config.taskID,\n id,\n cvrDB,\n new PipelineDriver(\n logger,\n config.log,\n new Snapshotter(\n logger,\n replicaFile,\n shard,\n undefined,\n snapshotRowCache,\n ),\n shard,\n operatorStorage.createClientGroupStorage(id),\n id,\n inspectorDelegate,\n () =>\n isPriorityOpRunning()\n ? priorityOpRunningYieldThresholdMs\n : normalYieldThresholdMs,\n config.enableQueryPlanner,\n config,\n deferredWritesBudget,\n queryStats,\n ),\n sub,\n drainCoordinator,\n config.log.slowHydrateThreshold,\n inspectorDelegate,\n connContextManager,\n customQueryTransformer,\n runPriorityOp,\n undefined,\n undefined,\n undefined,\n undefined,\n batchPacer,\n );\n };\n\n const mutagenFactory = upstreamDB\n ? (id: string) =>\n new MutagenService(\n lc\n .withContext('component', 'mutagen')\n .withContext('clientGroupID', id),\n shard,\n id,\n upstreamDB,\n config,\n writeAuthzStorage,\n )\n : undefined;\n\n const pusherFactory =\n pushConfig === undefined\n ? undefined\n : (id: string, connContextManager: ConnectionContextManager) =>\n new PusherService(\n config,\n lc.withContext('clientGroupID', id),\n id,\n connContextManager,\n );\n\n const syncer = new Syncer(\n lc,\n config,\n viewSyncerFactory,\n mutagenFactory,\n pusherFactory,\n parent,\n validateLegacyJWT,\n );\n\n startAnonymousTelemetry(lc, config);\n\n void dbWarmup.then(() => parent.send(['ready', {ready: true}]));\n\n try {\n return await runUntilKilled(lc, parent, syncer);\n } finally {\n // Logs the work done since the last interval.\n stopQueryStats?.();\n }\n}\n\n// fork()\nif (!singleProcessMode()) {\n void exitAfter(\n () => lc,\n () => runWorker(must(parentWorker), process.env, ...process.argv.slice(2)),\n );\n}\n"],"mappings":"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"}
@@ -103,6 +103,6 @@ function parsePath(url) {
103
103
  return URL_PATTERN.match(url.pathname) || void 0;
104
104
  }
105
105
  //#endregion
106
- export { WorkerDispatcher };
106
+ export { WorkerDispatcher, parsePath };
107
107
 
108
108
  //# sourceMappingURL=worker-dispatcher.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker-dispatcher.js","names":["#lc","#state","#assigner"],"sources":["../../../../../zero-cache/src/server/worker-dispatcher.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport UrlPattern from 'url-pattern';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport {\n getOrCreateCounter,\n getOrCreateGauge,\n} from '../observability/metrics.ts';\nimport {RunningState} from '../services/running-state.ts';\nimport type {Service} from '../services/service.ts';\nimport type {IncomingMessageSubset} from '../types/http.ts';\nimport type {ClientGroupStatusMessage, Worker} from '../types/processes.ts';\nimport {installWebSocketHandoff} from '../types/websocket-handoff.ts';\nimport {getConnectParams} from '../workers/connect-params.ts';\nimport {SyncerAssigner} from './syncer-assigner.ts';\n\nexport class WorkerDispatcher implements Service {\n readonly id = 'worker-dispatcher';\n readonly #lc: LogContext;\n readonly #state = new RunningState(this.id);\n readonly #assigner: SyncerAssigner;\n\n constructor(\n lc: LogContext,\n taskID: string,\n parent: Worker,\n syncers: Worker[],\n mutator: Worker | undefined,\n changeStreamer: Worker | undefined,\n ) {\n this.#lc = lc;\n\n const assigner = new SyncerAssigner(taskID, syncers.length);\n this.#assigner = assigner;\n\n const workerDispatchesCounter = getOrCreateCounter(\n 'sync',\n 'worker-dispatches',\n 'Dispatched client group connections to worker',\n );\n\n getOrCreateGauge(\n 'sync',\n 'worker-client-groups',\n 'Number of active client groups assigned to worker',\n ).addCallback(result => {\n for (let i = 0; i < syncers.length; i++) {\n result.observe(assigner.getWorkerLoad(i), {worker: String(i)});\n }\n });\n\n syncers.forEach((syncer, index) => {\n syncer.onMessageType<ClientGroupStatusMessage>(\n 'clientGroupStatus',\n ({clientGroupID, active, generation}) => {\n if (!active) {\n assigner.release(clientGroupID, index, generation);\n }\n },\n );\n });\n\n function connectParams(req: IncomingMessageSubset) {\n const {headers, url: u} = req;\n const url = new URL(u ?? '', 'http://unused/');\n const path = parsePath(url);\n if (!path) {\n throw new Error(`Invalid URL: ${u}`);\n }\n const version = Number(path.version);\n if (Number.isNaN(version)) {\n throw new Error(`Invalid version: ${u}`);\n }\n const {params, error} = getConnectParams(version, url, headers);\n if (error !== null) {\n throw new Error(error);\n }\n return params;\n }\n\n const handlePush = (req: IncomingMessageSubset) => {\n assert(\n mutator !== undefined,\n 'Received a push for a custom mutation but no `push.url` was configured.',\n );\n return {payload: connectParams(req), sender: mutator};\n };\n\n let maxProtocolVersion = 0;\n getOrCreateGauge(\n 'sync',\n 'max-protocol-version',\n 'Latest sync protocol version from a connecting client',\n ).addCallback(result => {\n if (maxProtocolVersion) {\n result.observe(maxProtocolVersion);\n }\n });\n\n const handleSync = (req: IncomingMessageSubset) => {\n assert(syncers.length, 'Received a sync request with no sync workers.');\n const params = connectParams(req);\n const {clientGroupID, protocolVersion} = params;\n maxProtocolVersion = Math.max(maxProtocolVersion, protocolVersion);\n\n const {worker: syncer, generation} = assigner.assign(clientGroupID);\n workerDispatchesCounter.add(1, {worker: String(syncer)});\n\n lc.debug?.(`connecting ${clientGroupID} to syncer ${syncer}`);\n return {payload: {...params, generation}, sender: syncers[syncer]};\n };\n\n const handleChangeStream = (req: IncomingMessageSubset) => {\n // Note: The change-streamer is generally not dispatched via the main\n // port, and in particular, should *not* be accessible via that\n // port in single-node mode. However, this plumbing is maintained\n // for the purpose of allowing --lazy-startup of the\n // replication-manager as a possible future feature.\n assert(\n syncers.length === 0 && mutator === undefined,\n 'Dispatch to the change-streamer via the main port ' +\n 'is only allowed in multi-node mode',\n );\n assert(\n changeStreamer,\n 'Received a change-streamer request without a change-streamer worker',\n );\n const url = new URL(req.url ?? '', 'http://unused/');\n const path = parsePath(url);\n if (!path) {\n throw new Error(`Invalid URL: ${req.url}`);\n }\n\n return {\n payload: path.action,\n sender: changeStreamer,\n };\n };\n\n // handoff messages from this ZeroDispatcher to the appropriate worker (pool).\n installWebSocketHandoff<unknown>(\n lc,\n request => {\n const {url: u} = request;\n const url = new URL(u ?? '', 'http://unused/');\n const path = parsePath(url);\n if (!path) {\n throw new Error(`Invalid URL: ${u}`);\n }\n switch (path.worker) {\n case 'sync':\n return handleSync(request);\n case 'replication':\n return handleChangeStream(request);\n case 'mutate':\n return handlePush(request);\n default:\n throw new Error(`Invalid URL: ${u}`);\n }\n },\n parent,\n );\n }\n\n run() {\n const readyStart = Date.now();\n getOrCreateGauge('server', 'uptime', {\n description: 'Cumulative uptime, starting from when requests are served',\n unit: 's',\n }).addCallback(result => result.observe((Date.now() - readyStart) / 1000));\n\n return this.#state.stopped();\n }\n\n stop() {\n this.#assigner.destroy();\n this.#state.stop(this.#lc);\n return this.#state.stopped();\n }\n}\n\nconst URL_PATTERN = new UrlPattern('(/:base)/:worker/v:version/:action');\n\nexport function parsePath(url: URL):\n | {\n base?: string;\n worker: 'sync' | 'mutate' | 'replication';\n version: string;\n action: string;\n }\n | undefined {\n // The match() returns both null and undefined.\n return URL_PATTERN.match(url.pathname) || undefined;\n} // The server allows the client to use any /:base/ path to facilitate\n// servicing requests on the same domain as the application.\n"],"mappings":"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"}
1
+ {"version":3,"file":"worker-dispatcher.js","names":[],"sources":["../../../../../zero-cache/src/server/worker-dispatcher.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport UrlPattern from 'url-pattern';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport {\n getOrCreateCounter,\n getOrCreateGauge,\n} from '../observability/metrics.ts';\nimport {RunningState} from '../services/running-state.ts';\nimport type {Service} from '../services/service.ts';\nimport type {IncomingMessageSubset} from '../types/http.ts';\nimport type {ClientGroupStatusMessage, Worker} from '../types/processes.ts';\nimport {installWebSocketHandoff} from '../types/websocket-handoff.ts';\nimport {getConnectParams} from '../workers/connect-params.ts';\nimport {SyncerAssigner} from './syncer-assigner.ts';\n\nexport class WorkerDispatcher implements Service {\n readonly id = 'worker-dispatcher';\n readonly #lc: LogContext;\n readonly #state = new RunningState(this.id);\n readonly #assigner: SyncerAssigner;\n\n constructor(\n lc: LogContext,\n taskID: string,\n parent: Worker,\n syncers: Worker[],\n mutator: Worker | undefined,\n changeStreamer: Worker | undefined,\n ) {\n this.#lc = lc;\n\n const assigner = new SyncerAssigner(taskID, syncers.length);\n this.#assigner = assigner;\n\n const workerDispatchesCounter = getOrCreateCounter(\n 'sync',\n 'worker-dispatches',\n 'Dispatched client group connections to worker',\n );\n\n getOrCreateGauge(\n 'sync',\n 'worker-client-groups',\n 'Number of active client groups assigned to worker',\n ).addCallback(result => {\n for (let i = 0; i < syncers.length; i++) {\n result.observe(assigner.getWorkerLoad(i), {worker: String(i)});\n }\n });\n\n syncers.forEach((syncer, index) => {\n syncer.onMessageType<ClientGroupStatusMessage>(\n 'clientGroupStatus',\n ({clientGroupID, active, generation}) => {\n if (!active) {\n assigner.release(clientGroupID, index, generation);\n }\n },\n );\n });\n\n function connectParams(req: IncomingMessageSubset) {\n const {headers, url: u} = req;\n const url = new URL(u ?? '', 'http://unused/');\n const path = parsePath(url);\n if (!path) {\n throw new Error(`Invalid URL: ${u}`);\n }\n const version = Number(path.version);\n if (Number.isNaN(version)) {\n throw new Error(`Invalid version: ${u}`);\n }\n const {params, error} = getConnectParams(version, url, headers);\n if (error !== null) {\n throw new Error(error);\n }\n return params;\n }\n\n const handlePush = (req: IncomingMessageSubset) => {\n assert(\n mutator !== undefined,\n 'Received a push for a custom mutation but no `push.url` was configured.',\n );\n return {payload: connectParams(req), sender: mutator};\n };\n\n let maxProtocolVersion = 0;\n getOrCreateGauge(\n 'sync',\n 'max-protocol-version',\n 'Latest sync protocol version from a connecting client',\n ).addCallback(result => {\n if (maxProtocolVersion) {\n result.observe(maxProtocolVersion);\n }\n });\n\n const handleSync = (req: IncomingMessageSubset) => {\n assert(syncers.length, 'Received a sync request with no sync workers.');\n const params = connectParams(req);\n const {clientGroupID, protocolVersion} = params;\n maxProtocolVersion = Math.max(maxProtocolVersion, protocolVersion);\n\n const {worker: syncer, generation} = assigner.assign(clientGroupID);\n workerDispatchesCounter.add(1, {worker: String(syncer)});\n\n lc.debug?.(`connecting ${clientGroupID} to syncer ${syncer}`);\n return {payload: {...params, generation}, sender: syncers[syncer]};\n };\n\n const handleChangeStream = (req: IncomingMessageSubset) => {\n // Note: The change-streamer is generally not dispatched via the main\n // port, and in particular, should *not* be accessible via that\n // port in single-node mode. However, this plumbing is maintained\n // for the purpose of allowing --lazy-startup of the\n // replication-manager as a possible future feature.\n assert(\n syncers.length === 0 && mutator === undefined,\n 'Dispatch to the change-streamer via the main port ' +\n 'is only allowed in multi-node mode',\n );\n assert(\n changeStreamer,\n 'Received a change-streamer request without a change-streamer worker',\n );\n const url = new URL(req.url ?? '', 'http://unused/');\n const path = parsePath(url);\n if (!path) {\n throw new Error(`Invalid URL: ${req.url}`);\n }\n\n return {\n payload: path.action,\n sender: changeStreamer,\n };\n };\n\n // handoff messages from this ZeroDispatcher to the appropriate worker (pool).\n installWebSocketHandoff<unknown>(\n lc,\n request => {\n const {url: u} = request;\n const url = new URL(u ?? '', 'http://unused/');\n const path = parsePath(url);\n if (!path) {\n throw new Error(`Invalid URL: ${u}`);\n }\n switch (path.worker) {\n case 'sync':\n return handleSync(request);\n case 'replication':\n return handleChangeStream(request);\n case 'mutate':\n return handlePush(request);\n default:\n throw new Error(`Invalid URL: ${u}`);\n }\n },\n parent,\n );\n }\n\n run() {\n const readyStart = Date.now();\n getOrCreateGauge('server', 'uptime', {\n description: 'Cumulative uptime, starting from when requests are served',\n unit: 's',\n }).addCallback(result => result.observe((Date.now() - readyStart) / 1000));\n\n return this.#state.stopped();\n }\n\n stop() {\n this.#assigner.destroy();\n this.#state.stop(this.#lc);\n return this.#state.stopped();\n }\n}\n\nconst URL_PATTERN = new UrlPattern('(/:base)/:worker/v:version/:action');\n\nexport function parsePath(url: URL):\n | {\n base?: string;\n worker: 'sync' | 'mutate' | 'replication';\n version: string;\n action: string;\n }\n | undefined {\n // The match() returns both null and undefined.\n return URL_PATTERN.match(url.pathname) || undefined;\n} // The server allows the client to use any /:base/ path to facilitate\n// servicing requests on the same domain as the application.\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"worker-urls.js","names":[],"sources":["../../../../../zero-cache/src/server/worker-urls.ts"],"sourcesContent":["// This module provides URLs for worker files.\n\nconst tsRe = /\\.ts$/;\n\nfunction resolve(path: string): URL {\n const {url} = import.meta;\n if (url.endsWith('.js')) {\n // When compiled, change .ts to .js\n path = path.replace(tsRe, '.js');\n }\n return new URL(path, url);\n}\n\n// These URLs are part of the build process. See ../../zero/tool/build.ts\n// All these urls must be relative to this file and be located in the same directory.\n\nexport const CHANGE_STREAMER_URL = resolve('./change-streamer.ts');\nexport const MAIN_URL = resolve('./main.ts');\nexport const MUTATOR_URL = resolve('./mutator.ts');\nexport const REAPER_URL = resolve('./reaper.ts');\nexport const REPLICATOR_URL = resolve('./replicator.ts');\nexport const SHADOW_SYNCER_URL = resolve('./shadow-syncer.ts');\nexport const SLOT_KEEPER_URL = resolve('./slot-keeper.ts');\nexport const SYNCER_URL = resolve('./syncer.ts');\nexport const WRITE_WORKER_URL = resolve('./write-worker.ts');\n"],"mappings":";AAEA,IAAM,OAAO;AAEb,SAAS,QAAQ,MAAmB;CAClC,MAAM,EAAC,QAAO,OAAO;CACrB,IAAI,IAAI,SAAS,KAAK,GAEpB,OAAO,KAAK,QAAQ,MAAM,KAAK;CAEjC,OAAO,IAAI,IAAI,MAAM,GAAG;AAC1B;AAKA,IAAa,sBAAsB,QAAQ,sBAAsB;AACjE,IAAa,WAAW,QAAQ,WAAW;AAChB,QAAQ,cAAc;AACjD,IAAa,aAAa,QAAQ,aAAa;AAC/C,IAAa,iBAAiB,QAAQ,iBAAiB;AACvD,IAAa,oBAAoB,QAAQ,oBAAoB;AAC7D,IAAa,kBAAkB,QAAQ,kBAAkB;AACzD,IAAa,aAAa,QAAQ,aAAa;AAC/C,IAAa,mBAAmB,QAAQ,mBAAmB"}
1
+ {"version":3,"file":"worker-urls.js","names":[],"sources":["../../../../../zero-cache/src/server/worker-urls.ts"],"sourcesContent":["// This module provides URLs for worker files.\n\nconst tsRe = /\\.ts$/;\n\nfunction resolve(path: string): URL {\n const {url} = import.meta;\n if (url.endsWith('.js')) {\n // When compiled, change .ts to .js\n path = path.replace(tsRe, '.js');\n }\n return new URL(path, url);\n}\n\n// These URLs are part of the build process. See ../../zero/tool/build.ts\n// All these urls must be relative to this file and be located in the same directory.\n\nexport const CHANGE_STREAMER_URL = resolve('./change-streamer.ts');\nexport const MAIN_URL = resolve('./main.ts');\nexport const MUTATOR_URL = resolve('./mutator.ts');\nexport const REAPER_URL = resolve('./reaper.ts');\nexport const REPLICATOR_URL = resolve('./replicator.ts');\nexport const SHADOW_SYNCER_URL = resolve('./shadow-syncer.ts');\nexport const SLOT_KEEPER_URL = resolve('./slot-keeper.ts');\nexport const SYNCER_URL = resolve('./syncer.ts');\nexport const WRITE_WORKER_URL = resolve('./write-worker.ts');\n"],"mappings":";AAEA,IAAM,OAAO;AAEb,SAAS,QAAQ,MAAmB;CAClC,MAAM,EAAC,QAAO;CACd,IAAI,IAAI,SAAS,KAAK,GAEpB,OAAO,KAAK,QAAQ,MAAM,KAAK;CAEjC,OAAO,IAAI,IAAI,MAAM,GAAG;AAC1B;AAKA,IAAa,sBAAsB,QAAQ,sBAAsB;AACjE,IAAa,WAAW,QAAQ,WAAW;AAChB,QAAQ,cAAc;AACjD,IAAa,aAAa,QAAQ,aAAa;AAC/C,IAAa,iBAAiB,QAAQ,iBAAiB;AACvD,IAAa,oBAAoB,QAAQ,oBAAoB;AAC7D,IAAa,kBAAkB,QAAQ,kBAAkB;AACzD,IAAa,aAAa,QAAQ,aAAa;AAC/C,IAAa,mBAAmB,QAAQ,mBAAmB"}
@@ -5,10 +5,10 @@ import { Debug } from "../../../zql/src/builder/debug-delegate.js";
5
5
  import { Database } from "../../../zqlite/src/db.js";
6
6
  import { TableSource } from "../../../zqlite/src/table-source.js";
7
7
  import { computeZqlSpecs, mustGetTableSpec } from "../db/lite-tables.js";
8
+ import _usingCtx from "../../../_virtual/_@oxc-project_runtime@0.154.0/helpers/esm/usingCtx.js";
8
9
  import { createSQLiteCostModel } from "../../../zqlite/src/sqlite-cost-model.js";
9
- import { MAX_ANALYZE_ROWS, runAst } from "./run-ast.js";
10
10
  import { explainQueries } from "../../../zqlite/src/explain-queries.js";
11
- import { _usingCtx } from "../../../_virtual/_@oxc-project_runtime@0.130.0/helpers/usingCtx.js";
11
+ import { MAX_ANALYZE_ROWS, runAst } from "./run-ast.js";
12
12
  import { TimeSliceTimer } from "./view-syncer/view-syncer.js";
13
13
  //#region ../zero-cache/src/services/analyze.ts
14
14
  var TIME_SLICE_LAP_THRESHOLD_MS = 200;
@@ -1 +1 @@
1
- {"version":3,"file":"analyze.js","names":[],"sources":["../../../../../zero-cache/src/services/analyze.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {getOrInsertComputed} from '../../../shared/src/map.ts';\nimport type {AnalyzeQueryResult} from '../../../zero-protocol/src/analyze-query-result.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {ClientSchema} from '../../../zero-protocol/src/client-schema.ts';\nimport type {PermissionsConfig} from '../../../zero-schema/src/compiled-permissions.ts';\nimport {Debug} from '../../../zql/src/builder/debug-delegate.ts';\nimport {MemoryStorage} from '../../../zql/src/ivm/memory-storage.ts';\nimport {\n AccumulatorDebugger,\n serializePlanDebugEvents,\n} from '../../../zql/src/planner/planner-debug.ts';\nimport {Database} from '../../../zqlite/src/db.ts';\nimport {explainQueries} from '../../../zqlite/src/explain-queries.ts';\nimport {createSQLiteCostModel} from '../../../zqlite/src/sqlite-cost-model.ts';\nimport {TableSource} from '../../../zqlite/src/table-source.ts';\nimport type {JWTAuth} from '../auth/auth.ts';\nimport type {NormalizedZeroConfig} from '../config/normalize.ts';\nimport {computeZqlSpecs, mustGetTableSpec} from '../db/lite-tables.ts';\nimport type {LiteAndZqlSpec, LiteTableSpec} from '../db/specs.ts';\nimport {MAX_ANALYZE_ROWS, runAst} from './run-ast.ts';\nimport {TimeSliceTimer} from './view-syncer/view-syncer.ts';\n\nconst TIME_SLICE_LAP_THRESHOLD_MS = 200;\n\nexport async function analyzeQuery(\n lc: LogContext,\n config: NormalizedZeroConfig,\n clientSchema: ClientSchema,\n ast: AST,\n syncedRows = true,\n vendedRows = false,\n permissions?: PermissionsConfig,\n auth?: JWTAuth,\n joinPlans = false,\n): Promise<AnalyzeQueryResult> {\n using db = new Database(lc, config.replica.file);\n const fullTables = new Map<string, LiteTableSpec>();\n const tableSpecs = new Map<string, LiteAndZqlSpec>();\n const tables = new Map<string, TableSource>();\n\n computeZqlSpecs(\n lc,\n db,\n {includeBackfillingColumns: false},\n tableSpecs,\n fullTables,\n );\n\n // Mirror production: the planner runs iff ZERO_ENABLE_QUERY_PLANNER is set\n // on the server, so the analysis reflects what actually executes. Diagnostic\n // event collection is orthogonal and opt-in via `joinPlans`.\n const costModel = config.enableQueryPlanner\n ? createSQLiteCostModel(db, tableSpecs)\n : undefined;\n const planDebugger = joinPlans ? new AccumulatorDebugger() : undefined;\n const timer = await new TimeSliceTimer(lc).start();\n const shouldYield = () => timer.elapsedLap() > TIME_SLICE_LAP_THRESHOLD_MS;\n const yieldProcess = () => timer.yieldProcess();\n const result = await runAst(\n lc,\n clientSchema,\n ast,\n true,\n {\n applyPermissions: permissions !== undefined,\n syncedRows,\n vendedRows,\n auth,\n db,\n tableSpecs,\n permissions,\n costModel,\n planDebugger,\n maxSyncedRowsPerTable: MAX_ANALYZE_ROWS,\n host: {\n debug: new Debug(vendedRows, MAX_ANALYZE_ROWS),\n enableNotExists: true,\n // Mirror production, as with the planner above.\n disableCorrelatedPredicatePushdown:\n config.enableCorrelatedPredicatePushdown === false,\n enablePlannerAwarePushdown: config.enablePlannerAwarePushdown !== false,\n getSource(tableName: string) {\n return getOrInsertComputed(tables, tableName, tableName => {\n const tableSpec = mustGetTableSpec(tableSpecs, tableName);\n const {primaryKey} = tableSpec.tableSpec;\n\n return new TableSource(\n lc,\n config.log,\n db,\n tableName,\n tableSpec.zqlSpec,\n primaryKey,\n shouldYield,\n );\n });\n },\n createStorage() {\n return new MemoryStorage();\n },\n decorateSourceInput: input => input,\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n },\n },\n yieldProcess,\n );\n\n // Fill in plans for any queries SQLite did not actually execute (and thus\n // did not populate scanStatus EXPLAIN for) using the substituted-binding\n // fallback. Plans captured at execution time use the real bindings and win.\n const fallback = explainQueries(result.readRowCountsByQuery ?? {}, db);\n const captured = result.sqlitePlans ?? {};\n for (const [query, plan] of Object.entries(fallback)) {\n if (!captured[query]) {\n captured[query] = plan;\n }\n }\n result.sqlitePlans = captured;\n\n if (planDebugger) {\n result.joinPlans = serializePlanDebugEvents(planDebugger.events);\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;AAuBA,IAAM,8BAA8B;AAEpC,eAAsB,aACpB,IACA,QACA,cACA,KACA,aAAa,MACb,aAAa,OACb,aACA,MACA,YAAY,OACiB;;;EAC7B,MAAM,KAAA,YAAA,EAAK,IAAI,SAAS,IAAI,OAAO,QAAQ,IAAI,CAAA;EAC/C,MAAM,6BAAa,IAAI,IAA2B;EAClD,MAAM,6BAAa,IAAI,IAA4B;EACnD,MAAM,yBAAS,IAAI,IAAyB;EAE5C,gBACE,IACA,IACA,EAAC,2BAA2B,MAAK,GACjC,YACA,UACF;EAKA,MAAM,YAAY,OAAO,qBACrB,sBAAsB,IAAI,UAAU,IACpC,KAAA;EACJ,MAAM,eAAe,YAAY,IAAI,oBAAoB,IAAI,KAAA;EAC7D,MAAM,QAAQ,MAAM,IAAI,eAAe,EAAE,EAAE,MAAM;EACjD,MAAM,oBAAoB,MAAM,WAAW,IAAI;EAC/C,MAAM,qBAAqB,MAAM,aAAa;EAC9C,MAAM,SAAS,MAAM,OACnB,IACA,cACA,KACA,MACA;GACE,kBAAkB,gBAAgB,KAAA;GAClC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,uBAAuB;GACvB,MAAM;IACJ,OAAO,IAAI,MAAM,YAAY,gBAAgB;IAC7C,iBAAiB;IAEjB,oCACE,OAAO,sCAAsC;IAC/C,4BAA4B,OAAO,+BAA+B;IAClE,UAAU,WAAmB;KAC3B,OAAO,oBAAoB,QAAQ,YAAW,cAAa;MACzD,MAAM,YAAY,iBAAiB,YAAY,SAAS;MACxD,MAAM,EAAC,eAAc,UAAU;MAE/B,OAAO,IAAI,YACT,IACA,OAAO,KACP,IACA,WACA,UAAU,SACV,YACA,WACF;KACF,CAAC;IACH;IACA,gBAAgB;KACd,OAAO,IAAI,cAAc;IAC3B;IACA,sBAAqB,UAAS;IAC9B,gBAAe,UAAS;IACxB,UAAU,CAAC;IACX,sBAAqB,UAAS;GAChC;EACF,GACA,YACF;EAKA,MAAM,WAAW,eAAe,OAAO,wBAAwB,CAAC,GAAG,EAAE;EACrE,MAAM,WAAW,OAAO,eAAe,CAAC;EACxC,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,QAAQ,GACjD,IAAI,CAAC,SAAS,QACZ,SAAS,SAAS;EAGtB,OAAO,cAAc;EAErB,IAAI,cACF,OAAO,YAAY,yBAAyB,aAAa,MAAM;EAGjE,OAAO;;;;;;AACT"}
1
+ {"version":3,"file":"analyze.js","names":[],"sources":["../../../../../zero-cache/src/services/analyze.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {getOrInsertComputed} from '../../../shared/src/map.ts';\nimport type {AnalyzeQueryResult} from '../../../zero-protocol/src/analyze-query-result.ts';\nimport type {AST} from '../../../zero-protocol/src/ast.ts';\nimport type {ClientSchema} from '../../../zero-protocol/src/client-schema.ts';\nimport type {PermissionsConfig} from '../../../zero-schema/src/compiled-permissions.ts';\nimport {Debug} from '../../../zql/src/builder/debug-delegate.ts';\nimport {MemoryStorage} from '../../../zql/src/ivm/memory-storage.ts';\nimport {\n AccumulatorDebugger,\n serializePlanDebugEvents,\n} from '../../../zql/src/planner/planner-debug.ts';\nimport {Database} from '../../../zqlite/src/db.ts';\nimport {explainQueries} from '../../../zqlite/src/explain-queries.ts';\nimport {createSQLiteCostModel} from '../../../zqlite/src/sqlite-cost-model.ts';\nimport {TableSource} from '../../../zqlite/src/table-source.ts';\nimport type {JWTAuth} from '../auth/auth.ts';\nimport type {NormalizedZeroConfig} from '../config/normalize.ts';\nimport {computeZqlSpecs, mustGetTableSpec} from '../db/lite-tables.ts';\nimport type {LiteAndZqlSpec, LiteTableSpec} from '../db/specs.ts';\nimport {MAX_ANALYZE_ROWS, runAst} from './run-ast.ts';\nimport {TimeSliceTimer} from './view-syncer/view-syncer.ts';\n\nconst TIME_SLICE_LAP_THRESHOLD_MS = 200;\n\nexport async function analyzeQuery(\n lc: LogContext,\n config: NormalizedZeroConfig,\n clientSchema: ClientSchema,\n ast: AST,\n syncedRows = true,\n vendedRows = false,\n permissions?: PermissionsConfig,\n auth?: JWTAuth,\n joinPlans = false,\n): Promise<AnalyzeQueryResult> {\n using db = new Database(lc, config.replica.file);\n const fullTables = new Map<string, LiteTableSpec>();\n const tableSpecs = new Map<string, LiteAndZqlSpec>();\n const tables = new Map<string, TableSource>();\n\n computeZqlSpecs(\n lc,\n db,\n {includeBackfillingColumns: false},\n tableSpecs,\n fullTables,\n );\n\n // Mirror production: the planner runs iff ZERO_ENABLE_QUERY_PLANNER is set\n // on the server, so the analysis reflects what actually executes. Diagnostic\n // event collection is orthogonal and opt-in via `joinPlans`.\n const costModel = config.enableQueryPlanner\n ? createSQLiteCostModel(db, tableSpecs)\n : undefined;\n const planDebugger = joinPlans ? new AccumulatorDebugger() : undefined;\n const timer = await new TimeSliceTimer(lc).start();\n const shouldYield = () => timer.elapsedLap() > TIME_SLICE_LAP_THRESHOLD_MS;\n const yieldProcess = () => timer.yieldProcess();\n const result = await runAst(\n lc,\n clientSchema,\n ast,\n true,\n {\n applyPermissions: permissions !== undefined,\n syncedRows,\n vendedRows,\n auth,\n db,\n tableSpecs,\n permissions,\n costModel,\n planDebugger,\n maxSyncedRowsPerTable: MAX_ANALYZE_ROWS,\n host: {\n debug: new Debug(vendedRows, MAX_ANALYZE_ROWS),\n enableNotExists: true,\n // Mirror production, as with the planner above.\n disableCorrelatedPredicatePushdown:\n config.enableCorrelatedPredicatePushdown === false,\n enablePlannerAwarePushdown: config.enablePlannerAwarePushdown !== false,\n getSource(tableName: string) {\n return getOrInsertComputed(tables, tableName, tableName => {\n const tableSpec = mustGetTableSpec(tableSpecs, tableName);\n const {primaryKey} = tableSpec.tableSpec;\n\n return new TableSource(\n lc,\n config.log,\n db,\n tableName,\n tableSpec.zqlSpec,\n primaryKey,\n shouldYield,\n );\n });\n },\n createStorage() {\n return new MemoryStorage();\n },\n decorateSourceInput: input => input,\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n },\n },\n yieldProcess,\n );\n\n // Fill in plans for any queries SQLite did not actually execute (and thus\n // did not populate scanStatus EXPLAIN for) using the substituted-binding\n // fallback. Plans captured at execution time use the real bindings and win.\n const fallback = explainQueries(result.readRowCountsByQuery ?? {}, db);\n const captured = result.sqlitePlans ?? {};\n for (const [query, plan] of Object.entries(fallback)) {\n if (!captured[query]) {\n captured[query] = plan;\n }\n }\n result.sqlitePlans = captured;\n\n if (planDebugger) {\n result.joinPlans = serializePlanDebugEvents(planDebugger.events);\n }\n\n return result;\n}\n"],"mappings":";;;;;;;;;;;;;AAuBA,IAAM,8BAA8B;AAEpC,eAAsB,aACpB,IACA,QACA,cACA,KACA,aAAa,MACb,aAAa,OACb,aACA,MACA,YAAY,OACiB;;;EAC7B,MAAM,KAAA,YAAA,EAAK,IAAI,SAAS,IAAI,OAAO,QAAQ,IAAI,CAAA;EAC/C,MAAM,6BAAa,IAAI,IAA2B;EAClD,MAAM,6BAAa,IAAI,IAA4B;EACnD,MAAM,yBAAS,IAAI,IAAyB;EAE5C,gBACE,IACA,IACA,EAAC,2BAA2B,MAAK,GACjC,YACA,UACF;EAKA,MAAM,YAAY,OAAO,qBACrB,sBAAsB,IAAI,UAAU,IACpC,KAAA;EACJ,MAAM,eAAe,YAAY,IAAI,oBAAoB,IAAI,KAAA;EAC7D,MAAM,QAAQ,MAAM,IAAI,eAAe,EAAE,CAAC,CAAC,MAAM;EACjD,MAAM,oBAAoB,MAAM,WAAW,IAAI;EAC/C,MAAM,qBAAqB,MAAM,aAAa;EAC9C,MAAM,SAAS,MAAM,OACnB,IACA,cACA,KACA,MACA;GACE,kBAAkB,gBAAgB,KAAA;GAClC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,uBAAuB;GACvB,MAAM;IACJ,OAAO,IAAI,MAAM,YAAY,gBAAgB;IAC7C,iBAAiB;IAEjB,oCACE,OAAO,sCAAsC;IAC/C,4BAA4B,OAAO,+BAA+B;IAClE,UAAU,WAAmB;KAC3B,OAAO,oBAAoB,QAAQ,YAAW,cAAa;MACzD,MAAM,YAAY,iBAAiB,YAAY,SAAS;MACxD,MAAM,EAAC,eAAc,UAAU;MAE/B,OAAO,IAAI,YACT,IACA,OAAO,KACP,IACA,WACA,UAAU,SACV,YACA,WACF;KACF,CAAC;IACH;IACA,gBAAgB;KACd,OAAO,IAAI,cAAc;IAC3B;IACA,sBAAqB,UAAS;IAC9B,gBAAe,UAAS;IACxB,UAAU,CAAC;IACX,sBAAqB,UAAS;GAChC;EACF,GACA,YACF;EAKA,MAAM,WAAW,eAAe,OAAO,wBAAwB,CAAC,GAAG,EAAE;EACrE,MAAM,WAAW,OAAO,eAAe,CAAC;EACxC,KAAK,MAAM,CAAC,OAAO,SAAS,OAAO,QAAQ,QAAQ,GACjD,IAAI,CAAC,SAAS,QACZ,SAAS,SAAS;EAGtB,OAAO,cAAc;EAErB,IAAI,cACF,OAAO,YAAY,yBAAyB,aAAa,MAAM;EAGjE,OAAO;;;;;;AACT"}
@@ -3,8 +3,8 @@ import { AbortError } from "../../../../../shared/src/abort-error.js";
3
3
  import { must } from "../../../../../shared/src/must.js";
4
4
  import { promiseOrAbort } from "../../../../../shared/src/promise-race.js";
5
5
  import { stringify } from "../../../../../shared/src/bigint-json.js";
6
- import "../../../types/lite.js";
7
6
  import { randInt } from "../../../../../shared/src/rand.js";
7
+ import "../../../types/lite.js";
8
8
  import { stateVersionFromString, stateVersionToString } from "../../../types/state-version.js";
9
9
  import { Queue } from "../../../../../shared/src/queue.js";
10
10
  import { CustomKeyMap } from "../../../../../shared/src/custom-key-map.js";
@@ -18,7 +18,7 @@ function tableKey({ schema, name }) {
18
18
  * backfill data have accumulated in it. Bounds the size of a single replica
19
19
  * COMMIT/checkpoint so it can't monopolize the replica.
20
20
  */
21
- var COMMIT_THRESHOLD_BYTES = 8 * 1024 * 1024;
21
+ var COMMIT_THRESHOLD_BYTES = 8388608;
22
22
  /**
23
23
  * How many backfill messages the prefetch producer may read ahead of the
24
24
  * reservation-holding consumer loop. This bounds the in-memory buffer (~this