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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (728) hide show
  1. package/README.md +28 -3
  2. package/out/_virtual/{_@oxc-project_runtime@0.122.0 → _@oxc-project_runtime@0.130.0}/helpers/usingCtx.js +1 -1
  3. package/out/_virtual/__vite-optional-peer-dep_pg-native_pg.js +13 -0
  4. package/out/_virtual/__vite-optional-peer-dep_pg-native_pg.js.map +1 -0
  5. package/out/_virtual/_rolldown/runtime.js +12 -1
  6. package/out/analyze-query/src/analyze-cli.js.map +1 -1
  7. package/out/analyze-query/src/bin-analyze.js +6 -1
  8. package/out/analyze-query/src/bin-analyze.js.map +1 -1
  9. package/out/analyze-query/src/bin-transform.js.map +1 -1
  10. package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
  11. package/out/ast-to-zql/src/bin.js.map +1 -1
  12. package/out/ast-to-zql/src/format.js.map +1 -1
  13. package/out/datadog/src/datadog-log-sink.js.map +1 -1
  14. package/out/node_modules/.pnpm/@opentelemetry_semantic-conventions@1.41.1/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js +12 -0
  15. package/out/node_modules/.pnpm/@opentelemetry_semantic-conventions@1.41.1/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js.map +1 -0
  16. package/out/node_modules/.pnpm/pg-cloudflare@1.3.0/node_modules/pg-cloudflare/dist/empty.js +11 -0
  17. package/out/node_modules/.pnpm/pg-cloudflare@1.3.0/node_modules/pg-cloudflare/dist/empty.js.map +1 -0
  18. package/out/node_modules/.pnpm/pg-connection-string@2.12.0/node_modules/pg-connection-string/index.js +130 -0
  19. package/out/node_modules/.pnpm/pg-connection-string@2.12.0/node_modules/pg-connection-string/index.js.map +1 -0
  20. package/out/node_modules/.pnpm/pg-int8@1.0.1/node_modules/pg-int8/index.js +62 -0
  21. package/out/node_modules/.pnpm/pg-int8@1.0.1/node_modules/pg-int8/index.js.map +1 -0
  22. package/out/node_modules/.pnpm/pg-pool@3.13.0_pg@8.20.0/node_modules/pg-pool/index.js +353 -0
  23. package/out/node_modules/.pnpm/pg-pool@3.13.0_pg@8.20.0/node_modules/pg-pool/index.js.map +1 -0
  24. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/buffer-reader.js +60 -0
  25. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/buffer-reader.js.map +1 -0
  26. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/buffer-writer.js +81 -0
  27. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/buffer-writer.js.map +1 -0
  28. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/index.js +35 -0
  29. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/index.js.map +1 -0
  30. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/messages.js +167 -0
  31. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/messages.js.map +1 -0
  32. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/parser.js +288 -0
  33. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/parser.js.map +1 -0
  34. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/serializer.js +177 -0
  35. package/out/node_modules/.pnpm/pg-protocol@1.13.0/node_modules/pg-protocol/dist/serializer.js.map +1 -0
  36. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/index.js +46 -0
  37. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/index.js.map +1 -0
  38. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/arrayParser.js +16 -0
  39. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/arrayParser.js.map +1 -0
  40. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/binaryParsers.js +165 -0
  41. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/binaryParsers.js.map +1 -0
  42. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/builtins.js +81 -0
  43. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/builtins.js.map +1 -0
  44. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/textParsers.js +167 -0
  45. package/out/node_modules/.pnpm/pg-types@2.2.0/node_modules/pg-types/lib/textParsers.js.map +1 -0
  46. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/esm/index.js +19 -0
  47. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/esm/index.js.map +1 -0
  48. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/client.js +508 -0
  49. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/client.js.map +1 -0
  50. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/connection-parameters.js +104 -0
  51. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/connection-parameters.js.map +1 -0
  52. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/connection.js +160 -0
  53. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/connection.js.map +1 -0
  54. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/cert-signatures.js +97 -0
  55. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/cert-signatures.js.map +1 -0
  56. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/sasl.js +131 -0
  57. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/sasl.js.map +1 -0
  58. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils-legacy.js +39 -0
  59. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils-legacy.js.map +1 -0
  60. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils-webcrypto.js +89 -0
  61. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils-webcrypto.js.map +1 -0
  62. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils.js +13 -0
  63. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/crypto/utils.js.map +1 -0
  64. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/defaults.js +46 -0
  65. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/defaults.js.map +1 -0
  66. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/index.js +71 -0
  67. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/index.js.map +1 -0
  68. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/client.js +226 -0
  69. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/client.js.map +1 -0
  70. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/index.js +11 -0
  71. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/index.js.map +1 -0
  72. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/query.js +117 -0
  73. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/native/query.js.map +1 -0
  74. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/query.js +151 -0
  75. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/query.js.map +1 -0
  76. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/result.js +76 -0
  77. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/result.js.map +1 -0
  78. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/stream.js +73 -0
  79. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/stream.js.map +1 -0
  80. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/type-overrides.js +35 -0
  81. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/type-overrides.js.map +1 -0
  82. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/utils.js +118 -0
  83. package/out/node_modules/.pnpm/pg@8.20.0/node_modules/pg/lib/utils.js.map +1 -0
  84. package/out/node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/helper.js +147 -0
  85. package/out/node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/helper.js.map +1 -0
  86. package/out/node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/index.js +21 -0
  87. package/out/node_modules/.pnpm/pgpass@1.0.5/node_modules/pgpass/lib/index.js.map +1 -0
  88. package/out/node_modules/.pnpm/postgres-array@2.0.0/node_modules/postgres-array/index.js +84 -0
  89. package/out/node_modules/.pnpm/postgres-array@2.0.0/node_modules/postgres-array/index.js.map +1 -0
  90. package/out/node_modules/.pnpm/postgres-bytea@1.0.1/node_modules/postgres-bytea/index.js +28 -0
  91. package/out/node_modules/.pnpm/postgres-bytea@1.0.1/node_modules/postgres-bytea/index.js.map +1 -0
  92. package/out/node_modules/.pnpm/postgres-date@1.0.7/node_modules/postgres-date/index.js +65 -0
  93. package/out/node_modules/.pnpm/postgres-date@1.0.7/node_modules/postgres-date/index.js.map +1 -0
  94. package/out/node_modules/.pnpm/postgres-interval@1.2.0/node_modules/postgres-interval/index.js +107 -0
  95. package/out/node_modules/.pnpm/postgres-interval@1.2.0/node_modules/postgres-interval/index.js.map +1 -0
  96. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.development.js +696 -0
  97. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.development.js.map +1 -0
  98. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.js +44 -0
  99. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.js.map +1 -0
  100. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.development.js +1585 -0
  101. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.development.js.map +1 -0
  102. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js +329 -0
  103. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js.map +1 -0
  104. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/index.js +13 -0
  105. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/index.js.map +1 -0
  106. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js +13 -0
  107. package/out/node_modules/.pnpm/react@18.3.1/node_modules/react/jsx-runtime.js.map +1 -0
  108. package/out/node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/dist/server.js +131 -0
  109. package/out/node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/dist/server.js.map +1 -0
  110. package/out/node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/store/dist/server.js +96 -0
  111. package/out/node_modules/.pnpm/solid-js@1.9.13/node_modules/solid-js/store/dist/server.js.map +1 -0
  112. package/out/node_modules/.pnpm/split2@4.2.0/node_modules/split2/index.js +95 -0
  113. package/out/node_modules/.pnpm/split2@4.2.0/node_modules/split2/index.js.map +1 -0
  114. package/out/node_modules/.pnpm/xtend@4.0.2/node_modules/xtend/mutable.js +18 -0
  115. package/out/node_modules/.pnpm/xtend@4.0.2/node_modules/xtend/mutable.js.map +1 -0
  116. package/out/otel/src/enabled.js.map +1 -1
  117. package/out/otel/src/log-options.js.map +1 -1
  118. package/out/otel/src/maybe-time.js.map +1 -1
  119. package/out/otel/src/span.js.map +1 -1
  120. package/out/replicache/src/async-iterable-to-array.js.map +1 -1
  121. package/out/replicache/src/bg-interval.js.map +1 -1
  122. package/out/replicache/src/btree/diff.js.map +1 -1
  123. package/out/replicache/src/btree/node.js.map +1 -1
  124. package/out/replicache/src/btree/read.js.map +1 -1
  125. package/out/replicache/src/btree/splice.js.map +1 -1
  126. package/out/replicache/src/btree/write.js +6 -3
  127. package/out/replicache/src/btree/write.js.map +1 -1
  128. package/out/replicache/src/call-default-fetch.js.map +1 -1
  129. package/out/replicache/src/connection-loop-delegates.js.map +1 -1
  130. package/out/replicache/src/connection-loop.js.map +1 -1
  131. package/out/replicache/src/cookies.js.map +1 -1
  132. package/out/replicache/src/dag/chunk.js.map +1 -1
  133. package/out/replicache/src/dag/gc.js.map +1 -1
  134. package/out/replicache/src/dag/key.js.map +1 -1
  135. package/out/replicache/src/dag/lazy-store.js.map +1 -1
  136. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  137. package/out/replicache/src/dag/store-impl.js +8 -3
  138. package/out/replicache/src/dag/store-impl.js.map +1 -1
  139. package/out/replicache/src/dag/store.js.map +1 -1
  140. package/out/replicache/src/dag/visitor.js.map +1 -1
  141. package/out/replicache/src/db/commit.js.map +1 -1
  142. package/out/replicache/src/db/index.js.map +1 -1
  143. package/out/replicache/src/db/read.js.map +1 -1
  144. package/out/replicache/src/db/rebase.js.map +1 -1
  145. package/out/replicache/src/db/write.js.map +1 -1
  146. package/out/replicache/src/deleted-clients.js.map +1 -1
  147. package/out/replicache/src/error-responses.js.map +1 -1
  148. package/out/replicache/src/frozen-json.js.map +1 -1
  149. package/out/replicache/src/get-default-puller.js.map +1 -1
  150. package/out/replicache/src/get-default-pusher.js.map +1 -1
  151. package/out/replicache/src/get-kv-store-provider.js.map +1 -1
  152. package/out/replicache/src/hash.js.map +1 -1
  153. package/out/replicache/src/http-request-info.js.map +1 -1
  154. package/out/replicache/src/index-defs.js.map +1 -1
  155. package/out/replicache/src/kv/expo-sqlite/store.d.ts +1 -1
  156. package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
  157. package/out/replicache/src/kv/expo-sqlite/store.js +6 -7
  158. package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
  159. package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
  160. package/out/replicache/src/kv/idb-store.js.map +1 -1
  161. package/out/replicache/src/kv/mem-store.js.map +1 -1
  162. package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
  163. package/out/replicache/src/kv/op-sqlite/store.js +6 -6
  164. package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
  165. package/out/replicache/src/kv/read-impl.js.map +1 -1
  166. package/out/replicache/src/kv/sqlite-store.d.ts +6 -6
  167. package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
  168. package/out/replicache/src/kv/sqlite-store.js +107 -22
  169. package/out/replicache/src/kv/sqlite-store.js.map +1 -1
  170. package/out/replicache/src/kv/throw-if-closed.d.ts +1 -0
  171. package/out/replicache/src/kv/throw-if-closed.d.ts.map +1 -1
  172. package/out/replicache/src/kv/throw-if-closed.js +1 -4
  173. package/out/replicache/src/kv/throw-if-closed.js.map +1 -1
  174. package/out/replicache/src/kv/write-impl-base.js.map +1 -1
  175. package/out/replicache/src/kv/write-impl.js.map +1 -1
  176. package/out/replicache/src/lazy.js.map +1 -1
  177. package/out/replicache/src/log-options.js.map +1 -1
  178. package/out/replicache/src/make-idb-name.js.map +1 -1
  179. package/out/replicache/src/new-client-channel.js.map +1 -1
  180. package/out/replicache/src/on-persist-channel.js.map +1 -1
  181. package/out/replicache/src/patch-operation.js.map +1 -1
  182. package/out/replicache/src/pending-mutations.js.map +1 -1
  183. package/out/replicache/src/persist/client-gc.js.map +1 -1
  184. package/out/replicache/src/persist/client-group-gc.js.map +1 -1
  185. package/out/replicache/src/persist/client-groups.js +40 -0
  186. package/out/replicache/src/persist/client-groups.js.map +1 -1
  187. package/out/replicache/src/persist/clients.js +28 -0
  188. package/out/replicache/src/persist/clients.js.map +1 -1
  189. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  190. package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
  191. package/out/replicache/src/persist/gather-not-cached-visitor.js.map +1 -1
  192. package/out/replicache/src/persist/heartbeat.js.map +1 -1
  193. package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
  194. package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
  195. package/out/replicache/src/persist/make-client-id.js.map +1 -1
  196. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  197. package/out/replicache/src/persist/persist.js +4 -2
  198. package/out/replicache/src/persist/persist.js.map +1 -1
  199. package/out/replicache/src/persist/refresh.js.map +1 -1
  200. package/out/replicache/src/process-scheduler.js.map +1 -1
  201. package/out/replicache/src/pusher.js.map +1 -1
  202. package/out/replicache/src/replicache-impl.js.map +1 -1
  203. package/out/replicache/src/report-error.js.map +1 -1
  204. package/out/replicache/src/request-idle.js.map +1 -1
  205. package/out/replicache/src/scan-iterator.js.map +1 -1
  206. package/out/replicache/src/scan-options.js.map +1 -1
  207. package/out/replicache/src/set-interval-with-signal.js.map +1 -1
  208. package/out/replicache/src/subscriptions.js.map +1 -1
  209. package/out/replicache/src/sync/diff.js.map +1 -1
  210. package/out/replicache/src/sync/ids.js.map +1 -1
  211. package/out/replicache/src/sync/patch.js.map +1 -1
  212. package/out/replicache/src/sync/pull-error.js.map +1 -1
  213. package/out/replicache/src/sync/pull.d.ts.map +1 -1
  214. package/out/replicache/src/sync/pull.js +9 -6
  215. package/out/replicache/src/sync/pull.js.map +1 -1
  216. package/out/replicache/src/sync/push.js.map +1 -1
  217. package/out/replicache/src/sync/request-id.js.map +1 -1
  218. package/out/replicache/src/to-error.js.map +1 -1
  219. package/out/replicache/src/transaction-closed-error.js.map +1 -1
  220. package/out/replicache/src/transactions.js.map +1 -1
  221. package/out/replicache/src/with-transactions.js.map +1 -1
  222. package/out/shared/src/abort-error.js.map +1 -1
  223. package/out/shared/src/arrays.js.map +1 -1
  224. package/out/shared/src/asserts.js.map +1 -1
  225. package/out/shared/src/bigint-json.js.map +1 -1
  226. package/out/shared/src/binary-search.js.map +1 -1
  227. package/out/shared/src/broadcast-channel.js.map +1 -1
  228. package/out/shared/src/browser-env.js.map +1 -1
  229. package/out/shared/src/btree-set.js.map +1 -1
  230. package/out/shared/src/cache.js.map +1 -1
  231. package/out/shared/src/centroid.js.map +1 -1
  232. package/out/shared/src/custom-key-map.js.map +1 -1
  233. package/out/shared/src/custom-key-set.js.map +1 -1
  234. package/out/shared/src/deep-clone.js.map +1 -1
  235. package/out/shared/src/deep-merge.js.map +1 -1
  236. package/out/shared/src/document-visible.js.map +1 -1
  237. package/out/shared/src/dotenv.js.map +1 -1
  238. package/out/shared/src/error.js.map +1 -1
  239. package/out/shared/src/hash.js.map +1 -1
  240. package/out/shared/src/iterables.js.map +1 -1
  241. package/out/shared/src/json-schema.js.map +1 -1
  242. package/out/shared/src/json.js.map +1 -1
  243. package/out/shared/src/logging-test-utils.js.map +1 -1
  244. package/out/shared/src/logging.js.map +1 -1
  245. package/out/shared/src/map.d.ts +6 -0
  246. package/out/shared/src/map.d.ts.map +1 -0
  247. package/out/shared/src/map.js +39 -0
  248. package/out/shared/src/map.js.map +1 -0
  249. package/out/shared/src/must.js.map +1 -1
  250. package/out/shared/src/object-traversal.js.map +1 -1
  251. package/out/shared/src/objects.js.map +1 -1
  252. package/out/shared/src/options.js.map +1 -1
  253. package/out/shared/src/parse-big-int.js.map +1 -1
  254. package/out/shared/src/promise-race.js.map +1 -1
  255. package/out/shared/src/queue.d.ts.map +1 -1
  256. package/out/shared/src/queue.js +15 -21
  257. package/out/shared/src/queue.js.map +1 -1
  258. package/out/shared/src/rand.js.map +1 -1
  259. package/out/shared/src/random-uint64.js.map +1 -1
  260. package/out/shared/src/random-values.js.map +1 -1
  261. package/out/shared/src/record-proxy.js.map +1 -1
  262. package/out/shared/src/resolved-promises.js.map +1 -1
  263. package/out/shared/src/ring-buffer.d.ts +32 -0
  264. package/out/shared/src/ring-buffer.d.ts.map +1 -0
  265. package/out/shared/src/ring-buffer.js +109 -0
  266. package/out/shared/src/ring-buffer.js.map +1 -0
  267. package/out/shared/src/sentinels.js.map +1 -1
  268. package/out/shared/src/set-utils.js.map +1 -1
  269. package/out/shared/src/size-of-value.js.map +1 -1
  270. package/out/shared/src/sleep.js.map +1 -1
  271. package/out/shared/src/sorted-entries.js.map +1 -1
  272. package/out/shared/src/string-compare.js.map +1 -1
  273. package/out/shared/src/subscribable.js.map +1 -1
  274. package/out/shared/src/tdigest-schema.js.map +1 -1
  275. package/out/shared/src/tdigest.js.map +1 -1
  276. package/out/shared/src/valita.js.map +1 -1
  277. package/out/z2s/src/compiler.js.map +1 -1
  278. package/out/z2s/src/sql.js.map +1 -1
  279. package/out/zero/package.js +23 -23
  280. package/out/zero/package.js.map +1 -1
  281. package/out/zero/src/build-schema.js.map +1 -1
  282. package/out/zero/src/zero-cache-dev.js.map +1 -1
  283. package/out/zero/src/zero-out.js.map +1 -1
  284. package/out/zero-cache/src/auth/auth.js.map +1 -1
  285. package/out/zero-cache/src/auth/jwt.js.map +1 -1
  286. package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
  287. package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
  288. package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
  289. package/out/zero-cache/src/config/network.js.map +1 -1
  290. package/out/zero-cache/src/config/normalize.js.map +1 -1
  291. package/out/zero-cache/src/config/server-context.js.map +1 -1
  292. package/out/zero-cache/src/config/zero-config.js +5 -0
  293. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  294. package/out/zero-cache/src/custom/fetch.js.map +1 -1
  295. package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
  296. package/out/zero-cache/src/db/create.js.map +1 -1
  297. package/out/zero-cache/src/db/delete-lite-db.js.map +1 -1
  298. package/out/zero-cache/src/db/lite-tables.js.map +1 -1
  299. package/out/zero-cache/src/db/migration-lite.js +19 -0
  300. package/out/zero-cache/src/db/migration-lite.js.map +1 -1
  301. package/out/zero-cache/src/db/migration.js +19 -0
  302. package/out/zero-cache/src/db/migration.js.map +1 -1
  303. package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
  304. package/out/zero-cache/src/db/pg-copy.js.map +1 -1
  305. package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
  306. package/out/zero-cache/src/db/pg-type-parser.js.map +1 -1
  307. package/out/zero-cache/src/db/run-transaction.js.map +1 -1
  308. package/out/zero-cache/src/db/specs.js.map +1 -1
  309. package/out/zero-cache/src/db/statements.js.map +1 -1
  310. package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
  311. package/out/zero-cache/src/db/warmup.js.map +1 -1
  312. package/out/zero-cache/src/observability/events.js.map +1 -1
  313. package/out/zero-cache/src/observability/metrics.js.map +1 -1
  314. package/out/zero-cache/src/scripts/decommission.js.map +1 -1
  315. package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
  316. package/out/zero-cache/src/scripts/permissions.js.map +1 -1
  317. package/out/zero-cache/src/server/anonymous-otel-start.js +11 -10
  318. package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
  319. package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
  320. package/out/zero-cache/src/server/change-streamer.js +13 -7
  321. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  322. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  323. package/out/zero-cache/src/server/logging.js.map +1 -1
  324. package/out/zero-cache/src/server/main.d.ts.map +1 -1
  325. package/out/zero-cache/src/server/main.js +4 -2
  326. package/out/zero-cache/src/server/main.js.map +1 -1
  327. package/out/zero-cache/src/server/mutator.js +4 -2
  328. package/out/zero-cache/src/server/mutator.js.map +1 -1
  329. package/out/zero-cache/src/server/otel-diag-logger.js.map +1 -1
  330. package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
  331. package/out/zero-cache/src/server/otel-start.js +1 -1
  332. package/out/zero-cache/src/server/otel-start.js.map +1 -1
  333. package/out/zero-cache/src/server/priority-op.js.map +1 -1
  334. package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
  335. package/out/zero-cache/src/server/reaper.js +6 -4
  336. package/out/zero-cache/src/server/reaper.js.map +1 -1
  337. package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
  338. package/out/zero-cache/src/server/replicator.js +4 -2
  339. package/out/zero-cache/src/server/replicator.js.map +1 -1
  340. package/out/zero-cache/src/server/runner/main.d.ts.map +1 -1
  341. package/out/zero-cache/src/server/runner/main.js +2 -1
  342. package/out/zero-cache/src/server/runner/main.js.map +1 -1
  343. package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
  344. package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
  345. package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
  346. package/out/zero-cache/src/server/shadow-syncer.js +6 -3
  347. package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
  348. package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
  349. package/out/zero-cache/src/server/syncer.js +8 -6
  350. package/out/zero-cache/src/server/syncer.js.map +1 -1
  351. package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
  352. package/out/zero-cache/src/server/worker-urls.js.map +1 -1
  353. package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
  354. package/out/zero-cache/src/services/analyze.js +5 -2
  355. package/out/zero-cache/src/services/analyze.js.map +1 -1
  356. package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
  357. package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
  358. package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
  359. package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
  360. package/out/zero-cache/src/services/change-source/pg/backfill-metadata.js.map +1 -1
  361. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +2 -2
  362. package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
  363. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  364. package/out/zero-cache/src/services/change-source/pg/change-source.js +2 -2
  365. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  366. package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
  367. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +8 -2
  368. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  369. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +13 -12
  370. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  371. package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
  372. package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
  373. package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
  374. package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
  375. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +1 -1
  376. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  377. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +33 -33
  378. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  379. package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
  380. package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
  381. package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
  382. package/out/zero-cache/src/services/change-source/pg/schema/shard.js +1 -1
  383. package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
  384. package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
  385. package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -1
  386. package/out/zero-cache/src/services/change-source/protocol/current/data.js +2 -0
  387. package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
  388. package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
  389. package/out/zero-cache/src/services/change-source/protocol/current/json.js.map +1 -1
  390. package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
  391. package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
  392. package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
  393. package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
  394. package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
  395. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  396. package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
  397. package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
  398. package/out/zero-cache/src/services/change-streamer/replica-monitor.js.map +1 -1
  399. package/out/zero-cache/src/services/change-streamer/schema/init.js +21 -25
  400. package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
  401. package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
  402. package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
  403. package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
  404. package/out/zero-cache/src/services/change-streamer/snapshot.js +15 -0
  405. package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
  406. package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
  407. package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
  408. package/out/zero-cache/src/services/heapz.js.map +1 -1
  409. package/out/zero-cache/src/services/http-service.js.map +1 -1
  410. package/out/zero-cache/src/services/life-cycle.d.ts +1 -1
  411. package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
  412. package/out/zero-cache/src/services/life-cycle.js +8 -3
  413. package/out/zero-cache/src/services/life-cycle.js.map +1 -1
  414. package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
  415. package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
  416. package/out/zero-cache/src/services/mutagen/error.js.map +1 -1
  417. package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
  418. package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
  419. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  420. package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
  421. package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
  422. package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
  423. package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
  424. package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
  425. package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
  426. package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
  427. package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
  428. package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
  429. package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
  430. package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
  431. package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
  432. package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
  433. package/out/zero-cache/src/services/run-ast.js +1 -0
  434. package/out/zero-cache/src/services/run-ast.js.map +1 -1
  435. package/out/zero-cache/src/services/runner.js.map +1 -1
  436. package/out/zero-cache/src/services/running-state.d.ts.map +1 -1
  437. package/out/zero-cache/src/services/running-state.js +3 -0
  438. package/out/zero-cache/src/services/running-state.js.map +1 -1
  439. package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
  440. package/out/zero-cache/src/services/statz.js.map +1 -1
  441. package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
  442. package/out/zero-cache/src/services/view-syncer/client-handler.js +1 -1
  443. package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
  444. package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
  445. package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
  446. package/out/zero-cache/src/services/view-syncer/cvr-purger.d.ts.map +1 -1
  447. package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -1
  448. package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
  449. package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
  450. package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
  451. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  452. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +1 -1
  453. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  454. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +1 -1
  455. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  456. package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
  457. package/out/zero-cache/src/services/view-syncer/row-set-signature.js.map +1 -1
  458. package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
  459. package/out/zero-cache/src/services/view-syncer/schema/init.js +97 -113
  460. package/out/zero-cache/src/services/view-syncer/schema/init.js.map +1 -1
  461. package/out/zero-cache/src/services/view-syncer/schema/types.js +103 -1
  462. package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
  463. package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
  464. package/out/zero-cache/src/services/view-syncer/tracer.js.map +1 -1
  465. package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
  466. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  467. package/out/zero-cache/src/services/view-syncer/view-syncer.js +15 -5
  468. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  469. package/out/zero-cache/src/types/configuration-error.d.ts +4 -0
  470. package/out/zero-cache/src/types/configuration-error.d.ts.map +1 -0
  471. package/out/zero-cache/src/types/configuration-error.js +11 -0
  472. package/out/zero-cache/src/types/configuration-error.js.map +1 -0
  473. package/out/zero-cache/src/types/error-with-level.js.map +1 -1
  474. package/out/zero-cache/src/types/http.js.map +1 -1
  475. package/out/zero-cache/src/types/lexi-version.js.map +1 -1
  476. package/out/zero-cache/src/types/lite.js.map +1 -1
  477. package/out/zero-cache/src/types/names.js.map +1 -1
  478. package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
  479. package/out/zero-cache/src/types/pg.d.ts +2 -0
  480. package/out/zero-cache/src/types/pg.d.ts.map +1 -1
  481. package/out/zero-cache/src/types/pg.js +34 -1
  482. package/out/zero-cache/src/types/pg.js.map +1 -1
  483. package/out/zero-cache/src/types/processes.js.map +1 -1
  484. package/out/zero-cache/src/types/profiler.js.map +1 -1
  485. package/out/zero-cache/src/types/row-key.js.map +1 -1
  486. package/out/zero-cache/src/types/shards.js.map +1 -1
  487. package/out/zero-cache/src/types/sql.js.map +1 -1
  488. package/out/zero-cache/src/types/state-version.js.map +1 -1
  489. package/out/zero-cache/src/types/streams.js.map +1 -1
  490. package/out/zero-cache/src/types/strings.js.map +1 -1
  491. package/out/zero-cache/src/types/subscription.js.map +1 -1
  492. package/out/zero-cache/src/types/timeout.js.map +1 -1
  493. package/out/zero-cache/src/types/url-params.js.map +1 -1
  494. package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
  495. package/out/zero-cache/src/types/ws.js.map +1 -1
  496. package/out/zero-cache/src/workers/connect-params.js.map +1 -1
  497. package/out/zero-cache/src/workers/connection.js.map +1 -1
  498. package/out/zero-cache/src/workers/mutator.js.map +1 -1
  499. package/out/zero-cache/src/workers/replicator.js.map +1 -1
  500. package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
  501. package/out/zero-cache/src/workers/syncer.js.map +1 -1
  502. package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
  503. package/out/zero-client/src/client/connection-manager.js +2 -1
  504. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  505. package/out/zero-client/src/client/connection.js.map +1 -1
  506. package/out/zero-client/src/client/context.js.map +1 -1
  507. package/out/zero-client/src/client/crud-impl.js.map +1 -1
  508. package/out/zero-client/src/client/crud.js.map +1 -1
  509. package/out/zero-client/src/client/custom.js +2 -1
  510. package/out/zero-client/src/client/custom.js.map +1 -1
  511. package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
  512. package/out/zero-client/src/client/enable-analytics.js.map +1 -1
  513. package/out/zero-client/src/client/error.js.map +1 -1
  514. package/out/zero-client/src/client/http-string.js.map +1 -1
  515. package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
  516. package/out/zero-client/src/client/inspector/client.js.map +1 -1
  517. package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
  518. package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
  519. package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
  520. package/out/zero-client/src/client/inspector/query.js.map +1 -1
  521. package/out/zero-client/src/client/ivm-branch.js.map +1 -1
  522. package/out/zero-client/src/client/keys.js.map +1 -1
  523. package/out/zero-client/src/client/log-options.js.map +1 -1
  524. package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
  525. package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
  526. package/out/zero-client/src/client/metrics.js.map +1 -1
  527. package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
  528. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  529. package/out/zero-client/src/client/options.js.map +1 -1
  530. package/out/zero-client/src/client/query-manager.js.map +1 -1
  531. package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
  532. package/out/zero-client/src/client/server-option.js.map +1 -1
  533. package/out/zero-client/src/client/version.js +1 -1
  534. package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
  535. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  536. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  537. package/out/zero-client/src/client/zero.js +58 -32
  538. package/out/zero-client/src/client/zero.js.map +1 -1
  539. package/out/zero-client/src/util/nanoid.js.map +1 -1
  540. package/out/zero-protocol/src/analyze-query-result.js +3 -0
  541. package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
  542. package/out/zero-protocol/src/application-error.js.map +1 -1
  543. package/out/zero-protocol/src/ast.js.map +1 -1
  544. package/out/zero-protocol/src/change-desired-queries.js +1 -0
  545. package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
  546. package/out/zero-protocol/src/client-schema.js.map +1 -1
  547. package/out/zero-protocol/src/close-connection.js.map +1 -1
  548. package/out/zero-protocol/src/connect.js +7 -0
  549. package/out/zero-protocol/src/connect.js.map +1 -1
  550. package/out/zero-protocol/src/custom-queries.js.map +1 -1
  551. package/out/zero-protocol/src/data.js.map +1 -1
  552. package/out/zero-protocol/src/delete-clients.js.map +1 -1
  553. package/out/zero-protocol/src/down.js.map +1 -1
  554. package/out/zero-protocol/src/error.js +7 -0
  555. package/out/zero-protocol/src/error.js.map +1 -1
  556. package/out/zero-protocol/src/inspect-down.js.map +1 -1
  557. package/out/zero-protocol/src/inspect-up.js +1 -0
  558. package/out/zero-protocol/src/inspect-up.js.map +1 -1
  559. package/out/zero-protocol/src/mutate-server.js.map +1 -1
  560. package/out/zero-protocol/src/mutation-id.js.map +1 -1
  561. package/out/zero-protocol/src/mutation.js.map +1 -1
  562. package/out/zero-protocol/src/mutations-patch.js.map +1 -1
  563. package/out/zero-protocol/src/ping.js.map +1 -1
  564. package/out/zero-protocol/src/poke.js +4 -0
  565. package/out/zero-protocol/src/poke.js.map +1 -1
  566. package/out/zero-protocol/src/pong.js.map +1 -1
  567. package/out/zero-protocol/src/primary-key.js.map +1 -1
  568. package/out/zero-protocol/src/protocol-version.js.map +1 -1
  569. package/out/zero-protocol/src/pull.js.map +1 -1
  570. package/out/zero-protocol/src/push.js +16 -0
  571. package/out/zero-protocol/src/push.js.map +1 -1
  572. package/out/zero-protocol/src/queries-patch.js.map +1 -1
  573. package/out/zero-protocol/src/query-hash.js.map +1 -1
  574. package/out/zero-protocol/src/query-server.js.map +1 -1
  575. package/out/zero-protocol/src/row-patch.js.map +1 -1
  576. package/out/zero-protocol/src/up.js.map +1 -1
  577. package/out/zero-protocol/src/update-auth.js.map +1 -1
  578. package/out/zero-protocol/src/version.js.map +1 -1
  579. package/out/zero-react/src/use-connection-state.js +4 -2
  580. package/out/zero-react/src/use-connection-state.js.map +1 -1
  581. package/out/zero-react/src/use-query.js +6 -4
  582. package/out/zero-react/src/use-query.js.map +1 -1
  583. package/out/zero-react/src/use-zero-online.js +4 -2
  584. package/out/zero-react/src/use-zero-online.js.map +1 -1
  585. package/out/zero-react/src/zero-provider.js +15 -12
  586. package/out/zero-react/src/zero-provider.js.map +1 -1
  587. package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
  588. package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
  589. package/out/zero-schema/src/builder/table-builder.js.map +1 -1
  590. package/out/zero-schema/src/compiled-permissions.js.map +1 -1
  591. package/out/zero-schema/src/name-mapper.js.map +1 -1
  592. package/out/zero-schema/src/permissions.js.map +1 -1
  593. package/out/zero-schema/src/schema-config.js.map +1 -1
  594. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  595. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  596. package/out/zero-server/src/adapters/pg.js +1 -1
  597. package/out/zero-server/src/adapters/pg.js.map +1 -1
  598. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  599. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  600. package/out/zero-server/src/custom.js +2 -1
  601. package/out/zero-server/src/custom.js.map +1 -1
  602. package/out/zero-server/src/logging.js.map +1 -1
  603. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  604. package/out/zero-server/src/process-mutations.js.map +1 -1
  605. package/out/zero-server/src/push-processor.js.map +1 -1
  606. package/out/zero-server/src/queries/process-queries.js.map +1 -1
  607. package/out/zero-server/src/schema.js.map +1 -1
  608. package/out/zero-server/src/zql-database.js.map +1 -1
  609. package/out/zero-solid/src/solid-view.js +1 -1
  610. package/out/zero-solid/src/solid-view.js.map +1 -1
  611. package/out/zero-solid/src/use-connection-state.js +1 -1
  612. package/out/zero-solid/src/use-connection-state.js.map +1 -1
  613. package/out/zero-solid/src/use-query.js +2 -2
  614. package/out/zero-solid/src/use-query.js.map +1 -1
  615. package/out/zero-solid/src/use-zero-online.js +1 -1
  616. package/out/zero-solid/src/use-zero-online.js.map +1 -1
  617. package/out/zero-solid/src/use-zero.js +1 -1
  618. package/out/zero-solid/src/use-zero.js.map +1 -1
  619. package/out/zero-types/src/format.js.map +1 -1
  620. package/out/zero-types/src/name-mapper.js.map +1 -1
  621. package/out/zql/src/builder/builder.d.ts.map +1 -1
  622. package/out/zql/src/builder/builder.js +18 -7
  623. package/out/zql/src/builder/builder.js.map +1 -1
  624. package/out/zql/src/builder/debug-delegate.d.ts +5 -0
  625. package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
  626. package/out/zql/src/builder/debug-delegate.js +10 -1
  627. package/out/zql/src/builder/debug-delegate.js.map +1 -1
  628. package/out/zql/src/builder/filter.js.map +1 -1
  629. package/out/zql/src/builder/like.js.map +1 -1
  630. package/out/zql/src/error.js.map +1 -1
  631. package/out/zql/src/ivm/array-view.js.map +1 -1
  632. package/out/zql/src/ivm/cap.d.ts +32 -0
  633. package/out/zql/src/ivm/cap.d.ts.map +1 -0
  634. package/out/zql/src/ivm/cap.js +205 -0
  635. package/out/zql/src/ivm/cap.js.map +1 -0
  636. package/out/zql/src/ivm/change.js.map +1 -1
  637. package/out/zql/src/ivm/constraint.js +1 -1
  638. package/out/zql/src/ivm/constraint.js.map +1 -1
  639. package/out/zql/src/ivm/data.js.map +1 -1
  640. package/out/zql/src/ivm/exists.js.map +1 -1
  641. package/out/zql/src/ivm/fan-in.js.map +1 -1
  642. package/out/zql/src/ivm/fan-out.js.map +1 -1
  643. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  644. package/out/zql/src/ivm/filter-push.js.map +1 -1
  645. package/out/zql/src/ivm/filter.js.map +1 -1
  646. package/out/zql/src/ivm/flipped-join.d.ts +4 -8
  647. package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
  648. package/out/zql/src/ivm/flipped-join.js +59 -63
  649. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  650. package/out/zql/src/ivm/join-utils.js.map +1 -1
  651. package/out/zql/src/ivm/join.js.map +1 -1
  652. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  653. package/out/zql/src/ivm/memory-source.js +1 -1
  654. package/out/zql/src/ivm/memory-source.js.map +1 -1
  655. package/out/zql/src/ivm/memory-storage.js.map +1 -1
  656. package/out/zql/src/ivm/operator.d.ts +1 -1
  657. package/out/zql/src/ivm/operator.js.map +1 -1
  658. package/out/zql/src/ivm/push-accumulated.js.map +1 -1
  659. package/out/zql/src/ivm/schema.d.ts +0 -8
  660. package/out/zql/src/ivm/schema.d.ts.map +1 -1
  661. package/out/zql/src/ivm/skip-yields.js.map +1 -1
  662. package/out/zql/src/ivm/skip.js.map +1 -1
  663. package/out/zql/src/ivm/source.js.map +1 -1
  664. package/out/zql/src/ivm/stream.js.map +1 -1
  665. package/out/zql/src/ivm/take.js +2 -2
  666. package/out/zql/src/ivm/take.js.map +1 -1
  667. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  668. package/out/zql/src/ivm/union-fan-in.js +3 -1
  669. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  670. package/out/zql/src/ivm/union-fan-out.js.map +1 -1
  671. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  672. package/out/zql/src/mutate/crud.js.map +1 -1
  673. package/out/zql/src/mutate/custom.js.map +1 -1
  674. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  675. package/out/zql/src/mutate/mutator.d.ts +12 -3
  676. package/out/zql/src/mutate/mutator.d.ts.map +1 -1
  677. package/out/zql/src/mutate/mutator.js.map +1 -1
  678. package/out/zql/src/planner/planner-builder.js.map +1 -1
  679. package/out/zql/src/planner/planner-connection.js.map +1 -1
  680. package/out/zql/src/planner/planner-constraint.js.map +1 -1
  681. package/out/zql/src/planner/planner-debug.js.map +1 -1
  682. package/out/zql/src/planner/planner-fan-in.js.map +1 -1
  683. package/out/zql/src/planner/planner-fan-out.js.map +1 -1
  684. package/out/zql/src/planner/planner-graph.js.map +1 -1
  685. package/out/zql/src/planner/planner-join.d.ts.map +1 -1
  686. package/out/zql/src/planner/planner-join.js +2 -1
  687. package/out/zql/src/planner/planner-join.js.map +1 -1
  688. package/out/zql/src/planner/planner-node.js.map +1 -1
  689. package/out/zql/src/planner/planner-source.js.map +1 -1
  690. package/out/zql/src/planner/planner-terminus.js.map +1 -1
  691. package/out/zql/src/query/complete-ordering.js.map +1 -1
  692. package/out/zql/src/query/create-builder.js.map +1 -1
  693. package/out/zql/src/query/error.js.map +1 -1
  694. package/out/zql/src/query/escape-like.js.map +1 -1
  695. package/out/zql/src/query/expression.js.map +1 -1
  696. package/out/zql/src/query/measure-push-operator.js.map +1 -1
  697. package/out/zql/src/query/metrics-delegate.js.map +1 -1
  698. package/out/zql/src/query/named.js.map +1 -1
  699. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  700. package/out/zql/src/query/query-impl.js +1 -1
  701. package/out/zql/src/query/query-impl.js.map +1 -1
  702. package/out/zql/src/query/query-internals.js.map +1 -1
  703. package/out/zql/src/query/query-registry.d.ts +10 -3
  704. package/out/zql/src/query/query-registry.d.ts.map +1 -1
  705. package/out/zql/src/query/query-registry.js.map +1 -1
  706. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  707. package/out/zql/src/query/static-query.js.map +1 -1
  708. package/out/zql/src/query/ttl.js.map +1 -1
  709. package/out/zql/src/query/validate-input.js.map +1 -1
  710. package/out/zqlite/src/database-storage.js.map +1 -1
  711. package/out/zqlite/src/db.js.map +1 -1
  712. package/out/zqlite/src/explain-queries.js.map +1 -1
  713. package/out/zqlite/src/internal/sql-inline.js.map +1 -1
  714. package/out/zqlite/src/internal/sql.js.map +1 -1
  715. package/out/zqlite/src/internal/statement-cache.js.map +1 -1
  716. package/out/zqlite/src/query-builder.js.map +1 -1
  717. package/out/zqlite/src/query-delegate.js.map +1 -1
  718. package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
  719. package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
  720. package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
  721. package/out/zqlite/src/table-source.d.ts.map +1 -1
  722. package/out/zqlite/src/table-source.js +7 -7
  723. package/out/zqlite/src/table-source.js.map +1 -1
  724. package/package.json +23 -23
  725. package/out/zero-client/src/util/socket.d.ts +0 -3
  726. package/out/zero-client/src/util/socket.d.ts.map +0 -1
  727. package/out/zero-client/src/util/socket.js +0 -8
  728. package/out/zero-client/src/util/socket.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"replica-schema.js","names":[],"sources":["../../../../../../../zero-cache/src/services/change-source/common/replica-schema.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {SqliteError} from '@rocicorp/zero-sqlite3';\nimport type {Database} from '../../../../../zqlite/src/db.ts';\nimport {listTables} from '../../../db/lite-tables.ts';\nimport {\n runSchemaMigrations,\n type IncrementalMigrationMap,\n type Migration,\n} from '../../../db/migration-lite.ts';\nimport {AutoResetSignal} from '../../change-streamer/schema/tables.ts';\nimport {populateFromExistingTables} from '../../replicator/schema/column-metadata.ts';\nimport {\n CREATE_RUNTIME_EVENTS_TABLE,\n recordEvent,\n} from '../../replicator/schema/replication-state.ts';\n\nexport async function initReplica(\n log: LogContext,\n debugName: string,\n dbPath: string,\n initialSync: (lc: LogContext, tx: Database) => Promise<void>,\n): Promise<void> {\n const setupMigration: Migration = {\n migrateSchema: (log, tx) => initialSync(log, tx),\n minSafeVersion: 1,\n };\n\n try {\n await runSchemaMigrations(\n log,\n debugName,\n dbPath,\n setupMigration,\n schemaVersionMigrationMap,\n );\n } catch (e) {\n if (e instanceof SqliteError && e.code === 'SQLITE_CORRUPT') {\n throw new AutoResetSignal(e.message);\n }\n throw e;\n }\n}\n\nexport async function upgradeReplica(\n log: LogContext,\n debugName: string,\n dbPath: string,\n) {\n await runSchemaMigrations(\n log,\n debugName,\n dbPath,\n // setupMigration should never be invoked\n {\n migrateSchema: () => {\n throw new Error(\n 'This should only be called for already synced replicas',\n );\n },\n },\n schemaVersionMigrationMap,\n );\n}\n\nexport const CREATE_V6_COLUMN_METADATA_TABLE = /*sql*/ `\n CREATE TABLE \"_zero.column_metadata\" (\n table_name TEXT NOT NULL,\n column_name TEXT NOT NULL,\n upstream_type TEXT NOT NULL,\n is_not_null INTEGER NOT NULL,\n is_enum INTEGER NOT NULL,\n is_array INTEGER NOT NULL,\n character_max_length INTEGER,\n PRIMARY KEY (table_name, column_name)\n );\n`;\n\nexport const CREATE_V7_CHANGE_LOG = /*sql*/ `\n CREATE TABLE \"_zero.changeLog2\" (\n \"stateVersion\" TEXT NOT NULL,\n \"pos\" INT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"rowKey\" TEXT NOT NULL,\n \"op\" TEXT NOT NULL,\n PRIMARY KEY(\"stateVersion\", \"pos\"),\n UNIQUE(\"table\", \"rowKey\")\n );\n`;\n\nexport const CREATE_V9_TABLE_METADATA_TABLE = /*sql*/ `\n CREATE TABLE \"_zero.tableMetadata\" (\n \"schema\" TEXT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"metadata\" TEXT NOT NULL,\n PRIMARY KEY (\"schema\", \"table\")\n );\n`;\n\nexport const schemaVersionMigrationMap: IncrementalMigrationMap = {\n // There's no incremental migration from v1. Just reset the replica.\n 4: {\n migrateSchema: () => {\n throw new AutoResetSignal('upgrading replica to new schema');\n },\n minSafeVersion: 3,\n },\n\n 5: {\n migrateSchema: (_, db) => {\n db.exec(CREATE_RUNTIME_EVENTS_TABLE);\n },\n migrateData: (_, db) => {\n recordEvent(db, 'upgrade');\n },\n },\n\n // Revised in the migration to v8 because the v6 code was incomplete.\n 6: {},\n\n 7: {\n migrateSchema: (_, db) => {\n // Note: The original \"changeLog\" table is kept so that the replica file\n // is compatible with older zero-caches. However, it is truncated for\n // space savings (since historic changes were never read).\n db.exec(`DELETE FROM \"_zero.changeLog\"`);\n // First version of changeLog2\n db.exec(CREATE_V7_CHANGE_LOG);\n },\n },\n\n 8: {\n migrateSchema: (_, db) => {\n const tableExists = db\n .prepare(\n `SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = '_zero.column_metadata'`,\n )\n .get();\n\n if (!tableExists) {\n db.exec(CREATE_V6_COLUMN_METADATA_TABLE);\n }\n },\n migrateData: (_, db) => {\n // Re-populate the ColumnMetadataStore; the original migration\n // at v6 was incomplete, as covered replicas migrated from earlier\n // versions but did not initialize the table for new replicas.\n db.exec(/*sql*/ `DELETE FROM \"_zero.column_metadata\"`);\n\n const tables = listTables(db, false, false);\n populateFromExistingTables(db, tables);\n },\n },\n\n 9: {\n migrateSchema: (_, db) => {\n db.exec(\n /*sql*/ `\n ALTER TABLE \"_zero.changeLog2\" \n ADD COLUMN \"backfillingColumnVersions\" TEXT DEFAULT '{}';\n ALTER TABLE \"_zero.column_metadata\"\n ADD COLUMN backfill TEXT;\n ` + CREATE_V9_TABLE_METADATA_TABLE,\n );\n },\n },\n\n 10: {\n migrateSchema: (_, db) => {\n db.exec(/*sql*/ `\n ALTER TABLE \"_zero.replicationConfig\" \n ADD COLUMN \"initialSyncContext\" TEXT DEFAULT '{}';\n `);\n },\n },\n\n 11: {\n migrateSchema: (_, db) => {\n db.exec(/*sql*/ `\n ALTER TABLE \"_zero.tableMetadata\"\n ADD COLUMN \"minRowVersion\" TEXT NOT NULL DEFAULT '00';\n\n -- Removing the NOT NULL constraint from \"metadata\" requires copying\n -- the column. We piggyback the rename to \"upstreamMetadata\" here.\n ALTER TABLE \"_zero.tableMetadata\"\n ADD COLUMN \"upstreamMetadata\" TEXT;\n UPDATE \"_zero.tableMetadata\" SET \"upstreamMetadata\" = \"metadata\";\n ALTER TABLE \"_zero.tableMetadata\" DROP \"metadata\";\n `);\n },\n },\n\n 12: {\n migrateSchema: (_, db) => {\n // Bring back the \"metadata\" column removed in v11, but as a NULL-able column.\n // It is needed for backwards compatibility.\n db.exec(/*sql*/ `\n ALTER TABLE \"_zero.tableMetadata\"\n ADD COLUMN \"metadata\" TEXT;\n `);\n },\n\n migrateData: (_, db) => {\n // For rollback then roll forward, re-copy anything written to metadata.\n db.exec(/*sql*/ `\n UPDATE \"_zero.tableMetadata\" \n SET \"upstreamMetadata\" = COALESCE(\"metadata\", \"upstreamMetadata\"),\n \"metadata\" = NULL;\n `);\n },\n },\n\n 13: {\n migrateSchema: (_, db) => {\n db.exec(/*sql*/ `\n ALTER TABLE \"_zero.replicationState\" ADD COLUMN writeTimeMs INTEGER;\n `);\n },\n\n migrateData: (_, db) => {\n db.exec(/*sql*/ `\n UPDATE \"_zero.replicationState\" \n SET writeTimeMs = COALESCE(writeTimeMs, unixepoch('subsec') * 1000)`);\n },\n },\n};\n\n// Referenced in tests.\nexport const CURRENT_SCHEMA_VERSION = Object.keys(\n schemaVersionMigrationMap,\n).reduce((prev, curr) => Math.max(prev, parseInt(curr)), 0);\n"],"mappings":";;;;;;;AAgBA,eAAsB,YACpB,KACA,WACA,QACA,aACe;CACf,MAAM,iBAA4B;EAChC,gBAAgB,KAAK,OAAO,YAAY,KAAK,GAAG;EAChD,gBAAgB;EACjB;AAED,KAAI;AACF,QAAM,oBACJ,KACA,WACA,QACA,gBACA,0BACD;UACM,GAAG;AACV,MAAI,aAAa,eAAe,EAAE,SAAS,iBACzC,OAAM,IAAI,gBAAgB,EAAE,QAAQ;AAEtC,QAAM;;;AAIV,eAAsB,eACpB,KACA,WACA,QACA;AACA,OAAM,oBACJ,KACA,WACA,QAEA,EACE,qBAAqB;AACnB,QAAM,IAAI,MACR,yDACD;IAEJ,EACD,0BACD;;AAGH,IAAa,kCAA0C;;;;;;;;;;;;AAavD,IAAa,uBAA+B;;;;;;;;;;;AAY5C,IAAa,iCAAyC;;;;;;;;AAStD,IAAa,4BAAqD;CAEhE,GAAG;EACD,qBAAqB;AACnB,SAAM,IAAI,gBAAgB,kCAAkC;;EAE9D,gBAAgB;EACjB;CAED,GAAG;EACD,gBAAgB,GAAG,OAAO;AACxB,MAAG,KAAK,4BAA4B;;EAEtC,cAAc,GAAG,OAAO;AACtB,eAAY,IAAI,UAAU;;EAE7B;CAGD,GAAG,EAAE;CAEL,GAAG,EACD,gBAAgB,GAAG,OAAO;AAIxB,KAAG,KAAK,gCAAgC;AAExC,KAAG,KAAK,qBAAqB;IAEhC;CAED,GAAG;EACD,gBAAgB,GAAG,OAAO;AAOxB,OAAI,CANgB,GACjB,QACC,sFACD,CACA,KAAK,CAGN,IAAG,KAAK,gCAAgC;;EAG5C,cAAc,GAAG,OAAO;AAItB,MAAG,KAAa,sCAAsC;AAGtD,8BAA2B,IADZ,WAAW,IAAI,OAAO,MAAM,CACL;;EAEzC;CAED,GAAG,EACD,gBAAgB,GAAG,OAAO;AACxB,KAAG,KACO;;;;;UAKN,+BACH;IAEJ;CAED,IAAI,EACF,gBAAgB,GAAG,OAAO;AACxB,KAAG,KAAa;;;QAGd;IAEL;CAED,IAAI,EACF,gBAAgB,GAAG,OAAO;AACxB,KAAG,KAAa;;;;;;;;;;QAUd;IAEL;CAED,IAAI;EACF,gBAAgB,GAAG,OAAO;AAGxB,MAAG,KAAa;;;QAGd;;EAGJ,cAAc,GAAG,OAAO;AAEtB,MAAG,KAAa;;;;QAId;;EAEL;CAED,IAAI;EACF,gBAAgB,GAAG,OAAO;AACxB,MAAG,KAAa;;QAEd;;EAGJ,cAAc,GAAG,OAAO;AACtB,MAAG,KAAa;;+EAEyD;;EAE5E;CACF;AAGqC,OAAO,KAC3C,0BACD,CAAC,QAAQ,MAAM,SAAS,KAAK,IAAI,MAAM,SAAS,KAAK,CAAC,EAAE,EAAE"}
1
+ {"version":3,"file":"replica-schema.js","names":[],"sources":["../../../../../../../zero-cache/src/services/change-source/common/replica-schema.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {SqliteError} from '@rocicorp/zero-sqlite3';\nimport type {Database} from '../../../../../zqlite/src/db.ts';\nimport {listTables} from '../../../db/lite-tables.ts';\nimport {\n runSchemaMigrations,\n type IncrementalMigrationMap,\n type Migration,\n} from '../../../db/migration-lite.ts';\nimport {AutoResetSignal} from '../../change-streamer/schema/tables.ts';\nimport {populateFromExistingTables} from '../../replicator/schema/column-metadata.ts';\nimport {\n CREATE_RUNTIME_EVENTS_TABLE,\n recordEvent,\n} from '../../replicator/schema/replication-state.ts';\n\nexport async function initReplica(\n log: LogContext,\n debugName: string,\n dbPath: string,\n initialSync: (lc: LogContext, tx: Database) => Promise<void>,\n): Promise<void> {\n const setupMigration: Migration = {\n migrateSchema: (log, tx) => initialSync(log, tx),\n minSafeVersion: 1,\n };\n\n try {\n await runSchemaMigrations(\n log,\n debugName,\n dbPath,\n setupMigration,\n schemaVersionMigrationMap,\n );\n } catch (e) {\n if (e instanceof SqliteError && e.code === 'SQLITE_CORRUPT') {\n throw new AutoResetSignal(e.message);\n }\n throw e;\n }\n}\n\nexport async function upgradeReplica(\n log: LogContext,\n debugName: string,\n dbPath: string,\n) {\n await runSchemaMigrations(\n log,\n debugName,\n dbPath,\n // setupMigration should never be invoked\n {\n migrateSchema: () => {\n throw new Error(\n 'This should only be called for already synced replicas',\n );\n },\n },\n schemaVersionMigrationMap,\n );\n}\n\nexport const CREATE_V6_COLUMN_METADATA_TABLE = /*sql*/ `\n CREATE TABLE \"_zero.column_metadata\" (\n table_name TEXT NOT NULL,\n column_name TEXT NOT NULL,\n upstream_type TEXT NOT NULL,\n is_not_null INTEGER NOT NULL,\n is_enum INTEGER NOT NULL,\n is_array INTEGER NOT NULL,\n character_max_length INTEGER,\n PRIMARY KEY (table_name, column_name)\n );\n`;\n\nexport const CREATE_V7_CHANGE_LOG = /*sql*/ `\n CREATE TABLE \"_zero.changeLog2\" (\n \"stateVersion\" TEXT NOT NULL,\n \"pos\" INT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"rowKey\" TEXT NOT NULL,\n \"op\" TEXT NOT NULL,\n PRIMARY KEY(\"stateVersion\", \"pos\"),\n UNIQUE(\"table\", \"rowKey\")\n );\n`;\n\nexport const CREATE_V9_TABLE_METADATA_TABLE = /*sql*/ `\n CREATE TABLE \"_zero.tableMetadata\" (\n \"schema\" TEXT NOT NULL,\n \"table\" TEXT NOT NULL,\n \"metadata\" TEXT NOT NULL,\n PRIMARY KEY (\"schema\", \"table\")\n );\n`;\n\nexport const schemaVersionMigrationMap: IncrementalMigrationMap = {\n // There's no incremental migration from v1. Just reset the replica.\n 4: {\n migrateSchema: () => {\n throw new AutoResetSignal('upgrading replica to new schema');\n },\n minSafeVersion: 3,\n },\n\n 5: {\n migrateSchema: (_, db) => {\n db.exec(CREATE_RUNTIME_EVENTS_TABLE);\n },\n migrateData: (_, db) => {\n recordEvent(db, 'upgrade');\n },\n },\n\n // Revised in the migration to v8 because the v6 code was incomplete.\n 6: {},\n\n 7: {\n migrateSchema: (_, db) => {\n // Note: The original \"changeLog\" table is kept so that the replica file\n // is compatible with older zero-caches. However, it is truncated for\n // space savings (since historic changes were never read).\n db.exec(`DELETE FROM \"_zero.changeLog\"`);\n // First version of changeLog2\n db.exec(CREATE_V7_CHANGE_LOG);\n },\n },\n\n 8: {\n migrateSchema: (_, db) => {\n const tableExists = db\n .prepare(\n `SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = '_zero.column_metadata'`,\n )\n .get();\n\n if (!tableExists) {\n db.exec(CREATE_V6_COLUMN_METADATA_TABLE);\n }\n },\n migrateData: (_, db) => {\n // Re-populate the ColumnMetadataStore; the original migration\n // at v6 was incomplete, as covered replicas migrated from earlier\n // versions but did not initialize the table for new replicas.\n db.exec(/*sql*/ `DELETE FROM \"_zero.column_metadata\"`);\n\n const tables = listTables(db, false, false);\n populateFromExistingTables(db, tables);\n },\n },\n\n 9: {\n migrateSchema: (_, db) => {\n db.exec(\n /*sql*/ `\n ALTER TABLE \"_zero.changeLog2\" \n ADD COLUMN \"backfillingColumnVersions\" TEXT DEFAULT '{}';\n ALTER TABLE \"_zero.column_metadata\"\n ADD COLUMN backfill TEXT;\n ` + CREATE_V9_TABLE_METADATA_TABLE,\n );\n },\n },\n\n 10: {\n migrateSchema: (_, db) => {\n db.exec(/*sql*/ `\n ALTER TABLE \"_zero.replicationConfig\" \n ADD COLUMN \"initialSyncContext\" TEXT DEFAULT '{}';\n `);\n },\n },\n\n 11: {\n migrateSchema: (_, db) => {\n db.exec(/*sql*/ `\n ALTER TABLE \"_zero.tableMetadata\"\n ADD COLUMN \"minRowVersion\" TEXT NOT NULL DEFAULT '00';\n\n -- Removing the NOT NULL constraint from \"metadata\" requires copying\n -- the column. We piggyback the rename to \"upstreamMetadata\" here.\n ALTER TABLE \"_zero.tableMetadata\"\n ADD COLUMN \"upstreamMetadata\" TEXT;\n UPDATE \"_zero.tableMetadata\" SET \"upstreamMetadata\" = \"metadata\";\n ALTER TABLE \"_zero.tableMetadata\" DROP \"metadata\";\n `);\n },\n },\n\n 12: {\n migrateSchema: (_, db) => {\n // Bring back the \"metadata\" column removed in v11, but as a NULL-able column.\n // It is needed for backwards compatibility.\n db.exec(/*sql*/ `\n ALTER TABLE \"_zero.tableMetadata\"\n ADD COLUMN \"metadata\" TEXT;\n `);\n },\n\n migrateData: (_, db) => {\n // For rollback then roll forward, re-copy anything written to metadata.\n db.exec(/*sql*/ `\n UPDATE \"_zero.tableMetadata\" \n SET \"upstreamMetadata\" = COALESCE(\"metadata\", \"upstreamMetadata\"),\n \"metadata\" = NULL;\n `);\n },\n },\n\n 13: {\n migrateSchema: (_, db) => {\n db.exec(/*sql*/ `\n ALTER TABLE \"_zero.replicationState\" ADD COLUMN writeTimeMs INTEGER;\n `);\n },\n\n migrateData: (_, db) => {\n db.exec(/*sql*/ `\n UPDATE \"_zero.replicationState\" \n SET writeTimeMs = COALESCE(writeTimeMs, unixepoch('subsec') * 1000)`);\n },\n },\n};\n\n// Referenced in tests.\nexport const CURRENT_SCHEMA_VERSION = Object.keys(\n schemaVersionMigrationMap,\n).reduce((prev, curr) => Math.max(prev, parseInt(curr)), 0);\n"],"mappings":";;;;;;;AAgBA,eAAsB,YACpB,KACA,WACA,QACA,aACe;CACf,MAAM,iBAA4B;EAChC,gBAAgB,KAAK,OAAO,YAAY,KAAK,EAAE;EAC/C,gBAAgB;CAClB;CAEA,IAAI;EACF,MAAM,oBACJ,KACA,WACA,QACA,gBACA,yBACF;CACF,SAAS,GAAG;EACV,IAAI,aAAa,eAAe,EAAE,SAAS,kBACzC,MAAM,IAAI,gBAAgB,EAAE,OAAO;EAErC,MAAM;CACR;AACF;AAEA,eAAsB,eACpB,KACA,WACA,QACA;CACA,MAAM,oBACJ,KACA,WACA,QAEA,EACE,qBAAqB;EACnB,MAAM,IAAI,MACR,wDACF;CACF,EACF,GACA,yBACF;AACF;AAEA,IAAa,kCAA0C;;;;;;;;;;;;AAavD,IAAa,uBAA+B;;;;;;;;;;;AAY5C,IAAa,iCAAyC;;;;;;;;AAStD,IAAa,4BAAqD;CAEhE,GAAG;EACD,qBAAqB;GACnB,MAAM,IAAI,gBAAgB,iCAAiC;EAC7D;EACA,gBAAgB;CAClB;CAEA,GAAG;EACD,gBAAgB,GAAG,OAAO;GACxB,GAAG,KAAK,2BAA2B;EACrC;EACA,cAAc,GAAG,OAAO;GACtB,YAAY,IAAI,SAAS;EAC3B;CACF;CAGA,GAAG,CAAC;CAEJ,GAAG,EACD,gBAAgB,GAAG,OAAO;EAIxB,GAAG,KAAK,+BAA+B;EAEvC,GAAG,KAAK,oBAAoB;CAC9B,EACF;CAEA,GAAG;EACD,gBAAgB,GAAG,OAAO;GAOxB,IAAI,CANgB,GACjB,QACC,qFACF,EACC,IAEE,GACH,GAAG,KAAK,+BAA+B;EAE3C;EACA,cAAc,GAAG,OAAO;GAItB,GAAG,KAAa,qCAAqC;GAGrD,2BAA2B,IADZ,WAAW,IAAI,OAAO,KACN,CAAM;EACvC;CACF;CAEA,GAAG,EACD,gBAAgB,GAAG,OAAO;EACxB,GAAG,KACO;;;;;UAKN,8BACJ;CACF,EACF;CAEA,IAAI,EACF,gBAAgB,GAAG,OAAO;EACxB,GAAG,KAAa;;;OAGf;CACH,EACF;CAEA,IAAI,EACF,gBAAgB,GAAG,OAAO;EACxB,GAAG,KAAa;;;;;;;;;;OAUf;CACH,EACF;CAEA,IAAI;EACF,gBAAgB,GAAG,OAAO;GAGxB,GAAG,KAAa;;;OAGf;EACH;EAEA,cAAc,GAAG,OAAO;GAEtB,GAAG,KAAa;;;;OAIf;EACH;CACF;CAEA,IAAI;EACF,gBAAgB,GAAG,OAAO;GACxB,GAAG,KAAa;;OAEf;EACH;EAEA,cAAc,GAAG,OAAO;GACtB,GAAG,KAAa;;8EAEwD;EAC1E;CACF;AACF;AAGsC,OAAO,KAC3C,yBACF,EAAE,QAAQ,MAAM,SAAS,KAAK,IAAI,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"change-source.js","names":["#lc","#upstreamUri","#shard","#replicationConfig","#startStream"],"sources":["../../../../../../../zero-cache/src/services/change-source/custom/change-source.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {WebSocket} from 'ws';\nimport {assert, unreachable} from '../../../../../shared/src/asserts.ts';\nimport {\n stringify,\n type JSONObject,\n} from '../../../../../shared/src/bigint-json.ts';\nimport {deepEqual} from '../../../../../shared/src/json.ts';\nimport type {SchemaValue} from '../../../../../zero-schema/src/table-schema.ts';\nimport {Database} from '../../../../../zqlite/src/db.ts';\nimport {computeZqlSpecs} from '../../../db/lite-tables.ts';\nimport {StatementRunner} from '../../../db/statements.ts';\nimport type {ShardConfig, ShardID} from '../../../types/shards.ts';\nimport {stream} from '../../../types/streams.ts';\nimport {\n AutoResetSignal,\n type ReplicationConfig,\n} from '../../change-streamer/schema/tables.ts';\nimport {ChangeProcessor} from '../../replicator/change-processor.ts';\nimport {ReplicationStatusPublisher} from '../../replicator/replication-status.ts';\nimport {\n createReplicationStateTables,\n getSubscriptionState,\n initReplicationState,\n type SubscriptionState,\n} from '../../replicator/schema/replication-state.ts';\nimport type {ChangeSource, ChangeStream} from '../change-source.ts';\nimport {initReplica} from '../common/replica-schema.ts';\nimport {changeStreamMessageSchema} from '../protocol/current/downstream.ts';\nimport {\n type BackfillRequest,\n type ChangeSourceUpstream,\n} from '../protocol/current/upstream.ts';\n\n/** Server context to store with the initial sync metadata for debugging. */\nexport type ServerContext = JSONObject;\n\n/**\n * Initializes a Custom change source before streaming changes from the\n * corresponding logical replication stream.\n */\nexport async function initializeCustomChangeSource(\n lc: LogContext,\n upstreamURI: string,\n shard: ShardConfig,\n replicaDbFile: string,\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, context),\n );\n\n const replica = new Database(lc, replicaDbFile);\n const subscriptionState = getSubscriptionState(new StatementRunner(replica));\n replica.close();\n\n if (shard.publications.length) {\n // Verify that the publications match what has been synced.\n const requested = shard.publications.toSorted();\n const replicated = subscriptionState.publications.sort();\n if (!deepEqual(requested, replicated)) {\n throw new Error(\n `Invalid ShardConfig. Requested publications [${requested}] do not match synced publications: [${replicated}]`,\n );\n }\n }\n\n const changeSource = new CustomChangeSource(\n lc,\n upstreamURI,\n shard,\n subscriptionState,\n );\n\n return {subscriptionState, changeSource};\n}\n\nclass CustomChangeSource implements ChangeSource {\n readonly #lc: LogContext;\n readonly #upstreamUri: string;\n readonly #shard: ShardID;\n readonly #replicationConfig: ReplicationConfig;\n\n constructor(\n lc: LogContext,\n upstreamUri: string,\n shard: ShardID,\n replicationConfig: ReplicationConfig,\n ) {\n this.#lc = lc.withContext('component', 'change-source');\n this.#upstreamUri = upstreamUri;\n this.#shard = shard;\n this.#replicationConfig = replicationConfig;\n }\n\n initialSync(): ChangeStream {\n return this.#startStream();\n }\n\n startLagReporter() {\n return null; // Not supported for custom sources\n }\n\n stop(): Promise<void> {\n return Promise.resolve();\n }\n\n startStream(\n clientWatermark: string,\n backfillRequests: BackfillRequest[] = [],\n ): Promise<ChangeStream> {\n if (backfillRequests?.length) {\n throw new Error(\n 'backfill is yet not supported for custom change sources',\n );\n }\n return Promise.resolve(this.#startStream(clientWatermark));\n }\n\n #startStream(clientWatermark?: string): ChangeStream {\n const {publications, replicaVersion} = this.#replicationConfig;\n const {appID, shardNum} = this.#shard;\n const url = new URL(this.#upstreamUri);\n url.searchParams.set('appID', appID);\n url.searchParams.set('shardNum', String(shardNum));\n for (const pub of publications) {\n url.searchParams.append('publications', pub);\n }\n if (clientWatermark) {\n assert(\n replicaVersion.length,\n 'replicaVersion is required when clientWatermark is set',\n );\n url.searchParams.set('lastWatermark', clientWatermark);\n url.searchParams.set('replicaVersion', replicaVersion);\n }\n\n const ws = new WebSocket(url);\n const {instream, outstream} = stream(\n this.#lc,\n ws,\n changeStreamMessageSchema,\n // Upstream acks coalesce. If upstream exhibits back-pressure,\n // only the last ACK is kept / buffered.\n {coalesce: (curr: ChangeSourceUpstream) => curr},\n );\n return {changes: instream, acks: outstream};\n }\n}\n\n/**\n * Initial sync for a custom change source makes a request to the\n * change source endpoint with no `replicaVersion` or `lastWatermark`.\n * The initial transaction returned by the endpoint is treated as\n * the initial sync, and the commit watermark of that transaction\n * becomes the `replicaVersion` of the initialized replica.\n *\n * Note that this is equivalent to how the LSN of the Postgres WAL\n * at initial sync time is the `replicaVersion` (and starting\n * version for all initially-synced rows).\n */\nexport async function initialSync(\n lc: LogContext,\n shard: ShardConfig,\n tx: Database,\n upstreamURI: string,\n context: ServerContext,\n) {\n const {appID: id, publications} = shard;\n const changeSource = new CustomChangeSource(lc, upstreamURI, shard, {\n replicaVersion: '', // ignored for initialSync()\n publications,\n });\n const {changes} = changeSource.initialSync();\n\n createReplicationStateTables(tx);\n const processor = new ChangeProcessor(\n new StatementRunner(tx),\n 'initial-sync',\n (_, err) => {\n throw err;\n },\n );\n\n const statusPublisher = ReplicationStatusPublisher.forRunningTransaction(tx);\n try {\n let num = 0;\n for await (const change of changes) {\n const [tag] = change;\n switch (tag) {\n case 'begin': {\n const {commitWatermark} = change[2];\n lc.info?.(\n `initial sync of shard ${id} at replicaVersion ${commitWatermark}`,\n );\n statusPublisher.publish(\n lc,\n 'Initializing',\n `Copying upstream tables at version ${commitWatermark}`,\n 5000,\n );\n initReplicationState(\n tx,\n publications.toSorted(),\n commitWatermark,\n context,\n false,\n );\n processor.processMessage(lc, change);\n break;\n }\n case 'data':\n processor.processMessage(lc, change);\n if (++num % 1000 === 0) {\n lc.debug?.(`processed ${num} changes`);\n }\n break;\n case 'commit':\n processor.processMessage(lc, change);\n validateInitiallySyncedData(lc, tx, shard);\n lc.info?.(`finished initial-sync of ${num} changes`);\n return;\n\n case 'status':\n break; // Ignored\n // @ts-expect-error: falls through if the tag is not 'reset-required\n case 'control': {\n const {tag, message} = change[1];\n if (tag === 'reset-required') {\n throw new AutoResetSignal(\n message ?? 'auto-reset signaled by change source',\n );\n }\n }\n // falls through\n case 'rollback':\n throw new Error(\n `unexpected message during initial-sync: ${stringify(change)}`,\n );\n default:\n unreachable(change);\n }\n }\n throw new Error(\n `change source ${upstreamURI} closed before initial-sync completed`,\n );\n } catch (e) {\n await statusPublisher.publishAndThrowError(lc, 'Initializing', e);\n } finally {\n statusPublisher.stop();\n }\n}\n\n// Verify that the upstream tables expected by the sync logic\n// have been properly initialized.\nfunction getRequiredTables({\n appID,\n shardNum,\n}: ShardID): Record<string, Record<string, SchemaValue>> {\n return {\n [`${appID}_${shardNum}.clients`]: {\n clientGroupID: {type: 'string'},\n clientID: {type: 'string'},\n lastMutationID: {type: 'number'},\n userID: {type: 'string'},\n },\n [`${appID}_${shardNum}.mutations`]: {\n clientGroupID: {type: 'string'},\n clientID: {type: 'string'},\n mutationID: {type: 'number'},\n mutation: {type: 'json'},\n },\n [`${appID}.permissions`]: {\n permissions: {type: 'json'},\n hash: {type: 'string'},\n },\n };\n}\n\nfunction validateInitiallySyncedData(\n lc: LogContext,\n db: Database,\n shard: ShardID,\n) {\n const tables = computeZqlSpecs(lc, db, {includeBackfillingColumns: true});\n const required = getRequiredTables(shard);\n for (const [name, columns] of Object.entries(required)) {\n const table = tables.get(name)?.zqlSpec;\n if (!table) {\n throw new Error(\n `Upstream is missing the \"${name}\" table. (Found ${[\n ...tables.keys(),\n ]})` +\n `Please ensure that each table has a unique index over one ` +\n `or more non-null columns.`,\n );\n }\n for (const [col, {type}] of Object.entries(columns)) {\n const found = table[col];\n if (!found) {\n throw new Error(\n `Upstream \"${table}\" table is missing the \"${col}\" column`,\n );\n }\n if (found.type !== type) {\n throw new Error(\n `Upstream \"${table}.${col}\" column is a ${found.type} type but must be a ${type} type.`,\n );\n }\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"change-source.js","names":["#lc","#upstreamUri","#shard","#replicationConfig","#startStream"],"sources":["../../../../../../../zero-cache/src/services/change-source/custom/change-source.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {WebSocket} from 'ws';\nimport {assert, unreachable} from '../../../../../shared/src/asserts.ts';\nimport {\n stringify,\n type JSONObject,\n} from '../../../../../shared/src/bigint-json.ts';\nimport {deepEqual} from '../../../../../shared/src/json.ts';\nimport type {SchemaValue} from '../../../../../zero-schema/src/table-schema.ts';\nimport {Database} from '../../../../../zqlite/src/db.ts';\nimport {computeZqlSpecs} from '../../../db/lite-tables.ts';\nimport {StatementRunner} from '../../../db/statements.ts';\nimport type {ShardConfig, ShardID} from '../../../types/shards.ts';\nimport {stream} from '../../../types/streams.ts';\nimport {\n AutoResetSignal,\n type ReplicationConfig,\n} from '../../change-streamer/schema/tables.ts';\nimport {ChangeProcessor} from '../../replicator/change-processor.ts';\nimport {ReplicationStatusPublisher} from '../../replicator/replication-status.ts';\nimport {\n createReplicationStateTables,\n getSubscriptionState,\n initReplicationState,\n type SubscriptionState,\n} from '../../replicator/schema/replication-state.ts';\nimport type {ChangeSource, ChangeStream} from '../change-source.ts';\nimport {initReplica} from '../common/replica-schema.ts';\nimport {changeStreamMessageSchema} from '../protocol/current/downstream.ts';\nimport {\n type BackfillRequest,\n type ChangeSourceUpstream,\n} from '../protocol/current/upstream.ts';\n\n/** Server context to store with the initial sync metadata for debugging. */\nexport type ServerContext = JSONObject;\n\n/**\n * Initializes a Custom change source before streaming changes from the\n * corresponding logical replication stream.\n */\nexport async function initializeCustomChangeSource(\n lc: LogContext,\n upstreamURI: string,\n shard: ShardConfig,\n replicaDbFile: string,\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, context),\n );\n\n const replica = new Database(lc, replicaDbFile);\n const subscriptionState = getSubscriptionState(new StatementRunner(replica));\n replica.close();\n\n if (shard.publications.length) {\n // Verify that the publications match what has been synced.\n const requested = shard.publications.toSorted();\n const replicated = subscriptionState.publications.sort();\n if (!deepEqual(requested, replicated)) {\n throw new Error(\n `Invalid ShardConfig. Requested publications [${requested}] do not match synced publications: [${replicated}]`,\n );\n }\n }\n\n const changeSource = new CustomChangeSource(\n lc,\n upstreamURI,\n shard,\n subscriptionState,\n );\n\n return {subscriptionState, changeSource};\n}\n\nclass CustomChangeSource implements ChangeSource {\n readonly #lc: LogContext;\n readonly #upstreamUri: string;\n readonly #shard: ShardID;\n readonly #replicationConfig: ReplicationConfig;\n\n constructor(\n lc: LogContext,\n upstreamUri: string,\n shard: ShardID,\n replicationConfig: ReplicationConfig,\n ) {\n this.#lc = lc.withContext('component', 'change-source');\n this.#upstreamUri = upstreamUri;\n this.#shard = shard;\n this.#replicationConfig = replicationConfig;\n }\n\n initialSync(): ChangeStream {\n return this.#startStream();\n }\n\n startLagReporter() {\n return null; // Not supported for custom sources\n }\n\n stop(): Promise<void> {\n return Promise.resolve();\n }\n\n startStream(\n clientWatermark: string,\n backfillRequests: BackfillRequest[] = [],\n ): Promise<ChangeStream> {\n if (backfillRequests?.length) {\n throw new Error(\n 'backfill is yet not supported for custom change sources',\n );\n }\n return Promise.resolve(this.#startStream(clientWatermark));\n }\n\n #startStream(clientWatermark?: string): ChangeStream {\n const {publications, replicaVersion} = this.#replicationConfig;\n const {appID, shardNum} = this.#shard;\n const url = new URL(this.#upstreamUri);\n url.searchParams.set('appID', appID);\n url.searchParams.set('shardNum', String(shardNum));\n for (const pub of publications) {\n url.searchParams.append('publications', pub);\n }\n if (clientWatermark) {\n assert(\n replicaVersion.length,\n 'replicaVersion is required when clientWatermark is set',\n );\n url.searchParams.set('lastWatermark', clientWatermark);\n url.searchParams.set('replicaVersion', replicaVersion);\n }\n\n const ws = new WebSocket(url);\n const {instream, outstream} = stream(\n this.#lc,\n ws,\n changeStreamMessageSchema,\n // Upstream acks coalesce. If upstream exhibits back-pressure,\n // only the last ACK is kept / buffered.\n {coalesce: (curr: ChangeSourceUpstream) => curr},\n );\n return {changes: instream, acks: outstream};\n }\n}\n\n/**\n * Initial sync for a custom change source makes a request to the\n * change source endpoint with no `replicaVersion` or `lastWatermark`.\n * The initial transaction returned by the endpoint is treated as\n * the initial sync, and the commit watermark of that transaction\n * becomes the `replicaVersion` of the initialized replica.\n *\n * Note that this is equivalent to how the LSN of the Postgres WAL\n * at initial sync time is the `replicaVersion` (and starting\n * version for all initially-synced rows).\n */\nexport async function initialSync(\n lc: LogContext,\n shard: ShardConfig,\n tx: Database,\n upstreamURI: string,\n context: ServerContext,\n) {\n const {appID: id, publications} = shard;\n const changeSource = new CustomChangeSource(lc, upstreamURI, shard, {\n replicaVersion: '', // ignored for initialSync()\n publications,\n });\n const {changes} = changeSource.initialSync();\n\n createReplicationStateTables(tx);\n const processor = new ChangeProcessor(\n new StatementRunner(tx),\n 'initial-sync',\n (_, err) => {\n throw err;\n },\n );\n\n const statusPublisher = ReplicationStatusPublisher.forRunningTransaction(tx);\n try {\n let num = 0;\n for await (const change of changes) {\n const [tag] = change;\n switch (tag) {\n case 'begin': {\n const {commitWatermark} = change[2];\n lc.info?.(\n `initial sync of shard ${id} at replicaVersion ${commitWatermark}`,\n );\n statusPublisher.publish(\n lc,\n 'Initializing',\n `Copying upstream tables at version ${commitWatermark}`,\n 5000,\n );\n initReplicationState(\n tx,\n publications.toSorted(),\n commitWatermark,\n context,\n false,\n );\n processor.processMessage(lc, change);\n break;\n }\n case 'data':\n processor.processMessage(lc, change);\n if (++num % 1000 === 0) {\n lc.debug?.(`processed ${num} changes`);\n }\n break;\n case 'commit':\n processor.processMessage(lc, change);\n validateInitiallySyncedData(lc, tx, shard);\n lc.info?.(`finished initial-sync of ${num} changes`);\n return;\n\n case 'status':\n break; // Ignored\n // @ts-expect-error: falls through if the tag is not 'reset-required\n case 'control': {\n const {tag, message} = change[1];\n if (tag === 'reset-required') {\n throw new AutoResetSignal(\n message ?? 'auto-reset signaled by change source',\n );\n }\n }\n // falls through\n case 'rollback':\n throw new Error(\n `unexpected message during initial-sync: ${stringify(change)}`,\n );\n default:\n unreachable(change);\n }\n }\n throw new Error(\n `change source ${upstreamURI} closed before initial-sync completed`,\n );\n } catch (e) {\n await statusPublisher.publishAndThrowError(lc, 'Initializing', e);\n } finally {\n statusPublisher.stop();\n }\n}\n\n// Verify that the upstream tables expected by the sync logic\n// have been properly initialized.\nfunction getRequiredTables({\n appID,\n shardNum,\n}: ShardID): Record<string, Record<string, SchemaValue>> {\n return {\n [`${appID}_${shardNum}.clients`]: {\n clientGroupID: {type: 'string'},\n clientID: {type: 'string'},\n lastMutationID: {type: 'number'},\n userID: {type: 'string'},\n },\n [`${appID}_${shardNum}.mutations`]: {\n clientGroupID: {type: 'string'},\n clientID: {type: 'string'},\n mutationID: {type: 'number'},\n mutation: {type: 'json'},\n },\n [`${appID}.permissions`]: {\n permissions: {type: 'json'},\n hash: {type: 'string'},\n },\n };\n}\n\nfunction validateInitiallySyncedData(\n lc: LogContext,\n db: Database,\n shard: ShardID,\n) {\n const tables = computeZqlSpecs(lc, db, {includeBackfillingColumns: true});\n const required = getRequiredTables(shard);\n for (const [name, columns] of Object.entries(required)) {\n const table = tables.get(name)?.zqlSpec;\n if (!table) {\n throw new Error(\n `Upstream is missing the \"${name}\" table. (Found ${[\n ...tables.keys(),\n ]})` +\n `Please ensure that each table has a unique index over one ` +\n `or more non-null columns.`,\n );\n }\n for (const [col, {type}] of Object.entries(columns)) {\n const found = table[col];\n if (!found) {\n throw new Error(\n `Upstream \"${table}\" table is missing the \"${col}\" column`,\n );\n }\n if (found.type !== type) {\n throw new Error(\n `Upstream \"${table}.${col}\" column is a ${found.type} type but must be a ${type} type.`,\n );\n }\n }\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"backfill-metadata.js","names":[],"sources":["../../../../../../../zero-cache/src/services/change-source/pg/backfill-metadata.ts"],"sourcesContent":["import * as v from '../../../../../shared/src/valita.ts';\n\n// PG-specific messages passed in the table metadata and backfill ID\n// messages.\n\nexport const columnMetadataSchema = v.object({\n attNum: v.number(),\n});\n\nexport type ColumnMetadata = v.Infer<typeof columnMetadataSchema>;\n\nexport const tableMetadataSchema = v.object({\n schemaOID: v.number(),\n relationOID: v.number(),\n rowKey: v.record(columnMetadataSchema),\n});\n\nexport type TableMetadata = v.Infer<typeof tableMetadataSchema>;\n"],"mappings":";;AAKA,IAAa,uBAAuB,eAAE,OAAO,EAC3C,QAAQ,eAAE,QAAQ,EACnB,CAAC;AAIF,IAAa,sBAAsB,eAAE,OAAO;CAC1C,WAAW,eAAE,QAAQ;CACrB,aAAa,eAAE,QAAQ;CACvB,QAAQ,eAAE,OAAO,qBAAqB;CACvC,CAAC"}
1
+ {"version":3,"file":"backfill-metadata.js","names":[],"sources":["../../../../../../../zero-cache/src/services/change-source/pg/backfill-metadata.ts"],"sourcesContent":["import * as v from '../../../../../shared/src/valita.ts';\n\n// PG-specific messages passed in the table metadata and backfill ID\n// messages.\n\nexport const columnMetadataSchema = v.object({\n attNum: v.number(),\n});\n\nexport type ColumnMetadata = v.Infer<typeof columnMetadataSchema>;\n\nexport const tableMetadataSchema = v.object({\n schemaOID: v.number(),\n relationOID: v.number(),\n rowKey: v.record(columnMetadataSchema),\n});\n\nexport type TableMetadata = v.Infer<typeof tableMetadataSchema>;\n"],"mappings":";;AAKA,IAAa,uBAAuB,eAAE,OAAO,EAC3C,QAAQ,eAAE,OAAO,EACnB,CAAC;AAID,IAAa,sBAAsB,eAAE,OAAO;CAC1C,WAAW,eAAE,OAAO;CACpB,aAAa,eAAE,OAAO;CACtB,QAAQ,eAAE,OAAO,oBAAoB;AACvC,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { assert } from "../../../../../shared/src/asserts.js";
2
2
  import { parse } from "../../../../../shared/src/valita.js";
3
3
  import { equals } from "../../../../../shared/src/set-utils.js";
4
- import { pgClient } from "../../../types/pg.js";
4
+ import { connectPgClient, pgClient } from "../../../types/pg.js";
5
5
  import { toStateVersionString } from "./lsn.js";
6
6
  import { READONLY } from "../../../db/mode-enum.js";
7
7
  import { getPublicationInfo } from "./schema/published.js";
@@ -27,7 +27,7 @@ var SAMPLE_OR_LIMIT_RE = /\sTABLESAMPLE\s+BERNOULLI\b|\sLIMIT\s+\d/i;
27
27
  async function* streamBackfill(lc, upstreamURI, { slot, publications }, bf, opts = {}) {
28
28
  lc = lc.withContext("component", "backfill").withContext("table", bf.table.name);
29
29
  const { flushThresholdBytes = POSTGRES_COPY_CHUNK_SIZE, textCopy = false } = opts;
30
- const db = pgClient(lc, upstreamURI, "backfill-stream", { ["max_lifetime"]: 7200 });
30
+ const db = await connectPgClient(lc, upstreamURI, "backfill-stream", { ["max_lifetime"]: 7200 });
31
31
  let tx;
32
32
  let watermark;
33
33
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"backfill-stream.js","names":[],"sources":["../../../../../../../zero-cache/src/services/change-source/pg/backfill-stream.ts"],"sourcesContent":["import {\n PG_UNDEFINED_COLUMN,\n PG_UNDEFINED_TABLE,\n} from '@drdgvhbh/postgres-error-codes';\nimport type {LogContext} from '@rocicorp/logger';\nimport postgres from 'postgres';\nimport {assert} from '../../../../../shared/src/asserts.ts';\nimport {equals} from '../../../../../shared/src/set-utils.ts';\nimport * as v from '../../../../../shared/src/valita.ts';\nimport {READONLY} from '../../../db/mode-enum.ts';\nimport {\n BinaryCopyParser,\n hasBinaryDecoder,\n makeBinaryDecoder,\n textCastDecoder,\n} from '../../../db/pg-copy-binary.ts';\nimport {TsvParser} from '../../../db/pg-copy.ts';\nimport {getTypeParsers} from '../../../db/pg-type-parser.ts';\nimport type {PublishedTableSpec} from '../../../db/specs.ts';\nimport {importSnapshot, TransactionPool} from '../../../db/transaction-pool.ts';\nimport {pgClient, type PostgresDB} from '../../../types/pg.ts';\nimport {SchemaIncompatibilityError} from '../common/backfill-manager.ts';\nimport type {\n BackfillCompleted,\n BackfillRequest,\n DownloadStatus,\n JSONValue,\n MessageBackfill,\n} from '../protocol/current.ts';\nimport {\n columnMetadataSchema,\n tableMetadataSchema,\n} from './backfill-metadata.ts';\nimport {\n makeBinarySelectExprs,\n makeDownloadStatements,\n type DownloadStatements,\n} from './initial-sync.ts';\nimport {toStateVersionString} from './lsn.ts';\nimport {createReplicationSlot} from './replication-slots.ts';\nimport {getPublicationInfo} from './schema/published.ts';\nimport type {Replica} from './schema/shard.ts';\n\ntype BackfillParams = Omit<BackfillCompleted, 'tag'>;\n\ntype StreamOptions = {\n /**\n * The number of bytes at which to flush a batch of rows in a\n * backfill message. Defaults to Node's getDefaultHighWatermark().\n */\n flushThresholdBytes?: number | undefined;\n\n /**\n * Use text-format COPY instead of binary COPY.\n * Binary is faster and handles all types (unknown types are cast to\n * `::text` in the SELECT). This flag exists as an escape hatch to\n * revert to the old code path if needed.\n */\n textCopy?: boolean | undefined;\n};\n\n// The size of chunks that Postgres sends on COPY stream.\n// This happens to match NodeJS's getDefaultHighWatermark()\n// (for Node v20+).\nconst POSTGRES_COPY_CHUNK_SIZE = 64 * 1024;\n\n// Matches the exact clauses emitted by makeDownloadStatements; quoted\n// identifiers like \"limit\" won't match because they lack the surrounding\n// whitespace.\nconst SAMPLE_OR_LIMIT_RE = /\\sTABLESAMPLE\\s+BERNOULLI\\b|\\sLIMIT\\s+\\d/i;\n\n/**\n * Streams a series of `backfill` messages (ending with `backfill-complete`)\n * at a set watermark (i.e. LSN). The data is retrieved via a COPY stream\n * made at a transaction snapshot corresponding to specific LSN, obtained by\n * creating a short-lived replication slot.\n */\nexport async function* streamBackfill(\n lc: LogContext,\n upstreamURI: string,\n {slot, publications}: Pick<Replica, 'slot' | 'publications'>,\n bf: BackfillRequest,\n opts: StreamOptions = {},\n): AsyncGenerator<MessageBackfill | BackfillCompleted> {\n lc = lc\n .withContext('component', 'backfill')\n .withContext('table', bf.table.name);\n\n const {flushThresholdBytes = POSTGRES_COPY_CHUNK_SIZE, textCopy = false} =\n opts;\n const db = pgClient(lc, upstreamURI, 'backfill-stream', {\n ['max_lifetime']: 120 * 60, // set a long (2h) limit for COPY streaming\n });\n let tx: TransactionPool | undefined;\n let watermark: string;\n try {\n ({tx, watermark} = await createSnapshotTransaction(\n lc,\n upstreamURI,\n db,\n slot,\n ));\n const {tableSpec, backfill} = await validateSchema(\n tx,\n publications,\n bf,\n watermark,\n );\n\n // Note: validateSchema ensures that the rowKey and columns are disjoint\n const {relation, columns} = backfill;\n const cols = [...relation.rowKey.columns, ...columns];\n const stmts = makeDownloadStatements(tableSpec, cols);\n\n if (textCopy) {\n const types = await getTypeParsers(db, {returnJsonAsString: true});\n yield* stream(\n lc,\n tx,\n backfill,\n stmts,\n `COPY (${stmts.select}) TO STDOUT`,\n new TsvParser(),\n cols.map(col => {\n const parser = types.getTypeParser(tableSpec.columns[col].typeOID);\n return (text: string) => parser(text) as JSONValue;\n }),\n flushThresholdBytes,\n );\n } else {\n const binaryStmts = makeDownloadStatements(\n tableSpec,\n cols,\n undefined,\n undefined,\n makeBinarySelectExprs(tableSpec, cols),\n );\n\n yield* stream(\n lc,\n tx,\n backfill,\n stmts,\n `COPY (${binaryStmts.select}) TO STDOUT WITH (FORMAT binary)`,\n new BinaryCopyParser(),\n cols.map(col => {\n const spec = tableSpec.columns[col];\n const decoder = hasBinaryDecoder(spec)\n ? makeBinaryDecoder(spec)\n : textCastDecoder;\n return (buf: Buffer) => decoder(buf) as unknown as JSONValue;\n }),\n flushThresholdBytes,\n );\n }\n } catch (e) {\n // Although we make the best effort to validate the schema at the\n // transaction snapshot, certain forms of `ALTER TABLE` are not\n // MVCC safe and not \"frozen\" in the snapshot:\n //\n // https://www.postgresql.org/docs/current/mvcc-caveats.html\n //\n // Handle these errors as schema incompatibility errors rather than\n // unknown runtime errors.\n if (\n e instanceof postgres.PostgresError &&\n (e.code === PG_UNDEFINED_TABLE || e.code === PG_UNDEFINED_COLUMN)\n ) {\n throw new SchemaIncompatibilityError(bf, String(e), {cause: e});\n }\n throw e;\n } finally {\n tx?.setDone();\n // Workaround postgres.js hanging at the end of some COPY commands:\n // https://github.com/porsager/postgres/issues/499\n void db.end().catch(e => lc.warn?.(`error closing backfill connection`, e));\n }\n}\n\nasync function* stream<T>(\n lc: LogContext,\n tx: TransactionPool,\n backfill: BackfillParams,\n {\n getTotalRows,\n getTotalBytes,\n }: Pick<DownloadStatements, 'getTotalRows' | 'getTotalBytes'>,\n copyCommand: string,\n parser: {parse(chunk: Buffer): Iterable<T | null>},\n decoders: ((field: T) => JSONValue)[],\n flushThresholdBytes: number,\n): AsyncGenerator<MessageBackfill | BackfillCompleted> {\n // Backfill must read every row: TABLESAMPLE / LIMIT are reserved for shadow\n // sync and must never appear in a backfill COPY.\n assert(\n !SAMPLE_OR_LIMIT_RE.test(copyCommand),\n `backfill COPY must not sample or limit: ${copyCommand}`,\n );\n const start = performance.now();\n const [rows, bytes] = await tx.processReadTask(sql =>\n Promise.all([\n sql.unsafe<{totalRows: bigint}[]>(getTotalRows),\n sql.unsafe<{totalBytes: bigint}[]>(getTotalBytes),\n ]),\n );\n const status: DownloadStatus = {\n rows: 0,\n totalRows: Number(rows[0].totalRows),\n totalBytes: Number(bytes[0].totalBytes),\n };\n\n let elapsed = (performance.now() - start).toFixed(3);\n lc.info?.(\n `Computed total rows and bytes for: ${copyCommand} (${elapsed} ms)`,\n {\n status,\n },\n );\n const copyStream = await tx.processReadTask(sql =>\n sql.unsafe(copyCommand).readable(),\n );\n\n let totalBytes = 0;\n let totalMsgs = 0;\n let rowValues: JSONValue[][] = [];\n let bufferedBytes = 0;\n\n const logFlushed = () => {\n lc.debug?.(\n `Flushed ${rowValues.length} rows, ${bufferedBytes} bytes ` +\n `(total: rows=${status.rows}, msgs=${totalMsgs}, bytes=${totalBytes})`,\n );\n };\n\n // Tracks the row being parsed.\n let row: JSONValue[] = Array.from({length: decoders.length});\n let col = 0;\n\n for await (const data of copyStream) {\n const chunk = data as Buffer;\n for (const field of parser.parse(chunk)) {\n row[col] = field === null ? null : decoders[col](field);\n\n if (++col === decoders.length) {\n rowValues.push(row);\n status.rows++;\n row = Array.from({length: decoders.length});\n col = 0;\n }\n }\n bufferedBytes += chunk.byteLength;\n totalBytes += chunk.byteLength;\n\n if (bufferedBytes >= flushThresholdBytes) {\n yield {tag: 'backfill', ...backfill, rowValues, status};\n totalMsgs++;\n logFlushed();\n rowValues = [];\n bufferedBytes = 0;\n }\n }\n\n // Flush the last batch of rows.\n if (rowValues.length > 0) {\n yield {tag: 'backfill', ...backfill, rowValues, status};\n totalMsgs++;\n logFlushed();\n }\n\n yield {tag: 'backfill-completed', ...backfill, status};\n elapsed = (performance.now() - start).toFixed(3);\n lc.info?.(\n `Finished streaming ${status.rows} rows, ${totalMsgs} msgs, ${totalBytes} bytes ` +\n `(${elapsed} ms)`,\n );\n}\n\n/**\n * Creates (and drops) a replication slot in order to obtain a snapshot\n * that corresponds with a specific LSN. Sets the snapshot on the\n * TransactionPool and returns the watermark corresponding to the LSN.\n *\n * (Note that PG's other LSN-related functions are not scoped to a\n * transaction; this is the only way to get set a transaction at a specific\n * LSN.)\n */\nasync function createSnapshotTransaction(\n lc: LogContext,\n upstreamURI: string,\n db: PostgresDB,\n slotNamePrefix: string,\n) {\n const replicationSession = pgClient(\n lc,\n upstreamURI,\n 'backfill-replication-session',\n {\n ['fetch_types']: false, // Necessary for the streaming protocol\n connection: {replication: 'database'}, // https://www.postgresql.org/docs/current/protocol-replication.html\n },\n );\n const slotName = `${slotNamePrefix}_bf_${Date.now()}`;\n try {\n const {snapshot_name: snapshot, consistent_point: lsn} =\n await createReplicationSlot(lc, replicationSession, {slotName});\n\n const {init, imported} = importSnapshot(snapshot);\n const tx = new TransactionPool(lc, {mode: READONLY, init}).run(db);\n await imported;\n await replicationSession.unsafe(`DROP_REPLICATION_SLOT \"${slotName}\"`);\n\n const watermark = toStateVersionString(lsn);\n lc.info?.(`Opened snapshot transaction at LSN ${lsn} (${watermark})`);\n return {tx, watermark};\n } catch (e) {\n // In the event of a failure, clean up the replication slot if created.\n await replicationSession.unsafe(\n /*sql*/\n `SELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots\n WHERE slot_name = '${slotName}'`,\n );\n lc.warn?.(`Failed to create backfill snapshot`, e);\n throw e;\n } finally {\n await replicationSession.end();\n }\n}\n\nfunction validateSchema(\n tx: TransactionPool,\n publications: string[],\n bf: BackfillRequest,\n watermark: string,\n): Promise<{\n tableSpec: PublishedTableSpec;\n backfill: BackfillParams;\n}> {\n return tx.processReadTask(async sql => {\n const {tables} = await getPublicationInfo(sql, publications);\n const spec = tables.find(\n spec => spec.schema === bf.table.schema && spec.name === bf.table.name,\n );\n if (!spec) {\n throw new SchemaIncompatibilityError(\n bf,\n `Table has been renamed or dropped`,\n );\n }\n const tableMeta = v.parse(bf.table.metadata, tableMetadataSchema);\n if (spec.schemaOID !== tableMeta.schemaOID) {\n throw new SchemaIncompatibilityError(\n bf,\n `Schema no longer corresponds to the original schema`,\n );\n }\n if (spec.oid !== tableMeta.relationOID) {\n throw new SchemaIncompatibilityError(\n bf,\n `Table no longer corresponds to the original table`,\n );\n }\n if (\n !equals(\n new Set(Object.keys(tableMeta.rowKey)),\n new Set(spec.replicaIdentityColumns),\n )\n ) {\n throw new SchemaIncompatibilityError(\n bf,\n 'Row key (e.g. PRIMARY KEY or INDEX) has changed',\n );\n }\n const allCols = [\n ...Object.entries(tableMeta.rowKey),\n ...Object.entries(bf.columns),\n ];\n for (const [col, val] of allCols) {\n const colSpec = spec.columns[col];\n if (!colSpec) {\n throw new SchemaIncompatibilityError(\n bf,\n `Column ${col} has been renamed or dropped`,\n );\n }\n const colMeta = v.parse(val, columnMetadataSchema);\n if (colMeta.attNum !== colSpec.pos) {\n throw new SchemaIncompatibilityError(\n bf,\n `Column ${col} no longer corresponds to the original column`,\n );\n }\n }\n const backfill: BackfillParams = {\n relation: {\n schema: bf.table.schema,\n name: bf.table.name,\n rowKey: {columns: Object.keys(tableMeta.rowKey)},\n },\n columns: Object.keys(bf.columns).filter(\n col => !(col in tableMeta.rowKey),\n ),\n watermark,\n };\n return {tableSpec: spec, backfill};\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgEA,IAAM,2BAA2B,KAAK;AAKtC,IAAM,qBAAqB;;;;;;;AAQ3B,gBAAuB,eACrB,IACA,aACA,EAAC,MAAM,gBACP,IACA,OAAsB,EAAE,EAC6B;AACrD,MAAK,GACF,YAAY,aAAa,WAAW,CACpC,YAAY,SAAS,GAAG,MAAM,KAAK;CAEtC,MAAM,EAAC,sBAAsB,0BAA0B,WAAW,UAChE;CACF,MAAM,KAAK,SAAS,IAAI,aAAa,mBAAmB,GACrD,iBAAiB,MACnB,CAAC;CACF,IAAI;CACJ,IAAI;AACJ,KAAI;AACF,GAAC,CAAC,IAAI,aAAa,MAAM,0BACvB,IACA,aACA,IACA,KACD;EACD,MAAM,EAAC,WAAW,aAAY,MAAM,eAClC,IACA,cACA,IACA,UACD;EAGD,MAAM,EAAC,UAAU,YAAW;EAC5B,MAAM,OAAO,CAAC,GAAG,SAAS,OAAO,SAAS,GAAG,QAAQ;EACrD,MAAM,QAAQ,uBAAuB,WAAW,KAAK;AAErD,MAAI,UAAU;GACZ,MAAM,QAAQ,MAAM,eAAe,IAAI,EAAC,oBAAoB,MAAK,CAAC;AAClE,UAAO,OACL,IACA,IACA,UACA,OACA,SAAS,MAAM,OAAO,cACtB,IAAI,WAAW,EACf,KAAK,KAAI,QAAO;IACd,MAAM,SAAS,MAAM,cAAc,UAAU,QAAQ,KAAK,QAAQ;AAClE,YAAQ,SAAiB,OAAO,KAAK;KACrC,EACF,oBACD;SACI;GACL,MAAM,cAAc,uBAClB,WACA,MACA,KAAA,GACA,KAAA,GACA,sBAAsB,WAAW,KAAK,CACvC;AAED,UAAO,OACL,IACA,IACA,UACA,OACA,SAAS,YAAY,OAAO,mCAC5B,IAAI,kBAAkB,EACtB,KAAK,KAAI,QAAO;IACd,MAAM,OAAO,UAAU,QAAQ;IAC/B,MAAM,UAAU,iBAAiB,KAAK,GAClC,kBAAkB,KAAK,GACvB;AACJ,YAAQ,QAAgB,QAAQ,IAAI;KACpC,EACF,oBACD;;UAEI,GAAG;AASV,MACE,aAAa,SAAS,kBACrB,EAAE,SAAS,sBAAsB,EAAE,SAAS,qBAE7C,OAAM,IAAI,2BAA2B,IAAI,OAAO,EAAE,EAAE,EAAC,OAAO,GAAE,CAAC;AAEjE,QAAM;WACE;AACR,MAAI,SAAS;AAGR,KAAG,KAAK,CAAC,OAAM,MAAK,GAAG,OAAO,qCAAqC,EAAE,CAAC;;;AAI/E,gBAAgB,OACd,IACA,IACA,UACA,EACE,cACA,iBAEF,aACA,QACA,UACA,qBACqD;AAGrD,QACE,CAAC,mBAAmB,KAAK,YAAY,EACrC,2CAA2C,cAC5C;CACD,MAAM,QAAQ,YAAY,KAAK;CAC/B,MAAM,CAAC,MAAM,SAAS,MAAM,GAAG,iBAAgB,QAC7C,QAAQ,IAAI,CACV,IAAI,OAA8B,aAAa,EAC/C,IAAI,OAA+B,cAAc,CAClD,CAAC,CACH;CACD,MAAM,SAAyB;EAC7B,MAAM;EACN,WAAW,OAAO,KAAK,GAAG,UAAU;EACpC,YAAY,OAAO,MAAM,GAAG,WAAW;EACxC;CAED,IAAI,WAAW,YAAY,KAAK,GAAG,OAAO,QAAQ,EAAE;AACpD,IAAG,OACD,sCAAsC,YAAY,IAAI,QAAQ,OAC9D,EACE,QACD,CACF;CACD,MAAM,aAAa,MAAM,GAAG,iBAAgB,QAC1C,IAAI,OAAO,YAAY,CAAC,UAAU,CACnC;CAED,IAAI,aAAa;CACjB,IAAI,YAAY;CAChB,IAAI,YAA2B,EAAE;CACjC,IAAI,gBAAgB;CAEpB,MAAM,mBAAmB;AACvB,KAAG,QACD,WAAW,UAAU,OAAO,SAAS,cAAc,sBACjC,OAAO,KAAK,SAAS,UAAU,UAAU,WAAW,GACvE;;CAIH,IAAI,MAAmB,MAAM,KAAK,EAAC,QAAQ,SAAS,QAAO,CAAC;CAC5D,IAAI,MAAM;AAEV,YAAW,MAAM,QAAQ,YAAY;EACnC,MAAM,QAAQ;AACd,OAAK,MAAM,SAAS,OAAO,MAAM,MAAM,EAAE;AACvC,OAAI,OAAO,UAAU,OAAO,OAAO,SAAS,KAAK,MAAM;AAEvD,OAAI,EAAE,QAAQ,SAAS,QAAQ;AAC7B,cAAU,KAAK,IAAI;AACnB,WAAO;AACP,UAAM,MAAM,KAAK,EAAC,QAAQ,SAAS,QAAO,CAAC;AAC3C,UAAM;;;AAGV,mBAAiB,MAAM;AACvB,gBAAc,MAAM;AAEpB,MAAI,iBAAiB,qBAAqB;AACxC,SAAM;IAAC,KAAK;IAAY,GAAG;IAAU;IAAW;IAAO;AACvD;AACA,eAAY;AACZ,eAAY,EAAE;AACd,mBAAgB;;;AAKpB,KAAI,UAAU,SAAS,GAAG;AACxB,QAAM;GAAC,KAAK;GAAY,GAAG;GAAU;GAAW;GAAO;AACvD;AACA,cAAY;;AAGd,OAAM;EAAC,KAAK;EAAsB,GAAG;EAAU;EAAO;AACtD,YAAW,YAAY,KAAK,GAAG,OAAO,QAAQ,EAAE;AAChD,IAAG,OACD,sBAAsB,OAAO,KAAK,SAAS,UAAU,SAAS,WAAW,UACnE,QAAQ,MACf;;;;;;;;;;;AAYH,eAAe,0BACb,IACA,aACA,IACA,gBACA;CACA,MAAM,qBAAqB,SACzB,IACA,aACA,gCACA;GACG,gBAAgB;EACjB,YAAY,EAAC,aAAa,YAAW;EACtC,CACF;CACD,MAAM,WAAW,GAAG,eAAe,MAAM,KAAK,KAAK;AACnD,KAAI;EACF,MAAM,EAAC,eAAe,UAAU,kBAAkB,QAChD,MAAM,sBAAsB,IAAI,oBAAoB,EAAC,UAAS,CAAC;EAEjE,MAAM,EAAC,MAAM,aAAY,eAAe,SAAS;EACjD,MAAM,KAAK,IAAI,gBAAgB,IAAI;GAAC,MAAM;GAAU;GAAK,CAAC,CAAC,IAAI,GAAG;AAClE,QAAM;AACN,QAAM,mBAAmB,OAAO,0BAA0B,SAAS,GAAG;EAEtE,MAAM,YAAY,qBAAqB,IAAI;AAC3C,KAAG,OAAO,sCAAsC,IAAI,IAAI,UAAU,GAAG;AACrE,SAAO;GAAC;GAAI;GAAU;UACf,GAAG;AAEV,QAAM,mBAAmB,OAEvB;8BACwB,SAAS,GAClC;AACD,KAAG,OAAO,sCAAsC,EAAE;AAClD,QAAM;WACE;AACR,QAAM,mBAAmB,KAAK;;;AAIlC,SAAS,eACP,IACA,cACA,IACA,WAIC;AACD,QAAO,GAAG,gBAAgB,OAAM,QAAO;EACrC,MAAM,EAAC,WAAU,MAAM,mBAAmB,KAAK,aAAa;EAC5D,MAAM,OAAO,OAAO,MAClB,SAAQ,KAAK,WAAW,GAAG,MAAM,UAAU,KAAK,SAAS,GAAG,MAAM,KACnE;AACD,MAAI,CAAC,KACH,OAAM,IAAI,2BACR,IACA,oCACD;EAEH,MAAM,YAAY,MAAQ,GAAG,MAAM,UAAU,oBAAoB;AACjE,MAAI,KAAK,cAAc,UAAU,UAC/B,OAAM,IAAI,2BACR,IACA,sDACD;AAEH,MAAI,KAAK,QAAQ,UAAU,YACzB,OAAM,IAAI,2BACR,IACA,oDACD;AAEH,MACE,CAAC,OACC,IAAI,IAAI,OAAO,KAAK,UAAU,OAAO,CAAC,EACtC,IAAI,IAAI,KAAK,uBAAuB,CACrC,CAED,OAAM,IAAI,2BACR,IACA,kDACD;EAEH,MAAM,UAAU,CACd,GAAG,OAAO,QAAQ,UAAU,OAAO,EACnC,GAAG,OAAO,QAAQ,GAAG,QAAQ,CAC9B;AACD,OAAK,MAAM,CAAC,KAAK,QAAQ,SAAS;GAChC,MAAM,UAAU,KAAK,QAAQ;AAC7B,OAAI,CAAC,QACH,OAAM,IAAI,2BACR,IACA,UAAU,IAAI,8BACf;AAGH,OADgB,MAAQ,KAAK,qBAAqB,CACtC,WAAW,QAAQ,IAC7B,OAAM,IAAI,2BACR,IACA,UAAU,IAAI,+CACf;;AAcL,SAAO;GAAC,WAAW;GAAM,UAXQ;IAC/B,UAAU;KACR,QAAQ,GAAG,MAAM;KACjB,MAAM,GAAG,MAAM;KACf,QAAQ,EAAC,SAAS,OAAO,KAAK,UAAU,OAAO,EAAC;KACjD;IACD,SAAS,OAAO,KAAK,GAAG,QAAQ,CAAC,QAC/B,QAAO,EAAE,OAAO,UAAU,QAC3B;IACD;IACD;GACiC;GAClC"}
1
+ {"version":3,"file":"backfill-stream.js","names":[],"sources":["../../../../../../../zero-cache/src/services/change-source/pg/backfill-stream.ts"],"sourcesContent":["import {\n PG_UNDEFINED_COLUMN,\n PG_UNDEFINED_TABLE,\n} from '@drdgvhbh/postgres-error-codes';\nimport type {LogContext} from '@rocicorp/logger';\nimport postgres from 'postgres';\nimport {assert} from '../../../../../shared/src/asserts.ts';\nimport {equals} from '../../../../../shared/src/set-utils.ts';\nimport * as v from '../../../../../shared/src/valita.ts';\nimport {READONLY} from '../../../db/mode-enum.ts';\nimport {\n BinaryCopyParser,\n hasBinaryDecoder,\n makeBinaryDecoder,\n textCastDecoder,\n} from '../../../db/pg-copy-binary.ts';\nimport {TsvParser} from '../../../db/pg-copy.ts';\nimport {getTypeParsers} from '../../../db/pg-type-parser.ts';\nimport type {PublishedTableSpec} from '../../../db/specs.ts';\nimport {importSnapshot, TransactionPool} from '../../../db/transaction-pool.ts';\nimport {connectPgClient, pgClient, type PostgresDB} from '../../../types/pg.ts';\nimport {SchemaIncompatibilityError} from '../common/backfill-manager.ts';\nimport type {\n BackfillCompleted,\n BackfillRequest,\n DownloadStatus,\n JSONValue,\n MessageBackfill,\n} from '../protocol/current.ts';\nimport {\n columnMetadataSchema,\n tableMetadataSchema,\n} from './backfill-metadata.ts';\nimport {\n makeBinarySelectExprs,\n makeDownloadStatements,\n type DownloadStatements,\n} from './initial-sync.ts';\nimport {toStateVersionString} from './lsn.ts';\nimport {createReplicationSlot} from './replication-slots.ts';\nimport {getPublicationInfo} from './schema/published.ts';\nimport type {Replica} from './schema/shard.ts';\n\ntype BackfillParams = Omit<BackfillCompleted, 'tag'>;\n\ntype StreamOptions = {\n /**\n * The number of bytes at which to flush a batch of rows in a\n * backfill message. Defaults to Node's getDefaultHighWatermark().\n */\n flushThresholdBytes?: number | undefined;\n\n /**\n * Use text-format COPY instead of binary COPY.\n * Binary is faster and handles all types (unknown types are cast to\n * `::text` in the SELECT). This flag exists as an escape hatch to\n * revert to the old code path if needed.\n */\n textCopy?: boolean | undefined;\n};\n\n// The size of chunks that Postgres sends on COPY stream.\n// This happens to match NodeJS's getDefaultHighWatermark()\n// (for Node v20+).\nconst POSTGRES_COPY_CHUNK_SIZE = 64 * 1024;\n\n// Matches the exact clauses emitted by makeDownloadStatements; quoted\n// identifiers like \"limit\" won't match because they lack the surrounding\n// whitespace.\nconst SAMPLE_OR_LIMIT_RE = /\\sTABLESAMPLE\\s+BERNOULLI\\b|\\sLIMIT\\s+\\d/i;\n\n/**\n * Streams a series of `backfill` messages (ending with `backfill-complete`)\n * at a set watermark (i.e. LSN). The data is retrieved via a COPY stream\n * made at a transaction snapshot corresponding to specific LSN, obtained by\n * creating a short-lived replication slot.\n */\nexport async function* streamBackfill(\n lc: LogContext,\n upstreamURI: string,\n {slot, publications}: Pick<Replica, 'slot' | 'publications'>,\n bf: BackfillRequest,\n opts: StreamOptions = {},\n): AsyncGenerator<MessageBackfill | BackfillCompleted> {\n lc = lc\n .withContext('component', 'backfill')\n .withContext('table', bf.table.name);\n\n const {flushThresholdBytes = POSTGRES_COPY_CHUNK_SIZE, textCopy = false} =\n opts;\n const db = await connectPgClient(lc, upstreamURI, 'backfill-stream', {\n ['max_lifetime']: 120 * 60, // set a long (2h) limit for COPY streaming\n });\n let tx: TransactionPool | undefined;\n let watermark: string;\n try {\n ({tx, watermark} = await createSnapshotTransaction(\n lc,\n upstreamURI,\n db,\n slot,\n ));\n const {tableSpec, backfill} = await validateSchema(\n tx,\n publications,\n bf,\n watermark,\n );\n\n // Note: validateSchema ensures that the rowKey and columns are disjoint\n const {relation, columns} = backfill;\n const cols = [...relation.rowKey.columns, ...columns];\n const stmts = makeDownloadStatements(tableSpec, cols);\n\n if (textCopy) {\n const types = await getTypeParsers(db, {returnJsonAsString: true});\n yield* stream(\n lc,\n tx,\n backfill,\n stmts,\n `COPY (${stmts.select}) TO STDOUT`,\n new TsvParser(),\n cols.map(col => {\n const parser = types.getTypeParser(tableSpec.columns[col].typeOID);\n return (text: string) => parser(text) as JSONValue;\n }),\n flushThresholdBytes,\n );\n } else {\n const binaryStmts = makeDownloadStatements(\n tableSpec,\n cols,\n undefined,\n undefined,\n makeBinarySelectExprs(tableSpec, cols),\n );\n\n yield* stream(\n lc,\n tx,\n backfill,\n stmts,\n `COPY (${binaryStmts.select}) TO STDOUT WITH (FORMAT binary)`,\n new BinaryCopyParser(),\n cols.map(col => {\n const spec = tableSpec.columns[col];\n const decoder = hasBinaryDecoder(spec)\n ? makeBinaryDecoder(spec)\n : textCastDecoder;\n return (buf: Buffer) => decoder(buf) as unknown as JSONValue;\n }),\n flushThresholdBytes,\n );\n }\n } catch (e) {\n // Although we make the best effort to validate the schema at the\n // transaction snapshot, certain forms of `ALTER TABLE` are not\n // MVCC safe and not \"frozen\" in the snapshot:\n //\n // https://www.postgresql.org/docs/current/mvcc-caveats.html\n //\n // Handle these errors as schema incompatibility errors rather than\n // unknown runtime errors.\n if (\n e instanceof postgres.PostgresError &&\n (e.code === PG_UNDEFINED_TABLE || e.code === PG_UNDEFINED_COLUMN)\n ) {\n throw new SchemaIncompatibilityError(bf, String(e), {cause: e});\n }\n throw e;\n } finally {\n tx?.setDone();\n // Workaround postgres.js hanging at the end of some COPY commands:\n // https://github.com/porsager/postgres/issues/499\n void db.end().catch(e => lc.warn?.(`error closing backfill connection`, e));\n }\n}\n\nasync function* stream<T>(\n lc: LogContext,\n tx: TransactionPool,\n backfill: BackfillParams,\n {\n getTotalRows,\n getTotalBytes,\n }: Pick<DownloadStatements, 'getTotalRows' | 'getTotalBytes'>,\n copyCommand: string,\n parser: {parse(chunk: Buffer): Iterable<T | null>},\n decoders: ((field: T) => JSONValue)[],\n flushThresholdBytes: number,\n): AsyncGenerator<MessageBackfill | BackfillCompleted> {\n // Backfill must read every row: TABLESAMPLE / LIMIT are reserved for shadow\n // sync and must never appear in a backfill COPY.\n assert(\n !SAMPLE_OR_LIMIT_RE.test(copyCommand),\n `backfill COPY must not sample or limit: ${copyCommand}`,\n );\n const start = performance.now();\n const [rows, bytes] = await tx.processReadTask(sql =>\n Promise.all([\n sql.unsafe<{totalRows: bigint}[]>(getTotalRows),\n sql.unsafe<{totalBytes: bigint}[]>(getTotalBytes),\n ]),\n );\n const status: DownloadStatus = {\n rows: 0,\n totalRows: Number(rows[0].totalRows),\n totalBytes: Number(bytes[0].totalBytes),\n };\n\n let elapsed = (performance.now() - start).toFixed(3);\n lc.info?.(\n `Computed total rows and bytes for: ${copyCommand} (${elapsed} ms)`,\n {\n status,\n },\n );\n const copyStream = await tx.processReadTask(sql =>\n sql.unsafe(copyCommand).readable(),\n );\n\n let totalBytes = 0;\n let totalMsgs = 0;\n let rowValues: JSONValue[][] = [];\n let bufferedBytes = 0;\n\n const logFlushed = () => {\n lc.debug?.(\n `Flushed ${rowValues.length} rows, ${bufferedBytes} bytes ` +\n `(total: rows=${status.rows}, msgs=${totalMsgs}, bytes=${totalBytes})`,\n );\n };\n\n // Tracks the row being parsed.\n let row: JSONValue[] = Array.from({length: decoders.length});\n let col = 0;\n\n for await (const data of copyStream) {\n const chunk = data as Buffer;\n for (const field of parser.parse(chunk)) {\n row[col] = field === null ? null : decoders[col](field);\n\n if (++col === decoders.length) {\n rowValues.push(row);\n status.rows++;\n row = Array.from({length: decoders.length});\n col = 0;\n }\n }\n bufferedBytes += chunk.byteLength;\n totalBytes += chunk.byteLength;\n\n if (bufferedBytes >= flushThresholdBytes) {\n yield {tag: 'backfill', ...backfill, rowValues, status};\n totalMsgs++;\n logFlushed();\n rowValues = [];\n bufferedBytes = 0;\n }\n }\n\n // Flush the last batch of rows.\n if (rowValues.length > 0) {\n yield {tag: 'backfill', ...backfill, rowValues, status};\n totalMsgs++;\n logFlushed();\n }\n\n yield {tag: 'backfill-completed', ...backfill, status};\n elapsed = (performance.now() - start).toFixed(3);\n lc.info?.(\n `Finished streaming ${status.rows} rows, ${totalMsgs} msgs, ${totalBytes} bytes ` +\n `(${elapsed} ms)`,\n );\n}\n\n/**\n * Creates (and drops) a replication slot in order to obtain a snapshot\n * that corresponds with a specific LSN. Sets the snapshot on the\n * TransactionPool and returns the watermark corresponding to the LSN.\n *\n * (Note that PG's other LSN-related functions are not scoped to a\n * transaction; this is the only way to get set a transaction at a specific\n * LSN.)\n */\nasync function createSnapshotTransaction(\n lc: LogContext,\n upstreamURI: string,\n db: PostgresDB,\n slotNamePrefix: string,\n) {\n const replicationSession = pgClient(\n lc,\n upstreamURI,\n 'backfill-replication-session',\n {\n ['fetch_types']: false, // Necessary for the streaming protocol\n connection: {replication: 'database'}, // https://www.postgresql.org/docs/current/protocol-replication.html\n },\n );\n const slotName = `${slotNamePrefix}_bf_${Date.now()}`;\n try {\n const {snapshot_name: snapshot, consistent_point: lsn} =\n await createReplicationSlot(lc, replicationSession, {slotName});\n\n const {init, imported} = importSnapshot(snapshot);\n const tx = new TransactionPool(lc, {mode: READONLY, init}).run(db);\n await imported;\n await replicationSession.unsafe(`DROP_REPLICATION_SLOT \"${slotName}\"`);\n\n const watermark = toStateVersionString(lsn);\n lc.info?.(`Opened snapshot transaction at LSN ${lsn} (${watermark})`);\n return {tx, watermark};\n } catch (e) {\n // In the event of a failure, clean up the replication slot if created.\n await replicationSession.unsafe(\n /*sql*/\n `SELECT pg_drop_replication_slot(slot_name) FROM pg_replication_slots\n WHERE slot_name = '${slotName}'`,\n );\n lc.warn?.(`Failed to create backfill snapshot`, e);\n throw e;\n } finally {\n await replicationSession.end();\n }\n}\n\nfunction validateSchema(\n tx: TransactionPool,\n publications: string[],\n bf: BackfillRequest,\n watermark: string,\n): Promise<{\n tableSpec: PublishedTableSpec;\n backfill: BackfillParams;\n}> {\n return tx.processReadTask(async sql => {\n const {tables} = await getPublicationInfo(sql, publications);\n const spec = tables.find(\n spec => spec.schema === bf.table.schema && spec.name === bf.table.name,\n );\n if (!spec) {\n throw new SchemaIncompatibilityError(\n bf,\n `Table has been renamed or dropped`,\n );\n }\n const tableMeta = v.parse(bf.table.metadata, tableMetadataSchema);\n if (spec.schemaOID !== tableMeta.schemaOID) {\n throw new SchemaIncompatibilityError(\n bf,\n `Schema no longer corresponds to the original schema`,\n );\n }\n if (spec.oid !== tableMeta.relationOID) {\n throw new SchemaIncompatibilityError(\n bf,\n `Table no longer corresponds to the original table`,\n );\n }\n if (\n !equals(\n new Set(Object.keys(tableMeta.rowKey)),\n new Set(spec.replicaIdentityColumns),\n )\n ) {\n throw new SchemaIncompatibilityError(\n bf,\n 'Row key (e.g. PRIMARY KEY or INDEX) has changed',\n );\n }\n const allCols = [\n ...Object.entries(tableMeta.rowKey),\n ...Object.entries(bf.columns),\n ];\n for (const [col, val] of allCols) {\n const colSpec = spec.columns[col];\n if (!colSpec) {\n throw new SchemaIncompatibilityError(\n bf,\n `Column ${col} has been renamed or dropped`,\n );\n }\n const colMeta = v.parse(val, columnMetadataSchema);\n if (colMeta.attNum !== colSpec.pos) {\n throw new SchemaIncompatibilityError(\n bf,\n `Column ${col} no longer corresponds to the original column`,\n );\n }\n }\n const backfill: BackfillParams = {\n relation: {\n schema: bf.table.schema,\n name: bf.table.name,\n rowKey: {columns: Object.keys(tableMeta.rowKey)},\n },\n columns: Object.keys(bf.columns).filter(\n col => !(col in tableMeta.rowKey),\n ),\n watermark,\n };\n return {tableSpec: spec, backfill};\n });\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"change-source.d.ts","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/change-source/pg/change-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAcjD,OAAO,KAAK,CAAC,MAAM,qCAAqC,CAAC;AAMzD,OAAO,KAAK,EAGV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,KAAK,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAGhE,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAC,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,wCAAwC,CAAC;AAchD,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAGV,eAAe,IAAI,gBAAgB,EACpC,MAAM,yCAAyC,CAAC;AAyBjD;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,UAAU,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,aAAa,EACtB,mBAAmB,SAAI,GACtB,OAAO,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAAC,YAAY,EAAE,YAAY,CAAA;CAAC,CAAC,CAuC7E;AA+ZD,qBAAa,KAAM,YAAW,QAAQ;;gBAIxB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAI9B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAgC3C,GAAG,CAAC,SAAS,EAAE,WAAW;CAoB3B;AAED,QAAA,MAAM,eAAe;;;;aAInB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAmzBxD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,gBAAgB,WAwB3E"}
1
+ {"version":3,"file":"change-source.d.ts","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/change-source/pg/change-source.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAcjD,OAAO,KAAK,CAAC,MAAM,qCAAqC,CAAC;AAMzD,OAAO,KAAK,EAGV,kBAAkB,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAC,KAAK,WAAW,EAAC,MAAM,gCAAgC,CAAC;AAQhE,OAAO,EAEL,KAAK,WAAW,EAEjB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,2BAA2B,CAAC;AAEpD,OAAO,EAEL,KAAK,iBAAiB,EAEvB,MAAM,8CAA8C,CAAC;AACtD,OAAO,KAAK,EAAC,YAAY,EAAe,MAAM,qBAAqB,CAAC;AAEpE,OAAO,EAEL,KAAK,QAAQ,EACd,MAAM,wCAAwC,CAAC;AAchD,OAAO,KAAK,EAEV,mBAAmB,EAEpB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAGV,eAAe,IAAI,gBAAgB,EACpC,MAAM,yCAAyC,CAAC;AAyBjD;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,EAAE,EAAE,UAAU,EACd,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,kBAAkB,EAC/B,OAAO,EAAE,aAAa,EACtB,mBAAmB,SAAI,GACtB,OAAO,CAAC;IAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAAC,YAAY,EAAE,YAAY,CAAA;CAAC,CAAC,CAuC7E;AA+ZD,qBAAa,KAAM,YAAW,QAAQ;;gBAIxB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;IAI9B,QAAQ,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAgC3C,GAAG,CAAC,SAAS,EAAE,WAAW;CAoB3B;AAED,QAAA,MAAM,eAAe;;;;aAInB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAmzBxD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,gBAAgB,WAwB3E"}
@@ -11,7 +11,7 @@ import { Database } from "../../../../../zqlite/src/db.js";
11
11
  import { UnsupportedColumnDefaultError, mapPostgresToLiteColumn } from "../../../db/pg-to-lite.js";
12
12
  import { getSubscriptionStateAndContext } from "../../replicator/schema/replication-state.js";
13
13
  import { StatementRunner } from "../../../db/statements.js";
14
- import { isPostgresError, pgClient } from "../../../types/pg.js";
14
+ import { connectPgClient, isPostgresError, pgClient } from "../../../types/pg.js";
15
15
  import { majorVersionFromString, majorVersionToString } from "../../../types/state-version.js";
16
16
  import { fromBigInt, toBigInt, toStateVersionString } from "./lsn.js";
17
17
  import { getPublicationInfo } from "./schema/published.js";
@@ -43,7 +43,7 @@ async function initializePostgresChangeSource(lc, upstreamURI, shard, replicaDbF
43
43
  const replica = new Database(lc, replicaDbFile);
44
44
  const subscriptionState = getSubscriptionStateAndContext(new StatementRunner(replica));
45
45
  replica.close();
46
- const db = pgClient(lc, upstreamURI, "change-source-init");
46
+ const db = await connectPgClient(lc, upstreamURI, "change-source-init");
47
47
  try {
48
48
  return {
49
49
  subscriptionState,