@rocicorp/zero 1.11.0-canary.7 → 1.11.0-canary.9

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 (258) hide show
  1. package/out/replicache/src/dag/gc.d.ts.map +1 -1
  2. package/out/replicache/src/dag/gc.js +2 -1
  3. package/out/replicache/src/dag/gc.js.map +1 -1
  4. package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
  5. package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
  6. package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
  7. package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
  8. package/out/replicache/src/dag/store-impl.d.ts +12 -2
  9. package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
  10. package/out/replicache/src/dag/store-impl.js +22 -8
  11. package/out/replicache/src/dag/store-impl.js.map +1 -1
  12. package/out/replicache/src/db/rebase.d.ts +14 -2
  13. package/out/replicache/src/db/rebase.d.ts.map +1 -1
  14. package/out/replicache/src/db/rebase.js +27 -5
  15. package/out/replicache/src/db/rebase.js.map +1 -1
  16. package/out/replicache/src/persist/collect-idb-databases.d.ts +10 -5
  17. package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
  18. package/out/replicache/src/persist/collect-idb-databases.js +16 -9
  19. package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
  20. package/out/replicache/src/persist/persist.d.ts.map +1 -1
  21. package/out/replicache/src/persist/persist.js +12 -5
  22. package/out/replicache/src/persist/persist.js.map +1 -1
  23. package/out/replicache/src/persist/refresh.js +6 -2
  24. package/out/replicache/src/persist/refresh.js.map +1 -1
  25. package/out/replicache/src/replicache-impl.d.ts +7 -3
  26. package/out/replicache/src/replicache-impl.d.ts.map +1 -1
  27. package/out/replicache/src/replicache-impl.js +98 -11
  28. package/out/replicache/src/replicache-impl.js.map +1 -1
  29. package/out/replicache/src/replicache-options.d.ts +9 -0
  30. package/out/replicache/src/replicache-options.d.ts.map +1 -1
  31. package/out/shared/src/iterables.d.ts +2 -0
  32. package/out/shared/src/iterables.d.ts.map +1 -1
  33. package/out/shared/src/iterables.js +18 -1
  34. package/out/shared/src/iterables.js.map +1 -1
  35. package/out/shared/src/ring-buffer.d.ts +8 -0
  36. package/out/shared/src/ring-buffer.d.ts.map +1 -1
  37. package/out/shared/src/ring-buffer.js +22 -1
  38. package/out/shared/src/ring-buffer.js.map +1 -1
  39. package/out/zero/package.js +2 -3
  40. package/out/zero/package.js.map +1 -1
  41. package/out/zero-cache/src/config/zero-config.js +2 -2
  42. package/out/zero-cache/src/config/zero-config.js.map +1 -1
  43. package/out/zero-cache/src/server/change-streamer.js +1 -1
  44. package/out/zero-cache/src/server/change-streamer.js.map +1 -1
  45. package/out/zero-cache/src/server/inspector-delegate.d.ts +18 -2
  46. package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
  47. package/out/zero-cache/src/server/inspector-delegate.js +20 -7
  48. package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
  49. package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts +156 -0
  50. package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts.map +1 -0
  51. package/out/zero-cache/src/services/change-source/pg/backfill-resume.js +15 -0
  52. package/out/zero-cache/src/services/change-source/pg/backfill-resume.js.map +1 -0
  53. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +15 -0
  54. package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
  55. package/out/zero-cache/src/services/change-source/pg/change-source-init.js +99 -0
  56. package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
  57. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +14 -16
  58. package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
  59. package/out/zero-cache/src/services/change-source/pg/change-source.js +33 -126
  60. package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
  61. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +16 -1
  62. package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
  63. package/out/zero-cache/src/services/change-source/pg/initial-sync.js +8 -4
  64. package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
  65. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
  66. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
  67. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
  68. package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
  69. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +1 -15
  70. package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
  71. package/out/zero-cache/src/services/change-source/pg/replication-slots.js +18 -21
  72. package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
  73. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +8 -9
  74. package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
  75. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +17 -1
  76. package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
  77. package/out/zero-cache/src/services/change-streamer/upstream-acker.js +19 -3
  78. package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
  79. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -1
  80. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +1 -0
  81. package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -1
  82. package/out/zero-cache/src/services/replicator/change-processor.js +1 -0
  83. package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
  84. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
  85. package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
  86. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
  87. package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
  88. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
  89. package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
  90. package/out/zero-cache/src/services/view-syncer/inspect-handler.js +2 -2
  91. package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
  92. package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
  93. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +6 -10
  94. package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
  95. package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
  96. package/out/zero-cache/src/services/view-syncer/view-syncer.js +14 -4
  97. package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
  98. package/out/zero-cache/src/types/streams.d.ts.map +1 -1
  99. package/out/zero-cache/src/types/streams.js +1 -1
  100. package/out/zero-cache/src/types/streams.js.map +1 -1
  101. package/out/zero-client/src/client/connection-manager.d.ts +20 -0
  102. package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
  103. package/out/zero-client/src/client/connection-manager.js +32 -14
  104. package/out/zero-client/src/client/connection-manager.js.map +1 -1
  105. package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
  106. package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
  107. package/out/zero-client/src/client/connection-status-enum.js +3 -1
  108. package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
  109. package/out/zero-client/src/client/connection.d.ts +6 -0
  110. package/out/zero-client/src/client/connection.d.ts.map +1 -1
  111. package/out/zero-client/src/client/connection.js +2 -1
  112. package/out/zero-client/src/client/connection.js.map +1 -1
  113. package/out/zero-client/src/client/context.d.ts +8 -11
  114. package/out/zero-client/src/client/context.d.ts.map +1 -1
  115. package/out/zero-client/src/client/context.js +11 -15
  116. package/out/zero-client/src/client/context.js.map +1 -1
  117. package/out/zero-client/src/client/custom.js +2 -2
  118. package/out/zero-client/src/client/custom.js.map +1 -1
  119. package/out/zero-client/src/client/error.js +1 -1
  120. package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
  121. package/out/zero-client/src/client/mutator-proxy.js +2 -1
  122. package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
  123. package/out/zero-client/src/client/options.d.ts +3 -0
  124. package/out/zero-client/src/client/options.d.ts.map +1 -1
  125. package/out/zero-client/src/client/options.js.map +1 -1
  126. package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
  127. package/out/zero-client/src/client/query-manager.js +42 -6
  128. package/out/zero-client/src/client/query-manager.js.map +1 -1
  129. package/out/zero-client/src/client/version.js +1 -1
  130. package/out/zero-client/src/client/zero-rep.d.ts +1 -0
  131. package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
  132. package/out/zero-client/src/client/zero-rep.js +7 -5
  133. package/out/zero-client/src/client/zero-rep.js.map +1 -1
  134. package/out/zero-client/src/client/zero.d.ts +9 -3
  135. package/out/zero-client/src/client/zero.d.ts.map +1 -1
  136. package/out/zero-client/src/client/zero.js +48 -11
  137. package/out/zero-client/src/client/zero.js.map +1 -1
  138. package/out/zero-client/src/types/query-result.d.ts +2 -0
  139. package/out/zero-client/src/types/query-result.d.ts.map +1 -1
  140. package/out/zero-react/src/use-query.d.ts +5 -4
  141. package/out/zero-react/src/use-query.d.ts.map +1 -1
  142. package/out/zero-react/src/use-query.js +12 -1
  143. package/out/zero-react/src/use-query.js.map +1 -1
  144. package/out/zero-server/src/adapters/drizzle.d.ts +2 -1
  145. package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
  146. package/out/zero-server/src/adapters/drizzle.js +12 -7
  147. package/out/zero-server/src/adapters/drizzle.js.map +1 -1
  148. package/out/zero-server/src/adapters/kysely.d.ts +2 -1
  149. package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
  150. package/out/zero-server/src/adapters/kysely.js +8 -2
  151. package/out/zero-server/src/adapters/kysely.js.map +1 -1
  152. package/out/zero-server/src/adapters/pg.d.ts +1 -0
  153. package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
  154. package/out/zero-server/src/adapters/pg.js +8 -2
  155. package/out/zero-server/src/adapters/pg.js.map +1 -1
  156. package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
  157. package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
  158. package/out/zero-server/src/adapters/postgresjs.js +7 -1
  159. package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
  160. package/out/zero-server/src/adapters/prisma.d.ts +3 -2
  161. package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
  162. package/out/zero-server/src/adapters/prisma.js +8 -2
  163. package/out/zero-server/src/adapters/prisma.js.map +1 -1
  164. package/out/zero-server/src/custom.d.ts +5 -1
  165. package/out/zero-server/src/custom.d.ts.map +1 -1
  166. package/out/zero-server/src/custom.js +6 -3
  167. package/out/zero-server/src/custom.js.map +1 -1
  168. package/out/zero-server/src/mod.d.ts +1 -1
  169. package/out/zero-server/src/mod.d.ts.map +1 -1
  170. package/out/zero-server/src/pg-query-executor.d.ts +2 -2
  171. package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
  172. package/out/zero-server/src/pg-query-executor.js +2 -2
  173. package/out/zero-server/src/pg-query-executor.js.map +1 -1
  174. package/out/zero-server/src/schema.d.ts +2 -2
  175. package/out/zero-server/src/schema.d.ts.map +1 -1
  176. package/out/zero-server/src/schema.js +2 -2
  177. package/out/zero-server/src/schema.js.map +1 -1
  178. package/out/zero-server/src/zql-database.d.ts +21 -1
  179. package/out/zero-server/src/zql-database.d.ts.map +1 -1
  180. package/out/zero-server/src/zql-database.js +33 -2
  181. package/out/zero-server/src/zql-database.js.map +1 -1
  182. package/out/zero-solid/src/solid-view.d.ts +10 -0
  183. package/out/zero-solid/src/solid-view.d.ts.map +1 -1
  184. package/out/zero-solid/src/solid-view.js +27 -0
  185. package/out/zero-solid/src/solid-view.js.map +1 -1
  186. package/out/zql/src/ivm/array-view.d.ts +10 -0
  187. package/out/zql/src/ivm/array-view.d.ts.map +1 -1
  188. package/out/zql/src/ivm/array-view.js +20 -8
  189. package/out/zql/src/ivm/array-view.js.map +1 -1
  190. package/out/zql/src/ivm/cap.d.ts.map +1 -1
  191. package/out/zql/src/ivm/cap.js +5 -3
  192. package/out/zql/src/ivm/cap.js.map +1 -1
  193. package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
  194. package/out/zql/src/ivm/deferred-input.js +3 -2
  195. package/out/zql/src/ivm/deferred-input.js.map +1 -1
  196. package/out/zql/src/ivm/exists.d.ts +1 -1
  197. package/out/zql/src/ivm/exists.d.ts.map +1 -1
  198. package/out/zql/src/ivm/exists.js.map +1 -1
  199. package/out/zql/src/ivm/fan-in.d.ts +2 -2
  200. package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
  201. package/out/zql/src/ivm/fan-in.js +6 -5
  202. package/out/zql/src/ivm/fan-in.js.map +1 -1
  203. package/out/zql/src/ivm/fan-out.d.ts +2 -2
  204. package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
  205. package/out/zql/src/ivm/fan-out.js.map +1 -1
  206. package/out/zql/src/ivm/filter-operators.d.ts +6 -6
  207. package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
  208. package/out/zql/src/ivm/filter-operators.js +10 -8
  209. package/out/zql/src/ivm/filter-operators.js.map +1 -1
  210. package/out/zql/src/ivm/filter.d.ts +2 -2
  211. package/out/zql/src/ivm/filter.d.ts.map +1 -1
  212. package/out/zql/src/ivm/filter.js +7 -4
  213. package/out/zql/src/ivm/filter.js.map +1 -1
  214. package/out/zql/src/ivm/flipped-join.js +2 -2
  215. package/out/zql/src/ivm/flipped-join.js.map +1 -1
  216. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
  217. package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
  218. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
  219. package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
  220. package/out/zql/src/ivm/memory-source.d.ts +2 -2
  221. package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
  222. package/out/zql/src/ivm/memory-source.js +9 -9
  223. package/out/zql/src/ivm/memory-source.js.map +1 -1
  224. package/out/zql/src/ivm/take.d.ts.map +1 -1
  225. package/out/zql/src/ivm/take.js +3 -4
  226. package/out/zql/src/ivm/take.js.map +1 -1
  227. package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
  228. package/out/zql/src/ivm/union-fan-in.js +9 -7
  229. package/out/zql/src/ivm/union-fan-in.js.map +1 -1
  230. package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
  231. package/out/zql/src/ivm/view-apply-change.js +3 -3
  232. package/out/zql/src/ivm/view-apply-change.js.map +1 -1
  233. package/out/zql/src/mutate/custom.d.ts +24 -1
  234. package/out/zql/src/mutate/custom.d.ts.map +1 -1
  235. package/out/zql/src/mutate/custom.js.map +1 -1
  236. package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
  237. package/out/zql/src/mutate/mutator-registry.js +2 -2
  238. package/out/zql/src/mutate/mutator-registry.js.map +1 -1
  239. package/out/zql/src/query/query-delegate-base.d.ts +2 -0
  240. package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
  241. package/out/zql/src/query/query-delegate-base.js +55 -28
  242. package/out/zql/src/query/query-delegate-base.js.map +1 -1
  243. package/out/zql/src/query/query-delegate.d.ts +11 -1
  244. package/out/zql/src/query/query-delegate.d.ts.map +1 -1
  245. package/out/zql/src/query/query-impl.d.ts +1 -0
  246. package/out/zql/src/query/query-impl.d.ts.map +1 -1
  247. package/out/zql/src/query/query-impl.js.map +1 -1
  248. package/out/zql/src/query/query.d.ts +7 -1
  249. package/out/zql/src/query/query.d.ts.map +1 -1
  250. package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
  251. package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
  252. package/out/zql/src/query/runnable-query-impl.js.map +1 -1
  253. package/out/zql/src/query/typed-view.d.ts +1 -1
  254. package/out/zql/src/query/typed-view.d.ts.map +1 -1
  255. package/out/zqlite/src/table-source.d.ts.map +1 -1
  256. package/out/zqlite/src/table-source.js +7 -5
  257. package/out/zqlite/src/table-source.js.map +1 -1
  258. package/package.json +2 -3
@@ -7,113 +7,28 @@ import { mapValues } from "../../../../../shared/src/objects.js";
7
7
  import { equals, intersection, symmetricDifferences } from "../../../../../shared/src/set-utils.js";
8
8
  import { stringify } from "../../../../../shared/src/bigint-json.js";
9
9
  import { upstreamSchema } from "../../../types/shards.js";
10
- import { Database } from "../../../../../zqlite/src/db.js";
11
10
  import { UnsupportedColumnDefaultError, mapPostgresToLiteColumn } from "../../../db/pg-to-lite.js";
12
11
  import { getOrCreateCounter } from "../../../observability/metrics.js";
13
- import { getSubscriptionStateAndContext } from "../../replicator/schema/replication-state.js";
14
- import { StatementRunner } from "../../../db/statements.js";
15
- import { connectPgClient, isPostgresError, pgClient } from "../../../types/pg.js";
12
+ import { isPostgresError, pgClient } from "../../../types/pg.js";
16
13
  import { majorVersionFromString, majorVersionToString } from "../../../types/state-version.js";
17
14
  import { fromBigInt, toBigInt, toStateVersionString } from "./lsn.js";
18
15
  import { getPublicationInfo, warnForSkippedIndexes } from "./schema/published.js";
19
16
  import { replicationEventSchema } from "./schema/ddl.js";
20
17
  import { validate } from "./schema/validation.js";
21
- import { dropShard, getActiveReplicas, getInternalShardConfig, getReplicaAtVersion, internalPublicationPrefix, replicaIdentitiesForTablesWithoutPrimaryKeys, replicationSlotPrefix } from "./schema/shard.js";
22
- import { AutoResetSignal } from "../../change-streamer/schema/tables.js";
18
+ import { getInternalShardConfig, getReplicaAtVersion, replicaIdentitiesForTablesWithoutPrimaryKeys, replicationSlotPrefix } from "./schema/shard.js";
23
19
  import { mapIndexPredicateColumns } from "../../../db/index-predicate.js";
24
- import { restoreReplica } from "../common/replica-restore.js";
25
- import { initReplica } from "../common/replica-schema.js";
26
20
  import "../../../types/pg-versions.js";
27
21
  import { BackfillManager } from "../common/backfill-manager.js";
28
22
  import { ChangeStreamMultiplexer } from "../common/change-stream-multiplexer.js";
29
23
  import { subscribe } from "./logical-replication/stream.js";
30
- import { dropOldReplicasAndSlots } from "./replication-slots.js";
31
- import { ensureShardSchema } from "./schema/init.js";
32
- import { initialSync } from "./initial-sync.js";
24
+ import "./initial-sync.js";
33
25
  import { streamBackfill } from "./backfill-stream.js";
26
+ import { ReplicationSlotCleanupMonitor } from "./replication-slot-cleanup-monitor.js";
34
27
  import { registerReplicationSlotHealthMetrics } from "./replication-slot-health.js";
35
28
  import { nanoid } from "nanoid";
36
29
  import postgres from "postgres";
37
30
  import { PG_ADMIN_SHUTDOWN, PG_INSUFFICIENT_PRIVILEGE } from "@drdgvhbh/postgres-error-codes";
38
31
  //#region ../zero-cache/src/services/change-source/pg/change-source.ts
39
- var REPLICA_SLOT_CLEANUP_INTERVAL_MS = 3e4;
40
- /**
41
- * Initializes a Postgres change source, including the initial sync of the
42
- * replica, before streaming changes from the corresponding logical replication
43
- * stream.
44
- */
45
- async function initializePostgresChangeSource(lc, upstreamURI, shard, replicaDbFile, syncOptions, context, lagReportIntervalMs = 0, restoreOptions = {}, { backupV5 } = { backupV5: true }, purgeLock, streamInboundTimeoutMs) {
46
- const db = await connectPgClient(lc, upstreamURI, "change-source-init");
47
- try {
48
- await ensureShardSchema(lc, db, shard, syncOptions.installPartialIndexTriggers);
49
- const restoredReplica = await selectAndRestoreReplica(lc, db, shard, replicaDbFile, restoreOptions);
50
- let initialSyncedReplica;
51
- await initReplica(lc, `replica-${shard.appID}-${shard.shardNum}`, replicaDbFile, async (log, tx) => {
52
- purgeLock?.release();
53
- initialSyncedReplica = await initialSync(log, shard, tx, upstreamURI, syncOptions, context, { backupV5 });
54
- });
55
- const replica = new Database(lc, replicaDbFile);
56
- const subscriptionState = getSubscriptionStateAndContext(new StatementRunner(replica));
57
- replica.close();
58
- const upstreamReplica = await checkAndUpdateUpstream(lc, db, shard, subscriptionState, (initialSyncedReplica ?? restoredReplica)?.id);
59
- const backupPath = initialSyncedReplica ? initialSyncedReplica.backupPath : backupV5 ? String(Date.now()) : restoredReplica?.backupPath ?? null;
60
- return {
61
- subscriptionState,
62
- changeSource: new PostgresChangeSource(lc, upstreamURI, shard, upstreamReplica, {
63
- backupPath,
64
- backupV5
65
- }, context, lagReportIntervalMs, syncOptions.textCopy, streamInboundTimeoutMs),
66
- destinationBackupURL: backupPath && restoreOptions.litestream?.backupURL ? new URL(backupPath, restoreOptions.litestream.backupURL).toString() : restoreOptions.litestream?.backupURL,
67
- replicaID: upstreamReplica.id,
68
- waitForBackupBeforeServing: initialSyncedReplica !== void 0 || backupPath !== (restoredReplica?.backupPath ?? null)
69
- };
70
- } finally {
71
- await db.end();
72
- }
73
- }
74
- async function selectAndRestoreReplica(lc, sql, shard, replicaFile, { litestream, constraints }) {
75
- const replicas = (await getActiveReplicas(lc, sql, shard)).filter(({ generation }) => generation === (constraints?.replicaVersion ?? generation));
76
- if (replicas.length === 0) {
77
- lc.info?.(`no suitable replicas to restore from`, { replicas });
78
- return;
79
- }
80
- const [replica] = replicas;
81
- if (litestream?.backupURL) {
82
- const { backupURL: backupBaseURL } = litestream;
83
- const { slot, backupPath, confirmedFlushLsn } = replica;
84
- const backupURL = new URL(backupPath ?? "", backupBaseURL).toString();
85
- lc.info?.(`restoring replica from ${backupURL} (${slot}@${confirmedFlushLsn})`, { replicas });
86
- await restoreReplica(lc, {
87
- ...litestream,
88
- backupURL
89
- }, replicaFile, constraints);
90
- }
91
- return replica;
92
- }
93
- async function checkAndUpdateUpstream(lc, sql, shard, { replicaVersion, publications: subscribed, initialSyncContext }, replicaID) {
94
- const upstreamReplica = await getReplicaAtVersion(lc, sql, shard, replicaVersion, replicaID, initialSyncContext);
95
- if (!upstreamReplica) throw new AutoResetSignal(`No replication slot for replica at version ${replicaVersion} and id ${replicaID}}`);
96
- const requested = shard.publications.toSorted();
97
- const replicated = upstreamReplica.publications.filter((p) => !p.startsWith(internalPublicationPrefix(shard))).sort();
98
- if (!deepEqual(requested, replicated)) {
99
- lc.warn?.(`Dropping shard to change publications to: [${requested}]`);
100
- await sql.unsafe(dropShard(shard.appID, shard.shardNum));
101
- throw new AutoResetSignal(`Requested publications [${requested}] do not match configured publications: [${replicated}]`);
102
- }
103
- if (!deepEqual(upstreamReplica.publications, subscribed)) throw new AutoResetSignal(`Upstream publications [${upstreamReplica.publications}] do not match subscribed publications [${subscribed}]`);
104
- const exists = await sql`
105
- SELECT pubname FROM pg_publication WHERE pubname IN ${sql(subscribed)};
106
- `.values();
107
- if (exists.length !== subscribed.length) throw new AutoResetSignal(`Upstream publications [${exists.flat()}] do not contain all subscribed publications [${subscribed}]`);
108
- const { slot } = upstreamReplica;
109
- const result = await sql`
110
- SELECT restart_lsn as "restartLSN", wal_status as "walStatus" FROM pg_replication_slots
111
- WHERE slot_name = ${slot}`;
112
- if (result.length === 0) throw new AutoResetSignal(`replication slot ${slot} is missing`);
113
- const [{ restartLSN, walStatus }] = result;
114
- if (restartLSN === null || walStatus === "lost") throw new AutoResetSignal(`replication slot ${slot} has been invalidated for exceeding the max_slot_wal_keep_size`);
115
- return upstreamReplica;
116
- }
117
32
  var MAX_LOW_PRIORITY_DELAY_MS = 1e3;
118
33
  /**
119
34
  * Postgres implementation of a {@link ChangeSource} backed by a logical
@@ -125,6 +40,7 @@ var PostgresChangeSource = class {
125
40
  #upstreamUri;
126
41
  #shard;
127
42
  #replica;
43
+ #slotCleanupMonitor;
128
44
  #backupOptions;
129
45
  #context;
130
46
  #lagReporter;
@@ -133,28 +49,28 @@ var PostgresChangeSource = class {
133
49
  #subscribe;
134
50
  #streamBackfill;
135
51
  #stopped = false;
136
- constructor(lc, upstreamUri, shard, replica, backupOptions, context, lagReportIntervalMs, textCopy, streamInboundTimeoutMs, deps = {}) {
52
+ constructor(lc, upstreamUri, shard, replica, pgVersion, backupOptions, context, lagReportIntervalMs, textCopy, streamInboundTimeoutMs, deps = {}) {
137
53
  this.#lc = lc.withContext("component", "change-source");
138
54
  this.#subscribe = deps.subscribe ?? subscribe;
139
55
  this.#streamBackfill = deps.streamBackfill ?? streamBackfill;
140
56
  this.#db = pgClient(lc, upstreamUri, "replication-monitor", {
141
- max: 1,
142
- ["idle_timeout"]: 60
57
+ max: 3,
58
+ idle_timeout: 60
143
59
  });
144
60
  this.#upstreamUri = upstreamUri;
145
61
  this.#shard = shard;
146
62
  this.#replica = replica;
63
+ this.#slotCleanupMonitor = new ReplicationSlotCleanupMonitor(lc.withContext("component", "replication-slot-monitor"), shard, this.#db, pgVersion, replica.slot);
147
64
  this.#backupOptions = backupOptions;
148
65
  this.#context = context;
149
66
  this.#textCopy = textCopy ?? false;
150
67
  this.#streamInboundTimeoutMs = streamInboundTimeoutMs;
151
- this.#lagReporter = lagReportIntervalMs > 0 ? new LagReporter(lc.withContext("component", "lag-reporter"), shard, this.#db, lagReportIntervalMs) : null;
68
+ this.#lagReporter = lagReportIntervalMs > 0 ? new LagReporter(lc.withContext("component", "lag-reporter"), shard, this.#db, pgVersion, lagReportIntervalMs) : null;
152
69
  registerReplicationSlotHealthMetrics(this.#lc, this.#db, replica.slot, () => this.#stopped);
153
70
  }
154
71
  async stop() {
155
72
  this.#stopped = true;
156
73
  this.#lagReporter?.stop();
157
- clearTimeout(this.#cleanupTimer);
158
74
  await this.#db.end();
159
75
  }
160
76
  async startLagReporter() {
@@ -173,12 +89,18 @@ var PostgresChangeSource = class {
173
89
  const config = await getInternalShardConfig(this.#db, this.#shard);
174
90
  const { slot } = this.#replica;
175
91
  this.#lc.info?.(`starting replication stream@${slot}`);
176
- return this.startStreamInternal(slot, clientWatermark, config, backfillRequests);
92
+ const changeStream = await this.startStreamInternal(slot, clientWatermark, config, backfillRequests);
93
+ const { signal } = changeStream.changes;
94
+ if (!signal.aborted) {
95
+ this.#slotCleanupMonitor.start();
96
+ signal.addEventListener("abort", () => this.#slotCleanupMonitor.stop());
97
+ }
98
+ return changeStream;
177
99
  }
178
100
  async startStreamInternal(slot, clientWatermark, shardConfig, backfillRequests) {
179
101
  const clientStart = majorVersionFromString(clientWatermark) + 1n;
180
102
  const { messages, acks } = await this.#subscribe(this.#lc, this.#db, slot, [...shardConfig.publications], clientStart, void 0, void 0, this.#streamInboundTimeoutMs);
181
- const acker = new Acker(acks);
103
+ const acker = new Acker(acks, clientWatermark);
182
104
  const changes = new ChangeStreamMultiplexer(this.#lc, clientWatermark);
183
105
  const backfillManager = new BackfillManager(this.#lc, changes, (req) => this.#streamBackfill(this.#lc, this.#upstreamUri, this.#replica, req, { textCopy: this.#textCopy }));
184
106
  changes.addProducers(messages, backfillManager).addListeners(backfillManager, acker);
@@ -312,29 +234,22 @@ var PostgresChangeSource = class {
312
234
  "backupPath" = ${this.#backupOptions.backupPath},
313
235
  "backupV5" = ${this.#backupOptions.backupV5}
314
236
  WHERE id = ${replicaID}`;
315
- this.#cleanUpOlderReplicasAndSlots();
316
- }
317
- #cleanupTimer;
318
- async #cleanUpOlderReplicasAndSlots() {
319
- clearTimeout(this.#cleanupTimer);
320
- try {
321
- const result = await dropOldReplicasAndSlots(this.#lc, this.#db, this.#shard, this.#replica.rank);
322
- if (result.draining === 0) {
323
- this.#lc.info?.(`finished cleaning up replicas and slots`, { result });
324
- return;
325
- }
326
- this.#lc.info?.(`old slots still draining`, { result });
327
- } catch (e) {
328
- this.#lc.warn?.(`error dropping replication slots`, e);
329
- }
330
- this.#cleanupTimer = setTimeout(() => this.#cleanUpOlderReplicasAndSlots(), REPLICA_SLOT_CLEANUP_INTERVAL_MS);
331
237
  }
332
238
  };
333
239
  var Acker = class {
334
240
  #acks;
335
- #waitingForDownstreamAck = null;
336
- constructor(acks) {
241
+ #waitingForDownstreamAck;
242
+ /**
243
+ * @param resumeWatermark the watermark the stream resumes after. What came
244
+ * before it was received on an earlier connection, and only the
245
+ * change-streamer knows whether it has persisted it, so keepalives are
246
+ * not acked until the change-streamer has acked it. A change-streamer
247
+ * whose SQLite change log is ahead of its backup would otherwise have
248
+ * the slot moved past transactions that only that log holds.
249
+ */
250
+ constructor(acks, resumeWatermark) {
337
251
  this.#acks = acks;
252
+ this.#waitingForDownstreamAck = resumeWatermark;
338
253
  }
339
254
  onChange(change) {
340
255
  switch (change[0]) {
@@ -381,25 +296,17 @@ var LagReporter = class LagReporter {
381
296
  #pgVersion;
382
297
  #expectingLagReport = null;
383
298
  #timer;
384
- constructor(lc, shard, db, lagIntervalMs) {
299
+ constructor(lc, shard, db, pgVersion, lagIntervalMs) {
385
300
  this.#lc = lc;
386
301
  this.messagePrefix = `${shard.appID}/${shard.shardNum}${LagReporter.MESSAGE_SUFFIX}`;
387
302
  this.#db = db;
303
+ this.#pgVersion = pgVersion;
388
304
  this.#lagIntervalMs = lagIntervalMs;
389
305
  }
390
- async #getPgVersion() {
391
- if (this.#pgVersion === void 0) {
392
- const [{ pgVersion }] = await this.#db`
393
- SELECT current_setting('server_version_num')::int as "pgVersion"`;
394
- this.#pgVersion = pgVersion;
395
- }
396
- return this.#pgVersion;
397
- }
398
306
  get pgVersion() {
399
307
  return this.#pgVersion;
400
308
  }
401
309
  async initiateLagReport(log = false) {
402
- const pgVersion = this.#pgVersion ?? await this.#getPgVersion();
403
310
  const now = Date.now();
404
311
  const id = nanoid();
405
312
  const lagReport = {
@@ -412,7 +319,7 @@ var LagReporter = class LagReporter {
412
319
  let commitTimeMs;
413
320
  let lsn;
414
321
  try {
415
- if (pgVersion >= 17e4) [{commitTimeMs, lsn}] = await this.#db`
322
+ if (this.#pgVersion >= 17e4) [{commitTimeMs, lsn}] = await this.#db`
416
323
  WITH CTE AS (SELECT extract(epoch from now()) * 1000 AS "commitTimeMs")
417
324
  SELECT "commitTimeMs", pg_logical_emit_message(
418
325
  false,
@@ -1071,6 +978,6 @@ function parseLogicalMessageContent(lc, msg, schema) {
1071
978
  }
1072
979
  }
1073
980
  //#endregion
1074
- export { initializePostgresChangeSource };
981
+ export { PostgresChangeSource };
1075
982
 
1076
983
  //# sourceMappingURL=change-source.js.map