@rocicorp/zero 0.26.1 → 0.26.2-canary.4

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 (1086) hide show
  1. package/out/_virtual/_@oxc-project_runtime@0.115.0/helpers/usingCtx.js +57 -0
  2. package/out/_virtual/_rolldown/runtime.js +27 -0
  3. package/out/analyze-query/src/bin-analyze.js +195 -283
  4. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  5. package/out/analyze-query/src/bin-transform.js +35 -40
  6. package/out/analyze-query/src/bin-transform.js.map +1 -1
  7. package/out/analyze-query/src/explain-queries.js +11 -13
  8. package/out/analyze-query/src/explain-queries.js.map +1 -1
  9. package/out/analyze-query/src/run-ast.js +68 -103
  10. package/out/analyze-query/src/run-ast.js.map +1 -1
  11. package/out/ast-to-zql/src/ast-to-zql.js +105 -153
  12. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  13. package/out/ast-to-zql/src/bin.js +57 -62
  14. package/out/ast-to-zql/src/bin.js.map +1 -1
  15. package/out/ast-to-zql/src/format.js +14 -13
  16. package/out/ast-to-zql/src/format.js.map +1 -1
  17. package/out/datadog/src/datadog-log-sink.js +148 -213
  18. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  19. package/out/otel/src/enabled.js +9 -11
  20. package/out/otel/src/enabled.js.map +1 -1
  21. package/out/otel/src/log-options.js +25 -35
  22. package/out/otel/src/log-options.js.map +1 -1
  23. package/out/otel/src/maybe-time.js +13 -14
  24. package/out/otel/src/maybe-time.js.map +1 -1
  25. package/out/otel/src/span.js +23 -26
  26. package/out/otel/src/span.js.map +1 -1
  27. package/out/otel/src/test-log-config.js +11 -10
  28. package/out/otel/src/test-log-config.js.map +1 -1
  29. package/out/otel/src/version.js +6 -5
  30. package/out/otel/src/version.js.map +1 -1
  31. package/out/replicache/src/async-iterable-to-array.js +8 -9
  32. package/out/replicache/src/async-iterable-to-array.js.map +1 -1
  33. package/out/replicache/src/bg-interval.js +28 -35
  34. package/out/replicache/src/bg-interval.js.map +1 -1
  35. package/out/replicache/src/btree/diff.js +6 -5
  36. package/out/replicache/src/btree/diff.js.map +1 -1
  37. package/out/replicache/src/btree/node.js +281 -372
  38. package/out/replicache/src/btree/node.js.map +1 -1
  39. package/out/replicache/src/btree/read.js +155 -256
  40. package/out/replicache/src/btree/read.js.map +1 -1
  41. package/out/replicache/src/btree/splice.js +60 -80
  42. package/out/replicache/src/btree/splice.js.map +1 -1
  43. package/out/replicache/src/btree/write.js +134 -158
  44. package/out/replicache/src/btree/write.js.map +1 -1
  45. package/out/replicache/src/call-default-fetch.js +28 -32
  46. package/out/replicache/src/call-default-fetch.js.map +1 -1
  47. package/out/replicache/src/config.js +2 -0
  48. package/out/replicache/src/connection-loop-delegates.js +31 -33
  49. package/out/replicache/src/connection-loop-delegates.js.map +1 -1
  50. package/out/replicache/src/connection-loop.js +174 -240
  51. package/out/replicache/src/connection-loop.js.map +1 -1
  52. package/out/replicache/src/cookies.js +22 -32
  53. package/out/replicache/src/cookies.js.map +1 -1
  54. package/out/replicache/src/dag/chunk.js +44 -50
  55. package/out/replicache/src/dag/chunk.js.map +1 -1
  56. package/out/replicache/src/dag/gc.js +94 -114
  57. package/out/replicache/src/dag/gc.js.map +1 -1
  58. package/out/replicache/src/dag/key.js +9 -11
  59. package/out/replicache/src/dag/key.js.map +1 -1
  60. package/out/replicache/src/dag/lazy-store.js +458 -510
  61. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  62. package/out/replicache/src/dag/store-impl.js +147 -178
  63. package/out/replicache/src/dag/store-impl.js.map +1 -1
  64. package/out/replicache/src/dag/store.js +19 -22
  65. package/out/replicache/src/dag/store.js.map +1 -1
  66. package/out/replicache/src/dag/visitor.js +23 -21
  67. package/out/replicache/src/dag/visitor.js.map +1 -1
  68. package/out/replicache/src/db/commit.js +209 -283
  69. package/out/replicache/src/db/commit.js.map +1 -1
  70. package/out/replicache/src/db/index.js +79 -122
  71. package/out/replicache/src/db/index.js.map +1 -1
  72. package/out/replicache/src/db/read.js +44 -60
  73. package/out/replicache/src/db/read.js.map +1 -1
  74. package/out/replicache/src/db/rebase.js +22 -77
  75. package/out/replicache/src/db/rebase.js.map +1 -1
  76. package/out/replicache/src/db/write.js +162 -296
  77. package/out/replicache/src/db/write.js.map +1 -1
  78. package/out/replicache/src/deleted-clients.js +59 -87
  79. package/out/replicache/src/deleted-clients.js.map +1 -1
  80. package/out/replicache/src/error-responses.js +18 -26
  81. package/out/replicache/src/error-responses.js.map +1 -1
  82. package/out/replicache/src/expo-sqlite.js +2 -0
  83. package/out/replicache/src/frozen-json.js +74 -108
  84. package/out/replicache/src/frozen-json.js.map +1 -1
  85. package/out/replicache/src/get-default-puller.js +34 -46
  86. package/out/replicache/src/get-default-puller.js.map +1 -1
  87. package/out/replicache/src/get-default-pusher.js +25 -33
  88. package/out/replicache/src/get-default-pusher.js.map +1 -1
  89. package/out/replicache/src/get-kv-store-provider.js +18 -20
  90. package/out/replicache/src/get-kv-store-provider.js.map +1 -1
  91. package/out/replicache/src/hash.js +29 -29
  92. package/out/replicache/src/hash.js.map +1 -1
  93. package/out/replicache/src/http-request-info.js +9 -8
  94. package/out/replicache/src/http-request-info.js.map +1 -1
  95. package/out/replicache/src/impl.js +2 -0
  96. package/out/replicache/src/index-defs.js +17 -28
  97. package/out/replicache/src/index-defs.js.map +1 -1
  98. package/out/replicache/src/kv/expo-sqlite/store.js +52 -50
  99. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  100. package/out/replicache/src/kv/idb-store-with-mem-fallback.js +71 -68
  101. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  102. package/out/replicache/src/kv/idb-store.js +144 -168
  103. package/out/replicache/src/kv/idb-store.js.map +1 -1
  104. package/out/replicache/src/kv/mem-store.js +57 -45
  105. package/out/replicache/src/kv/mem-store.js.map +1 -1
  106. package/out/replicache/src/kv/op-sqlite/store.js +56 -62
  107. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  108. package/out/replicache/src/kv/op-sqlite/types.d.ts.map +1 -1
  109. package/out/replicache/src/kv/op-sqlite/types.js +7 -6
  110. package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
  111. package/out/replicache/src/kv/read-impl.js +26 -25
  112. package/out/replicache/src/kv/read-impl.js.map +1 -1
  113. package/out/replicache/src/kv/sqlite-store.js +194 -207
  114. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  115. package/out/replicache/src/kv/throw-if-closed.js +12 -19
  116. package/out/replicache/src/kv/throw-if-closed.js.map +1 -1
  117. package/out/replicache/src/kv/write-impl-base.js +44 -56
  118. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  119. package/out/replicache/src/kv/write-impl.js +22 -26
  120. package/out/replicache/src/kv/write-impl.js.map +1 -1
  121. package/out/replicache/src/lazy.js +10 -11
  122. package/out/replicache/src/lazy.js.map +1 -1
  123. package/out/replicache/src/log-options.js +14 -7
  124. package/out/replicache/src/log-options.js.map +1 -1
  125. package/out/replicache/src/make-idb-name.js +14 -9
  126. package/out/replicache/src/make-idb-name.js.map +1 -1
  127. package/out/replicache/src/mutation-recovery.js +12 -0
  128. package/out/replicache/src/mutation-recovery.js.map +1 -0
  129. package/out/replicache/src/new-client-channel.js +34 -42
  130. package/out/replicache/src/new-client-channel.js.map +1 -1
  131. package/out/replicache/src/on-persist-channel.js +26 -29
  132. package/out/replicache/src/on-persist-channel.js.map +1 -1
  133. package/out/replicache/src/op-sqlite.js +2 -0
  134. package/out/replicache/src/patch-operation.js +27 -36
  135. package/out/replicache/src/patch-operation.js.map +1 -1
  136. package/out/replicache/src/pending-mutations.js +14 -12
  137. package/out/replicache/src/pending-mutations.js.map +1 -1
  138. package/out/replicache/src/persist/client-gc.js +36 -51
  139. package/out/replicache/src/persist/client-gc.js.map +1 -1
  140. package/out/replicache/src/persist/client-group-gc.js +29 -36
  141. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  142. package/out/replicache/src/persist/client-groups.js +80 -154
  143. package/out/replicache/src/persist/client-groups.js.map +1 -1
  144. package/out/replicache/src/persist/clients.js +212 -307
  145. package/out/replicache/src/persist/clients.js.map +1 -1
  146. package/out/replicache/src/persist/collect-idb-databases.js +109 -171
  147. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  148. package/out/replicache/src/persist/gather-mem-only-visitor.js +23 -24
  149. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  150. package/out/replicache/src/persist/gather-not-cached-visitor.js +35 -33
  151. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  152. package/out/replicache/src/persist/heartbeat.js +31 -41
  153. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  154. package/out/replicache/src/persist/idb-databases-store-db-name.js +9 -12
  155. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
  156. package/out/replicache/src/persist/idb-databases-store.js +78 -97
  157. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  158. package/out/replicache/src/persist/make-client-id.js +13 -9
  159. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  160. package/out/replicache/src/persist/persist.js +113 -174
  161. package/out/replicache/src/persist/persist.js.map +1 -1
  162. package/out/replicache/src/persist/refresh.js +94 -183
  163. package/out/replicache/src/persist/refresh.js.map +1 -1
  164. package/out/replicache/src/process-scheduler.js +122 -143
  165. package/out/replicache/src/process-scheduler.js.map +1 -1
  166. package/out/replicache/src/pusher.js +21 -26
  167. package/out/replicache/src/pusher.js.map +1 -1
  168. package/out/replicache/src/replicache-impl.js +844 -1184
  169. package/out/replicache/src/replicache-impl.js.map +1 -1
  170. package/out/replicache/src/report-error.js +9 -6
  171. package/out/replicache/src/report-error.js.map +1 -1
  172. package/out/replicache/src/request-idle.js +13 -11
  173. package/out/replicache/src/request-idle.js.map +1 -1
  174. package/out/replicache/src/scan-iterator.d.ts.map +1 -1
  175. package/out/replicache/src/scan-iterator.js +108 -135
  176. package/out/replicache/src/scan-iterator.js.map +1 -1
  177. package/out/replicache/src/scan-options.js +33 -39
  178. package/out/replicache/src/scan-options.js.map +1 -1
  179. package/out/replicache/src/set-interval-with-signal.js +11 -10
  180. package/out/replicache/src/set-interval-with-signal.js.map +1 -1
  181. package/out/replicache/src/sqlite.js +2 -0
  182. package/out/replicache/src/subscriptions.js +222 -338
  183. package/out/replicache/src/subscriptions.js.map +1 -1
  184. package/out/replicache/src/sync/diff.js +52 -65
  185. package/out/replicache/src/sync/diff.js.map +1 -1
  186. package/out/replicache/src/sync/ids.js +8 -9
  187. package/out/replicache/src/sync/ids.js.map +1 -1
  188. package/out/replicache/src/sync/patch.js +34 -45
  189. package/out/replicache/src/sync/patch.js.map +1 -1
  190. package/out/replicache/src/sync/pull-error.js +15 -15
  191. package/out/replicache/src/sync/pull-error.js.map +1 -1
  192. package/out/replicache/src/sync/pull.js +145 -283
  193. package/out/replicache/src/sync/pull.js.map +1 -1
  194. package/out/replicache/src/sync/push.js +64 -79
  195. package/out/replicache/src/sync/push.js.map +1 -1
  196. package/out/replicache/src/sync/request-id.js +23 -15
  197. package/out/replicache/src/sync/request-id.js.map +1 -1
  198. package/out/replicache/src/sync/sync-head-name.js +6 -5
  199. package/out/replicache/src/sync/sync-head-name.js.map +1 -1
  200. package/out/replicache/src/to-error.js +7 -8
  201. package/out/replicache/src/to-error.js.map +1 -1
  202. package/out/replicache/src/transaction-closed-error.js +15 -15
  203. package/out/replicache/src/transaction-closed-error.js.map +1 -1
  204. package/out/replicache/src/transactions.js +120 -140
  205. package/out/replicache/src/transactions.js.map +1 -1
  206. package/out/replicache/src/version.js +9 -5
  207. package/out/replicache/src/version.js.map +1 -1
  208. package/out/replicache/src/with-transactions.js +23 -20
  209. package/out/replicache/src/with-transactions.js.map +1 -1
  210. package/out/shared/src/abort-error.js +7 -6
  211. package/out/shared/src/abort-error.js.map +1 -1
  212. package/out/shared/src/arrays.js +35 -42
  213. package/out/shared/src/arrays.js.map +1 -1
  214. package/out/shared/src/asserts.js +21 -45
  215. package/out/shared/src/asserts.js.map +1 -1
  216. package/out/shared/src/bigint-json.js +42 -38
  217. package/out/shared/src/bigint-json.js.map +1 -1
  218. package/out/shared/src/binary-search.js +27 -18
  219. package/out/shared/src/binary-search.js.map +1 -1
  220. package/out/shared/src/broadcast-channel.js +20 -23
  221. package/out/shared/src/broadcast-channel.js.map +1 -1
  222. package/out/shared/src/browser-env.js +11 -17
  223. package/out/shared/src/browser-env.js.map +1 -1
  224. package/out/shared/src/btree-set.js +419 -481
  225. package/out/shared/src/btree-set.js.map +1 -1
  226. package/out/shared/src/cache.js +43 -36
  227. package/out/shared/src/cache.js.map +1 -1
  228. package/out/shared/src/centroid.js +24 -26
  229. package/out/shared/src/centroid.js.map +1 -1
  230. package/out/shared/src/config.js +6 -6
  231. package/out/shared/src/config.js.map +1 -1
  232. package/out/shared/src/custom-key-map.js +54 -58
  233. package/out/shared/src/custom-key-map.js.map +1 -1
  234. package/out/shared/src/custom-key-set.js +53 -51
  235. package/out/shared/src/custom-key-set.js.map +1 -1
  236. package/out/shared/src/deep-clone.js +30 -41
  237. package/out/shared/src/deep-clone.js.map +1 -1
  238. package/out/shared/src/deep-merge.js +25 -24
  239. package/out/shared/src/deep-merge.js.map +1 -1
  240. package/out/shared/src/document-visible.js +63 -70
  241. package/out/shared/src/document-visible.js.map +1 -1
  242. package/out/shared/src/dotenv.js +7 -3
  243. package/out/shared/src/dotenv.js.map +1 -1
  244. package/out/shared/src/error.js +43 -64
  245. package/out/shared/src/error.js.map +1 -1
  246. package/out/shared/src/has-own.js +6 -5
  247. package/out/shared/src/has-own.js.map +1 -1
  248. package/out/shared/src/hash.js +15 -14
  249. package/out/shared/src/hash.js.map +1 -1
  250. package/out/shared/src/iterables.js +34 -47
  251. package/out/shared/src/iterables.js.map +1 -1
  252. package/out/shared/src/json-schema.js +25 -30
  253. package/out/shared/src/json-schema.js.map +1 -1
  254. package/out/shared/src/json.js +90 -129
  255. package/out/shared/src/json.js.map +1 -1
  256. package/out/shared/src/logging-test-utils.js +9 -11
  257. package/out/shared/src/logging-test-utils.js.map +1 -1
  258. package/out/shared/src/logging.js +75 -95
  259. package/out/shared/src/logging.js.map +1 -1
  260. package/out/shared/src/must.js +7 -8
  261. package/out/shared/src/must.js.map +1 -1
  262. package/out/shared/src/navigator.js +6 -5
  263. package/out/shared/src/navigator.js.map +1 -1
  264. package/out/shared/src/object-traversal.js +23 -23
  265. package/out/shared/src/object-traversal.js.map +1 -1
  266. package/out/shared/src/objects.js +15 -18
  267. package/out/shared/src/objects.js.map +1 -1
  268. package/out/shared/src/options.js +225 -302
  269. package/out/shared/src/options.js.map +1 -1
  270. package/out/shared/src/parse-big-int.js +12 -11
  271. package/out/shared/src/parse-big-int.js.map +1 -1
  272. package/out/shared/src/promise-race.js +21 -17
  273. package/out/shared/src/promise-race.js.map +1 -1
  274. package/out/shared/src/queue.js +124 -124
  275. package/out/shared/src/queue.js.map +1 -1
  276. package/out/shared/src/rand.js +13 -7
  277. package/out/shared/src/rand.js.map +1 -1
  278. package/out/shared/src/random-uint64.js +8 -7
  279. package/out/shared/src/random-uint64.js.map +1 -1
  280. package/out/shared/src/random-values.js +8 -11
  281. package/out/shared/src/random-values.js.map +1 -1
  282. package/out/shared/src/record-proxy.js +68 -57
  283. package/out/shared/src/record-proxy.js.map +1 -1
  284. package/out/shared/src/resolved-promises.js +9 -11
  285. package/out/shared/src/resolved-promises.js.map +1 -1
  286. package/out/shared/src/sentinels.js +9 -12
  287. package/out/shared/src/sentinels.js.map +1 -1
  288. package/out/shared/src/set-utils.js +41 -63
  289. package/out/shared/src/set-utils.js.map +1 -1
  290. package/out/shared/src/size-of-value.js +55 -51
  291. package/out/shared/src/size-of-value.js.map +1 -1
  292. package/out/shared/src/sleep.js +50 -45
  293. package/out/shared/src/sleep.js.map +1 -1
  294. package/out/shared/src/string-compare.js +8 -11
  295. package/out/shared/src/string-compare.js.map +1 -1
  296. package/out/shared/src/subscribable.js +34 -33
  297. package/out/shared/src/subscribable.js.map +1 -1
  298. package/out/shared/src/tdigest-schema.js +11 -7
  299. package/out/shared/src/tdigest-schema.js.map +1 -1
  300. package/out/shared/src/tdigest.js +197 -270
  301. package/out/shared/src/tdigest.js.map +1 -1
  302. package/out/shared/src/valita.js +145 -174
  303. package/out/shared/src/valita.js.map +1 -1
  304. package/out/z2s/src/compiler.d.ts.map +1 -1
  305. package/out/z2s/src/compiler.js +238 -468
  306. package/out/z2s/src/compiler.js.map +1 -1
  307. package/out/z2s/src/sql.d.ts +0 -1
  308. package/out/z2s/src/sql.d.ts.map +1 -1
  309. package/out/z2s/src/sql.js +149 -194
  310. package/out/z2s/src/sql.js.map +1 -1
  311. package/out/zero/package.js +194 -0
  312. package/out/zero/package.js.map +1 -0
  313. package/out/zero/src/adapters/drizzle.js +1 -6
  314. package/out/zero/src/adapters/pg.js +1 -6
  315. package/out/zero/src/adapters/postgresjs.js +1 -6
  316. package/out/zero/src/adapters/prisma.js +1 -5
  317. package/out/zero/src/analyze-query.js +1 -1
  318. package/out/zero/src/ast-to-zql.js +1 -1
  319. package/out/zero/src/bindings.js +6 -21
  320. package/out/zero/src/build-schema.js +5 -1
  321. package/out/zero/src/build-schema.js.map +1 -1
  322. package/out/zero/src/change-protocol/v0.js +3 -5
  323. package/out/zero/src/cli.js +2 -2
  324. package/out/zero/src/deploy-permissions.js +1 -1
  325. package/out/zero/src/expo-sqlite.js +2 -4
  326. package/out/zero/src/op-sqlite.js +2 -4
  327. package/out/zero/src/pg.js +2 -20
  328. package/out/zero/src/react-native.js +16 -12
  329. package/out/zero/src/react-native.js.map +1 -1
  330. package/out/zero/src/react.js +3 -12
  331. package/out/zero/src/server/runner/main.js +2 -0
  332. package/out/zero/src/server.js +2 -17
  333. package/out/zero/src/solid.js +3 -12
  334. package/out/zero/src/sqlite.js +2 -6
  335. package/out/zero/src/transform-query.js +1 -1
  336. package/out/zero/src/zero-cache-dev.js +124 -151
  337. package/out/zero/src/zero-cache-dev.js.map +1 -1
  338. package/out/zero/src/zero-out.js +9 -6
  339. package/out/zero/src/zero-out.js.map +1 -1
  340. package/out/zero/src/zero.js +6 -55
  341. package/out/zero/src/zqlite.js +2 -7
  342. package/out/zero-cache/src/auth/auth.js +138 -172
  343. package/out/zero-cache/src/auth/auth.js.map +1 -1
  344. package/out/zero-cache/src/auth/jwt.js +25 -33
  345. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  346. package/out/zero-cache/src/auth/load-permissions.js +54 -62
  347. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  348. package/out/zero-cache/src/auth/read-authorizer.js +70 -80
  349. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  350. package/out/zero-cache/src/auth/write-authorizer.js +284 -432
  351. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  352. package/out/zero-cache/src/config/network.js +31 -45
  353. package/out/zero-cache/src/config/network.js.map +1 -1
  354. package/out/zero-cache/src/config/normalize.js +81 -83
  355. package/out/zero-cache/src/config/normalize.js.map +1 -1
  356. package/out/zero-cache/src/config/server-context.js +32 -29
  357. package/out/zero-cache/src/config/server-context.js.map +1 -1
  358. package/out/zero-cache/src/config/zero-config.js +753 -833
  359. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  360. package/out/zero-cache/src/custom/fetch.js +183 -230
  361. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  362. package/out/zero-cache/src/custom-queries/transform-query.js +93 -99
  363. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  364. package/out/zero-cache/src/db/create.js +27 -29
  365. package/out/zero-cache/src/db/create.js.map +1 -1
  366. package/out/zero-cache/src/db/delete-lite-db.js +11 -7
  367. package/out/zero-cache/src/db/delete-lite-db.js.map +1 -1
  368. package/out/zero-cache/src/db/lite-tables.js +118 -158
  369. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  370. package/out/zero-cache/src/db/migration-lite.js +110 -178
  371. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  372. package/out/zero-cache/src/db/migration.js +82 -151
  373. package/out/zero-cache/src/db/migration.js.map +1 -1
  374. package/out/zero-cache/src/db/mode-enum.js +8 -9
  375. package/out/zero-cache/src/db/mode-enum.js.map +1 -1
  376. package/out/zero-cache/src/db/pg-copy.js +56 -54
  377. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  378. package/out/zero-cache/src/db/pg-to-lite.js +74 -110
  379. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  380. package/out/zero-cache/src/db/pg-type-parser.js +19 -36
  381. package/out/zero-cache/src/db/pg-type-parser.js.map +1 -1
  382. package/out/zero-cache/src/db/run-transaction.js +19 -20
  383. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  384. package/out/zero-cache/src/db/specs.js +42 -78
  385. package/out/zero-cache/src/db/specs.js.map +1 -1
  386. package/out/zero-cache/src/db/statements.js +52 -59
  387. package/out/zero-cache/src/db/statements.js.map +1 -1
  388. package/out/zero-cache/src/db/transaction-pool.js +376 -400
  389. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  390. package/out/zero-cache/src/db/warmup.js +13 -24
  391. package/out/zero-cache/src/db/warmup.js.map +1 -1
  392. package/out/zero-cache/src/observability/events.js +89 -99
  393. package/out/zero-cache/src/observability/events.js.map +1 -1
  394. package/out/zero-cache/src/observability/metrics.js +30 -54
  395. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  396. package/out/zero-cache/src/scripts/decommission.js +42 -47
  397. package/out/zero-cache/src/scripts/decommission.js.map +1 -1
  398. package/out/zero-cache/src/scripts/deploy-permissions.js +106 -144
  399. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  400. package/out/zero-cache/src/scripts/permissions.js +86 -107
  401. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  402. package/out/zero-cache/src/server/anonymous-otel-start.js +306 -440
  403. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  404. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  405. package/out/zero-cache/src/server/change-streamer.js +57 -130
  406. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  407. package/out/zero-cache/src/server/inspector-delegate.js +89 -100
  408. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  409. package/out/zero-cache/src/server/logging.js +18 -26
  410. package/out/zero-cache/src/server/logging.js.map +1 -1
  411. package/out/zero-cache/src/server/main.js +85 -142
  412. package/out/zero-cache/src/server/main.js.map +1 -1
  413. package/out/zero-cache/src/server/mutator.js +16 -13
  414. package/out/zero-cache/src/server/mutator.js.map +1 -1
  415. package/out/zero-cache/src/server/otel-diag-logger.js +42 -49
  416. package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
  417. package/out/zero-cache/src/server/otel-log-sink.js +34 -44
  418. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  419. package/out/zero-cache/src/server/otel-start.js +43 -51
  420. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  421. package/out/zero-cache/src/server/priority-op.js +27 -25
  422. package/out/zero-cache/src/server/priority-op.js.map +1 -1
  423. package/out/zero-cache/src/server/reaper.js +32 -43
  424. package/out/zero-cache/src/server/reaper.js.map +1 -1
  425. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  426. package/out/zero-cache/src/server/replicator.js +41 -57
  427. package/out/zero-cache/src/server/replicator.js.map +1 -1
  428. package/out/zero-cache/src/server/runner/main.js +7 -8
  429. package/out/zero-cache/src/server/runner/main.js.map +1 -1
  430. package/out/zero-cache/src/server/runner/run-worker.js +56 -52
  431. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  432. package/out/zero-cache/src/server/runner/runtime.js +26 -32
  433. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  434. package/out/zero-cache/src/server/runner/zero-dispatcher.js +22 -27
  435. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  436. package/out/zero-cache/src/server/syncer.js +79 -148
  437. package/out/zero-cache/src/server/syncer.js.map +1 -1
  438. package/out/zero-cache/src/server/worker-dispatcher.js +84 -113
  439. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  440. package/out/zero-cache/src/server/worker-urls.d.ts +2 -1
  441. package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
  442. package/out/zero-cache/src/server/worker-urls.js +14 -18
  443. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  444. package/out/zero-cache/src/server/write-worker.js +2 -0
  445. package/out/zero-cache/src/services/analyze.js +61 -130
  446. package/out/zero-cache/src/services/analyze.js.map +1 -1
  447. package/out/zero-cache/src/services/change-source/common/backfill-manager.js +420 -419
  448. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  449. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +111 -114
  450. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  451. package/out/zero-cache/src/services/change-source/common/replica-schema.js +80 -148
  452. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  453. package/out/zero-cache/src/services/change-source/custom/change-source.js +154 -216
  454. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  455. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js +11 -14
  456. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  457. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +168 -212
  458. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  459. package/out/zero-cache/src/services/change-source/pg/change-source.js +672 -892
  460. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  461. package/out/zero-cache/src/services/change-source/pg/decommission.js +19 -23
  462. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  463. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +258 -411
  464. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  465. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js +59 -65
  466. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  467. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js +218 -247
  468. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  469. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +100 -142
  470. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  471. package/out/zero-cache/src/services/change-source/pg/lsn.js +17 -19
  472. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  473. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +88 -98
  474. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  475. package/out/zero-cache/src/services/change-source/pg/schema/init.js +96 -177
  476. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  477. package/out/zero-cache/src/services/change-source/pg/schema/published.js +69 -107
  478. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  479. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +151 -212
  480. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  481. package/out/zero-cache/src/services/change-source/pg/schema/validation.js +22 -53
  482. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  483. package/out/zero-cache/src/services/change-source/protocol/current/control.js +24 -12
  484. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  485. package/out/zero-cache/src/services/change-source/protocol/current/data.js +180 -290
  486. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  487. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js +21 -33
  488. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  489. package/out/zero-cache/src/services/change-source/protocol/current/json.js +7 -18
  490. package/out/zero-cache/src/services/change-source/protocol/current/json.js.map +1 -1
  491. package/out/zero-cache/src/services/change-source/protocol/current/path.js +24 -5
  492. package/out/zero-cache/src/services/change-source/protocol/current/path.js.map +1 -1
  493. package/out/zero-cache/src/services/change-source/protocol/current/status.js +25 -19
  494. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  495. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +24 -16
  496. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  497. package/out/zero-cache/src/services/change-source/protocol/current.js +51 -46
  498. package/out/zero-cache/src/services/change-source/protocol/current.js.map +1 -1
  499. package/out/zero-cache/src/services/change-source/protocol/mod.js +2 -0
  500. package/out/zero-cache/src/services/change-streamer/backup-monitor.js +165 -171
  501. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  502. package/out/zero-cache/src/services/change-streamer/broadcast.js +163 -169
  503. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  504. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +154 -221
  505. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  506. package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
  507. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +340 -299
  508. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  509. package/out/zero-cache/src/services/change-streamer/change-streamer.js +17 -24
  510. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  511. package/out/zero-cache/src/services/change-streamer/forwarder.js +84 -103
  512. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  513. package/out/zero-cache/src/services/change-streamer/replica-monitor.js +49 -43
  514. package/out/zero-cache/src/services/change-streamer/replica-monitor.js.map +1 -1
  515. package/out/zero-cache/src/services/change-streamer/schema/init.js +61 -89
  516. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  517. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +20 -1
  518. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  519. package/out/zero-cache/src/services/change-streamer/schema/tables.js +131 -109
  520. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  521. package/out/zero-cache/src/services/change-streamer/snapshot.js +26 -28
  522. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  523. package/out/zero-cache/src/services/change-streamer/storer.js +434 -513
  524. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  525. package/out/zero-cache/src/services/change-streamer/subscriber.js +142 -155
  526. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  527. package/out/zero-cache/src/services/heapz.js +18 -20
  528. package/out/zero-cache/src/services/heapz.js.map +1 -1
  529. package/out/zero-cache/src/services/http-service.js +59 -57
  530. package/out/zero-cache/src/services/http-service.js.map +1 -1
  531. package/out/zero-cache/src/services/life-cycle.js +182 -214
  532. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  533. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +102 -81
  534. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  535. package/out/zero-cache/src/services/litestream/commands.js +144 -205
  536. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  537. package/out/zero-cache/src/services/mutagen/error.js +10 -14
  538. package/out/zero-cache/src/services/mutagen/error.js.map +1 -1
  539. package/out/zero-cache/src/services/mutagen/mutagen.js +166 -264
  540. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  541. package/out/zero-cache/src/services/mutagen/pusher.js +372 -487
  542. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  543. package/out/zero-cache/src/services/replicator/change-processor.js +483 -592
  544. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  545. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +4 -2
  546. package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
  547. package/out/zero-cache/src/services/replicator/incremental-sync.js +118 -143
  548. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  549. package/out/zero-cache/src/services/replicator/notifier.js +52 -28
  550. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  551. package/out/zero-cache/src/services/replicator/replication-status.js +105 -128
  552. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  553. package/out/zero-cache/src/services/replicator/replicator.d.ts +2 -1
  554. package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
  555. package/out/zero-cache/src/services/replicator/replicator.js +32 -34
  556. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  557. package/out/zero-cache/src/services/replicator/schema/change-log.js +101 -133
  558. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  559. package/out/zero-cache/src/services/replicator/schema/column-metadata.js +145 -174
  560. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  561. package/out/zero-cache/src/services/replicator/schema/constants.js +11 -5
  562. package/out/zero-cache/src/services/replicator/schema/constants.js.map +1 -1
  563. package/out/zero-cache/src/services/replicator/schema/replication-state.js +56 -107
  564. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  565. package/out/zero-cache/src/services/replicator/schema/table-metadata.js +81 -66
  566. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  567. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +69 -0
  568. package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -0
  569. package/out/zero-cache/src/services/replicator/write-worker-client.js +96 -0
  570. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -0
  571. package/out/zero-cache/src/services/replicator/write-worker.js +68 -0
  572. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -0
  573. package/out/zero-cache/src/services/run-ast.js +79 -120
  574. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  575. package/out/zero-cache/src/services/runner.js +39 -41
  576. package/out/zero-cache/src/services/runner.js.map +1 -1
  577. package/out/zero-cache/src/services/running-state.js +129 -134
  578. package/out/zero-cache/src/services/running-state.js.map +1 -1
  579. package/out/zero-cache/src/services/statz.js +139 -200
  580. package/out/zero-cache/src/services/statz.js.map +1 -1
  581. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +46 -49
  582. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  583. package/out/zero-cache/src/services/view-syncer/client-handler.js +257 -299
  584. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  585. package/out/zero-cache/src/services/view-syncer/client-schema.js +52 -82
  586. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  587. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +85 -107
  588. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  589. package/out/zero-cache/src/services/view-syncer/cvr-store.js +604 -757
  590. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  591. package/out/zero-cache/src/services/view-syncer/cvr.js +631 -739
  592. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  593. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +60 -40
  594. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  595. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +95 -178
  596. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  597. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  598. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +571 -722
  599. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  600. package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
  601. package/out/zero-cache/src/services/view-syncer/row-record-cache.js +246 -257
  602. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  603. package/out/zero-cache/src/services/view-syncer/schema/cvr.js +59 -45
  604. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  605. package/out/zero-cache/src/services/view-syncer/schema/init.js +121 -189
  606. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
  607. package/out/zero-cache/src/services/view-syncer/schema/types.js +138 -263
  608. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  609. package/out/zero-cache/src/services/view-syncer/snapshotter.js +322 -335
  610. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  611. package/out/zero-cache/src/services/view-syncer/tracer.js +7 -6
  612. package/out/zero-cache/src/services/view-syncer/tracer.js.map +1 -1
  613. package/out/zero-cache/src/services/view-syncer/ttl-clock.js +9 -11
  614. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  615. package/out/zero-cache/src/services/view-syncer/view-syncer.js +1067 -1603
  616. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  617. package/out/zero-cache/src/types/error-with-level.js +19 -25
  618. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  619. package/out/zero-cache/src/types/http.js +17 -26
  620. package/out/zero-cache/src/types/http.js.map +1 -1
  621. package/out/zero-cache/src/types/lexi-version.js +28 -42
  622. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  623. package/out/zero-cache/src/types/lite.js +101 -121
  624. package/out/zero-cache/src/types/lite.js.map +1 -1
  625. package/out/zero-cache/src/types/names.js +6 -5
  626. package/out/zero-cache/src/types/names.js.map +1 -1
  627. package/out/zero-cache/src/types/pg-data-type.d.ts +1 -0
  628. package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
  629. package/out/zero-cache/src/types/pg-data-type.js +58 -73
  630. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  631. package/out/zero-cache/src/types/pg-types.js +12 -19
  632. package/out/zero-cache/src/types/pg-types.js.map +1 -1
  633. package/out/zero-cache/src/types/pg.js +144 -218
  634. package/out/zero-cache/src/types/pg.js.map +1 -1
  635. package/out/zero-cache/src/types/processes.js +95 -90
  636. package/out/zero-cache/src/types/processes.js.map +1 -1
  637. package/out/zero-cache/src/types/profiler.js +32 -27
  638. package/out/zero-cache/src/types/profiler.js.map +1 -1
  639. package/out/zero-cache/src/types/row-key.js +42 -30
  640. package/out/zero-cache/src/types/row-key.js.map +1 -1
  641. package/out/zero-cache/src/types/shards.js +36 -45
  642. package/out/zero-cache/src/types/shards.js.map +1 -1
  643. package/out/zero-cache/src/types/sql.js +20 -9
  644. package/out/zero-cache/src/types/sql.js.map +1 -1
  645. package/out/zero-cache/src/types/state-version.js +17 -23
  646. package/out/zero-cache/src/types/state-version.js.map +1 -1
  647. package/out/zero-cache/src/types/streams.js +234 -270
  648. package/out/zero-cache/src/types/streams.js.map +1 -1
  649. package/out/zero-cache/src/types/strings.js +10 -13
  650. package/out/zero-cache/src/types/strings.js.map +1 -1
  651. package/out/zero-cache/src/types/subscription.js +266 -226
  652. package/out/zero-cache/src/types/subscription.js.map +1 -1
  653. package/out/zero-cache/src/types/url-params.js +30 -39
  654. package/out/zero-cache/src/types/url-params.js.map +1 -1
  655. package/out/zero-cache/src/types/websocket-handoff.js +62 -75
  656. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  657. package/out/zero-cache/src/types/ws.js +43 -53
  658. package/out/zero-cache/src/types/ws.js.map +1 -1
  659. package/out/zero-cache/src/workers/connect-params.js +42 -43
  660. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  661. package/out/zero-cache/src/workers/connection.js +213 -282
  662. package/out/zero-cache/src/workers/connection.js.map +1 -1
  663. package/out/zero-cache/src/workers/mutator.js +22 -21
  664. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  665. package/out/zero-cache/src/workers/replicator.d.ts +7 -0
  666. package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
  667. package/out/zero-cache/src/workers/replicator.js +92 -97
  668. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  669. package/out/zero-cache/src/workers/syncer-ws-message-handler.js +121 -203
  670. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  671. package/out/zero-cache/src/workers/syncer.js +147 -201
  672. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  673. package/out/zero-client/src/client/active-clients-manager.js +178 -187
  674. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  675. package/out/zero-client/src/client/bindings.js +11 -0
  676. package/out/zero-client/src/client/client-error-kind-enum.js +18 -29
  677. package/out/zero-client/src/client/client-error-kind-enum.js.map +1 -1
  678. package/out/zero-client/src/client/connection-manager.js +291 -346
  679. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  680. package/out/zero-client/src/client/connection-status-enum.js +20 -15
  681. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  682. package/out/zero-client/src/client/connection.js +92 -110
  683. package/out/zero-client/src/client/connection.js.map +1 -1
  684. package/out/zero-client/src/client/context.js +84 -100
  685. package/out/zero-client/src/client/context.js.map +1 -1
  686. package/out/zero-client/src/client/crud-impl.js +56 -88
  687. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  688. package/out/zero-client/src/client/crud.js +127 -129
  689. package/out/zero-client/src/client/crud.js.map +1 -1
  690. package/out/zero-client/src/client/custom.d.ts.map +1 -1
  691. package/out/zero-client/src/client/custom.js +50 -74
  692. package/out/zero-client/src/client/custom.js.map +1 -1
  693. package/out/zero-client/src/client/delete-clients-manager.js +72 -93
  694. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  695. package/out/zero-client/src/client/enable-analytics.js +8 -16
  696. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  697. package/out/zero-client/src/client/error.js +118 -133
  698. package/out/zero-client/src/client/error.js.map +1 -1
  699. package/out/zero-client/src/client/http-string.js +7 -7
  700. package/out/zero-client/src/client/http-string.js.map +1 -1
  701. package/out/zero-client/src/client/inspector/client-group.js +21 -26
  702. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  703. package/out/zero-client/src/client/inspector/client.js +23 -26
  704. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  705. package/out/zero-client/src/client/inspector/html-dialog-prompt.js +72 -73
  706. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  707. package/out/zero-client/src/client/inspector/inspector.js +46 -51
  708. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  709. package/out/zero-client/src/client/inspector/lazy-inspector.js +132 -192
  710. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  711. package/out/zero-client/src/client/inspector/query.js +72 -77
  712. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  713. package/out/zero-client/src/client/ivm-branch.js +118 -145
  714. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  715. package/out/zero-client/src/client/keys.js +15 -31
  716. package/out/zero-client/src/client/keys.js.map +1 -1
  717. package/out/zero-client/src/client/log-options.js +43 -57
  718. package/out/zero-client/src/client/log-options.js.map +1 -1
  719. package/out/zero-client/src/client/make-mutate-property.js +46 -29
  720. package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
  721. package/out/zero-client/src/client/make-replicache-mutators.js +80 -96
  722. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  723. package/out/zero-client/src/client/metric-name-enum.js +11 -15
  724. package/out/zero-client/src/client/metric-name-enum.js.map +1 -1
  725. package/out/zero-client/src/client/metrics.js +210 -237
  726. package/out/zero-client/src/client/metrics.js.map +1 -1
  727. package/out/zero-client/src/client/mutation-tracker.js +264 -354
  728. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  729. package/out/zero-client/src/client/mutator-proxy.js +122 -151
  730. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  731. package/out/zero-client/src/client/options.js +7 -10
  732. package/out/zero-client/src/client/options.js.map +1 -1
  733. package/out/zero-client/src/client/query-manager.js +305 -373
  734. package/out/zero-client/src/client/query-manager.js.map +1 -1
  735. package/out/zero-client/src/client/reload-error-handler.js +80 -101
  736. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  737. package/out/zero-client/src/client/server-option.js +30 -59
  738. package/out/zero-client/src/client/server-option.js.map +1 -1
  739. package/out/zero-client/src/client/update-needed-reason-type-enum.js +27 -9
  740. package/out/zero-client/src/client/update-needed-reason-type-enum.js.map +1 -1
  741. package/out/zero-client/src/client/version.js +9 -5
  742. package/out/zero-client/src/client/version.js.map +1 -1
  743. package/out/zero-client/src/client/zero-poke-handler.d.ts +1 -1
  744. package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
  745. package/out/zero-client/src/client/zero-poke-handler.js +205 -293
  746. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  747. package/out/zero-client/src/client/zero-rep.js +61 -68
  748. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  749. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  750. package/out/zero-client/src/client/zero.js +1367 -1834
  751. package/out/zero-client/src/client/zero.js.map +1 -1
  752. package/out/zero-client/src/mod.js +21 -0
  753. package/out/zero-client/src/util/nanoid.js +13 -18
  754. package/out/zero-client/src/util/nanoid.js.map +1 -1
  755. package/out/zero-client/src/util/socket.js +6 -5
  756. package/out/zero-client/src/util/socket.js.map +1 -1
  757. package/out/zero-pg/src/mod.js +10 -0
  758. package/out/zero-protocol/src/analyze-query-result.js +108 -148
  759. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  760. package/out/zero-protocol/src/application-error.js +36 -34
  761. package/out/zero-protocol/src/application-error.js.map +1 -1
  762. package/out/zero-protocol/src/ast.js +236 -309
  763. package/out/zero-protocol/src/ast.js.map +1 -1
  764. package/out/zero-protocol/src/change-desired-queries.js +8 -13
  765. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  766. package/out/zero-protocol/src/client-schema.js +21 -42
  767. package/out/zero-protocol/src/client-schema.js.map +1 -1
  768. package/out/zero-protocol/src/close-connection.js +20 -12
  769. package/out/zero-protocol/src/close-connection.js.map +1 -1
  770. package/out/zero-protocol/src/connect.js +37 -52
  771. package/out/zero-protocol/src/connect.js.map +1 -1
  772. package/out/zero-protocol/src/custom-queries.js +34 -65
  773. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  774. package/out/zero-protocol/src/data.js +6 -9
  775. package/out/zero-protocol/src/data.js.map +1 -1
  776. package/out/zero-protocol/src/delete-clients.js +11 -17
  777. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  778. package/out/zero-protocol/src/down.js +11 -23
  779. package/out/zero-protocol/src/down.js.map +1 -1
  780. package/out/zero-protocol/src/error-kind-enum.js +24 -41
  781. package/out/zero-protocol/src/error-kind-enum.js.map +1 -1
  782. package/out/zero-protocol/src/error-origin-enum.js +8 -9
  783. package/out/zero-protocol/src/error-origin-enum.js.map +1 -1
  784. package/out/zero-protocol/src/error-reason-enum.js +12 -17
  785. package/out/zero-protocol/src/error-reason-enum.js.map +1 -1
  786. package/out/zero-protocol/src/error.js +76 -152
  787. package/out/zero-protocol/src/error.js.map +1 -1
  788. package/out/zero-protocol/src/inspect-down.js +51 -74
  789. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  790. package/out/zero-protocol/src/inspect-up.js +28 -46
  791. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  792. package/out/zero-protocol/src/mutation-id.js +9 -9
  793. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  794. package/out/zero-protocol/src/mutation-type-enum.js +7 -7
  795. package/out/zero-protocol/src/mutation-type-enum.js.map +1 -1
  796. package/out/zero-protocol/src/mutations-patch.js +21 -16
  797. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  798. package/out/zero-protocol/src/ping.js +8 -9
  799. package/out/zero-protocol/src/ping.js.map +1 -1
  800. package/out/zero-protocol/src/poke.js +53 -59
  801. package/out/zero-protocol/src/poke.js.map +1 -1
  802. package/out/zero-protocol/src/pong.js +8 -9
  803. package/out/zero-protocol/src/pong.js.map +1 -1
  804. package/out/zero-protocol/src/primary-key.js +9 -19
  805. package/out/zero-protocol/src/primary-key.js.map +1 -1
  806. package/out/zero-protocol/src/protocol-version.js +5 -11
  807. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  808. package/out/zero-protocol/src/pull.js +16 -28
  809. package/out/zero-protocol/src/pull.js.map +1 -1
  810. package/out/zero-protocol/src/push.js +162 -209
  811. package/out/zero-protocol/src/push.js.map +1 -1
  812. package/out/zero-protocol/src/queries-patch.js +22 -30
  813. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  814. package/out/zero-protocol/src/query-hash.js +14 -17
  815. package/out/zero-protocol/src/query-hash.js.map +1 -1
  816. package/out/zero-protocol/src/row-patch.js +23 -30
  817. package/out/zero-protocol/src/row-patch.js.map +1 -1
  818. package/out/zero-protocol/src/up.js +11 -22
  819. package/out/zero-protocol/src/up.js.map +1 -1
  820. package/out/zero-protocol/src/update-auth.js +8 -13
  821. package/out/zero-protocol/src/update-auth.js.map +1 -1
  822. package/out/zero-protocol/src/version.js +8 -9
  823. package/out/zero-protocol/src/version.js.map +1 -1
  824. package/out/zero-react/src/bindings.js +12 -0
  825. package/out/zero-react/src/mod.js +5 -0
  826. package/out/zero-react/src/use-connection-state.js +14 -11
  827. package/out/zero-react/src/use-connection-state.js.map +1 -1
  828. package/out/zero-react/src/use-query.js +283 -281
  829. package/out/zero-react/src/use-query.js.map +1 -1
  830. package/out/zero-react/src/use-zero-online.js +17 -11
  831. package/out/zero-react/src/use-zero-online.js.map +1 -1
  832. package/out/zero-react/src/zero-provider.js +53 -69
  833. package/out/zero-react/src/zero-provider.js.map +1 -1
  834. package/out/zero-react/src/zero.js +22 -0
  835. package/out/zero-schema/src/builder/relationship-builder.js +25 -21
  836. package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
  837. package/out/zero-schema/src/builder/schema-builder.js +51 -79
  838. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  839. package/out/zero-schema/src/builder/table-builder.js +99 -116
  840. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  841. package/out/zero-schema/src/compiled-permissions.js +21 -25
  842. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  843. package/out/zero-schema/src/name-mapper.js +31 -47
  844. package/out/zero-schema/src/name-mapper.js.map +1 -1
  845. package/out/zero-schema/src/permissions.js +94 -181
  846. package/out/zero-schema/src/permissions.js.map +1 -1
  847. package/out/zero-schema/src/schema-config.js +26 -32
  848. package/out/zero-schema/src/schema-config.js.map +1 -1
  849. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  850. package/out/zero-server/src/adapters/drizzle.js +79 -76
  851. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  852. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  853. package/out/zero-server/src/adapters/pg.js +79 -55
  854. package/out/zero-server/src/adapters/pg.js.map +1 -1
  855. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  856. package/out/zero-server/src/adapters/postgresjs.js +66 -40
  857. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  858. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  859. package/out/zero-server/src/adapters/prisma.js +75 -55
  860. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  861. package/out/zero-server/src/custom.d.ts.map +1 -1
  862. package/out/zero-server/src/custom.js +188 -265
  863. package/out/zero-server/src/custom.js.map +1 -1
  864. package/out/zero-server/src/logging.js +6 -5
  865. package/out/zero-server/src/logging.js.map +1 -1
  866. package/out/zero-server/src/mod.js +8 -0
  867. package/out/zero-server/src/pg-query-executor.js +14 -17
  868. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  869. package/out/zero-server/src/process-mutations.js +293 -365
  870. package/out/zero-server/src/process-mutations.js.map +1 -1
  871. package/out/zero-server/src/push-processor.js +33 -49
  872. package/out/zero-server/src/push-processor.js.map +1 -1
  873. package/out/zero-server/src/queries/process-queries.js +106 -96
  874. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  875. package/out/zero-server/src/schema.js +98 -144
  876. package/out/zero-server/src/schema.js.map +1 -1
  877. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  878. package/out/zero-server/src/zql-database.js +54 -69
  879. package/out/zero-server/src/zql-database.js.map +1 -1
  880. package/out/zero-solid/src/bindings.js +12 -0
  881. package/out/zero-solid/src/mod.js +5 -0
  882. package/out/zero-solid/src/solid-view.js +135 -227
  883. package/out/zero-solid/src/solid-view.js.map +1 -1
  884. package/out/zero-solid/src/use-connection-state.js +18 -14
  885. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  886. package/out/zero-solid/src/use-query.js +55 -100
  887. package/out/zero-solid/src/use-query.js.map +1 -1
  888. package/out/zero-solid/src/use-zero-online.js +18 -12
  889. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  890. package/out/zero-solid/src/use-zero.js +65 -77
  891. package/out/zero-solid/src/use-zero.js.map +1 -1
  892. package/out/zero-solid/src/zero.js +22 -0
  893. package/out/zero-types/src/format.js +8 -7
  894. package/out/zero-types/src/format.js.map +1 -1
  895. package/out/zero-types/src/name-mapper.js +34 -47
  896. package/out/zero-types/src/name-mapper.js.map +1 -1
  897. package/out/zql/src/builder/builder.d.ts.map +1 -1
  898. package/out/zql/src/builder/builder.js +315 -476
  899. package/out/zql/src/builder/builder.js.map +1 -1
  900. package/out/zql/src/builder/debug-delegate.js +69 -74
  901. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  902. package/out/zql/src/builder/filter.js +116 -140
  903. package/out/zql/src/builder/filter.js.map +1 -1
  904. package/out/zql/src/builder/like.js +41 -46
  905. package/out/zql/src/builder/like.js.map +1 -1
  906. package/out/zql/src/error.js +10 -9
  907. package/out/zql/src/error.js.map +1 -1
  908. package/out/zql/src/ivm/array-view.js +89 -91
  909. package/out/zql/src/ivm/array-view.js.map +1 -1
  910. package/out/zql/src/ivm/constraint.js +65 -74
  911. package/out/zql/src/ivm/constraint.js.map +1 -1
  912. package/out/zql/src/ivm/data.js +61 -48
  913. package/out/zql/src/ivm/data.js.map +1 -1
  914. package/out/zql/src/ivm/exists.js +164 -213
  915. package/out/zql/src/ivm/exists.js.map +1 -1
  916. package/out/zql/src/ivm/fan-in.js +62 -59
  917. package/out/zql/src/ivm/fan-in.js.map +1 -1
  918. package/out/zql/src/ivm/fan-out.js +52 -61
  919. package/out/zql/src/ivm/fan-out.js.map +1 -1
  920. package/out/zql/src/ivm/filter-operators.js +91 -96
  921. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  922. package/out/zql/src/ivm/filter-push.js +22 -26
  923. package/out/zql/src/ivm/filter-push.js.map +1 -1
  924. package/out/zql/src/ivm/filter.js +41 -35
  925. package/out/zql/src/ivm/filter.js.map +1 -1
  926. package/out/zql/src/ivm/flipped-join.js +282 -391
  927. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  928. package/out/zql/src/ivm/join-utils.js +85 -115
  929. package/out/zql/src/ivm/join-utils.js.map +1 -1
  930. package/out/zql/src/ivm/join.js +162 -231
  931. package/out/zql/src/ivm/join.js.map +1 -1
  932. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +21 -25
  933. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  934. package/out/zql/src/ivm/memory-source.js +364 -503
  935. package/out/zql/src/ivm/memory-source.js.map +1 -1
  936. package/out/zql/src/ivm/memory-storage.js +33 -34
  937. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  938. package/out/zql/src/ivm/operator.js +13 -15
  939. package/out/zql/src/ivm/operator.js.map +1 -1
  940. package/out/zql/src/ivm/push-accumulated.js +267 -270
  941. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  942. package/out/zql/src/ivm/skip.js +91 -104
  943. package/out/zql/src/ivm/skip.js.map +1 -1
  944. package/out/zql/src/ivm/stream.js +10 -10
  945. package/out/zql/src/ivm/stream.js.map +1 -1
  946. package/out/zql/src/ivm/take.js +422 -569
  947. package/out/zql/src/ivm/take.js.map +1 -1
  948. package/out/zql/src/ivm/union-fan-in.js +157 -231
  949. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  950. package/out/zql/src/ivm/union-fan-out.js +38 -43
  951. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  952. package/out/zql/src/ivm/view-apply-change.js +166 -255
  953. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  954. package/out/zql/src/mutate/crud.js +35 -34
  955. package/out/zql/src/mutate/crud.js.map +1 -1
  956. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  957. package/out/zql/src/mutate/custom.js +7 -11
  958. package/out/zql/src/mutate/custom.js.map +1 -1
  959. package/out/zql/src/mutate/mutator-registry.js +67 -71
  960. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  961. package/out/zql/src/mutate/mutator.js +26 -25
  962. package/out/zql/src/mutate/mutator.js.map +1 -1
  963. package/out/zql/src/planner/planner-builder.js +134 -239
  964. package/out/zql/src/planner/planner-builder.js.map +1 -1
  965. package/out/zql/src/planner/planner-connection.js +222 -212
  966. package/out/zql/src/planner/planner-connection.js.map +1 -1
  967. package/out/zql/src/planner/planner-constraint.js +15 -7
  968. package/out/zql/src/planner/planner-constraint.js.map +1 -1
  969. package/out/zql/src/planner/planner-debug.js +199 -224
  970. package/out/zql/src/planner/planner-debug.js.map +1 -1
  971. package/out/zql/src/planner/planner-fan-in.js +146 -162
  972. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  973. package/out/zql/src/planner/planner-fan-out.js +62 -74
  974. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  975. package/out/zql/src/planner/planner-graph.js +302 -334
  976. package/out/zql/src/planner/planner-graph.js.map +1 -1
  977. package/out/zql/src/planner/planner-join.js +255 -240
  978. package/out/zql/src/planner/planner-join.js.map +1 -1
  979. package/out/zql/src/planner/planner-node.js +10 -6
  980. package/out/zql/src/planner/planner-node.js.map +1 -1
  981. package/out/zql/src/planner/planner-source.js +15 -22
  982. package/out/zql/src/planner/planner-source.js.map +1 -1
  983. package/out/zql/src/planner/planner-terminus.js +28 -28
  984. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  985. package/out/zql/src/query/complete-ordering.js +37 -61
  986. package/out/zql/src/query/complete-ordering.js.map +1 -1
  987. package/out/zql/src/query/create-builder.js +14 -22
  988. package/out/zql/src/query/create-builder.js.map +1 -1
  989. package/out/zql/src/query/error.js +10 -12
  990. package/out/zql/src/query/error.js.map +1 -1
  991. package/out/zql/src/query/escape-like.js +6 -5
  992. package/out/zql/src/query/escape-like.js.map +1 -1
  993. package/out/zql/src/query/expression.js +138 -157
  994. package/out/zql/src/query/expression.js.map +1 -1
  995. package/out/zql/src/query/measure-push-operator.js +35 -38
  996. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  997. package/out/zql/src/query/metrics-delegate.js +7 -7
  998. package/out/zql/src/query/metrics-delegate.js.map +1 -1
  999. package/out/zql/src/query/named.js +52 -51
  1000. package/out/zql/src/query/named.js.map +1 -1
  1001. package/out/zql/src/query/query-delegate-base.js +190 -238
  1002. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  1003. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  1004. package/out/zql/src/query/query-impl.js +271 -405
  1005. package/out/zql/src/query/query-impl.js.map +1 -1
  1006. package/out/zql/src/query/query-internals.js +16 -8
  1007. package/out/zql/src/query/query-internals.js.map +1 -1
  1008. package/out/zql/src/query/query-registry.js +83 -98
  1009. package/out/zql/src/query/query-registry.js.map +1 -1
  1010. package/out/zql/src/query/query.d.ts.map +1 -1
  1011. package/out/zql/src/query/query.js +2 -0
  1012. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  1013. package/out/zql/src/query/runnable-query-impl.js +30 -55
  1014. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  1015. package/out/zql/src/query/static-query.js +7 -14
  1016. package/out/zql/src/query/static-query.js.map +1 -1
  1017. package/out/zql/src/query/ttl.js +45 -67
  1018. package/out/zql/src/query/ttl.js.map +1 -1
  1019. package/out/zql/src/query/validate-input.js +23 -20
  1020. package/out/zql/src/query/validate-input.js.map +1 -1
  1021. package/out/zqlite/src/database-storage.js +99 -103
  1022. package/out/zqlite/src/database-storage.js.map +1 -1
  1023. package/out/zqlite/src/db.js +206 -249
  1024. package/out/zqlite/src/db.js.map +1 -1
  1025. package/out/zqlite/src/explain-queries.js +11 -13
  1026. package/out/zqlite/src/explain-queries.js.map +1 -1
  1027. package/out/zqlite/src/internal/sql-inline.js +54 -37
  1028. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  1029. package/out/zqlite/src/internal/sql.js +17 -15
  1030. package/out/zqlite/src/internal/sql.js.map +1 -1
  1031. package/out/zqlite/src/internal/statement-cache.js +117 -92
  1032. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  1033. package/out/zqlite/src/mod.js +5 -0
  1034. package/out/zqlite/src/query-builder.js +81 -172
  1035. package/out/zqlite/src/query-builder.js.map +1 -1
  1036. package/out/zqlite/src/query-delegate.js +45 -55
  1037. package/out/zqlite/src/query-delegate.js.map +1 -1
  1038. package/out/zqlite/src/resolve-scalar-subqueries.js +134 -124
  1039. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  1040. package/out/zqlite/src/sqlite-cost-model.js +92 -97
  1041. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  1042. package/out/zqlite/src/sqlite-stat-fanout.js +304 -286
  1043. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  1044. package/out/zqlite/src/table-source.js +281 -455
  1045. package/out/zqlite/src/table-source.js.map +1 -1
  1046. package/package.json +8 -7
  1047. package/out/replicache/src/db/index-operation-enum.js +0 -7
  1048. package/out/replicache/src/db/index-operation-enum.js.map +0 -1
  1049. package/out/replicache/src/db/meta-type-enum.js +0 -7
  1050. package/out/replicache/src/db/meta-type-enum.js.map +0 -1
  1051. package/out/replicache/src/format-version-enum.js +0 -11
  1052. package/out/replicache/src/format-version-enum.js.map +0 -1
  1053. package/out/replicache/src/http-status-unauthorized.js +0 -5
  1054. package/out/replicache/src/http-status-unauthorized.js.map +0 -1
  1055. package/out/replicache/src/invoke-kind-enum.js +0 -7
  1056. package/out/replicache/src/invoke-kind-enum.js.map +0 -1
  1057. package/out/replicache/src/sync/handle-pull-response-result-type-enum.js +0 -9
  1058. package/out/replicache/src/sync/handle-pull-response-result-type-enum.js.map +0 -1
  1059. package/out/zero/package.json.js +0 -9
  1060. package/out/zero/package.json.js.map +0 -1
  1061. package/out/zero/src/adapters/drizzle.js.map +0 -1
  1062. package/out/zero/src/adapters/pg.js.map +0 -1
  1063. package/out/zero/src/adapters/postgresjs.js.map +0 -1
  1064. package/out/zero/src/adapters/prisma.js.map +0 -1
  1065. package/out/zero/src/analyze-query.js.map +0 -1
  1066. package/out/zero/src/ast-to-zql.js.map +0 -1
  1067. package/out/zero/src/bindings.js.map +0 -1
  1068. package/out/zero/src/change-protocol/v0.js.map +0 -1
  1069. package/out/zero/src/cli.js.map +0 -1
  1070. package/out/zero/src/deploy-permissions.js.map +0 -1
  1071. package/out/zero/src/expo-sqlite.js.map +0 -1
  1072. package/out/zero/src/op-sqlite.js.map +0 -1
  1073. package/out/zero/src/pg.js.map +0 -1
  1074. package/out/zero/src/react.js.map +0 -1
  1075. package/out/zero/src/server.js.map +0 -1
  1076. package/out/zero/src/solid.js.map +0 -1
  1077. package/out/zero/src/sqlite.js.map +0 -1
  1078. package/out/zero/src/transform-query.js.map +0 -1
  1079. package/out/zero/src/zero.js.map +0 -1
  1080. package/out/zero/src/zqlite.js.map +0 -1
  1081. package/out/zero-cache/src/db/postgres-replica-identity-enum.js +0 -11
  1082. package/out/zero-cache/src/db/postgres-replica-identity-enum.js.map +0 -1
  1083. package/out/zero-cache/src/db/postgres-type-class-enum.js +0 -17
  1084. package/out/zero-cache/src/db/postgres-type-class-enum.js.map +0 -1
  1085. package/out/zero-cache/src/services/change-streamer/error-type-enum.js +0 -9
  1086. package/out/zero-cache/src/services/change-streamer/error-type-enum.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"change-source.js","sources":["../../../../../../../zero-cache/src/services/change-source/pg/change-source.ts"],"sourcesContent":["import {\n PG_ADMIN_SHUTDOWN,\n PG_OBJECT_IN_USE,\n} from '@drdgvhbh/postgres-error-codes';\nimport type {LogContext} from '@rocicorp/logger';\nimport postgres from 'postgres';\nimport {AbortError} from '../../../../../shared/src/abort-error.ts';\nimport {stringify} from '../../../../../shared/src/bigint-json.ts';\nimport {deepEqual} from '../../../../../shared/src/json.ts';\nimport {must} from '../../../../../shared/src/must.ts';\nimport {mapValues} from '../../../../../shared/src/objects.ts';\nimport {promiseVoid} from '../../../../../shared/src/resolved-promises.ts';\nimport {\n equals,\n intersection,\n symmetricDifferences,\n} from '../../../../../shared/src/set-utils.ts';\nimport {sleep} from '../../../../../shared/src/sleep.ts';\nimport * as v from '../../../../../shared/src/valita.ts';\nimport {Database} from '../../../../../zqlite/src/db.ts';\nimport {\n mapPostgresToLiteColumn,\n UnsupportedColumnDefaultError,\n} from '../../../db/pg-to-lite.ts';\nimport {runTx} from '../../../db/run-transaction.ts';\nimport type {\n ColumnSpec,\n PublishedIndexSpec,\n PublishedTableSpec,\n} from '../../../db/specs.ts';\nimport {StatementRunner} from '../../../db/statements.ts';\nimport {type LexiVersion} from '../../../types/lexi-version.ts';\nimport {pgClient, type PostgresDB} from '../../../types/pg.ts';\nimport {\n upstreamSchema,\n type ShardConfig,\n type ShardID,\n} from '../../../types/shards.ts';\nimport {\n majorVersionFromString,\n majorVersionToString,\n} from '../../../types/state-version.ts';\nimport type {Sink} from '../../../types/streams.ts';\nimport {AutoResetSignal} from '../../change-streamer/schema/tables.ts';\nimport {\n getSubscriptionStateAndContext,\n type SubscriptionState,\n type SubscriptionStateAndContext,\n} from '../../replicator/schema/replication-state.ts';\nimport type {ChangeSource, ChangeStream} from '../change-source.ts';\nimport {BackfillManager} from '../common/backfill-manager.ts';\nimport {\n ChangeStreamMultiplexer,\n type Listener,\n} from '../common/change-stream-multiplexer.ts';\nimport {initReplica} from '../common/replica-schema.ts';\nimport type {BackfillRequest, JSONObject} from '../protocol/current.ts';\nimport type {\n ColumnAdd,\n Identifier,\n MessageRelation,\n SchemaChange,\n TableCreate,\n} from '../protocol/current/data.ts';\nimport type {\n ChangeStreamData,\n ChangeStreamMessage,\n Data,\n} from '../protocol/current/downstream.ts';\nimport type {ColumnMetadata, TableMetadata} from './backfill-metadata.ts';\nimport {streamBackfill} from './backfill-stream.ts';\nimport {\n initialSync,\n type InitialSyncOptions,\n type ServerContext,\n} from './initial-sync.ts';\nimport type {\n Message,\n MessageMessage,\n MessageRelation as PostgresRelation,\n} from './logical-replication/pgoutput.types.ts';\nimport {subscribe} from './logical-replication/stream.ts';\nimport {fromBigInt, toStateVersionString, type LSN} from './lsn.ts';\nimport {replicationEventSchema, type DdlUpdateEvent} from './schema/ddl.ts';\nimport {updateShardSchema} from './schema/init.ts';\nimport {\n getPublicationInfo,\n type PublishedSchema,\n type PublishedTableWithReplicaIdentity,\n} from './schema/published.ts';\nimport {\n dropShard,\n getInternalShardConfig,\n getReplicaAtVersion,\n internalPublicationPrefix,\n legacyReplicationSlot,\n replicaIdentitiesForTablesWithoutPrimaryKeys,\n replicationSlotExpression,\n type InternalShardConfig,\n type Replica,\n} from './schema/shard.ts';\nimport {validate} from './schema/validation.ts';\n\n/**\n * Initializes a Postgres change source, including the initial sync of the\n * replica, before streaming changes from the corresponding logical replication\n * stream.\n */\nexport async function initializePostgresChangeSource(\n lc: LogContext,\n upstreamURI: string,\n shard: ShardConfig,\n replicaDbFile: string,\n syncOptions: InitialSyncOptions,\n context: ServerContext,\n): Promise<{subscriptionState: SubscriptionState; changeSource: ChangeSource}> {\n await initReplica(\n lc,\n `replica-${shard.appID}-${shard.shardNum}`,\n replicaDbFile,\n (log, tx) => initialSync(log, shard, tx, upstreamURI, syncOptions, context),\n );\n\n const replica = new Database(lc, replicaDbFile);\n const subscriptionState = getSubscriptionStateAndContext(\n new StatementRunner(replica),\n );\n replica.close();\n\n // Check that upstream is properly setup, and throw an AutoReset to re-run\n // initial sync if not.\n const db = pgClient(lc, upstreamURI);\n try {\n const upstreamReplica = await checkAndUpdateUpstream(\n lc,\n db,\n shard,\n subscriptionState,\n );\n\n const changeSource = new PostgresChangeSource(\n lc,\n upstreamURI,\n shard,\n upstreamReplica,\n context,\n );\n\n return {subscriptionState, changeSource};\n } finally {\n await db.end();\n }\n}\n\nasync function checkAndUpdateUpstream(\n lc: LogContext,\n sql: PostgresDB,\n shard: ShardConfig,\n {\n replicaVersion,\n publications: subscribed,\n initialSyncContext,\n }: SubscriptionStateAndContext,\n) {\n // Perform any shard schema updates\n await updateShardSchema(lc, sql, shard, replicaVersion);\n\n const upstreamReplica = await getReplicaAtVersion(\n lc,\n sql,\n shard,\n replicaVersion,\n initialSyncContext,\n );\n if (!upstreamReplica) {\n throw new AutoResetSignal(\n `No replication slot for replica at version ${replicaVersion}`,\n );\n }\n\n // Verify that the publications match what is being replicated.\n const requested = [...shard.publications].sort();\n const replicated = upstreamReplica.publications\n .filter(p => !p.startsWith(internalPublicationPrefix(shard)))\n .sort();\n if (!deepEqual(requested, replicated)) {\n lc.warn?.(`Dropping shard to change publications to: [${requested}]`);\n await sql.unsafe(dropShard(shard.appID, shard.shardNum));\n throw new AutoResetSignal(\n `Requested publications [${requested}] do not match configured ` +\n `publications: [${replicated}]`,\n );\n }\n\n // Sanity check: The subscription state on the replica should have the\n // same publications. This should be guaranteed by the equivalence of the\n // replicaVersion, but it doesn't hurt to verify.\n if (!deepEqual(upstreamReplica.publications, subscribed)) {\n throw new AutoResetSignal(\n `Upstream publications [${upstreamReplica.publications}] do not ` +\n `match subscribed publications [${subscribed}]`,\n );\n }\n\n // Verify that the publications exist.\n const exists = await sql`\n SELECT pubname FROM pg_publication WHERE pubname IN ${sql(subscribed)};\n `.values();\n if (exists.length !== subscribed.length) {\n throw new AutoResetSignal(\n `Upstream publications [${exists.flat()}] do not contain ` +\n `all subscribed publications [${subscribed}]`,\n );\n }\n\n const {slot} = upstreamReplica;\n const result = await sql<\n {restartLSN: LSN | null; walStatus: string | null}[]\n > /*sql*/ `\n SELECT restart_lsn as \"restartLSN\", wal_status as \"walStatus\" FROM pg_replication_slots\n WHERE slot_name = ${slot}`;\n if (result.length === 0) {\n throw new AutoResetSignal(`replication slot ${slot} is missing`);\n }\n const [{restartLSN, walStatus}] = result;\n if (restartLSN === null || walStatus === 'lost') {\n throw new AutoResetSignal(\n `replication slot ${slot} has been invalidated for exceeding the max_slot_wal_keep_size`,\n );\n }\n return upstreamReplica;\n}\n\n// Parameterize this if necessary. In practice starvation may never happen.\nconst MAX_LOW_PRIORITY_DELAY_MS = 1000;\n\ntype ReservationState = {\n lastWatermark?: string;\n};\n\n/**\n * Postgres implementation of a {@link ChangeSource} backed by a logical\n * replication stream.\n */\nclass PostgresChangeSource implements ChangeSource {\n readonly #lc: LogContext;\n readonly #upstreamUri: string;\n readonly #shard: ShardID;\n readonly #replica: Replica;\n readonly #context: ServerContext;\n\n constructor(\n lc: LogContext,\n upstreamUri: string,\n shard: ShardID,\n replica: Replica,\n context: ServerContext,\n ) {\n this.#lc = lc.withContext('component', 'change-source');\n this.#upstreamUri = upstreamUri;\n this.#shard = shard;\n this.#replica = replica;\n this.#context = context;\n }\n\n async startStream(\n clientWatermark: string,\n backfillRequests: BackfillRequest[] = [],\n ): Promise<ChangeStream> {\n const db = pgClient(this.#lc, this.#upstreamUri);\n const {slot} = this.#replica;\n\n let cleanup = promiseVoid;\n try {\n ({cleanup} = await this.#stopExistingReplicationSlotSubscribers(\n db,\n slot,\n ));\n const config = await getInternalShardConfig(db, this.#shard);\n this.#lc.info?.(`starting replication stream@${slot}`);\n return await this.#startStream(\n db,\n slot,\n clientWatermark,\n config,\n backfillRequests,\n );\n } finally {\n void cleanup.then(() => db.end());\n }\n }\n\n async #startStream(\n db: PostgresDB,\n slot: string,\n clientWatermark: string,\n shardConfig: InternalShardConfig,\n backfillRequests: BackfillRequest[],\n ): Promise<ChangeStream> {\n const clientStart = majorVersionFromString(clientWatermark) + 1n;\n const {messages, acks} = await subscribe(\n this.#lc,\n db,\n slot,\n [...shardConfig.publications],\n clientStart,\n );\n const acker = new Acker(acks);\n\n // The ChangeStreamMultiplexer facilitates cooperative streaming from\n // the main replication stream and backfill streams initiated by the\n // BackfillManager.\n const changes = new ChangeStreamMultiplexer(this.#lc, clientWatermark);\n const backfillManager = new BackfillManager(this.#lc, changes, req =>\n streamBackfill(this.#lc, this.#upstreamUri, this.#replica, req),\n );\n changes\n .addProducers(messages, backfillManager)\n .addListeners(backfillManager, acker);\n backfillManager.run(clientWatermark, backfillRequests);\n\n const changeMaker = new ChangeMaker(\n this.#lc,\n this.#shard,\n shardConfig,\n this.#replica.initialSchema,\n this.#upstreamUri,\n );\n\n void (async () => {\n try {\n let reservation: ReservationState | null = null;\n let inTransaction = false;\n\n for await (const [lsn, msg] of messages) {\n // Note: no reservation is needed for pushStatus().\n if (msg.tag === 'keepalive') {\n changes.pushStatus([\n 'status',\n {ack: msg.shouldRespond},\n {watermark: majorVersionToString(lsn)},\n ]);\n\n // If we're not in a transaction but the last reservation was kept\n // because of pending keepalives in the queue, release the\n // reservation.\n if (!inTransaction && reservation?.lastWatermark) {\n changes.release(reservation.lastWatermark);\n reservation = null;\n }\n continue;\n }\n\n if (!reservation) {\n const res = changes.reserve('replication');\n typeof res === 'string' || (await res); // awaits should be uncommon\n reservation = {};\n }\n\n let lastChange: ChangeStreamMessage | undefined;\n for (const change of await changeMaker.makeChanges(lsn, msg)) {\n await changes.push(change); // Allow the change-streamer to push back.\n lastChange = change;\n }\n\n switch (lastChange?.[0]) {\n case 'begin':\n inTransaction = true;\n break;\n case 'commit':\n inTransaction = false;\n reservation.lastWatermark = lastChange[2].watermark;\n if (\n messages.queued === 0 ||\n changes.waiterDelay() > MAX_LOW_PRIORITY_DELAY_MS\n ) {\n // After each transaction, release the reservation:\n // - if there are no pending upstream messages\n // - or if a low priority request has been waiting for longer\n // than MAX_LOW_PRIORITY_DELAY_MS. This is to prevent\n // (backfill) starvation on very active upstreams.\n changes.release(reservation.lastWatermark);\n reservation = null;\n }\n break;\n }\n }\n } catch (e) {\n // Note: no need to worry about reservations here since downstream\n // is being completely canceled.\n const err = translateError(e);\n if (err instanceof ShutdownSignal) {\n // Log the new state of the replica to surface information about the\n // server that sent the shutdown signal, if any.\n await this.#logCurrentReplicaInfo();\n }\n changes.fail(err);\n }\n })();\n\n this.#lc.info?.(\n `started replication stream@${slot} from ${clientWatermark} (replicaVersion: ${\n this.#replica.version\n })`,\n );\n\n return {\n changes: changes.asSource(),\n acks: {push: status => acker.ack(status[2].watermark)},\n };\n }\n\n async #logCurrentReplicaInfo() {\n const db = pgClient(this.#lc, this.#upstreamUri);\n try {\n const replica = await getReplicaAtVersion(\n this.#lc,\n db,\n this.#shard,\n this.#replica.version,\n );\n if (replica) {\n this.#lc.info?.(\n `Shutdown signal from replica@${this.#replica.version}: ${stringify(replica.subscriberContext)}`,\n );\n }\n } catch (e) {\n this.#lc.warn?.(`error logging replica info`, e);\n } finally {\n await db.end();\n }\n }\n\n /**\n * Stops replication slots associated with this shard, and returns\n * a `cleanup` task that drops any slot other than the specified\n * `slotToKeep`.\n *\n * Note that replication slots created after `slotToKeep` (as indicated by\n * the timestamp suffix) are preserved, as those are newly syncing replicas\n * that will soon take over the slot.\n */\n async #stopExistingReplicationSlotSubscribers(\n db: PostgresDB,\n slotToKeep: string,\n ): Promise<{cleanup: Promise<void>}> {\n const slotExpression = replicationSlotExpression(this.#shard);\n const legacySlotName = legacyReplicationSlot(this.#shard);\n\n const result = await runTx(db, async sql => {\n // Note: `slot_name <= slotToKeep` uses a string compare of the millisecond\n // timestamp, which works until it exceeds 13 digits (sometime in 2286).\n const result = await sql<\n {slot: string; pid: string | null; terminated: boolean | null}[]\n > /*sql*/ `\n SELECT slot_name as slot, pg_terminate_backend(active_pid) as terminated, active_pid as pid\n FROM pg_replication_slots \n WHERE (slot_name LIKE ${slotExpression} OR slot_name = ${legacySlotName})\n AND slot_name <= ${slotToKeep}`;\n this.#lc.info?.(\n `terminated replication slots: ${JSON.stringify(result)}`,\n );\n const replicasTable = `${upstreamSchema(this.#shard)}.replicas`;\n const replicasBefore = await sql`\n SELECT slot, version, \"initialSyncContext\", \"subscriberContext\" \n FROM ${sql(replicasTable)} ORDER BY slot`;\n\n if (result.length === 0) {\n const shardSlots = await sql`\n SELECT slot_name as slot, active, active_pid as pid\n FROM pg_replication_slots\n WHERE slot_name LIKE ${slotExpression} OR slot_name = ${legacySlotName}\n ORDER BY slot_name`;\n this.#lc.warn?.(\n `slot ${slotToKeep} not found while cleaning subscribers`,\n {slots: shardSlots, replicas: replicasBefore},\n );\n throw new AbortError(\n `replication slot ${slotToKeep} is missing. A different ` +\n `replication-manager should now be running on a new ` +\n `replication slot.`,\n );\n }\n // Clear the state of the older replicas.\n this.#lc.info?.(\n `replicas before cleanup (slotToKeep=${slotToKeep}): ${JSON.stringify(\n replicasBefore,\n )}`,\n );\n await sql`\n DELETE FROM ${sql(replicasTable)} WHERE slot < ${slotToKeep}`;\n await sql`\n UPDATE ${sql(replicasTable)} \n SET \"subscriberContext\" = ${this.#context}\n WHERE slot = ${slotToKeep}`;\n const replicasAfter = await sql<{slot: string; version: string}[]>`\n SELECT slot, version FROM ${sql(replicasTable)} ORDER BY slot`;\n this.#lc.info?.(\n `replicas after cleanup (slotToKeep=${slotToKeep}): ${JSON.stringify(\n replicasAfter,\n )}`,\n );\n return result;\n });\n\n const pids = result.filter(({pid}) => pid !== null).map(({pid}) => pid);\n if (pids.length) {\n this.#lc.info?.(`signaled subscriber ${pids} to shut down`);\n }\n const otherSlots = result\n .filter(({slot}) => slot !== slotToKeep)\n .map(({slot}) => slot);\n return {\n cleanup: otherSlots.length\n ? this.#dropReplicationSlots(db, otherSlots)\n : promiseVoid,\n };\n }\n\n async #dropReplicationSlots(sql: PostgresDB, slots: string[]) {\n this.#lc.info?.(`dropping other replication slot(s) ${slots}`);\n for (let i = 0; i < 5; i++) {\n try {\n await sql`\n SELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots\n WHERE slot_name IN ${sql(slots)}\n `;\n this.#lc.info?.(`successfully dropped ${slots}`);\n return;\n } catch (e) {\n // error: replication slot \"zero_slot_change_source_test_id\" is active for PID 268\n if (\n e instanceof postgres.PostgresError &&\n e.code === PG_OBJECT_IN_USE\n ) {\n // The freeing up of the replication slot is not transactional;\n // sometimes it takes time for Postgres to consider the slot\n // inactive.\n this.#lc.debug?.(`attempt ${i + 1}: ${String(e)}`, e);\n } else {\n this.#lc.warn?.(`error dropping ${slots}`, e);\n }\n await sleep(1000);\n }\n }\n this.#lc.warn?.(`maximum attempts exceeded dropping ${slots}`);\n }\n}\n\n// Exported for testing.\nexport class Acker implements Listener {\n #acks: Sink<bigint>;\n #waitingForDownstreamAck: string | null = null;\n\n constructor(acks: Sink<bigint>) {\n this.#acks = acks;\n }\n\n onChange(change: ChangeStreamMessage): void {\n switch (change[0]) {\n case 'status':\n const {watermark} = change[2];\n if (change[1].ack) {\n this.#expectDownstreamAck(watermark);\n } else {\n // Keepalives with shouldRespond = false are sent to Listeners,\n // but for efficiency they are not sent downstream to the\n // change-streamer. Ack them here if the change-streamer is caught\n // up. This updates the replication slot's `confirmed_flush_lsn`\n // more quickly (rather than waiting for the periodic shouldRespond),\n // which is useful for monitoring replication slot lag.\n this.#ackIfDownstreamIsCaughtUp(watermark);\n }\n break;\n case 'begin':\n // Mark the commit watermark as being expected so that any intermediate\n // shouldRespond=false watermarks, which will be at the\n // commitWatermark, are *not* acked, as the ack must come from\n // change-streamer after it commits the transaction.\n if (!change[1].skipAck) {\n this.#expectDownstreamAck(change[2].commitWatermark);\n }\n break;\n }\n }\n\n #expectDownstreamAck(watermark: string) {\n this.#waitingForDownstreamAck = watermark;\n }\n\n ack(watermark: LexiVersion) {\n if (\n this.#waitingForDownstreamAck &&\n this.#waitingForDownstreamAck <= watermark\n ) {\n this.#waitingForDownstreamAck = null;\n }\n this.#sendAck(watermark);\n }\n\n #ackIfDownstreamIsCaughtUp(watermark: string) {\n if (this.#waitingForDownstreamAck === null) {\n this.#sendAck(watermark);\n }\n }\n\n #sendAck(watermark: LexiVersion) {\n const lsn = majorVersionFromString(watermark);\n this.#acks.push(lsn);\n }\n}\n\ntype ReplicationError = {\n lsn: bigint;\n msg: Message;\n err: unknown;\n lastLogTime: number;\n};\n\nconst SET_REPLICA_IDENTITY_DELAY_MS = 50;\n\nclass ChangeMaker {\n readonly #lc: LogContext;\n readonly #shardPrefix: string;\n readonly #shardConfig: InternalShardConfig;\n readonly #initialSchema: PublishedSchema;\n readonly #upstreamDB: PostgresDB;\n\n #replicaIdentityTimer: NodeJS.Timeout | undefined;\n #error: ReplicationError | undefined;\n\n constructor(\n lc: LogContext,\n {appID, shardNum}: ShardID,\n shardConfig: InternalShardConfig,\n initialSchema: PublishedSchema,\n upstreamURI: string,\n ) {\n this.#lc = lc;\n // Note: This matches the prefix used in pg_logical_emit_message() in pg/schema/ddl.ts.\n this.#shardPrefix = `${appID}/${shardNum}`;\n this.#shardConfig = shardConfig;\n this.#initialSchema = initialSchema;\n this.#upstreamDB = pgClient(lc, upstreamURI, {\n ['idle_timeout']: 10, // only used occasionally\n connection: {['application_name']: 'zero-schema-change-detector'},\n });\n }\n\n async makeChanges(lsn: bigint, msg: Message): Promise<ChangeStreamMessage[]> {\n if (this.#error) {\n this.#logError(this.#error);\n return [];\n }\n try {\n return await this.#makeChanges(msg);\n } catch (err) {\n this.#error = {lsn, msg, err, lastLogTime: 0};\n this.#logError(this.#error);\n\n const message = `Unable to continue replication from LSN ${fromBigInt(lsn)}`;\n const errorDetails: JSONObject = {error: message};\n if (err instanceof UnsupportedSchemaChangeError) {\n errorDetails.reason = err.description;\n errorDetails.context = err.ddlUpdate.context;\n } else {\n errorDetails.reason = String(err);\n }\n\n // Rollback the current transaction to avoid dangling transactions in\n // downstream processors (i.e. changeLog, replicator).\n return [\n ['rollback', {tag: 'rollback'}],\n ['control', {tag: 'reset-required', message, errorDetails}],\n ];\n }\n }\n\n #logError(error: ReplicationError) {\n const {lsn, msg, err, lastLogTime} = error;\n const now = Date.now();\n\n // Output an error to logs as replication messages continue to be dropped,\n // at most once a minute.\n if (now - lastLogTime > 60_000) {\n this.#lc.error?.(\n `Unable to continue replication from LSN ${fromBigInt(lsn)}: ${String(\n err,\n )}`,\n err instanceof UnsupportedSchemaChangeError\n ? err.ddlUpdate.context\n : // 'content' can be a large byte Buffer. Exclude it from logging output.\n {...msg, content: undefined},\n );\n error.lastLogTime = now;\n }\n }\n\n // oxlint-disable-next-line require-await\n async #makeChanges(msg: Message): Promise<ChangeStreamData[]> {\n switch (msg.tag) {\n case 'begin':\n return [\n [\n 'begin',\n {...msg, json: 's'},\n {commitWatermark: toStateVersionString(must(msg.commitLsn))},\n ],\n ];\n\n case 'delete': {\n if (!(msg.key ?? msg.old)) {\n throw new Error(\n `Invalid DELETE msg (missing key): ${stringify(msg)}`,\n );\n }\n return [\n [\n 'data',\n {\n ...msg,\n relation: makeRelation(msg.relation),\n // https://www.postgresql.org/docs/current/protocol-logicalrep-message-formats.html#PROTOCOL-LOGICALREP-MESSAGE-FORMATS-DELETE\n key: must(msg.old ?? msg.key),\n },\n ],\n ];\n }\n\n case 'update': {\n return [\n [\n 'data',\n {\n ...msg,\n relation: makeRelation(msg.relation),\n // https://www.postgresql.org/docs/current/protocol-logicalrep-message-formats.html#PROTOCOL-LOGICALREP-MESSAGE-FORMATS-UPDATE\n key: msg.old ?? msg.key,\n },\n ],\n ];\n }\n\n case 'insert':\n return [['data', {...msg, relation: makeRelation(msg.relation)}]];\n case 'truncate':\n return [['data', {...msg, relations: msg.relations.map(makeRelation)}]];\n\n case 'message':\n if (msg.prefix !== this.#shardPrefix) {\n this.#lc.debug?.('ignoring message for different shard', msg.prefix);\n return [];\n }\n return this.#handleCustomMessage(msg);\n\n case 'commit':\n return [\n [\n 'commit',\n msg,\n {watermark: toStateVersionString(must(msg.commitLsn))},\n ],\n ];\n\n case 'relation':\n return this.#handleRelation(msg);\n case 'type':\n return []; // Nothing need be done for custom types.\n case 'origin':\n // No need to detect replication loops since we are not a\n // PG replication source.\n return [];\n default:\n msg satisfies never;\n throw new Error(`Unexpected message type ${stringify(msg)}`);\n }\n }\n\n #preSchema: PublishedSchema | undefined;\n\n #handleCustomMessage(msg: MessageMessage) {\n const event = this.#parseReplicationEvent(msg.content);\n // Cancel manual schema adjustment timeouts when an upstream schema change\n // is about to happen, so as to avoid interfering / redundant work.\n clearTimeout(this.#replicaIdentityTimer);\n\n if (event.type === 'ddlStart') {\n // Store the schema in order to diff it with a potential ddlUpdate.\n this.#preSchema = event.schema;\n return [];\n }\n // ddlUpdate\n const changes = this.#makeSchemaChanges(\n must(this.#preSchema, `ddlUpdate received without a ddlStart`),\n event,\n ).map(change => ['data', change] satisfies Data);\n\n this.#lc\n .withContext('tag', event.event.tag)\n .withContext('query', event.context.query)\n .info?.(`${changes.length} schema change(s)`, {changes});\n\n const replicaIdentities = replicaIdentitiesForTablesWithoutPrimaryKeys(\n event.schema,\n );\n if (replicaIdentities) {\n this.#replicaIdentityTimer = setTimeout(async () => {\n try {\n await replicaIdentities.apply(this.#lc, this.#upstreamDB);\n } catch (err) {\n this.#lc.warn?.(`error setting replica identities`, err);\n }\n }, SET_REPLICA_IDENTITY_DELAY_MS);\n }\n\n return changes;\n }\n\n /**\n * A note on operation order:\n *\n * Postgres will drop related indexes when columns are dropped,\n * but SQLite will error instead (https://sqlite.org/forum/forumpost/2e62dba69f?t=c&hist).\n * The current workaround is to drop indexes first.\n *\n * Also note that although it should not be possible to both rename and\n * add/drop tables/columns in a single statement, the operations are\n * ordered to handle that possibility, by always dropping old entities,\n * then modifying kept entities, and then adding new entities.\n *\n * Thus, the order of replicating DDL updates is:\n * - drop indexes\n * - drop tables\n * - alter tables\n * - drop columns\n * - alter columns\n * - add columns\n * - create tables\n * - create indexes\n *\n * In the future the replication logic should be improved to handle this\n * behavior in SQLite by dropping dependent indexes manually before dropping\n * columns. This, for example, would be needed to properly support changing\n * the type of a column that's indexed.\n */\n #makeSchemaChanges(\n preSchema: PublishedSchema,\n update: DdlUpdateEvent,\n ): SchemaChange[] {\n try {\n const [prevTbl, prevIdx] = specsByID(preSchema);\n const [nextTbl, nextIdx] = specsByID(update.schema);\n const changes: SchemaChange[] = [];\n\n // Validate the new table schemas\n for (const table of nextTbl.values()) {\n validate(this.#lc, table);\n }\n\n const [droppedIdx, createdIdx] = symmetricDifferences(prevIdx, nextIdx);\n\n // Detect modified indexes (same name, different definition).\n // This happens when a constraint is dropped and recreated with the\n // same name in a single ALTER TABLE statement.\n // Note: We compare using stable column attnums rather than names,\n // because table/column renames change the index spec cosmetically\n // (tableName, column keys) without the index actually being recreated.\n const keptIdx = intersection(prevIdx, nextIdx);\n for (const id of keptIdx) {\n if (\n isIndexStructurallyChanged(\n must(prevIdx.get(id)),\n must(nextIdx.get(id)),\n prevTbl,\n nextTbl,\n )\n ) {\n droppedIdx.add(id);\n createdIdx.add(id);\n }\n }\n\n for (const id of droppedIdx) {\n const {schema, name} = must(prevIdx.get(id));\n changes.push({tag: 'drop-index', id: {schema, name}});\n }\n\n // DROP\n const [droppedTbl, createdTbl] = symmetricDifferences(prevTbl, nextTbl);\n for (const id of droppedTbl) {\n const {schema, name} = must(prevTbl.get(id));\n changes.push({tag: 'drop-table', id: {schema, name}});\n }\n // ALTER TABLE | ALTER PUBLICATION\n const tables = intersection(prevTbl, nextTbl);\n for (const id of tables) {\n changes.push(\n ...this.#getTableChanges(\n must(prevTbl.get(id)),\n must(nextTbl.get(id)),\n update.event.tag,\n ),\n );\n }\n // CREATE\n for (const id of createdTbl) {\n const spec = must(nextTbl.get(id));\n const createTable: TableCreate = {\n tag: 'create-table',\n spec,\n metadata: getMetadata(spec),\n };\n if (!update.event.tag.startsWith('CREATE')) {\n // Tables introduced to the publication via ALTER statements\n // must be backfilled.\n createTable.backfill = mapValues(spec.columns, ({pos: attNum}) => ({\n attNum,\n })) satisfies Record<string, ColumnMetadata>;\n }\n changes.push(createTable);\n }\n\n // Add indexes last since they may reference tables / columns that need\n // to be created first.\n for (const id of createdIdx) {\n const spec = must(nextIdx.get(id));\n changes.push({tag: 'create-index', spec});\n }\n return changes;\n } catch (e) {\n throw new UnsupportedSchemaChangeError(String(e), update, {cause: e});\n }\n }\n\n #getTableChanges(\n oldTable: PublishedTableWithReplicaIdentity,\n newTable: PublishedTableWithReplicaIdentity,\n ddlTag: string,\n ): SchemaChange[] {\n const changes: SchemaChange[] = [];\n if (\n oldTable.schema !== newTable.schema ||\n oldTable.name !== newTable.name\n ) {\n changes.push({\n tag: 'rename-table',\n old: {schema: oldTable.schema, name: oldTable.name},\n new: {schema: newTable.schema, name: newTable.name},\n });\n }\n const oldMetadata = getMetadata(oldTable);\n const newMetadata = getMetadata(newTable);\n if (!deepEqual(oldMetadata, newMetadata)) {\n changes.push({\n tag: 'update-table-metadata',\n table: {schema: newTable.schema, name: newTable.name},\n old: oldMetadata,\n new: newMetadata,\n });\n }\n const table = {schema: newTable.schema, name: newTable.name};\n const oldColumns = columnsByID(oldTable.columns);\n const newColumns = columnsByID(newTable.columns);\n\n // DROP\n const [dropped, added] = symmetricDifferences(oldColumns, newColumns);\n for (const id of dropped) {\n const {name: column} = must(oldColumns.get(id));\n changes.push({tag: 'drop-column', table, column});\n }\n\n // ALTER\n const both = intersection(oldColumns, newColumns);\n for (const id of both) {\n const {name: oldName, ...oldSpec} = must(oldColumns.get(id));\n const {name: newName, ...newSpec} = must(newColumns.get(id));\n // The three things that we care about are:\n // 1. name\n // 2. type\n // 3. not-null\n if (\n oldName !== newName ||\n oldSpec.dataType !== newSpec.dataType ||\n oldSpec.notNull !== newSpec.notNull\n ) {\n changes.push({\n tag: 'update-column',\n table,\n old: {name: oldName, spec: oldSpec},\n new: {name: newName, spec: newSpec},\n });\n }\n }\n\n // All columns introduced by a publication change require backfill.\n // Columns created by ALTER TABLE, on the other hand, only require\n // backfill if they have non-constant defaults.\n const alwaysBackfill = ddlTag === 'ALTER PUBLICATION';\n\n // ADD\n for (const id of added) {\n const {name, ...spec} = must(newColumns.get(id));\n const column = {name, spec};\n const addColumn: ColumnAdd = {\n tag: 'add-column',\n table,\n column,\n tableMetadata: getMetadata(newTable),\n };\n if (alwaysBackfill) {\n addColumn.column.spec.dflt = null;\n addColumn.backfill = {attNum: spec.pos} satisfies ColumnMetadata;\n } else {\n // Determine if the ChangeProcessor will accept the column add as is.\n try {\n mapPostgresToLiteColumn(table.name, column);\n } catch (e) {\n if (!(e instanceof UnsupportedColumnDefaultError)) {\n // Note: mapPostgresToLiteColumn is not expected to throw any other\n // types of errors.\n throw e;\n }\n // If the column has an unsupported default (e.g. an expression or a\n // generated value), create the column as initially hidden with a\n // `null` default, and publish it after backfilling the values from\n // upstream. Note that this does require that the table have a valid\n // REPLICA IDENTITY, since backfill relies on merging new data with\n // an existing row.\n this.#lc.info?.(\n `Backfilling column ${table.name}.${name}: ${String(e)}`,\n );\n addColumn.column.spec.dflt = null;\n addColumn.backfill = {attNum: spec.pos} satisfies ColumnMetadata;\n }\n }\n changes.push(addColumn);\n }\n return changes;\n }\n\n #parseReplicationEvent(content: Uint8Array) {\n const str =\n content instanceof Buffer\n ? content.toString('utf-8')\n : new TextDecoder().decode(content);\n const json = JSON.parse(str);\n return v.parse(json, replicationEventSchema, 'passthrough');\n }\n\n /**\n * If `ddlDetection === true`, relation messages are irrelevant,\n * as schema changes are detected by event triggers that\n * emit custom messages.\n *\n * For degraded-mode replication (`ddlDetection === false`):\n * 1. query the current published schemas on upstream\n * 2. compare that with the InternalShardConfig.initialSchema\n * 3. compare that with the incoming MessageRelation\n * 4. On any discrepancy, throw an UnsupportedSchemaChangeError\n * to halt replication.\n *\n * Note that schemas queried in step [1] will be *post-transaction*\n * schemas, which are not necessarily suitable for actually processing\n * the statements in the transaction being replicated. In other words,\n * this mechanism cannot be used to reliably *replicate* schema changes.\n * However, they serve the purpose determining if schemas have changed.\n */\n async #handleRelation(rel: PostgresRelation): Promise<ChangeStreamData[]> {\n const {publications, ddlDetection} = this.#shardConfig;\n if (ddlDetection) {\n return [];\n }\n const currentSchema = await getPublicationInfo(\n this.#upstreamDB,\n publications,\n );\n const difference = getSchemaDifference(this.#initialSchema, currentSchema);\n if (difference !== null) {\n throw new MissingEventTriggerSupport(difference);\n }\n // Even if the currentSchema is equal to the initialSchema, the\n // MessageRelation itself must be checked to detect transient\n // schema changes within the transaction (e.g. adding and dropping\n // a table, or renaming a column and then renaming it back).\n const orel = this.#initialSchema.tables.find(\n t => t.oid === rel.relationOid,\n );\n if (!orel) {\n // Can happen if a table is created and then dropped in the same transaction.\n throw new MissingEventTriggerSupport(\n `relation not in initialSchema: ${stringify(rel)}`,\n );\n }\n if (relationDifferent(orel, rel)) {\n throw new MissingEventTriggerSupport(\n `relation has changed within the transaction: ${stringify(orel)} vs ${stringify(rel)}`,\n );\n }\n return [];\n }\n}\n\nfunction getSchemaDifference(\n a: PublishedSchema,\n b: PublishedSchema,\n): string | null {\n // Note: ignore indexes since changes need not to halt replication\n if (a.tables.length !== b.tables.length) {\n return `tables created or dropped`;\n }\n for (let i = 0; i < a.tables.length; i++) {\n const at = a.tables[i];\n const bt = b.tables[i];\n const difference = getTableDifference(at, bt);\n if (difference) {\n return difference;\n }\n }\n return null;\n}\n\n// ColumnSpec comparator\nconst byColumnPos = (a: [string, ColumnSpec], b: [string, ColumnSpec]) =>\n a[1].pos < b[1].pos ? -1 : a[1].pos > b[1].pos ? 1 : 0;\n\nfunction getTableDifference(\n a: PublishedTableSpec,\n b: PublishedTableSpec,\n): string | null {\n if (a.oid !== b.oid || a.schema !== b.schema || a.name !== b.name) {\n return `Table \"${a.name}\" differs from table \"${b.name}\"`;\n }\n if (!deepEqual(a.primaryKey, b.primaryKey)) {\n return `Primary key of table \"${a.name}\" has changed`;\n }\n const acols = Object.entries(a.columns).sort(byColumnPos);\n const bcols = Object.entries(b.columns).sort(byColumnPos);\n if (\n acols.length !== bcols.length ||\n acols.some(([aname, acol], i) => {\n const [bname, bcol] = bcols[i];\n return (\n aname !== bname ||\n acol.pos !== bcol.pos ||\n acol.typeOID !== bcol.typeOID ||\n acol.notNull !== bcol.notNull\n );\n })\n ) {\n return `Columns of table \"${a.name}\" have changed`;\n }\n return null;\n}\n\nexport function relationDifferent(a: PublishedTableSpec, b: PostgresRelation) {\n if (a.oid !== b.relationOid || a.schema !== b.schema || a.name !== b.name) {\n return true;\n }\n if (\n // The MessageRelation's `keyColumns` field contains the columns in column\n // declaration order, whereas the PublishedTableSpec's `primaryKey`\n // contains the columns in primary key (i.e. index) order. Do an\n // order-agnostic compare here since it is not possible to detect\n // key-order changes from the MessageRelation message alone.\n b.replicaIdentity === 'default' &&\n !equals(new Set(a.primaryKey), new Set(b.keyColumns))\n ) {\n return true;\n }\n const acols = Object.entries(a.columns).sort(byColumnPos);\n const bcols = b.columns;\n return (\n acols.length !== bcols.length ||\n acols.some(([aname, acol], i) => {\n const bcol = bcols[i];\n return aname !== bcol.name || acol.typeOID !== bcol.typeOid;\n })\n );\n}\n\nfunction translateError(e: unknown): Error {\n if (!(e instanceof Error)) {\n return new Error(String(e));\n }\n if (e instanceof postgres.PostgresError && e.code === PG_ADMIN_SHUTDOWN) {\n return new ShutdownSignal(e);\n }\n return e;\n}\nconst idString = (id: Identifier) => `${id.schema}.${id.name}`;\n\nfunction specsByID(published: PublishedSchema) {\n return [\n // It would have been nice to use a CustomKeyMap here, but we rely on set-utils\n // operations which use plain Sets.\n new Map(published.tables.map(t => [t.oid, t])),\n new Map(published.indexes.map(i => [idString(i), i])),\n ] as const;\n}\n\n/**\n * Determines if an index was structurally changed (e.g. constraint dropped\n * and recreated with different columns) vs cosmetically changed (e.g. the\n * index spec changed because the table or a column was renamed).\n *\n * Compares boolean properties directly and resolves column names to their\n * stable attnums (pg_attribute `attnum`) for the column comparison.\n */\nfunction isIndexStructurallyChanged(\n prev: PublishedIndexSpec,\n next: PublishedIndexSpec,\n prevTables: Map<number, PublishedTableWithReplicaIdentity>,\n nextTables: Map<number, PublishedTableWithReplicaIdentity>,\n): boolean {\n if (\n prev.unique !== next.unique ||\n prev.isPrimaryKey !== next.isPrimaryKey ||\n prev.isReplicaIdentity !== next.isReplicaIdentity ||\n prev.isImmediate !== next.isImmediate\n ) {\n return true;\n }\n\n const prevTable = findTableBySchemaAndName(\n prevTables,\n prev.schema,\n prev.tableName,\n );\n const nextTable = findTableBySchemaAndName(\n nextTables,\n next.schema,\n next.tableName,\n );\n if (!prevTable || !nextTable) {\n // Can't resolve tables; conservatively treat as changed.\n return true;\n }\n\n const prevEntries = Object.entries(prev.columns);\n const nextEntries = Object.entries(next.columns);\n if (prevEntries.length !== nextEntries.length) {\n return true;\n }\n\n // Resolve column names → attnums and compare.\n const prevByAttnum = new Map<number | undefined, string>(\n prevEntries.map(([name, dir]) => [prevTable.columns[name]?.pos, dir]),\n );\n const nextByAttnum = new Map<number | undefined, string>(\n nextEntries.map(([name, dir]) => [nextTable.columns[name]?.pos, dir]),\n );\n\n if (prevByAttnum.has(undefined) || nextByAttnum.has(undefined)) {\n // Column not found in table spec; conservatively treat as changed.\n return true;\n }\n if (prevByAttnum.size !== nextByAttnum.size) {\n return true;\n }\n for (const [attnum, dir] of prevByAttnum) {\n if (nextByAttnum.get(attnum) !== dir) {\n return true;\n }\n }\n return false;\n}\n\nfunction findTableBySchemaAndName(\n tables: Map<number, PublishedTableWithReplicaIdentity>,\n schema: string,\n name: string,\n): PublishedTableWithReplicaIdentity | undefined {\n for (const table of tables.values()) {\n if (table.schema === schema && table.name === name) {\n return table;\n }\n }\n return undefined;\n}\n\nfunction columnsByID(\n columns: Record<string, ColumnSpec>,\n): Map<number, ColumnSpec & {name: string}> {\n const colsByID = new Map<number, ColumnSpec & {name: string}>();\n for (const [name, spec] of Object.entries(columns)) {\n // The `pos` field is the `attnum` in `pg_attribute`, which is a stable\n // identifier for the column in this table (i.e. never reused).\n colsByID.set(spec.pos, {...spec, name});\n }\n return colsByID;\n}\n\nfunction getMetadata(table: PublishedTableWithReplicaIdentity): TableMetadata {\n return {\n schemaOID: must(table.schemaOID),\n relationOID: table.oid,\n rowKey: Object.fromEntries(\n table.replicaIdentityColumns.map(k => [\n k,\n {attNum: table.columns[k].pos},\n ]),\n ),\n };\n}\n\n// Avoid sending the `columns` from the Postgres MessageRelation message.\n// They are not used downstream and the message can be large.\nfunction makeRelation(relation: PostgresRelation): MessageRelation {\n // Avoid sending the `columns` from the Postgres MessageRelation message.\n // They are not used downstream and the message can be large.\n const {columns: _, keyColumns, replicaIdentity, ...rest} = relation;\n return {\n ...rest,\n rowKey: {\n columns: keyColumns,\n type: replicaIdentity,\n },\n // For now, deprecated columns are sent for backwards compatibility.\n // These can be removed when bumping the MIN_PROTOCOL_VERSION to 5.\n keyColumns,\n replicaIdentity,\n };\n}\n\nclass UnsupportedSchemaChangeError extends Error {\n readonly name = 'UnsupportedSchemaChangeError';\n readonly description: string;\n readonly ddlUpdate: DdlUpdateEvent;\n\n constructor(\n description: string,\n ddlUpdate: DdlUpdateEvent,\n options?: ErrorOptions,\n ) {\n super(\n `Replication halted. Resync the replica to recover: ${description}`,\n options,\n );\n this.description = description;\n this.ddlUpdate = ddlUpdate;\n }\n}\n\nclass MissingEventTriggerSupport extends Error {\n readonly name = 'MissingEventTriggerSupport';\n\n constructor(msg: string) {\n super(\n `${msg}. Schema changes cannot be reliably replicated without event trigger support.`,\n );\n }\n}\n\n// TODO(0xcadams): should this be a ProtocolError?\nclass ShutdownSignal extends AbortError {\n readonly name = 'ShutdownSignal';\n\n constructor(cause: unknown) {\n super(\n 'shutdown signal received (e.g. another zero-cache taking over the replication stream)',\n {\n cause,\n },\n );\n }\n}\n"],"names":["result","v.parse"],"mappings":"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"}
1
+ {"version":3,"file":"change-source.js","names":["#lc","#upstreamUri","#shard","#replica","#context","#stopExistingReplicationSlotSubscribers","#startStream","#logCurrentReplicaInfo","#dropReplicationSlots","#acks","#expectDownstreamAck","#ackIfDownstreamIsCaughtUp","#waitingForDownstreamAck","#sendAck","#shardPrefix","#shardConfig","#initialSchema","#upstreamDB","#error","#logError","#makeChanges","#handleCustomMessage","#handleRelation","#parseReplicationEvent","#replicaIdentityTimer","#preSchema","#makeSchemaChanges","#getTableChanges"],"sources":["../../../../../../../zero-cache/src/services/change-source/pg/change-source.ts"],"sourcesContent":["import {\n PG_ADMIN_SHUTDOWN,\n PG_OBJECT_IN_USE,\n} from '@drdgvhbh/postgres-error-codes';\nimport type {LogContext} from '@rocicorp/logger';\nimport postgres from 'postgres';\nimport {AbortError} from '../../../../../shared/src/abort-error.ts';\nimport {stringify} from '../../../../../shared/src/bigint-json.ts';\nimport {deepEqual} from '../../../../../shared/src/json.ts';\nimport {must} from '../../../../../shared/src/must.ts';\nimport {mapValues} from '../../../../../shared/src/objects.ts';\nimport {promiseVoid} from '../../../../../shared/src/resolved-promises.ts';\nimport {\n equals,\n intersection,\n symmetricDifferences,\n} from '../../../../../shared/src/set-utils.ts';\nimport {sleep} from '../../../../../shared/src/sleep.ts';\nimport * as v from '../../../../../shared/src/valita.ts';\nimport {Database} from '../../../../../zqlite/src/db.ts';\nimport {\n mapPostgresToLiteColumn,\n UnsupportedColumnDefaultError,\n} from '../../../db/pg-to-lite.ts';\nimport {runTx} from '../../../db/run-transaction.ts';\nimport type {\n ColumnSpec,\n PublishedIndexSpec,\n PublishedTableSpec,\n} from '../../../db/specs.ts';\nimport {StatementRunner} from '../../../db/statements.ts';\nimport {type LexiVersion} from '../../../types/lexi-version.ts';\nimport {pgClient, type PostgresDB} from '../../../types/pg.ts';\nimport {\n upstreamSchema,\n type ShardConfig,\n type ShardID,\n} from '../../../types/shards.ts';\nimport {\n majorVersionFromString,\n majorVersionToString,\n} from '../../../types/state-version.ts';\nimport type {Sink} from '../../../types/streams.ts';\nimport {AutoResetSignal} from '../../change-streamer/schema/tables.ts';\nimport {\n getSubscriptionStateAndContext,\n type SubscriptionState,\n type SubscriptionStateAndContext,\n} from '../../replicator/schema/replication-state.ts';\nimport type {ChangeSource, ChangeStream} from '../change-source.ts';\nimport {BackfillManager} from '../common/backfill-manager.ts';\nimport {\n ChangeStreamMultiplexer,\n type Listener,\n} from '../common/change-stream-multiplexer.ts';\nimport {initReplica} from '../common/replica-schema.ts';\nimport type {BackfillRequest, JSONObject} from '../protocol/current.ts';\nimport type {\n ColumnAdd,\n Identifier,\n MessageRelation,\n SchemaChange,\n TableCreate,\n} from '../protocol/current/data.ts';\nimport type {\n ChangeStreamData,\n ChangeStreamMessage,\n Data,\n} from '../protocol/current/downstream.ts';\nimport type {ColumnMetadata, TableMetadata} from './backfill-metadata.ts';\nimport {streamBackfill} from './backfill-stream.ts';\nimport {\n initialSync,\n type InitialSyncOptions,\n type ServerContext,\n} from './initial-sync.ts';\nimport type {\n Message,\n MessageMessage,\n MessageRelation as PostgresRelation,\n} from './logical-replication/pgoutput.types.ts';\nimport {subscribe} from './logical-replication/stream.ts';\nimport {fromBigInt, toStateVersionString, type LSN} from './lsn.ts';\nimport {replicationEventSchema, type DdlUpdateEvent} from './schema/ddl.ts';\nimport {updateShardSchema} from './schema/init.ts';\nimport {\n getPublicationInfo,\n type PublishedSchema,\n type PublishedTableWithReplicaIdentity,\n} from './schema/published.ts';\nimport {\n dropShard,\n getInternalShardConfig,\n getReplicaAtVersion,\n internalPublicationPrefix,\n legacyReplicationSlot,\n replicaIdentitiesForTablesWithoutPrimaryKeys,\n replicationSlotExpression,\n type InternalShardConfig,\n type Replica,\n} from './schema/shard.ts';\nimport {validate} from './schema/validation.ts';\n\n/**\n * Initializes a Postgres change source, including the initial sync of the\n * replica, before streaming changes from the corresponding logical replication\n * stream.\n */\nexport async function initializePostgresChangeSource(\n lc: LogContext,\n upstreamURI: string,\n shard: ShardConfig,\n replicaDbFile: string,\n syncOptions: InitialSyncOptions,\n context: ServerContext,\n): Promise<{subscriptionState: SubscriptionState; changeSource: ChangeSource}> {\n await initReplica(\n lc,\n `replica-${shard.appID}-${shard.shardNum}`,\n replicaDbFile,\n (log, tx) => initialSync(log, shard, tx, upstreamURI, syncOptions, context),\n );\n\n const replica = new Database(lc, replicaDbFile);\n const subscriptionState = getSubscriptionStateAndContext(\n new StatementRunner(replica),\n );\n replica.close();\n\n // Check that upstream is properly setup, and throw an AutoReset to re-run\n // initial sync if not.\n const db = pgClient(lc, upstreamURI);\n try {\n const upstreamReplica = await checkAndUpdateUpstream(\n lc,\n db,\n shard,\n subscriptionState,\n );\n\n const changeSource = new PostgresChangeSource(\n lc,\n upstreamURI,\n shard,\n upstreamReplica,\n context,\n );\n\n return {subscriptionState, changeSource};\n } finally {\n await db.end();\n }\n}\n\nasync function checkAndUpdateUpstream(\n lc: LogContext,\n sql: PostgresDB,\n shard: ShardConfig,\n {\n replicaVersion,\n publications: subscribed,\n initialSyncContext,\n }: SubscriptionStateAndContext,\n) {\n // Perform any shard schema updates\n await updateShardSchema(lc, sql, shard, replicaVersion);\n\n const upstreamReplica = await getReplicaAtVersion(\n lc,\n sql,\n shard,\n replicaVersion,\n initialSyncContext,\n );\n if (!upstreamReplica) {\n throw new AutoResetSignal(\n `No replication slot for replica at version ${replicaVersion}`,\n );\n }\n\n // Verify that the publications match what is being replicated.\n const requested = [...shard.publications].sort();\n const replicated = upstreamReplica.publications\n .filter(p => !p.startsWith(internalPublicationPrefix(shard)))\n .sort();\n if (!deepEqual(requested, replicated)) {\n lc.warn?.(`Dropping shard to change publications to: [${requested}]`);\n await sql.unsafe(dropShard(shard.appID, shard.shardNum));\n throw new AutoResetSignal(\n `Requested publications [${requested}] do not match configured ` +\n `publications: [${replicated}]`,\n );\n }\n\n // Sanity check: The subscription state on the replica should have the\n // same publications. This should be guaranteed by the equivalence of the\n // replicaVersion, but it doesn't hurt to verify.\n if (!deepEqual(upstreamReplica.publications, subscribed)) {\n throw new AutoResetSignal(\n `Upstream publications [${upstreamReplica.publications}] do not ` +\n `match subscribed publications [${subscribed}]`,\n );\n }\n\n // Verify that the publications exist.\n const exists = await sql`\n SELECT pubname FROM pg_publication WHERE pubname IN ${sql(subscribed)};\n `.values();\n if (exists.length !== subscribed.length) {\n throw new AutoResetSignal(\n `Upstream publications [${exists.flat()}] do not contain ` +\n `all subscribed publications [${subscribed}]`,\n );\n }\n\n const {slot} = upstreamReplica;\n const result = await sql<\n {restartLSN: LSN | null; walStatus: string | null}[]\n > /*sql*/ `\n SELECT restart_lsn as \"restartLSN\", wal_status as \"walStatus\" FROM pg_replication_slots\n WHERE slot_name = ${slot}`;\n if (result.length === 0) {\n throw new AutoResetSignal(`replication slot ${slot} is missing`);\n }\n const [{restartLSN, walStatus}] = result;\n if (restartLSN === null || walStatus === 'lost') {\n throw new AutoResetSignal(\n `replication slot ${slot} has been invalidated for exceeding the max_slot_wal_keep_size`,\n );\n }\n return upstreamReplica;\n}\n\n// Parameterize this if necessary. In practice starvation may never happen.\nconst MAX_LOW_PRIORITY_DELAY_MS = 1000;\n\ntype ReservationState = {\n lastWatermark?: string;\n};\n\n/**\n * Postgres implementation of a {@link ChangeSource} backed by a logical\n * replication stream.\n */\nclass PostgresChangeSource implements ChangeSource {\n readonly #lc: LogContext;\n readonly #upstreamUri: string;\n readonly #shard: ShardID;\n readonly #replica: Replica;\n readonly #context: ServerContext;\n\n constructor(\n lc: LogContext,\n upstreamUri: string,\n shard: ShardID,\n replica: Replica,\n context: ServerContext,\n ) {\n this.#lc = lc.withContext('component', 'change-source');\n this.#upstreamUri = upstreamUri;\n this.#shard = shard;\n this.#replica = replica;\n this.#context = context;\n }\n\n async startStream(\n clientWatermark: string,\n backfillRequests: BackfillRequest[] = [],\n ): Promise<ChangeStream> {\n const db = pgClient(this.#lc, this.#upstreamUri);\n const {slot} = this.#replica;\n\n let cleanup = promiseVoid;\n try {\n ({cleanup} = await this.#stopExistingReplicationSlotSubscribers(\n db,\n slot,\n ));\n const config = await getInternalShardConfig(db, this.#shard);\n this.#lc.info?.(`starting replication stream@${slot}`);\n return await this.#startStream(\n db,\n slot,\n clientWatermark,\n config,\n backfillRequests,\n );\n } finally {\n void cleanup.then(() => db.end());\n }\n }\n\n async #startStream(\n db: PostgresDB,\n slot: string,\n clientWatermark: string,\n shardConfig: InternalShardConfig,\n backfillRequests: BackfillRequest[],\n ): Promise<ChangeStream> {\n const clientStart = majorVersionFromString(clientWatermark) + 1n;\n const {messages, acks} = await subscribe(\n this.#lc,\n db,\n slot,\n [...shardConfig.publications],\n clientStart,\n );\n const acker = new Acker(acks);\n\n // The ChangeStreamMultiplexer facilitates cooperative streaming from\n // the main replication stream and backfill streams initiated by the\n // BackfillManager.\n const changes = new ChangeStreamMultiplexer(this.#lc, clientWatermark);\n const backfillManager = new BackfillManager(this.#lc, changes, req =>\n streamBackfill(this.#lc, this.#upstreamUri, this.#replica, req),\n );\n changes\n .addProducers(messages, backfillManager)\n .addListeners(backfillManager, acker);\n backfillManager.run(clientWatermark, backfillRequests);\n\n const changeMaker = new ChangeMaker(\n this.#lc,\n this.#shard,\n shardConfig,\n this.#replica.initialSchema,\n this.#upstreamUri,\n );\n\n void (async () => {\n try {\n let reservation: ReservationState | null = null;\n let inTransaction = false;\n\n for await (const [lsn, msg] of messages) {\n // Note: no reservation is needed for pushStatus().\n if (msg.tag === 'keepalive') {\n changes.pushStatus([\n 'status',\n {ack: msg.shouldRespond},\n {watermark: majorVersionToString(lsn)},\n ]);\n\n // If we're not in a transaction but the last reservation was kept\n // because of pending keepalives in the queue, release the\n // reservation.\n if (!inTransaction && reservation?.lastWatermark) {\n changes.release(reservation.lastWatermark);\n reservation = null;\n }\n continue;\n }\n\n if (!reservation) {\n const res = changes.reserve('replication');\n typeof res === 'string' || (await res); // awaits should be uncommon\n reservation = {};\n }\n\n let lastChange: ChangeStreamMessage | undefined;\n for (const change of await changeMaker.makeChanges(lsn, msg)) {\n await changes.push(change); // Allow the change-streamer to push back.\n lastChange = change;\n }\n\n switch (lastChange?.[0]) {\n case 'begin':\n inTransaction = true;\n break;\n case 'commit':\n inTransaction = false;\n reservation.lastWatermark = lastChange[2].watermark;\n if (\n messages.queued === 0 ||\n changes.waiterDelay() > MAX_LOW_PRIORITY_DELAY_MS\n ) {\n // After each transaction, release the reservation:\n // - if there are no pending upstream messages\n // - or if a low priority request has been waiting for longer\n // than MAX_LOW_PRIORITY_DELAY_MS. This is to prevent\n // (backfill) starvation on very active upstreams.\n changes.release(reservation.lastWatermark);\n reservation = null;\n }\n break;\n }\n }\n } catch (e) {\n // Note: no need to worry about reservations here since downstream\n // is being completely canceled.\n const err = translateError(e);\n if (err instanceof ShutdownSignal) {\n // Log the new state of the replica to surface information about the\n // server that sent the shutdown signal, if any.\n await this.#logCurrentReplicaInfo();\n }\n changes.fail(err);\n }\n })();\n\n this.#lc.info?.(\n `started replication stream@${slot} from ${clientWatermark} (replicaVersion: ${\n this.#replica.version\n })`,\n );\n\n return {\n changes: changes.asSource(),\n acks: {push: status => acker.ack(status[2].watermark)},\n };\n }\n\n async #logCurrentReplicaInfo() {\n const db = pgClient(this.#lc, this.#upstreamUri);\n try {\n const replica = await getReplicaAtVersion(\n this.#lc,\n db,\n this.#shard,\n this.#replica.version,\n );\n if (replica) {\n this.#lc.info?.(\n `Shutdown signal from replica@${this.#replica.version}: ${stringify(replica.subscriberContext)}`,\n );\n }\n } catch (e) {\n this.#lc.warn?.(`error logging replica info`, e);\n } finally {\n await db.end();\n }\n }\n\n /**\n * Stops replication slots associated with this shard, and returns\n * a `cleanup` task that drops any slot other than the specified\n * `slotToKeep`.\n *\n * Note that replication slots created after `slotToKeep` (as indicated by\n * the timestamp suffix) are preserved, as those are newly syncing replicas\n * that will soon take over the slot.\n */\n async #stopExistingReplicationSlotSubscribers(\n db: PostgresDB,\n slotToKeep: string,\n ): Promise<{cleanup: Promise<void>}> {\n const slotExpression = replicationSlotExpression(this.#shard);\n const legacySlotName = legacyReplicationSlot(this.#shard);\n\n const result = await runTx(db, async sql => {\n // Note: `slot_name <= slotToKeep` uses a string compare of the millisecond\n // timestamp, which works until it exceeds 13 digits (sometime in 2286).\n const result = await sql<\n {slot: string; pid: string | null; terminated: boolean | null}[]\n > /*sql*/ `\n SELECT slot_name as slot, pg_terminate_backend(active_pid) as terminated, active_pid as pid\n FROM pg_replication_slots \n WHERE (slot_name LIKE ${slotExpression} OR slot_name = ${legacySlotName})\n AND slot_name <= ${slotToKeep}`;\n this.#lc.info?.(\n `terminated replication slots: ${JSON.stringify(result)}`,\n );\n const replicasTable = `${upstreamSchema(this.#shard)}.replicas`;\n const replicasBefore = await sql`\n SELECT slot, version, \"initialSyncContext\", \"subscriberContext\" \n FROM ${sql(replicasTable)} ORDER BY slot`;\n\n if (result.length === 0) {\n const shardSlots = await sql`\n SELECT slot_name as slot, active, active_pid as pid\n FROM pg_replication_slots\n WHERE slot_name LIKE ${slotExpression} OR slot_name = ${legacySlotName}\n ORDER BY slot_name`;\n this.#lc.warn?.(\n `slot ${slotToKeep} not found while cleaning subscribers`,\n {slots: shardSlots, replicas: replicasBefore},\n );\n throw new AbortError(\n `replication slot ${slotToKeep} is missing. A different ` +\n `replication-manager should now be running on a new ` +\n `replication slot.`,\n );\n }\n // Clear the state of the older replicas.\n this.#lc.info?.(\n `replicas before cleanup (slotToKeep=${slotToKeep}): ${JSON.stringify(\n replicasBefore,\n )}`,\n );\n await sql`\n DELETE FROM ${sql(replicasTable)} WHERE slot < ${slotToKeep}`;\n await sql`\n UPDATE ${sql(replicasTable)} \n SET \"subscriberContext\" = ${this.#context}\n WHERE slot = ${slotToKeep}`;\n const replicasAfter = await sql<{slot: string; version: string}[]>`\n SELECT slot, version FROM ${sql(replicasTable)} ORDER BY slot`;\n this.#lc.info?.(\n `replicas after cleanup (slotToKeep=${slotToKeep}): ${JSON.stringify(\n replicasAfter,\n )}`,\n );\n return result;\n });\n\n const pids = result.filter(({pid}) => pid !== null).map(({pid}) => pid);\n if (pids.length) {\n this.#lc.info?.(`signaled subscriber ${pids} to shut down`);\n }\n const otherSlots = result\n .filter(({slot}) => slot !== slotToKeep)\n .map(({slot}) => slot);\n return {\n cleanup: otherSlots.length\n ? this.#dropReplicationSlots(db, otherSlots)\n : promiseVoid,\n };\n }\n\n async #dropReplicationSlots(sql: PostgresDB, slots: string[]) {\n this.#lc.info?.(`dropping other replication slot(s) ${slots}`);\n for (let i = 0; i < 5; i++) {\n try {\n await sql`\n SELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots\n WHERE slot_name IN ${sql(slots)}\n `;\n this.#lc.info?.(`successfully dropped ${slots}`);\n return;\n } catch (e) {\n // error: replication slot \"zero_slot_change_source_test_id\" is active for PID 268\n if (\n e instanceof postgres.PostgresError &&\n e.code === PG_OBJECT_IN_USE\n ) {\n // The freeing up of the replication slot is not transactional;\n // sometimes it takes time for Postgres to consider the slot\n // inactive.\n this.#lc.debug?.(`attempt ${i + 1}: ${String(e)}`, e);\n } else {\n this.#lc.warn?.(`error dropping ${slots}`, e);\n }\n await sleep(1000);\n }\n }\n this.#lc.warn?.(`maximum attempts exceeded dropping ${slots}`);\n }\n}\n\n// Exported for testing.\nexport class Acker implements Listener {\n #acks: Sink<bigint>;\n #waitingForDownstreamAck: string | null = null;\n\n constructor(acks: Sink<bigint>) {\n this.#acks = acks;\n }\n\n onChange(change: ChangeStreamMessage): void {\n switch (change[0]) {\n case 'status':\n const {watermark} = change[2];\n if (change[1].ack) {\n this.#expectDownstreamAck(watermark);\n } else {\n // Keepalives with shouldRespond = false are sent to Listeners,\n // but for efficiency they are not sent downstream to the\n // change-streamer. Ack them here if the change-streamer is caught\n // up. This updates the replication slot's `confirmed_flush_lsn`\n // more quickly (rather than waiting for the periodic shouldRespond),\n // which is useful for monitoring replication slot lag.\n this.#ackIfDownstreamIsCaughtUp(watermark);\n }\n break;\n case 'begin':\n // Mark the commit watermark as being expected so that any intermediate\n // shouldRespond=false watermarks, which will be at the\n // commitWatermark, are *not* acked, as the ack must come from\n // change-streamer after it commits the transaction.\n if (!change[1].skipAck) {\n this.#expectDownstreamAck(change[2].commitWatermark);\n }\n break;\n }\n }\n\n #expectDownstreamAck(watermark: string) {\n this.#waitingForDownstreamAck = watermark;\n }\n\n ack(watermark: LexiVersion) {\n if (\n this.#waitingForDownstreamAck &&\n this.#waitingForDownstreamAck <= watermark\n ) {\n this.#waitingForDownstreamAck = null;\n }\n this.#sendAck(watermark);\n }\n\n #ackIfDownstreamIsCaughtUp(watermark: string) {\n if (this.#waitingForDownstreamAck === null) {\n this.#sendAck(watermark);\n }\n }\n\n #sendAck(watermark: LexiVersion) {\n const lsn = majorVersionFromString(watermark);\n this.#acks.push(lsn);\n }\n}\n\ntype ReplicationError = {\n lsn: bigint;\n msg: Message;\n err: unknown;\n lastLogTime: number;\n};\n\nconst SET_REPLICA_IDENTITY_DELAY_MS = 50;\n\nclass ChangeMaker {\n readonly #lc: LogContext;\n readonly #shardPrefix: string;\n readonly #shardConfig: InternalShardConfig;\n readonly #initialSchema: PublishedSchema;\n readonly #upstreamDB: PostgresDB;\n\n #replicaIdentityTimer: NodeJS.Timeout | undefined;\n #error: ReplicationError | undefined;\n\n constructor(\n lc: LogContext,\n {appID, shardNum}: ShardID,\n shardConfig: InternalShardConfig,\n initialSchema: PublishedSchema,\n upstreamURI: string,\n ) {\n this.#lc = lc;\n // Note: This matches the prefix used in pg_logical_emit_message() in pg/schema/ddl.ts.\n this.#shardPrefix = `${appID}/${shardNum}`;\n this.#shardConfig = shardConfig;\n this.#initialSchema = initialSchema;\n this.#upstreamDB = pgClient(lc, upstreamURI, {\n ['idle_timeout']: 10, // only used occasionally\n connection: {['application_name']: 'zero-schema-change-detector'},\n });\n }\n\n async makeChanges(lsn: bigint, msg: Message): Promise<ChangeStreamMessage[]> {\n if (this.#error) {\n this.#logError(this.#error);\n return [];\n }\n try {\n return await this.#makeChanges(msg);\n } catch (err) {\n this.#error = {lsn, msg, err, lastLogTime: 0};\n this.#logError(this.#error);\n\n const message = `Unable to continue replication from LSN ${fromBigInt(lsn)}`;\n const errorDetails: JSONObject = {error: message};\n if (err instanceof UnsupportedSchemaChangeError) {\n errorDetails.reason = err.description;\n errorDetails.context = err.ddlUpdate.context;\n } else {\n errorDetails.reason = String(err);\n }\n\n // Rollback the current transaction to avoid dangling transactions in\n // downstream processors (i.e. changeLog, replicator).\n return [\n ['rollback', {tag: 'rollback'}],\n ['control', {tag: 'reset-required', message, errorDetails}],\n ];\n }\n }\n\n #logError(error: ReplicationError) {\n const {lsn, msg, err, lastLogTime} = error;\n const now = Date.now();\n\n // Output an error to logs as replication messages continue to be dropped,\n // at most once a minute.\n if (now - lastLogTime > 60_000) {\n this.#lc.error?.(\n `Unable to continue replication from LSN ${fromBigInt(lsn)}: ${String(\n err,\n )}`,\n err instanceof UnsupportedSchemaChangeError\n ? err.ddlUpdate.context\n : // 'content' can be a large byte Buffer. Exclude it from logging output.\n {...msg, content: undefined},\n );\n error.lastLogTime = now;\n }\n }\n\n // oxlint-disable-next-line require-await\n async #makeChanges(msg: Message): Promise<ChangeStreamData[]> {\n switch (msg.tag) {\n case 'begin':\n return [\n [\n 'begin',\n {...msg, json: 's'},\n {commitWatermark: toStateVersionString(must(msg.commitLsn))},\n ],\n ];\n\n case 'delete': {\n if (!(msg.key ?? msg.old)) {\n throw new Error(\n `Invalid DELETE msg (missing key): ${stringify(msg)}`,\n );\n }\n return [\n [\n 'data',\n {\n ...msg,\n relation: makeRelation(msg.relation),\n // https://www.postgresql.org/docs/current/protocol-logicalrep-message-formats.html#PROTOCOL-LOGICALREP-MESSAGE-FORMATS-DELETE\n key: must(msg.old ?? msg.key),\n },\n ],\n ];\n }\n\n case 'update': {\n return [\n [\n 'data',\n {\n ...msg,\n relation: makeRelation(msg.relation),\n // https://www.postgresql.org/docs/current/protocol-logicalrep-message-formats.html#PROTOCOL-LOGICALREP-MESSAGE-FORMATS-UPDATE\n key: msg.old ?? msg.key,\n },\n ],\n ];\n }\n\n case 'insert':\n return [['data', {...msg, relation: makeRelation(msg.relation)}]];\n case 'truncate':\n return [['data', {...msg, relations: msg.relations.map(makeRelation)}]];\n\n case 'message':\n if (msg.prefix !== this.#shardPrefix) {\n this.#lc.debug?.('ignoring message for different shard', msg.prefix);\n return [];\n }\n return this.#handleCustomMessage(msg);\n\n case 'commit':\n return [\n [\n 'commit',\n msg,\n {watermark: toStateVersionString(must(msg.commitLsn))},\n ],\n ];\n\n case 'relation':\n return this.#handleRelation(msg);\n case 'type':\n return []; // Nothing need be done for custom types.\n case 'origin':\n // No need to detect replication loops since we are not a\n // PG replication source.\n return [];\n default:\n msg satisfies never;\n throw new Error(`Unexpected message type ${stringify(msg)}`);\n }\n }\n\n #preSchema: PublishedSchema | undefined;\n\n #handleCustomMessage(msg: MessageMessage) {\n const event = this.#parseReplicationEvent(msg.content);\n // Cancel manual schema adjustment timeouts when an upstream schema change\n // is about to happen, so as to avoid interfering / redundant work.\n clearTimeout(this.#replicaIdentityTimer);\n\n if (event.type === 'ddlStart') {\n // Store the schema in order to diff it with a potential ddlUpdate.\n this.#preSchema = event.schema;\n return [];\n }\n // ddlUpdate\n const changes = this.#makeSchemaChanges(\n must(this.#preSchema, `ddlUpdate received without a ddlStart`),\n event,\n ).map(change => ['data', change] satisfies Data);\n\n this.#lc\n .withContext('tag', event.event.tag)\n .withContext('query', event.context.query)\n .info?.(`${changes.length} schema change(s)`, {changes});\n\n const replicaIdentities = replicaIdentitiesForTablesWithoutPrimaryKeys(\n event.schema,\n );\n if (replicaIdentities) {\n this.#replicaIdentityTimer = setTimeout(async () => {\n try {\n await replicaIdentities.apply(this.#lc, this.#upstreamDB);\n } catch (err) {\n this.#lc.warn?.(`error setting replica identities`, err);\n }\n }, SET_REPLICA_IDENTITY_DELAY_MS);\n }\n\n return changes;\n }\n\n /**\n * A note on operation order:\n *\n * Postgres will drop related indexes when columns are dropped,\n * but SQLite will error instead (https://sqlite.org/forum/forumpost/2e62dba69f?t=c&hist).\n * The current workaround is to drop indexes first.\n *\n * Also note that although it should not be possible to both rename and\n * add/drop tables/columns in a single statement, the operations are\n * ordered to handle that possibility, by always dropping old entities,\n * then modifying kept entities, and then adding new entities.\n *\n * Thus, the order of replicating DDL updates is:\n * - drop indexes\n * - drop tables\n * - alter tables\n * - drop columns\n * - alter columns\n * - add columns\n * - create tables\n * - create indexes\n *\n * In the future the replication logic should be improved to handle this\n * behavior in SQLite by dropping dependent indexes manually before dropping\n * columns. This, for example, would be needed to properly support changing\n * the type of a column that's indexed.\n */\n #makeSchemaChanges(\n preSchema: PublishedSchema,\n update: DdlUpdateEvent,\n ): SchemaChange[] {\n try {\n const [prevTbl, prevIdx] = specsByID(preSchema);\n const [nextTbl, nextIdx] = specsByID(update.schema);\n const changes: SchemaChange[] = [];\n\n // Validate the new table schemas\n for (const table of nextTbl.values()) {\n validate(this.#lc, table);\n }\n\n const [droppedIdx, createdIdx] = symmetricDifferences(prevIdx, nextIdx);\n\n // Detect modified indexes (same name, different definition).\n // This happens when a constraint is dropped and recreated with the\n // same name in a single ALTER TABLE statement.\n // Note: We compare using stable column attnums rather than names,\n // because table/column renames change the index spec cosmetically\n // (tableName, column keys) without the index actually being recreated.\n const keptIdx = intersection(prevIdx, nextIdx);\n for (const id of keptIdx) {\n if (\n isIndexStructurallyChanged(\n must(prevIdx.get(id)),\n must(nextIdx.get(id)),\n prevTbl,\n nextTbl,\n )\n ) {\n droppedIdx.add(id);\n createdIdx.add(id);\n }\n }\n\n for (const id of droppedIdx) {\n const {schema, name} = must(prevIdx.get(id));\n changes.push({tag: 'drop-index', id: {schema, name}});\n }\n\n // DROP\n const [droppedTbl, createdTbl] = symmetricDifferences(prevTbl, nextTbl);\n for (const id of droppedTbl) {\n const {schema, name} = must(prevTbl.get(id));\n changes.push({tag: 'drop-table', id: {schema, name}});\n }\n // ALTER TABLE | ALTER PUBLICATION\n const tables = intersection(prevTbl, nextTbl);\n for (const id of tables) {\n changes.push(\n ...this.#getTableChanges(\n must(prevTbl.get(id)),\n must(nextTbl.get(id)),\n update.event.tag,\n ),\n );\n }\n // CREATE\n for (const id of createdTbl) {\n const spec = must(nextTbl.get(id));\n const createTable: TableCreate = {\n tag: 'create-table',\n spec,\n metadata: getMetadata(spec),\n };\n if (!update.event.tag.startsWith('CREATE')) {\n // Tables introduced to the publication via ALTER statements\n // must be backfilled.\n createTable.backfill = mapValues(spec.columns, ({pos: attNum}) => ({\n attNum,\n })) satisfies Record<string, ColumnMetadata>;\n }\n changes.push(createTable);\n }\n\n // Add indexes last since they may reference tables / columns that need\n // to be created first.\n for (const id of createdIdx) {\n const spec = must(nextIdx.get(id));\n changes.push({tag: 'create-index', spec});\n }\n return changes;\n } catch (e) {\n throw new UnsupportedSchemaChangeError(String(e), update, {cause: e});\n }\n }\n\n #getTableChanges(\n oldTable: PublishedTableWithReplicaIdentity,\n newTable: PublishedTableWithReplicaIdentity,\n ddlTag: string,\n ): SchemaChange[] {\n const changes: SchemaChange[] = [];\n if (\n oldTable.schema !== newTable.schema ||\n oldTable.name !== newTable.name\n ) {\n changes.push({\n tag: 'rename-table',\n old: {schema: oldTable.schema, name: oldTable.name},\n new: {schema: newTable.schema, name: newTable.name},\n });\n }\n const oldMetadata = getMetadata(oldTable);\n const newMetadata = getMetadata(newTable);\n if (!deepEqual(oldMetadata, newMetadata)) {\n changes.push({\n tag: 'update-table-metadata',\n table: {schema: newTable.schema, name: newTable.name},\n old: oldMetadata,\n new: newMetadata,\n });\n }\n const table = {schema: newTable.schema, name: newTable.name};\n const oldColumns = columnsByID(oldTable.columns);\n const newColumns = columnsByID(newTable.columns);\n\n // DROP\n const [dropped, added] = symmetricDifferences(oldColumns, newColumns);\n for (const id of dropped) {\n const {name: column} = must(oldColumns.get(id));\n changes.push({tag: 'drop-column', table, column});\n }\n\n // ALTER\n const both = intersection(oldColumns, newColumns);\n for (const id of both) {\n const {name: oldName, ...oldSpec} = must(oldColumns.get(id));\n const {name: newName, ...newSpec} = must(newColumns.get(id));\n // The three things that we care about are:\n // 1. name\n // 2. type\n // 3. not-null\n if (\n oldName !== newName ||\n oldSpec.dataType !== newSpec.dataType ||\n oldSpec.notNull !== newSpec.notNull\n ) {\n changes.push({\n tag: 'update-column',\n table,\n old: {name: oldName, spec: oldSpec},\n new: {name: newName, spec: newSpec},\n });\n }\n }\n\n // All columns introduced by a publication change require backfill.\n // Columns created by ALTER TABLE, on the other hand, only require\n // backfill if they have non-constant defaults.\n const alwaysBackfill = ddlTag === 'ALTER PUBLICATION';\n\n // ADD\n for (const id of added) {\n const {name, ...spec} = must(newColumns.get(id));\n const column = {name, spec};\n const addColumn: ColumnAdd = {\n tag: 'add-column',\n table,\n column,\n tableMetadata: getMetadata(newTable),\n };\n if (alwaysBackfill) {\n addColumn.column.spec.dflt = null;\n addColumn.backfill = {attNum: spec.pos} satisfies ColumnMetadata;\n } else {\n // Determine if the ChangeProcessor will accept the column add as is.\n try {\n mapPostgresToLiteColumn(table.name, column);\n } catch (e) {\n if (!(e instanceof UnsupportedColumnDefaultError)) {\n // Note: mapPostgresToLiteColumn is not expected to throw any other\n // types of errors.\n throw e;\n }\n // If the column has an unsupported default (e.g. an expression or a\n // generated value), create the column as initially hidden with a\n // `null` default, and publish it after backfilling the values from\n // upstream. Note that this does require that the table have a valid\n // REPLICA IDENTITY, since backfill relies on merging new data with\n // an existing row.\n this.#lc.info?.(\n `Backfilling column ${table.name}.${name}: ${String(e)}`,\n );\n addColumn.column.spec.dflt = null;\n addColumn.backfill = {attNum: spec.pos} satisfies ColumnMetadata;\n }\n }\n changes.push(addColumn);\n }\n return changes;\n }\n\n #parseReplicationEvent(content: Uint8Array) {\n const str =\n content instanceof Buffer\n ? content.toString('utf-8')\n : new TextDecoder().decode(content);\n const json = JSON.parse(str);\n return v.parse(json, replicationEventSchema, 'passthrough');\n }\n\n /**\n * If `ddlDetection === true`, relation messages are irrelevant,\n * as schema changes are detected by event triggers that\n * emit custom messages.\n *\n * For degraded-mode replication (`ddlDetection === false`):\n * 1. query the current published schemas on upstream\n * 2. compare that with the InternalShardConfig.initialSchema\n * 3. compare that with the incoming MessageRelation\n * 4. On any discrepancy, throw an UnsupportedSchemaChangeError\n * to halt replication.\n *\n * Note that schemas queried in step [1] will be *post-transaction*\n * schemas, which are not necessarily suitable for actually processing\n * the statements in the transaction being replicated. In other words,\n * this mechanism cannot be used to reliably *replicate* schema changes.\n * However, they serve the purpose determining if schemas have changed.\n */\n async #handleRelation(rel: PostgresRelation): Promise<ChangeStreamData[]> {\n const {publications, ddlDetection} = this.#shardConfig;\n if (ddlDetection) {\n return [];\n }\n const currentSchema = await getPublicationInfo(\n this.#upstreamDB,\n publications,\n );\n const difference = getSchemaDifference(this.#initialSchema, currentSchema);\n if (difference !== null) {\n throw new MissingEventTriggerSupport(difference);\n }\n // Even if the currentSchema is equal to the initialSchema, the\n // MessageRelation itself must be checked to detect transient\n // schema changes within the transaction (e.g. adding and dropping\n // a table, or renaming a column and then renaming it back).\n const orel = this.#initialSchema.tables.find(\n t => t.oid === rel.relationOid,\n );\n if (!orel) {\n // Can happen if a table is created and then dropped in the same transaction.\n throw new MissingEventTriggerSupport(\n `relation not in initialSchema: ${stringify(rel)}`,\n );\n }\n if (relationDifferent(orel, rel)) {\n throw new MissingEventTriggerSupport(\n `relation has changed within the transaction: ${stringify(orel)} vs ${stringify(rel)}`,\n );\n }\n return [];\n }\n}\n\nfunction getSchemaDifference(\n a: PublishedSchema,\n b: PublishedSchema,\n): string | null {\n // Note: ignore indexes since changes need not to halt replication\n if (a.tables.length !== b.tables.length) {\n return `tables created or dropped`;\n }\n for (let i = 0; i < a.tables.length; i++) {\n const at = a.tables[i];\n const bt = b.tables[i];\n const difference = getTableDifference(at, bt);\n if (difference) {\n return difference;\n }\n }\n return null;\n}\n\n// ColumnSpec comparator\nconst byColumnPos = (a: [string, ColumnSpec], b: [string, ColumnSpec]) =>\n a[1].pos < b[1].pos ? -1 : a[1].pos > b[1].pos ? 1 : 0;\n\nfunction getTableDifference(\n a: PublishedTableSpec,\n b: PublishedTableSpec,\n): string | null {\n if (a.oid !== b.oid || a.schema !== b.schema || a.name !== b.name) {\n return `Table \"${a.name}\" differs from table \"${b.name}\"`;\n }\n if (!deepEqual(a.primaryKey, b.primaryKey)) {\n return `Primary key of table \"${a.name}\" has changed`;\n }\n const acols = Object.entries(a.columns).sort(byColumnPos);\n const bcols = Object.entries(b.columns).sort(byColumnPos);\n if (\n acols.length !== bcols.length ||\n acols.some(([aname, acol], i) => {\n const [bname, bcol] = bcols[i];\n return (\n aname !== bname ||\n acol.pos !== bcol.pos ||\n acol.typeOID !== bcol.typeOID ||\n acol.notNull !== bcol.notNull\n );\n })\n ) {\n return `Columns of table \"${a.name}\" have changed`;\n }\n return null;\n}\n\nexport function relationDifferent(a: PublishedTableSpec, b: PostgresRelation) {\n if (a.oid !== b.relationOid || a.schema !== b.schema || a.name !== b.name) {\n return true;\n }\n if (\n // The MessageRelation's `keyColumns` field contains the columns in column\n // declaration order, whereas the PublishedTableSpec's `primaryKey`\n // contains the columns in primary key (i.e. index) order. Do an\n // order-agnostic compare here since it is not possible to detect\n // key-order changes from the MessageRelation message alone.\n b.replicaIdentity === 'default' &&\n !equals(new Set(a.primaryKey), new Set(b.keyColumns))\n ) {\n return true;\n }\n const acols = Object.entries(a.columns).sort(byColumnPos);\n const bcols = b.columns;\n return (\n acols.length !== bcols.length ||\n acols.some(([aname, acol], i) => {\n const bcol = bcols[i];\n return aname !== bcol.name || acol.typeOID !== bcol.typeOid;\n })\n );\n}\n\nfunction translateError(e: unknown): Error {\n if (!(e instanceof Error)) {\n return new Error(String(e));\n }\n if (e instanceof postgres.PostgresError && e.code === PG_ADMIN_SHUTDOWN) {\n return new ShutdownSignal(e);\n }\n return e;\n}\nconst idString = (id: Identifier) => `${id.schema}.${id.name}`;\n\nfunction specsByID(published: PublishedSchema) {\n return [\n // It would have been nice to use a CustomKeyMap here, but we rely on set-utils\n // operations which use plain Sets.\n new Map(published.tables.map(t => [t.oid, t])),\n new Map(published.indexes.map(i => [idString(i), i])),\n ] as const;\n}\n\n/**\n * Determines if an index was structurally changed (e.g. constraint dropped\n * and recreated with different columns) vs cosmetically changed (e.g. the\n * index spec changed because the table or a column was renamed).\n *\n * Compares boolean properties directly and resolves column names to their\n * stable attnums (pg_attribute `attnum`) for the column comparison.\n */\nfunction isIndexStructurallyChanged(\n prev: PublishedIndexSpec,\n next: PublishedIndexSpec,\n prevTables: Map<number, PublishedTableWithReplicaIdentity>,\n nextTables: Map<number, PublishedTableWithReplicaIdentity>,\n): boolean {\n if (\n prev.unique !== next.unique ||\n prev.isPrimaryKey !== next.isPrimaryKey ||\n prev.isReplicaIdentity !== next.isReplicaIdentity ||\n prev.isImmediate !== next.isImmediate\n ) {\n return true;\n }\n\n const prevTable = findTableBySchemaAndName(\n prevTables,\n prev.schema,\n prev.tableName,\n );\n const nextTable = findTableBySchemaAndName(\n nextTables,\n next.schema,\n next.tableName,\n );\n if (!prevTable || !nextTable) {\n // Can't resolve tables; conservatively treat as changed.\n return true;\n }\n\n const prevEntries = Object.entries(prev.columns);\n const nextEntries = Object.entries(next.columns);\n if (prevEntries.length !== nextEntries.length) {\n return true;\n }\n\n // Resolve column names → attnums and compare.\n const prevByAttnum = new Map<number | undefined, string>(\n prevEntries.map(([name, dir]) => [prevTable.columns[name]?.pos, dir]),\n );\n const nextByAttnum = new Map<number | undefined, string>(\n nextEntries.map(([name, dir]) => [nextTable.columns[name]?.pos, dir]),\n );\n\n if (prevByAttnum.has(undefined) || nextByAttnum.has(undefined)) {\n // Column not found in table spec; conservatively treat as changed.\n return true;\n }\n if (prevByAttnum.size !== nextByAttnum.size) {\n return true;\n }\n for (const [attnum, dir] of prevByAttnum) {\n if (nextByAttnum.get(attnum) !== dir) {\n return true;\n }\n }\n return false;\n}\n\nfunction findTableBySchemaAndName(\n tables: Map<number, PublishedTableWithReplicaIdentity>,\n schema: string,\n name: string,\n): PublishedTableWithReplicaIdentity | undefined {\n for (const table of tables.values()) {\n if (table.schema === schema && table.name === name) {\n return table;\n }\n }\n return undefined;\n}\n\nfunction columnsByID(\n columns: Record<string, ColumnSpec>,\n): Map<number, ColumnSpec & {name: string}> {\n const colsByID = new Map<number, ColumnSpec & {name: string}>();\n for (const [name, spec] of Object.entries(columns)) {\n // The `pos` field is the `attnum` in `pg_attribute`, which is a stable\n // identifier for the column in this table (i.e. never reused).\n colsByID.set(spec.pos, {...spec, name});\n }\n return colsByID;\n}\n\nfunction getMetadata(table: PublishedTableWithReplicaIdentity): TableMetadata {\n return {\n schemaOID: must(table.schemaOID),\n relationOID: table.oid,\n rowKey: Object.fromEntries(\n table.replicaIdentityColumns.map(k => [\n k,\n {attNum: table.columns[k].pos},\n ]),\n ),\n };\n}\n\n// Avoid sending the `columns` from the Postgres MessageRelation message.\n// They are not used downstream and the message can be large.\nfunction makeRelation(relation: PostgresRelation): MessageRelation {\n // Avoid sending the `columns` from the Postgres MessageRelation message.\n // They are not used downstream and the message can be large.\n const {columns: _, keyColumns, replicaIdentity, ...rest} = relation;\n return {\n ...rest,\n rowKey: {\n columns: keyColumns,\n type: replicaIdentity,\n },\n // For now, deprecated columns are sent for backwards compatibility.\n // These can be removed when bumping the MIN_PROTOCOL_VERSION to 5.\n keyColumns,\n replicaIdentity,\n };\n}\n\nclass UnsupportedSchemaChangeError extends Error {\n readonly name = 'UnsupportedSchemaChangeError';\n readonly description: string;\n readonly ddlUpdate: DdlUpdateEvent;\n\n constructor(\n description: string,\n ddlUpdate: DdlUpdateEvent,\n options?: ErrorOptions,\n ) {\n super(\n `Replication halted. Resync the replica to recover: ${description}`,\n options,\n );\n this.description = description;\n this.ddlUpdate = ddlUpdate;\n }\n}\n\nclass MissingEventTriggerSupport extends Error {\n readonly name = 'MissingEventTriggerSupport';\n\n constructor(msg: string) {\n super(\n `${msg}. Schema changes cannot be reliably replicated without event trigger support.`,\n );\n }\n}\n\n// TODO(0xcadams): should this be a ProtocolError?\nclass ShutdownSignal extends AbortError {\n readonly name = 'ShutdownSignal';\n\n constructor(cause: unknown) {\n super(\n 'shutdown signal received (e.g. another zero-cache taking over the replication stream)',\n {\n cause,\n },\n );\n }\n}\n"],"mappings":"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"}
@@ -1,34 +1,30 @@
1
1
  import { runTx } from "../../../db/run-transaction.js";
2
2
  import { dropShard } from "./schema/shard.js";
3
+ //#region ../zero-cache/src/services/change-source/pg/decommission.ts
3
4
  async function decommissionShard(lc, db, appID, shardID) {
4
- const shard = `${appID}_${shardID}`;
5
- lc.info?.(`Decommissioning zero shard ${shard}`);
6
- await runTx(db, async (sql) => {
7
- const slots = await sql`
5
+ const shard = `${appID}_${shardID}`;
6
+ lc.info?.(`Decommissioning zero shard ${shard}`);
7
+ await runTx(db, async (sql) => {
8
+ const slots = await sql`
8
9
  SELECT pg_terminate_backend(active_pid), active_pid as pid
9
10
  FROM pg_replication_slots
10
11
  WHERE slot_name = ${shard}
11
12
  OR slot_name LIKE ${shard + "_%"}`;
12
- if (slots.length > 0) {
13
- if (slots[0].pid !== null) {
14
- lc.info?.(`signaled subscriber ${slots[0].pid} to shut down`);
15
- }
16
- const slotExpression = `${appID}_${shardID}_%`.replaceAll("_", "\\_");
17
- const dropped = await sql`
13
+ if (slots.length > 0) {
14
+ if (slots[0].pid !== null) lc.info?.(`signaled subscriber ${slots[0].pid} to shut down`);
15
+ const dropped = await sql`
18
16
  SELECT pg_drop_replication_slot(slot_name), slot_name as "slotName"
19
17
  FROM pg_replication_slots
20
18
  WHERE slot_name = ${shard}
21
- OR slot_name LIKE ${slotExpression}`;
22
- lc.debug?.(
23
- `Dropped replication slot(s) ${dropped.map(({ slotName }) => slotName)}`
24
- );
25
- await sql.unsafe(dropShard(appID, shardID));
26
- lc.debug?.(`Dropped upstream shard schema ${shard} and event triggers`);
27
- }
28
- });
29
- lc.info?.(`Finished decommissioning zero shard ${shard}`);
19
+ OR slot_name LIKE ${`${appID}_${shardID}_%`.replaceAll("_", "\\_")}`;
20
+ lc.debug?.(`Dropped replication slot(s) ${dropped.map(({ slotName }) => slotName)}`);
21
+ await sql.unsafe(dropShard(appID, shardID));
22
+ lc.debug?.(`Dropped upstream shard schema ${shard} and event triggers`);
23
+ }
24
+ });
25
+ lc.info?.(`Finished decommissioning zero shard ${shard}`);
30
26
  }
31
- export {
32
- decommissionShard
33
- };
34
- //# sourceMappingURL=decommission.js.map
27
+ //#endregion
28
+ export { decommissionShard };
29
+
30
+ //# sourceMappingURL=decommission.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"decommission.js","sources":["../../../../../../../zero-cache/src/services/change-source/pg/decommission.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {runTx} from '../../../db/run-transaction.ts';\nimport type {PostgresDB} from '../../../types/pg.ts';\nimport {dropShard} from './schema/shard.ts';\n\nexport async function decommissionShard(\n lc: LogContext,\n db: PostgresDB,\n appID: string,\n shardID: string | number,\n) {\n const shard = `${appID}_${shardID}`;\n\n lc.info?.(`Decommissioning zero shard ${shard}`);\n await runTx(db, async sql => {\n // Kill the active_pid's on existing slots before altering publications,\n // as deleting a publication associated with an existing subscriber causes\n // weirdness; the active_pid becomes null and thus unable to be terminated.\n const slots = await sql<{pid: string | null}[]>`\n SELECT pg_terminate_backend(active_pid), active_pid as pid\n FROM pg_replication_slots \n WHERE slot_name = ${shard} \n OR slot_name LIKE ${shard + '_%'}`;\n if (slots.length > 0) {\n if (slots[0].pid !== null) {\n lc.info?.(`signaled subscriber ${slots[0].pid} to shut down`);\n }\n // Escape underscores for the LIKE expression.\n const slotExpression = `${appID}_${shardID}_%`.replaceAll('_', '\\\\_');\n const dropped = await sql<{slotName: string}[]>`\n SELECT pg_drop_replication_slot(slot_name), slot_name as \"slotName\"\n FROM pg_replication_slots \n WHERE slot_name = ${shard} \n OR slot_name LIKE ${slotExpression}`;\n lc.debug?.(\n `Dropped replication slot(s) ${dropped.map(({slotName}) => slotName)}`,\n );\n await sql.unsafe(dropShard(appID, shardID));\n lc.debug?.(`Dropped upstream shard schema ${shard} and event triggers`);\n }\n });\n lc.info?.(`Finished decommissioning zero shard ${shard}`);\n}\n"],"names":[],"mappings":";;AAKA,eAAsB,kBACpB,IACA,IACA,OACA,SACA;AACA,QAAM,QAAQ,GAAG,KAAK,IAAI,OAAO;AAEjC,KAAG,OAAO,8BAA8B,KAAK,EAAE;AAC/C,QAAM,MAAM,IAAI,OAAM,QAAO;AAI3B,UAAM,QAAQ,MAAM;AAAA;AAAA;AAAA,0BAGE,KAAK;AAAA,6BACF,QAAQ,IAAI;AACrC,QAAI,MAAM,SAAS,GAAG;AACpB,UAAI,MAAM,CAAC,EAAE,QAAQ,MAAM;AACzB,WAAG,OAAO,uBAAuB,MAAM,CAAC,EAAE,GAAG,eAAe;AAAA,MAC9D;AAEA,YAAM,iBAAiB,GAAG,KAAK,IAAI,OAAO,KAAK,WAAW,KAAK,KAAK;AACpE,YAAM,UAAU,MAAM;AAAA;AAAA;AAAA,8BAGE,KAAK;AAAA,iCACF,cAAc;AACzC,SAAG;AAAA,QACD,+BAA+B,QAAQ,IAAI,CAAC,EAAC,SAAA,MAAc,QAAQ,CAAC;AAAA,MAAA;AAEtE,YAAM,IAAI,OAAO,UAAU,OAAO,OAAO,CAAC;AAC1C,SAAG,QAAQ,iCAAiC,KAAK,qBAAqB;AAAA,IACxE;AAAA,EACF,CAAC;AACD,KAAG,OAAO,uCAAuC,KAAK,EAAE;AAC1D;"}
1
+ {"version":3,"file":"decommission.js","names":[],"sources":["../../../../../../../zero-cache/src/services/change-source/pg/decommission.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {runTx} from '../../../db/run-transaction.ts';\nimport type {PostgresDB} from '../../../types/pg.ts';\nimport {dropShard} from './schema/shard.ts';\n\nexport async function decommissionShard(\n lc: LogContext,\n db: PostgresDB,\n appID: string,\n shardID: string | number,\n) {\n const shard = `${appID}_${shardID}`;\n\n lc.info?.(`Decommissioning zero shard ${shard}`);\n await runTx(db, async sql => {\n // Kill the active_pid's on existing slots before altering publications,\n // as deleting a publication associated with an existing subscriber causes\n // weirdness; the active_pid becomes null and thus unable to be terminated.\n const slots = await sql<{pid: string | null}[]>`\n SELECT pg_terminate_backend(active_pid), active_pid as pid\n FROM pg_replication_slots \n WHERE slot_name = ${shard} \n OR slot_name LIKE ${shard + '_%'}`;\n if (slots.length > 0) {\n if (slots[0].pid !== null) {\n lc.info?.(`signaled subscriber ${slots[0].pid} to shut down`);\n }\n // Escape underscores for the LIKE expression.\n const slotExpression = `${appID}_${shardID}_%`.replaceAll('_', '\\\\_');\n const dropped = await sql<{slotName: string}[]>`\n SELECT pg_drop_replication_slot(slot_name), slot_name as \"slotName\"\n FROM pg_replication_slots \n WHERE slot_name = ${shard} \n OR slot_name LIKE ${slotExpression}`;\n lc.debug?.(\n `Dropped replication slot(s) ${dropped.map(({slotName}) => slotName)}`,\n );\n await sql.unsafe(dropShard(appID, shardID));\n lc.debug?.(`Dropped upstream shard schema ${shard} and event triggers`);\n }\n });\n lc.info?.(`Finished decommissioning zero shard ${shard}`);\n}\n"],"mappings":";;;AAKA,eAAsB,kBACpB,IACA,IACA,OACA,SACA;CACA,MAAM,QAAQ,GAAG,MAAM,GAAG;AAE1B,IAAG,OAAO,8BAA8B,QAAQ;AAChD,OAAM,MAAM,IAAI,OAAM,QAAO;EAI3B,MAAM,QAAQ,MAAM,GAA2B;;;0BAGzB,MAAM;6BACH,QAAQ;AACjC,MAAI,MAAM,SAAS,GAAG;AACpB,OAAI,MAAM,GAAG,QAAQ,KACnB,IAAG,OAAO,uBAAuB,MAAM,GAAG,IAAI,eAAe;GAI/D,MAAM,UAAU,MAAM,GAAyB;;;8BAGvB,MAAM;iCAJP,GAAG,MAAM,GAAG,QAAQ,IAAI,WAAW,KAAK,MAAM;AAMrE,MAAG,QACD,+BAA+B,QAAQ,KAAK,EAAC,eAAc,SAAS,GACrE;AACD,SAAM,IAAI,OAAO,UAAU,OAAO,QAAQ,CAAC;AAC3C,MAAG,QAAQ,iCAAiC,MAAM,qBAAqB;;GAEzE;AACF,IAAG,OAAO,uCAAuC,QAAQ"}