@rocicorp/zero 1.11.0-canary.4 → 1.11.0-canary.41
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.
- package/out/analyze-query/src/analyze-cli.js +4 -4
- package/out/analyze-query/src/analyze-cli.js.map +1 -1
- package/out/analyze-query/src/bin-analyze.js +13 -12
- package/out/analyze-query/src/bin-analyze.js.map +1 -1
- package/out/analyze-query/src/bin-transform.js +1 -1
- package/out/analyze-query/src/bin-transform.js.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.d.ts +8 -1
- package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.js +25 -25
- package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
- package/out/otel/src/log-options.d.ts +16 -0
- package/out/otel/src/log-options.d.ts.map +1 -1
- package/out/otel/src/log-options.js +60 -6
- package/out/otel/src/log-options.js.map +1 -1
- package/out/replicache/src/bg-interval.d.ts +2 -1
- package/out/replicache/src/bg-interval.d.ts.map +1 -1
- package/out/replicache/src/bg-interval.js +13 -4
- package/out/replicache/src/bg-interval.js.map +1 -1
- package/out/replicache/src/btree/node.d.ts.map +1 -1
- package/out/replicache/src/btree/node.js +3 -6
- package/out/replicache/src/btree/node.js.map +1 -1
- package/out/replicache/src/dag/gc.d.ts.map +1 -1
- package/out/replicache/src/dag/gc.js +8 -11
- package/out/replicache/src/dag/gc.js.map +1 -1
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
- package/out/replicache/src/dag/lazy-store.d.ts +17 -4
- package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
- package/out/replicache/src/dag/lazy-store.js +35 -9
- package/out/replicache/src/dag/lazy-store.js.map +1 -1
- package/out/replicache/src/dag/store-impl.d.ts +12 -2
- package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
- package/out/replicache/src/dag/store-impl.js +29 -9
- package/out/replicache/src/dag/store-impl.js.map +1 -1
- package/out/replicache/src/db/rebase.d.ts +14 -2
- package/out/replicache/src/db/rebase.d.ts.map +1 -1
- package/out/replicache/src/db/rebase.js +27 -5
- package/out/replicache/src/db/rebase.js.map +1 -1
- package/out/replicache/src/get-kv-store-provider.d.ts +1 -1
- package/out/replicache/src/get-kv-store-provider.d.ts.map +1 -1
- package/out/replicache/src/get-kv-store-provider.js +4 -4
- package/out/replicache/src/get-kv-store-provider.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js +28 -5
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/idb-store.d.ts +18 -0
- package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
- package/out/replicache/src/kv/idb-store.js +30 -2
- package/out/replicache/src/kv/idb-store.js.map +1 -1
- package/out/replicache/src/kv/mem-fallback-store.d.ts +54 -0
- package/out/replicache/src/kv/mem-fallback-store.d.ts.map +1 -0
- package/out/replicache/src/kv/mem-fallback-store.js +177 -0
- package/out/replicache/src/kv/mem-fallback-store.js.map +1 -0
- package/out/replicache/src/kv/mem-store.d.ts +1 -0
- package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
- package/out/replicache/src/kv/mem-store.js +3 -0
- package/out/replicache/src/kv/mem-store.js.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.js +4 -4
- package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts +22 -1
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +159 -14
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/kv/store.d.ts +6 -0
- package/out/replicache/src/kv/store.d.ts.map +1 -1
- package/out/replicache/src/new-client-channel.js.map +1 -1
- package/out/replicache/src/persist/client-gc.d.ts +2 -1
- package/out/replicache/src/persist/client-gc.d.ts.map +1 -1
- package/out/replicache/src/persist/client-gc.js +2 -2
- package/out/replicache/src/persist/client-gc.js.map +1 -1
- package/out/replicache/src/persist/client-group-gc.d.ts +2 -1
- package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
- package/out/replicache/src/persist/client-group-gc.js +2 -2
- package/out/replicache/src/persist/client-group-gc.js.map +1 -1
- package/out/replicache/src/persist/clients.d.ts +2 -2
- package/out/replicache/src/persist/collect-idb-databases.d.ts +28 -8
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.js +97 -20
- package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
- package/out/replicache/src/persist/heartbeat.d.ts +2 -1
- package/out/replicache/src/persist/heartbeat.d.ts.map +1 -1
- package/out/replicache/src/persist/heartbeat.js +2 -2
- package/out/replicache/src/persist/heartbeat.js.map +1 -1
- package/out/replicache/src/persist/idb-databases-store-db-name.js +1 -1
- package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
- package/out/replicache/src/persist/persist.d.ts.map +1 -1
- package/out/replicache/src/persist/persist.js +18 -8
- package/out/replicache/src/persist/persist.js.map +1 -1
- package/out/replicache/src/persist/refresh.js +6 -2
- package/out/replicache/src/persist/refresh.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +85 -3
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +321 -29
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/replicache-options.d.ts +9 -0
- package/out/replicache/src/replicache-options.d.ts.map +1 -1
- package/out/replicache/src/storage-failure.d.ts +37 -0
- package/out/replicache/src/storage-failure.d.ts.map +1 -0
- package/out/replicache/src/storage-failure.js +31 -0
- package/out/replicache/src/storage-failure.js.map +1 -0
- package/out/shared/src/arrays.d.ts +5 -0
- package/out/shared/src/arrays.d.ts.map +1 -1
- package/out/shared/src/arrays.js +8 -10
- package/out/shared/src/arrays.js.map +1 -1
- package/out/shared/src/centroid.d.ts +0 -1
- package/out/shared/src/centroid.d.ts.map +1 -1
- package/out/shared/src/centroid.js +1 -4
- package/out/shared/src/centroid.js.map +1 -1
- package/out/shared/src/error.d.ts +11 -0
- package/out/shared/src/error.d.ts.map +1 -1
- package/out/shared/src/error.js +35 -1
- package/out/shared/src/error.js.map +1 -1
- package/out/shared/src/hash.d.ts.map +1 -1
- package/out/shared/src/hash.js +32 -7
- package/out/shared/src/hash.js.map +1 -1
- package/out/shared/src/iterables.d.ts +2 -0
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js +18 -1
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/map.d.ts +24 -2
- package/out/shared/src/map.d.ts.map +1 -1
- package/out/shared/src/map.js +18 -4
- package/out/shared/src/map.js.map +1 -1
- package/out/shared/src/options-types.d.ts +2 -2
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +10 -7
- package/out/shared/src/options.js.map +1 -1
- package/out/shared/src/random-values.js +12 -1
- package/out/shared/src/random-values.js.map +1 -1
- package/out/shared/src/ring-buffer.d.ts +10 -0
- package/out/shared/src/ring-buffer.d.ts.map +1 -1
- package/out/shared/src/ring-buffer.js +26 -1
- package/out/shared/src/ring-buffer.js.map +1 -1
- package/out/shared/src/tdigest.d.ts +10 -0
- package/out/shared/src/tdigest.d.ts.map +1 -1
- package/out/shared/src/tdigest.js +147 -63
- package/out/shared/src/tdigest.js.map +1 -1
- package/out/shared/src/valita.d.ts +88 -0
- package/out/shared/src/valita.d.ts.map +1 -1
- package/out/shared/src/valita.js +141 -23
- package/out/shared/src/valita.js.map +1 -1
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +10 -6
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +9 -5
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +5 -6
- package/out/zero/package.js.map +1 -1
- package/out/zero/src/zero.js +2 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +1 -0
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts +1 -0
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +47 -4
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +148 -25
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +500 -167
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js +3 -4
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
- package/out/zero-cache/src/db/migration-lite.js +5 -3
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/observability/events.js +4 -1
- package/out/zero-cache/src/observability/events.js.map +1 -1
- package/out/zero-cache/src/observability/log-throttle.d.ts +44 -0
- package/out/zero-cache/src/observability/log-throttle.d.ts.map +1 -0
- package/out/zero-cache/src/observability/log-throttle.js +76 -0
- package/out/zero-cache/src/observability/log-throttle.js.map +1 -0
- package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/observability/metrics.js +2 -7
- package/out/zero-cache/src/observability/metrics.js.map +1 -1
- package/out/zero-cache/src/scripts/permissions.d.ts +16 -0
- package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
- package/out/zero-cache/src/scripts/permissions.js +3 -3
- package/out/zero-cache/src/scripts/permissions.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +123 -87
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +28 -2
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +37 -17
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +13 -2
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/mutator.js +2 -0
- package/out/zero-cache/src/server/mutator.js.map +1 -1
- package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
- package/out/zero-cache/src/server/reaper.js +2 -0
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts +7 -0
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +103 -22
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +12 -6
- package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.js +5 -0
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/slot-keeper.d.ts +26 -0
- package/out/zero-cache/src/server/slot-keeper.d.ts.map +1 -0
- package/out/zero-cache/src/server/slot-keeper.js +181 -0
- package/out/zero-cache/src/server/slot-keeper.js.map +1 -0
- package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
- package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
- package/out/zero-cache/src/server/syncer-assigner.js +72 -0
- package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +40 -2
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/worker-urls.d.ts +1 -0
- package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-urls.js +2 -1
- package/out/zero-cache/src/server/worker-urls.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +11 -9
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +198 -24
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +16 -4
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts +24 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.js +44 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +82 -2
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.js +21 -10
- package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js +15 -3
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +7 -3
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +9 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +213 -21
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +65 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js +312 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +31 -18
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +132 -157
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +44 -2
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +65 -28
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +66 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +207 -24
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +66 -21
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +274 -68
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +46 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +68 -27
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +116 -35
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +68 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +141 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +45 -2
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js +10 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +60 -3
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +23 -10
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +17 -7
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current.js +2 -1
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts +72 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js +162 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts +50 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.js +268 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +6 -17
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +59 -8
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +8 -2
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +24 -4
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -4
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js +28 -8
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +17 -0
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +44 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +54 -6
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +145 -35
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +36 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +267 -118
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +161 -17
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js +33 -2
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts +24 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js +67 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +53 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +156 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts +243 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.js +317 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +78 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js +173 -47
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts +92 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js +42 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +14 -2
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +23 -10
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +7 -69
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.js +21 -53
- package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +106 -5
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +299 -86
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +485 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.js +93 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +80 -2
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +157 -20
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +19 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js +23 -3
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
- package/out/zero-cache/src/services/http-service.d.ts +7 -1
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +14 -2
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts +68 -2
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +155 -19
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +35 -3
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +137 -35
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +6 -7
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +51 -24
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +10 -2
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.js +3 -2
- package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts +24 -0
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/restore-progress.js +91 -0
- package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +5 -6
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/plannerz.d.ts +163 -0
- package/out/zero-cache/src/services/plannerz.d.ts.map +1 -0
- package/out/zero-cache/src/services/plannerz.js +267 -0
- package/out/zero-cache/src/services/plannerz.js.map +1 -0
- package/out/zero-cache/src/services/profz.d.ts +30 -0
- package/out/zero-cache/src/services/profz.d.ts.map +1 -0
- package/out/zero-cache/src/services/profz.js +163 -0
- package/out/zero-cache/src/services/profz.js.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-cookies.js +1 -1
- package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +5 -4
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +20 -22
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +51 -5
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/drain-handler.d.ts +74 -0
- package/out/zero-cache/src/services/replicator/drain-handler.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/drain-handler.js +185 -0
- package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -0
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +6 -2
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js +114 -28
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts +35 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.js +99 -8
- package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +5 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js +5 -2
- package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +16 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js +70 -27
- package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +23 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.js +54 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +6 -6
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +19 -14
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +11 -3
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +5 -1
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts +12 -0
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +42 -22
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/runner.d.ts +2 -1
- package/out/zero-cache/src/services/runner.d.ts.map +1 -1
- package/out/zero-cache/src/services/runner.js +10 -2
- package/out/zero-cache/src/services/runner.js.map +1 -1
- package/out/zero-cache/src/services/statz.d.ts +4 -0
- package/out/zero-cache/src/services/statz.d.ts.map +1 -1
- package/out/zero-cache/src/services/statz.js +22 -5
- package/out/zero-cache/src/services/statz.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts +26 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.js +26 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts +79 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.js +249 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +19 -2
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +42 -30
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +27 -2
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +86 -21
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +75 -12
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +234 -43
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +81 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +128 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +12 -2
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +29 -5
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +165 -9
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +953 -209
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +7 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js +35 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.d.ts +132 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.js +164 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts +55 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.js +56 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -6
- package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +25 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js +28 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +89 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js +233 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +2 -107
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +5 -20
- package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +95 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +155 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +229 -16
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +455 -43
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +8 -2
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +788 -71
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.d.ts +2 -0
- package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.js +6 -1
- package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +2 -2
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +50 -0
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +43 -4
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/profiler.d.ts +12 -0
- package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
- package/out/zero-cache/src/types/profiler.js +46 -1
- package/out/zero-cache/src/types/profiler.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts +1 -15
- package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
- package/out/zero-cache/src/types/row-key.js +6 -8
- package/out/zero-cache/src/types/row-key.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts +49 -7
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +190 -58
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +15 -0
- package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
- package/out/zero-cache/src/types/subscription.js +123 -31
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +18 -9
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/types/ws.d.ts.map +1 -1
- package/out/zero-cache/src/types/ws.js +1 -16
- package/out/zero-cache/src/types/ws.js.map +1 -1
- package/out/zero-cache/src/workers/connect-params.d.ts +1 -0
- package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connect-params.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +2 -1
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +9 -1
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +24 -7
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +55 -4
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.js +4 -1
- package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +20 -0
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +77 -13
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
- package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.js +3 -1
- package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +6 -0
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js +2 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +23 -13
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +94 -26
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/crud-impl.d.ts.map +1 -1
- package/out/zero-client/src/client/crud-impl.js +1 -1
- package/out/zero-client/src/client/crud-impl.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts +5 -4
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.js +3 -3
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +1 -1
- package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
- package/out/zero-client/src/client/ivm-branch.js +20 -3
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/keys.d.ts.map +1 -1
- package/out/zero-client/src/client/keys.js +19 -1
- package/out/zero-client/src/client/keys.js.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.d.ts.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts +2 -2
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.js +3 -7
- package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js +9 -4
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +33 -0
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts +9 -0
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.js +47 -14
- package/out/zero-client/src/client/query-manager.js.map +1 -1
- package/out/zero-client/src/client/reload-error-handler.js +2 -2
- package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
- package/out/zero-client/src/client/storage-version.d.ts +23 -0
- package/out/zero-client/src/client/storage-version.d.ts.map +1 -0
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts +1 -0
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +8 -6
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +18 -3
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +86 -48
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +2 -1
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-client/src/mod.js +1 -0
- package/out/zero-client/src/types/query-result.d.ts +2 -0
- package/out/zero-client/src/types/query-result.d.ts.map +1 -1
- package/out/zero-events/src/status.d.ts +64 -0
- package/out/zero-events/src/status.d.ts.map +1 -1
- package/out/zero-protocol/src/analyze-query-result.d.ts +12 -12
- package/out/zero-protocol/src/analyze-query-result.d.ts.map +1 -1
- package/out/zero-protocol/src/analyze-query-result.js +3 -3
- package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
- package/out/zero-protocol/src/ast.d.ts +24 -0
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +39 -16
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +36 -36
- package/out/zero-protocol/src/inspect-down.d.ts +31 -31
- package/out/zero-protocol/src/inspect-up.d.ts +158 -61
- package/out/zero-protocol/src/inspect-up.d.ts.map +1 -1
- package/out/zero-protocol/src/inspect-up.js +12 -6
- package/out/zero-protocol/src/inspect-up.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +4 -1
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/queries-patch.js +2 -2
- package/out/zero-protocol/src/queries-patch.js.map +1 -1
- package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
- package/out/zero-protocol/src/query-hash.js +2 -5
- package/out/zero-protocol/src/query-hash.js.map +1 -1
- package/out/zero-protocol/src/up.d.ts +766 -256
- package/out/zero-protocol/src/up.d.ts.map +1 -1
- package/out/zero-protocol/src/up.js +25 -3
- package/out/zero-protocol/src/up.js.map +1 -1
- package/out/zero-react/src/use-query.d.ts +5 -4
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +75 -8
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-react/src/zero.js +1 -0
- package/out/zero-server/src/adapters/drizzle.d.ts +16 -4
- package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
- package/out/zero-server/src/adapters/drizzle.js +19 -11
- package/out/zero-server/src/adapters/drizzle.js.map +1 -1
- package/out/zero-server/src/adapters/kysely.d.ts +6 -3
- package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
- package/out/zero-server/src/adapters/kysely.js +16 -6
- package/out/zero-server/src/adapters/kysely.js.map +1 -1
- package/out/zero-server/src/adapters/pg.d.ts +7 -2
- package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
- package/out/zero-server/src/adapters/pg.js +34 -10
- package/out/zero-server/src/adapters/pg.js.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.d.ts +4 -2
- package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.js +15 -5
- package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
- package/out/zero-server/src/adapters/prisma.d.ts +17 -5
- package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
- package/out/zero-server/src/adapters/prisma.js +20 -6
- package/out/zero-server/src/adapters/prisma.js.map +1 -1
- package/out/zero-server/src/closable-db-transaction.d.ts +16 -0
- package/out/zero-server/src/closable-db-transaction.d.ts.map +1 -0
- package/out/zero-server/src/closable-db-transaction.js +31 -0
- package/out/zero-server/src/closable-db-transaction.js.map +1 -0
- package/out/zero-server/src/custom.d.ts +10 -4
- package/out/zero-server/src/custom.d.ts.map +1 -1
- package/out/zero-server/src/custom.js +15 -6
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/logging.d.ts +2 -2
- package/out/zero-server/src/logging.d.ts.map +1 -1
- package/out/zero-server/src/logging.js +2 -2
- package/out/zero-server/src/logging.js.map +1 -1
- package/out/zero-server/src/mod.d.ts +2 -1
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.d.ts +2 -2
- package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.js +2 -2
- package/out/zero-server/src/pg-query-executor.js.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +25 -4
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +103 -52
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/push-processor.d.ts +8 -2
- package/out/zero-server/src/push-processor.d.ts.map +1 -1
- package/out/zero-server/src/push-processor.js +12 -4
- package/out/zero-server/src/push-processor.js.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +1 -1
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-server/src/schema.d.ts +2 -2
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +3 -2
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-server/src/transaction-options.d.ts +24 -0
- package/out/zero-server/src/transaction-options.d.ts.map +1 -0
- package/out/zero-server/src/transaction-options.js +11 -0
- package/out/zero-server/src/transaction-options.js.map +1 -0
- package/out/zero-server/src/zql-database.d.ts +21 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js +61 -24
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +17 -0
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +39 -1
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-query.js +1 -2
- package/out/zero-solid/src/use-query.js.map +1 -1
- package/out/zero-solid/src/zero.js +1 -0
- package/out/zql/src/builder/builder.d.ts +25 -0
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +69 -19
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +43 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +1 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.js +161 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -0
- package/out/zql/src/builder/debug-delegate.d.ts +6 -1
- package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
- package/out/zql/src/builder/debug-delegate.js +14 -2
- package/out/zql/src/builder/debug-delegate.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts +29 -0
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +74 -16
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/cap.d.ts +2 -1
- package/out/zql/src/ivm/cap.d.ts.map +1 -1
- package/out/zql/src/ivm/cap.js +14 -4
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +8 -3
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
- package/out/zql/src/ivm/deferred-input.js +3 -2
- package/out/zql/src/ivm/deferred-input.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +3 -1
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +4 -1
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +6 -2
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +13 -5
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +5 -2
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js +4 -0
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +8 -6
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +19 -8
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +5 -2
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +10 -4
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts +9 -4
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +97 -46
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join-index-tap.d.ts +33 -0
- package/out/zql/src/ivm/join-index-tap.d.ts.map +1 -0
- package/out/zql/src/ivm/join-index-tap.js +70 -0
- package/out/zql/src/ivm/join-index-tap.js.map +1 -0
- package/out/zql/src/ivm/join-index.d.ts +35 -0
- package/out/zql/src/ivm/join-index.d.ts.map +1 -0
- package/out/zql/src/ivm/join-index.js +141 -0
- package/out/zql/src/ivm/join-index.js.map +1 -0
- package/out/zql/src/ivm/join-utils.d.ts +6 -0
- package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
- package/out/zql/src/ivm/join-utils.js +22 -1
- package/out/zql/src/ivm/join-utils.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts +19 -1
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +107 -15
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +29 -4
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +70 -34
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/memory-storage.d.ts +1 -0
- package/out/zql/src/ivm/memory-storage.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-storage.js +1 -0
- package/out/zql/src/ivm/memory-storage.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +45 -10
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js +9 -4
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/push-accumulated.d.ts +6 -1
- package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
- package/out/zql/src/ivm/push-accumulated.js +47 -2
- package/out/zql/src/ivm/push-accumulated.js.map +1 -1
- package/out/zql/src/ivm/skip.d.ts +2 -1
- package/out/zql/src/ivm/skip.d.ts.map +1 -1
- package/out/zql/src/ivm/skip.js +3 -0
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/take-gate.d.ts +57 -0
- package/out/zql/src/ivm/take-gate.d.ts.map +1 -0
- package/out/zql/src/ivm/take-gate.js +106 -0
- package/out/zql/src/ivm/take-gate.js.map +1 -0
- package/out/zql/src/ivm/take.d.ts +8 -2
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +139 -103
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +3 -0
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +63 -10
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts +2 -1
- package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js +5 -0
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +9 -4
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/ivm/view.d.ts +15 -0
- package/out/zql/src/ivm/view.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.d.ts +53 -1
- package/out/zql/src/mutate/custom.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +3 -3
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +2 -2
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/planner/planner-builder.d.ts +23 -3
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
- package/out/zql/src/planner/planner-builder.js +34 -17
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-connection.d.ts +58 -2
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
- package/out/zql/src/planner/planner-connection.js +103 -11
- package/out/zql/src/planner/planner-connection.js.map +1 -1
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js +3 -8
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-graph.d.ts +10 -0
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
- package/out/zql/src/planner/planner-graph.js +14 -0
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zql/src/planner/planner-source.d.ts +2 -2
- package/out/zql/src/planner/planner-source.d.ts.map +1 -1
- package/out/zql/src/planner/planner-source.js +2 -2
- package/out/zql/src/planner/planner-source.js.map +1 -1
- package/out/zql/src/planner/planner-warnings.d.ts +83 -0
- package/out/zql/src/planner/planner-warnings.d.ts.map +1 -0
- package/out/zql/src/planner/planner-warnings.js +78 -0
- package/out/zql/src/planner/planner-warnings.js.map +1 -0
- package/out/zql/src/query/expression.d.ts +2 -2
- package/out/zql/src/query/expression.d.ts.map +1 -1
- package/out/zql/src/query/expression.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts +9 -2
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +52 -5
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +4 -2
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +66 -33
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +33 -6
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +1 -0
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +6 -23
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-registry.js +1 -1
- package/out/zql/src/query/query-transitions.d.ts.map +1 -1
- package/out/zql/src/query/query-transitions.js +2 -5
- package/out/zql/src/query/query-transitions.js.map +1 -1
- package/out/zql/src/query/query.d.ts +26 -10
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js +2 -10
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/typed-view.d.ts +1 -1
- package/out/zql/src/query/typed-view.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.js +9 -1
- package/out/zqlite/src/database-storage.js.map +1 -1
- package/out/zqlite/src/db.d.ts +17 -1
- package/out/zqlite/src/db.d.ts.map +1 -1
- package/out/zqlite/src/db.js +73 -30
- package/out/zqlite/src/db.js.map +1 -1
- package/out/zqlite/src/index-usage.d.ts +19 -0
- package/out/zqlite/src/index-usage.d.ts.map +1 -0
- package/out/zqlite/src/index-usage.js +49 -0
- package/out/zqlite/src/index-usage.js.map +1 -0
- package/out/zqlite/src/pending-delta.d.ts +110 -0
- package/out/zqlite/src/pending-delta.d.ts.map +1 -0
- package/out/zqlite/src/pending-delta.js +278 -0
- package/out/zqlite/src/pending-delta.js.map +1 -0
- package/out/zqlite/src/query-builder.d.ts +17 -1
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +111 -20
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-delegate.js +10 -7
- package/out/zqlite/src/query-delegate.js.map +1 -1
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts +3 -1
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
- package/out/zqlite/src/resolve-scalar-subqueries.js +1 -0
- package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +53 -1
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +5 -31
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/sqlite-stat4-sample.d.ts +37 -0
- package/out/zqlite/src/sqlite-stat4-sample.d.ts.map +1 -0
- package/out/zqlite/src/sqlite-stat4-sample.js +61 -0
- package/out/zqlite/src/sqlite-stat4-sample.js.map +1 -0
- package/out/zqlite/src/table-source.d.ts +87 -2
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +276 -42
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +5 -6
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +0 -25
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +0 -1
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js +0 -83
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +0 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +0 -29
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +0 -154
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +0 -1
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
1
2
|
import type { LogContext } from '@rocicorp/logger';
|
|
2
3
|
import postgres from 'postgres';
|
|
4
|
+
import type { SlotKeeperConfig } from '../../../../server/slot-keeper.ts';
|
|
3
5
|
import { type PostgresDB } from '../../../../types/pg.ts';
|
|
6
|
+
import { type Worker } from '../../../../types/processes.ts';
|
|
4
7
|
import { type Sink, type Source } from '../../../../types/streams.ts';
|
|
5
8
|
import type { Message } from './pgoutput.types.ts';
|
|
9
|
+
export declare const DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE = 5;
|
|
6
10
|
export type StreamMessage = [
|
|
7
11
|
lsn: bigint,
|
|
8
12
|
Message | {
|
|
@@ -18,6 +22,37 @@ export declare function subscribe(lc: LogContext, db: PostgresDB, slot: string,
|
|
|
18
22
|
messages: SourceWithPendingQueue<StreamMessage>;
|
|
19
23
|
acks: Sink<bigint>;
|
|
20
24
|
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Measures how long upstream takes to decode the WAL between the slot's
|
|
27
|
+
* `restart_lsn` and the start of the stream, during which the stream
|
|
28
|
+
* delivers nothing but keepalives. This span can be large, e.g. for a slot
|
|
29
|
+
* that was created (or last acked) long before the requested start LSN.
|
|
30
|
+
*
|
|
31
|
+
* The walsender streams from `max(lsn, confirmed_flush_lsn)`, but must
|
|
32
|
+
* decode from `restart_lsn` to rebuild its transaction state. The decode is
|
|
33
|
+
* considered complete upon the first message at or past the start:
|
|
34
|
+
* * any XLogData message, since only transactions committed after the
|
|
35
|
+
* start are sent, or
|
|
36
|
+
* * a keepalive at or past the start. Keepalives report the decoding
|
|
37
|
+
* position, except for the first one of the stream, which reports the
|
|
38
|
+
* slot's `confirmed_flush_lsn` and is thus ignored if it is at or past the
|
|
39
|
+
* start.
|
|
40
|
+
*
|
|
41
|
+
* Note that on an idle upstream, a walsender whose start is already
|
|
42
|
+
* confirmed may not send a keepalive until other WAL is written or the
|
|
43
|
+
* periodic keepalive (`wal_sender_timeout / 2`) is due, so the measured
|
|
44
|
+
* time is an upper bound when completed by a keepalive.
|
|
45
|
+
*/
|
|
46
|
+
export declare class InitialDecodeTracker {
|
|
47
|
+
#private;
|
|
48
|
+
static start(lc: LogContext, session: postgres.Sql, slot: string, lsn: bigint): Promise<InitialDecodeTracker>;
|
|
49
|
+
constructor(lc: LogContext, lsn: bigint, restartLSN: bigint | undefined, confirmedFlushLSN: bigint | undefined, startTime: number);
|
|
50
|
+
/**
|
|
51
|
+
* Observes a received message, returning the elapsed decode time (ms) if
|
|
52
|
+
* this message completed the initial decode.
|
|
53
|
+
*/
|
|
54
|
+
observe([lsn, msg]: StreamMessage, now: number): number | undefined;
|
|
55
|
+
}
|
|
21
56
|
/**
|
|
22
57
|
* Derives the timings for the replication liveness timer from the server's
|
|
23
58
|
* `wal_sender_timeout` (in milliseconds).
|
|
@@ -82,6 +117,7 @@ export declare function evaluateInboundLiveness({ sinceLastReceived, inboundTime
|
|
|
82
117
|
resetWindow: boolean;
|
|
83
118
|
timedOut: boolean;
|
|
84
119
|
};
|
|
120
|
+
export declare function startReplicationStream(lc: LogContext, session: postgres.Sql, slot: string, publications: string[], lsn: bigint, maxAttempts?: number): Promise<[Readable, import("stream").Writable]>;
|
|
85
121
|
/**
|
|
86
122
|
* Starts a "dummy" replication session for the specified `slot` which:
|
|
87
123
|
* * does not consume any records
|
|
@@ -99,6 +135,35 @@ export declare function evaluateInboundLiveness({ sinceLastReceived, inboundTime
|
|
|
99
135
|
* Note that caller should not close the supplied `session`, as that will
|
|
100
136
|
* also terminate the dummy replication session.
|
|
101
137
|
*/
|
|
102
|
-
export declare
|
|
138
|
+
export declare class SlotReservationHandle extends Readable {
|
|
139
|
+
#private;
|
|
140
|
+
constructor(worker: Worker);
|
|
141
|
+
_destroy(error: Error | null, callback: (error?: Error | null) => void): void;
|
|
142
|
+
end(timeoutMs?: number): Promise<void>;
|
|
143
|
+
}
|
|
144
|
+
export declare function endSession(session?: Readable): Promise<void>;
|
|
145
|
+
export type PgConnectionConfig = {
|
|
146
|
+
host?: string | string[] | undefined;
|
|
147
|
+
port?: number | number[] | undefined;
|
|
148
|
+
path?: string | undefined;
|
|
149
|
+
database?: string | undefined;
|
|
150
|
+
user?: string | undefined;
|
|
151
|
+
pass?: string | null | undefined;
|
|
152
|
+
ssl?: boolean | string | {
|
|
153
|
+
rejectUnauthorized?: boolean | undefined;
|
|
154
|
+
} | undefined;
|
|
155
|
+
};
|
|
156
|
+
export declare function extractConnectionConfig(session: postgres.Sql): PgConnectionConfig;
|
|
157
|
+
/**
|
|
158
|
+
* Starts a "dummy" replication session for the specified `slot` which:
|
|
159
|
+
* * does not consume any records
|
|
160
|
+
* * keeps the session alive by sending status messages at the starting LSN
|
|
161
|
+
*
|
|
162
|
+
* Runs in a separate process with its own event loop and connection reconnect
|
|
163
|
+
* loop to prevent slot drop races during heavy initial sync table copy or
|
|
164
|
+
* SQLite index building.
|
|
165
|
+
*/
|
|
166
|
+
export declare function keepSlotActiveUntilTakenOver(lc: LogContext, config: SlotKeeperConfig): Promise<Readable>;
|
|
167
|
+
export declare function makeAck(lsn: bigint): Buffer;
|
|
103
168
|
export {};
|
|
104
169
|
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/stream.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAC;AAMrC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,QAA2C,MAAM,UAAU,CAAC;AAInE,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,mCAAmC,CAAC;AAExE,OAAO,EAAC,KAAK,UAAU,EAAC,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAc,KAAK,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAExE,OAAO,EAAO,KAAK,IAAI,EAAE,KAAK,MAAM,EAAC,MAAM,8BAA8B,CAAC;AAK1E,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,qBAAqB,CAAC;AAEjD,eAAO,MAAM,0CAA0C,IAAI,CAAC;AAE5D,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM;IACX,OAAO,GAAG;QAAC,GAAG,EAAE,WAAW,CAAC;QAAC,aAAa,EAAE,OAAO,CAAA;KAAC;CACrD,CAAC;AAKF,KAAK,sBAAsB,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG;IAC3C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAgB,2BAA2B,CACzC,EAAE,EAAE,UAAU,EACd,eAAe,EAAE,MAAM,oBAqBxB;AAED,wBAAsB,SAAS,CAC7B,EAAE,EAAE,UAAU,EACd,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,EACtB,GAAG,EAAE,MAAM,EACX,8BAA8B,SAA6C,EAC3E,eAAe,SAAoB,EACnC,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,GAC5C,OAAO,CAAC;IACT,QAAQ,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IAChD,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;CACpB,CAAC,CA4ID;AAgBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,oBAAoB;;IAC/B,OAAa,KAAK,CAChB,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,QAAQ,CAAC,GAAG,EACrB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,oBAAoB,CAAC,CA4B/B;IAUD,YACE,EAAE,EAAE,UAAU,EACd,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,iBAAiB,EAAE,MAAM,GAAG,SAAS,EACrC,SAAS,EAAE,MAAM,EAmBlB;IAED;;;OAGG;IACH,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA0BlE;CACF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,sBAAsB,CACpC,kBAAkB,EAAE,MAAM,EAC1B,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,GAC5C;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;CACzB,CA6BA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,iBAAiB,EACjB,gBAAgB,EAChB,MAAM,GACP,EAAE;IACD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG;IAAC,WAAW,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAC,CAK5C;AAaD,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,QAAQ,CAAC,GAAG,EACrB,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EAAE,EACtB,GAAG,EAAE,MAAM,EACX,WAAW,GAAE,MAAuD,kDAyCrE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,qBAAsB,SAAQ,QAAQ;;IAMjD,YAAY,MAAM,EAAE,MAAM,EAqBzB;IAEQ,QAAQ,CACf,KAAK,EAAE,KAAK,GAAG,IAAI,EACnB,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GACvC,IAAI,CAgBN;IAEK,GAAG,CAAC,SAAS,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAc1C;CACF;AAED,wBAAsB,UAAU,CAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CASlE;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC;IACrC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC,GAAG,CAAC,EACA,OAAO,GACP,MAAM,GACN;QAAC,kBAAkB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAC,GAC1C,SAAS,CAAC;CACf,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,QAAQ,CAAC,GAAG,GACpB,kBAAkB,CAkBpB;AAED;;;;;;;;GAQG;AACH,wBAAsB,4BAA4B,CAChD,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,QAAQ,CAAC,CAqCnB;AAyBD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAU3C"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { sleep } from "../../../../../../shared/src/sleep.js";
|
|
2
|
+
import { childWorker } from "../../../../types/processes.js";
|
|
3
|
+
import { getOrCreateHistogram } from "../../../../observability/metrics.js";
|
|
2
4
|
import { id, lit } from "../../../../types/sql.js";
|
|
3
5
|
import "../../../../types/pg.js";
|
|
4
|
-
import {
|
|
6
|
+
import { SLOT_KEEPER_URL } from "../../../../server/worker-urls.js";
|
|
7
|
+
import { fromBigInt, toBigInt } from "../lsn.js";
|
|
5
8
|
import { Subscription } from "../../../../types/subscription.js";
|
|
6
9
|
import { pipe } from "../../../../types/streams.js";
|
|
7
10
|
import { AutoResetSignal } from "../../../change-streamer/schema/tables.js";
|
|
@@ -10,8 +13,7 @@ import { PgoutputParser } from "./pgoutput-parser.js";
|
|
|
10
13
|
import { defu } from "defu";
|
|
11
14
|
import postgres from "postgres";
|
|
12
15
|
import { PG_ADMIN_SHUTDOWN, PG_OBJECT_IN_USE, PG_OBJECT_NOT_IN_PREREQUISITE_STATE } from "@drdgvhbh/postgres-error-codes";
|
|
13
|
-
|
|
14
|
-
var DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE = 5;
|
|
16
|
+
import { Readable } from "node:stream";
|
|
15
17
|
function createReplicationSessionFor(db, applicationName) {
|
|
16
18
|
return postgres(defu({
|
|
17
19
|
max: 1,
|
|
@@ -24,13 +26,14 @@ function createReplicationSessionFor(db, applicationName) {
|
|
|
24
26
|
}
|
|
25
27
|
}, db.options));
|
|
26
28
|
}
|
|
27
|
-
async function subscribe(lc, db, slot, publications, lsn, retriesIfReplicationSlotActive =
|
|
29
|
+
async function subscribe(lc, db, slot, publications, lsn, retriesIfReplicationSlotActive = 5, applicationName = "zero-replicator", inboundTimeoutOverrideMs) {
|
|
28
30
|
const session = createReplicationSessionFor(db, applicationName);
|
|
29
31
|
const [{ walSenderTimeoutMs }] = await session`SELECT EXTRACT(EPOCH FROM (setting || unit)::interval) * 1000
|
|
30
32
|
AS "walSenderTimeoutMs" FROM pg_settings
|
|
31
33
|
WHERE name = 'wal_sender_timeout'`.simple();
|
|
32
34
|
const { enabled: livenessEnabled, manualKeepaliveTimeout, inboundTimeoutMs, timerIntervalMs } = computeLivenessTimings(walSenderTimeoutMs, inboundTimeoutOverrideMs);
|
|
33
35
|
lc.info?.(livenessEnabled ? `wal_sender_timeout: ${walSenderTimeoutMs}ms. Ensuring manual keepalives at least every ${manualKeepaliveTimeout}ms. Inbound timeout: ${inboundTimeoutMs}ms` + (inboundTimeoutMs === walSenderTimeoutMs * 2 ? "" : " (configured override)") : "wal_sender_timeout is disabled (0); skipping manual keepalives and inbound liveness detection.");
|
|
36
|
+
const decode = await InitialDecodeTracker.start(lc, session, slot, lsn);
|
|
34
37
|
const [readable, writable] = await startReplicationStream(lc, session, slot, publications, lsn, retriesIfReplicationSlotActive + 1);
|
|
35
38
|
let lastAckTime = Date.now();
|
|
36
39
|
function sendAck(lsn) {
|
|
@@ -71,7 +74,9 @@ async function subscribe(lc, db, slot, publications, lsn, retriesIfReplicationSl
|
|
|
71
74
|
sink: messages,
|
|
72
75
|
parse: (buffer) => {
|
|
73
76
|
lastReceivedTime = Date.now();
|
|
74
|
-
|
|
77
|
+
const msg = parseStreamMessage(lc, buffer, parser);
|
|
78
|
+
if (msg) decode.observe(msg, lastReceivedTime);
|
|
79
|
+
return msg;
|
|
75
80
|
},
|
|
76
81
|
bufferMessages: 5
|
|
77
82
|
});
|
|
@@ -80,6 +85,100 @@ async function subscribe(lc, db, slot, publications, lsn, retriesIfReplicationSl
|
|
|
80
85
|
acks: { push: sendAck }
|
|
81
86
|
};
|
|
82
87
|
}
|
|
88
|
+
var INITIAL_DECODE_HISTOGRAM_BOUNDARIES_S = [
|
|
89
|
+
.1,
|
|
90
|
+
.5,
|
|
91
|
+
1,
|
|
92
|
+
2,
|
|
93
|
+
5,
|
|
94
|
+
10,
|
|
95
|
+
30,
|
|
96
|
+
60,
|
|
97
|
+
120,
|
|
98
|
+
300,
|
|
99
|
+
600,
|
|
100
|
+
1200,
|
|
101
|
+
2400,
|
|
102
|
+
3600,
|
|
103
|
+
7200
|
|
104
|
+
];
|
|
105
|
+
function initialDecodeHistogram() {
|
|
106
|
+
return getOrCreateHistogram("replication", "stream_initial_decode", {
|
|
107
|
+
description: "Time from START_REPLICATION until upstream has decoded the WAL between the slot's restart_lsn and the start of the stream",
|
|
108
|
+
unit: "s",
|
|
109
|
+
bucketBoundaries: INITIAL_DECODE_HISTOGRAM_BOUNDARIES_S
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Measures how long upstream takes to decode the WAL between the slot's
|
|
114
|
+
* `restart_lsn` and the start of the stream, during which the stream
|
|
115
|
+
* delivers nothing but keepalives. This span can be large, e.g. for a slot
|
|
116
|
+
* that was created (or last acked) long before the requested start LSN.
|
|
117
|
+
*
|
|
118
|
+
* The walsender streams from `max(lsn, confirmed_flush_lsn)`, but must
|
|
119
|
+
* decode from `restart_lsn` to rebuild its transaction state. The decode is
|
|
120
|
+
* considered complete upon the first message at or past the start:
|
|
121
|
+
* * any XLogData message, since only transactions committed after the
|
|
122
|
+
* start are sent, or
|
|
123
|
+
* * a keepalive at or past the start. Keepalives report the decoding
|
|
124
|
+
* position, except for the first one of the stream, which reports the
|
|
125
|
+
* slot's `confirmed_flush_lsn` and is thus ignored if it is at or past the
|
|
126
|
+
* start.
|
|
127
|
+
*
|
|
128
|
+
* Note that on an idle upstream, a walsender whose start is already
|
|
129
|
+
* confirmed may not send a keepalive until other WAL is written or the
|
|
130
|
+
* periodic keepalive (`wal_sender_timeout / 2`) is due, so the measured
|
|
131
|
+
* time is an upper bound when completed by a keepalive.
|
|
132
|
+
*/
|
|
133
|
+
var InitialDecodeTracker = class InitialDecodeTracker {
|
|
134
|
+
static async start(lc, session, slot, lsn) {
|
|
135
|
+
let restartLSN;
|
|
136
|
+
let confirmedFlushLSN;
|
|
137
|
+
try {
|
|
138
|
+
const [row] = await session.unsafe(`SELECT restart_lsn AS "restartLSN",
|
|
139
|
+
confirmed_flush_lsn AS "confirmedFlushLSN"
|
|
140
|
+
FROM pg_replication_slots
|
|
141
|
+
WHERE slot_name = ${lit(slot)}`).simple();
|
|
142
|
+
restartLSN = row?.restartLSN ? toBigInt(row.restartLSN) : void 0;
|
|
143
|
+
confirmedFlushLSN = row?.confirmedFlushLSN ? toBigInt(row.confirmedFlushLSN) : void 0;
|
|
144
|
+
} catch (e) {
|
|
145
|
+
lc.warn?.(`unable to read position of replication slot ${slot}`, e);
|
|
146
|
+
}
|
|
147
|
+
return new InitialDecodeTracker(lc, lsn, restartLSN, confirmedFlushLSN, Date.now());
|
|
148
|
+
}
|
|
149
|
+
#lc;
|
|
150
|
+
#start;
|
|
151
|
+
#restartLSN;
|
|
152
|
+
#confirmedFlushLSN;
|
|
153
|
+
#startTime;
|
|
154
|
+
#first = true;
|
|
155
|
+
#done = false;
|
|
156
|
+
constructor(lc, lsn, restartLSN, confirmedFlushLSN, startTime) {
|
|
157
|
+
this.#start = confirmedFlushLSN !== void 0 && confirmedFlushLSN > lsn ? confirmedFlushLSN : lsn;
|
|
158
|
+
this.#lc = lc.withContext("decodeStart", fromBigInt(this.#start));
|
|
159
|
+
this.#restartLSN = restartLSN;
|
|
160
|
+
this.#confirmedFlushLSN = confirmedFlushLSN;
|
|
161
|
+
this.#startTime = startTime;
|
|
162
|
+
if (restartLSN !== void 0) this.#lc.info?.(`decoding ${this.#start - restartLSN} bytes of WAL from restart_lsn ${fromBigInt(restartLSN)} to the start of the stream`);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Observes a received message, returning the elapsed decode time (ms) if
|
|
166
|
+
* this message completed the initial decode.
|
|
167
|
+
*/
|
|
168
|
+
observe([lsn, msg], now) {
|
|
169
|
+
if (this.#done) return;
|
|
170
|
+
const first = this.#first;
|
|
171
|
+
this.#first = false;
|
|
172
|
+
if (msg.tag === "keepalive") {
|
|
173
|
+
if (lsn < this.#start || first && lsn === this.#confirmedFlushLSN) return;
|
|
174
|
+
}
|
|
175
|
+
this.#done = true;
|
|
176
|
+
const elapsed = now - this.#startTime;
|
|
177
|
+
initialDecodeHistogram().recordMs(elapsed);
|
|
178
|
+
this.#lc.info?.(`upstream decoded the WAL to the start of the stream in ${elapsed} ms (${msg.tag} at ${fromBigInt(lsn)}` + (this.#restartLSN === void 0 ? ")" : `, ${this.#start - this.#restartLSN} bytes from restart_lsn)`), { elapsed });
|
|
179
|
+
return elapsed;
|
|
180
|
+
}
|
|
181
|
+
};
|
|
83
182
|
/**
|
|
84
183
|
* Derives the timings for the replication liveness timer from the server's
|
|
85
184
|
* `wal_sender_timeout` (in milliseconds).
|
|
@@ -163,7 +262,7 @@ function evaluateInboundLiveness({ sinceLastReceived, inboundTimeoutMs, queued }
|
|
|
163
262
|
function formatPublicationNames(publications) {
|
|
164
263
|
return publications.map((p) => lit(p).slice(1, -1)).join(",");
|
|
165
264
|
}
|
|
166
|
-
async function startReplicationStream(lc, session, slot, publications, lsn, maxAttempts) {
|
|
265
|
+
async function startReplicationStream(lc, session, slot, publications, lsn, maxAttempts = 6) {
|
|
167
266
|
for (let i = 0; i < maxAttempts; i++) try {
|
|
168
267
|
const stream = session.unsafe(`START_REPLICATION SLOT ${id(slot)} LOGICAL ${fromBigInt(lsn)} (
|
|
169
268
|
proto_version '1',
|
|
@@ -175,7 +274,7 @@ async function startReplicationStream(lc, session, slot, publications, lsn, maxA
|
|
|
175
274
|
if (e instanceof postgres.PostgresError) {
|
|
176
275
|
if (e.code === PG_OBJECT_IN_USE) {
|
|
177
276
|
lc.warn?.(`attempt ${i + 1}: ${String(e)}`, e);
|
|
178
|
-
await sleep(10);
|
|
277
|
+
await sleep(Math.min(10 * 2 ** i, 1e3));
|
|
179
278
|
continue;
|
|
180
279
|
}
|
|
181
280
|
if (e.code === PG_OBJECT_NOT_IN_PREREQUISITE_STATE) {
|
|
@@ -204,25 +303,109 @@ async function startReplicationStream(lc, session, slot, publications, lsn, maxA
|
|
|
204
303
|
* Note that caller should not close the supplied `session`, as that will
|
|
205
304
|
* also terminate the dummy replication session.
|
|
206
305
|
*/
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
306
|
+
var SlotReservationHandle = class extends Readable {
|
|
307
|
+
#worker;
|
|
308
|
+
#closedPromise;
|
|
309
|
+
#stopped = false;
|
|
310
|
+
#sigtermTimer;
|
|
311
|
+
constructor(worker) {
|
|
312
|
+
super({ read() {} });
|
|
313
|
+
this.#worker = worker;
|
|
314
|
+
this.#closedPromise = new Promise((resolve) => {
|
|
315
|
+
worker.once("close", () => {
|
|
316
|
+
clearTimeout(this.#sigtermTimer);
|
|
317
|
+
resolve();
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
this.on("error", () => {});
|
|
321
|
+
worker.on("close", () => {
|
|
322
|
+
if (!this.destroyed) this.destroy();
|
|
323
|
+
});
|
|
324
|
+
worker.on("error", (err) => {
|
|
325
|
+
if (!this.destroyed) this.destroy(err instanceof Error ? err : new Error(String(err)));
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
_destroy(error, callback) {
|
|
329
|
+
if (!this.#stopped) {
|
|
330
|
+
this.#stopped = true;
|
|
331
|
+
try {
|
|
332
|
+
this.#worker.send(["stop", {}]);
|
|
333
|
+
} catch {}
|
|
334
|
+
this.#sigtermTimer = setTimeout(() => {
|
|
335
|
+
try {
|
|
336
|
+
this.#worker.kill("SIGTERM");
|
|
337
|
+
} catch {}
|
|
338
|
+
}, 5e3);
|
|
339
|
+
this.#sigtermTimer.unref();
|
|
340
|
+
}
|
|
341
|
+
callback(error);
|
|
342
|
+
}
|
|
343
|
+
async end(timeoutMs = 5e3) {
|
|
344
|
+
this.destroy();
|
|
345
|
+
if (!await Promise.race([this.#closedPromise.then(() => true), sleep(timeoutMs).then(() => false)])) {
|
|
346
|
+
try {
|
|
347
|
+
this.#worker.kill("SIGKILL");
|
|
348
|
+
} catch {}
|
|
349
|
+
await Promise.race([this.#closedPromise, sleep(2e3)]);
|
|
219
350
|
}
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
async function endSession(session) {
|
|
354
|
+
if (!session) return;
|
|
355
|
+
if ("end" in session && typeof session.end === "function") await session.end();
|
|
356
|
+
else session.destroy();
|
|
357
|
+
}
|
|
358
|
+
function extractConnectionConfig(session) {
|
|
359
|
+
const opts = session.options;
|
|
360
|
+
return {
|
|
361
|
+
host: opts.host,
|
|
362
|
+
port: opts.port,
|
|
363
|
+
path: opts.path,
|
|
364
|
+
database: opts.database,
|
|
365
|
+
user: opts.user,
|
|
366
|
+
pass: opts.pass,
|
|
367
|
+
ssl: typeof opts.ssl === "object" && opts.ssl !== null ? { rejectUnauthorized: opts.ssl.rejectUnauthorized } : opts.ssl
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Starts a "dummy" replication session for the specified `slot` which:
|
|
372
|
+
* * does not consume any records
|
|
373
|
+
* * keeps the session alive by sending status messages at the starting LSN
|
|
374
|
+
*
|
|
375
|
+
* Runs in a separate process with its own event loop and connection reconnect
|
|
376
|
+
* loop to prevent slot drop races during heavy initial sync table copy or
|
|
377
|
+
* SQLite index building.
|
|
378
|
+
*/
|
|
379
|
+
async function keepSlotActiveUntilTakenOver(lc, config) {
|
|
380
|
+
const { slot, lsn } = config;
|
|
381
|
+
lc.info?.(`spawning slot-keeper process for ${slot} at lsn ${lsn} ...`);
|
|
382
|
+
const worker = childWorker(SLOT_KEEPER_URL, process.env);
|
|
383
|
+
worker.onMessageType("init", () => {
|
|
384
|
+
worker.send(["start", config]);
|
|
220
385
|
});
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
386
|
+
await new Promise((resolve, reject) => {
|
|
387
|
+
const onReady = () => {
|
|
388
|
+
cleanup();
|
|
389
|
+
resolve();
|
|
390
|
+
};
|
|
391
|
+
const onError = (err) => {
|
|
392
|
+
cleanup();
|
|
393
|
+
reject(err);
|
|
394
|
+
};
|
|
395
|
+
const onClose = (code) => {
|
|
396
|
+
cleanup();
|
|
397
|
+
reject(/* @__PURE__ */ new Error(`slot-keeper for ${slot} exited with code ${code} before becoming ready`));
|
|
398
|
+
};
|
|
399
|
+
function cleanup() {
|
|
400
|
+
worker.off("error", onError);
|
|
401
|
+
worker.off("close", onClose);
|
|
402
|
+
}
|
|
403
|
+
worker.onceMessageType("ready", onReady);
|
|
404
|
+
worker.once("error", onError);
|
|
405
|
+
worker.once("close", onClose);
|
|
224
406
|
});
|
|
225
|
-
|
|
407
|
+
lc.info?.(`slot-keeper active for ${slot}`);
|
|
408
|
+
return new SlotReservationHandle(worker);
|
|
226
409
|
}
|
|
227
410
|
function parseStreamMessage(lc, buffer, parser) {
|
|
228
411
|
if (buffer[0] !== 119 && buffer[0] !== 107) {
|
|
@@ -247,6 +430,6 @@ function makeAck(lsn) {
|
|
|
247
430
|
return x;
|
|
248
431
|
}
|
|
249
432
|
//#endregion
|
|
250
|
-
export { createReplicationSessionFor, keepSlotActiveUntilTakenOver, subscribe };
|
|
433
|
+
export { createReplicationSessionFor, endSession, extractConnectionConfig, keepSlotActiveUntilTakenOver, makeAck, startReplicationStream, subscribe };
|
|
251
434
|
|
|
252
435
|
//# sourceMappingURL=stream.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","names":[],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/stream.ts"],"sourcesContent":["import {\n PG_ADMIN_SHUTDOWN,\n PG_OBJECT_IN_USE,\n PG_OBJECT_NOT_IN_PREREQUISITE_STATE,\n} from '@drdgvhbh/postgres-error-codes';\nimport type {LogContext} from '@rocicorp/logger';\nimport {defu} from 'defu';\nimport postgres, {type Options, type PostgresType} from 'postgres';\nimport {sleep} from '../../../../../../shared/src/sleep.ts';\nimport {getTypeParsers} from '../../../../db/pg-type-parser.ts';\nimport {type PostgresDB} from '../../../../types/pg.ts';\nimport {id, lit} from '../../../../types/sql.ts';\nimport {pipe, type Sink, type Source} from '../../../../types/streams.ts';\nimport {Subscription} from '../../../../types/subscription.ts';\nimport {AutoResetSignal} from '../../../change-streamer/schema/tables.ts';\nimport {fromBigInt} from '../lsn.ts';\nimport {PgoutputParser} from './pgoutput-parser.ts';\nimport type {Message} from './pgoutput.types.ts';\n\nconst DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE = 5;\n\nexport type StreamMessage = [\n lsn: bigint,\n Message | {tag: 'keepalive'; shouldRespond: boolean},\n];\n\n// Expose the `queued` variable of the Subscription to allow\n// the change-source to determine if there are more messages\n// immediately available.\ntype SourceWithPendingQueue<T> = Source<T> & {\n queued: number;\n};\n\nexport function createReplicationSessionFor(\n db: PostgresDB,\n applicationName: string,\n) {\n return postgres(\n defu(\n {\n max: 1,\n ['fetch_types']: false, // Necessary for the streaming protocol\n ['idle_timeout']: null,\n ['max_lifetime']: null as unknown as number,\n connection: {\n ['application_name']: applicationName,\n replication: 'database', // https://www.postgresql.org/docs/current/protocol-replication.html\n },\n },\n // ParsedOptions are technically compatible with Options, but happen\n // to not be typed that way. The postgres.js author does an equivalent\n // merge of ParsedOptions and Options here:\n // https://github.com/porsager/postgres/blob/089214e85c23c90cf142d47fb30bd03f42874984/src/subscribe.js#L13\n db.options as unknown as Options<Record<string, PostgresType>>,\n ),\n );\n}\n\nexport async function subscribe(\n lc: LogContext,\n db: PostgresDB,\n slot: string,\n publications: string[],\n lsn: bigint,\n retriesIfReplicationSlotActive = DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE,\n applicationName = 'zero-replicator',\n inboundTimeoutOverrideMs?: number | undefined,\n): Promise<{\n messages: SourceWithPendingQueue<StreamMessage>;\n acks: Sink<bigint>;\n}> {\n const session = createReplicationSessionFor(db, applicationName);\n\n // Postgres will send keepalives before timing out a wal_sender. It is possible that\n // these keepalives are not received if there is back-pressure in the replication\n // stream. To keep the connection alive, explicitly send keepalives if none have been\n // sent within the last 75% of the wal_sender_timeout.\n //\n // https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-SENDER-TIMEOUT\n const [{walSenderTimeoutMs}] = await session<\n {walSenderTimeoutMs: number}[]\n >`SELECT EXTRACT(EPOCH FROM (setting || unit)::interval) * 1000 \n AS \"walSenderTimeoutMs\" FROM pg_settings\n WHERE name = 'wal_sender_timeout'`.simple();\n const {\n enabled: livenessEnabled,\n manualKeepaliveTimeout,\n inboundTimeoutMs,\n timerIntervalMs,\n } = computeLivenessTimings(walSenderTimeoutMs, inboundTimeoutOverrideMs);\n lc.info?.(\n livenessEnabled\n ? `wal_sender_timeout: ${walSenderTimeoutMs}ms. ` +\n `Ensuring manual keepalives at least every ${manualKeepaliveTimeout}ms. ` +\n `Inbound timeout: ${inboundTimeoutMs}ms` +\n (inboundTimeoutMs === walSenderTimeoutMs * 2\n ? ''\n : ' (configured override)')\n : `wal_sender_timeout is disabled (0); skipping manual keepalives and ` +\n `inbound liveness detection.`,\n );\n\n const [readable, writable] = await startReplicationStream(\n lc,\n session,\n slot,\n publications,\n lsn,\n retriesIfReplicationSlotActive + 1,\n );\n\n let lastAckTime = Date.now();\n function sendAck(lsn: bigint) {\n writable.write(makeAck(lsn));\n lastAckTime = Date.now();\n }\n\n // Tear down the readable to force a reconnect if the inbound half of the\n // connection goes silent (our outbound acks keep flowing into the void,\n // neither side errors, and the change-source would otherwise sit there\n // forever). See computeLivenessTimings for the derivation of these\n // thresholds — and why the whole timer is disabled when wal_sender_timeout\n // is 0.\n let lastReceivedTime = Date.now();\n\n const livenessTimer = livenessEnabled\n ? setInterval(() => {\n const now = Date.now();\n if (now - lastAckTime > manualKeepaliveTimeout) {\n sendAck(0n);\n lc.debug?.(`sent manual keepalive`);\n }\n const sinceLastReceived = now - lastReceivedTime;\n const {resetWindow, timedOut} = evaluateInboundLiveness({\n sinceLastReceived,\n inboundTimeoutMs,\n queued: messages.queued,\n });\n if (resetWindow) {\n // Downstream back-pressure is preventing us from consuming (and thus\n // receiving) upstream messages. Keep the inbound window fresh so that\n // when the backlog finally drains we grant a full inboundTimeoutMs\n // before concluding the connection is dead — otherwise a long stall\n // would leave lastReceivedTime stale and fire this watchdog on the\n // first post-drain tick, tearing down a healthy connection.\n lastReceivedTime = now;\n } else if (timedOut && !readable.destroyed) {\n lc.warn?.(\n `no message received from ${db.options.host} in ${sinceLastReceived}ms ` +\n `(> inbound timeout ${inboundTimeoutMs}ms). Destroying ` +\n `replication stream to force reconnect.`,\n );\n readable.destroy(\n new Error(\n `replication stream inbound timeout after ${sinceLastReceived}ms`,\n ),\n );\n }\n }, timerIntervalMs)\n : undefined;\n\n let destroyed = false;\n const typeParsers = await getTypeParsers(db, {returnJsonAsString: true});\n const parser = new PgoutputParser(typeParsers);\n const messages = Subscription.create<StreamMessage>({\n cleanup: () => {\n destroyed = true;\n readable.destroyed || readable.destroy();\n clearInterval(livenessTimer);\n return session.end();\n },\n });\n\n readable.once(\n 'close',\n () =>\n // Only log a warning if the stream was not manually closed.\n destroyed || lc.warn?.(`replication stream closed by ${db.options.host}`),\n );\n readable.once(\n 'error',\n e =>\n // Don't log the shutdown signal. This is the expected way for upstream\n // to close the connection (and will be logged downstream).\n (e instanceof postgres.PostgresError && e.code === PG_ADMIN_SHUTDOWN) ||\n lc.warn?.(`error from ${db.options.host}`, e),\n );\n\n pipe({\n source: readable,\n sink: messages,\n parse: buffer => {\n lastReceivedTime = Date.now();\n return parseStreamMessage(lc, buffer, parser);\n },\n // Allow a small buffer of messages to be queued in the subscription so\n // that the change-source loop can check the queue to determine if more\n // messages are immediately available.\n bufferMessages: 5,\n });\n\n return {\n messages,\n acks: {push: sendAck},\n };\n}\n\n/**\n * Derives the timings for the replication liveness timer from the server's\n * `wal_sender_timeout` (in milliseconds).\n *\n * Postgres treats `wal_sender_timeout = 0` as \"disabled\": it will neither\n * terminate an idle wal sender nor emit the periodic keepalives it otherwise\n * sends at roughly `wal_sender_timeout / 2`. Every timing below is derived from\n * that interval, so a disabled timeout disables the liveness machinery entirely\n * (`enabled: false`). Otherwise the derived thresholds would all collapse to 0,\n * inverting the intended meaning: the inbound watchdog would fire on the very\n * first tick and destroy the stream, while the timer itself would busy-spin at\n * a 0ms interval — together producing a continuous reconnect storm.\n *\n * An `inboundTimeoutOverrideMs` (when positive) replaces the default\n * `2x wal_sender_timeout` inbound threshold. The two timeouts protect\n * different parties with asymmetric false-positive costs: `wal_sender_timeout`\n * is the server reaping dead clients (a false positive there costs a cheap\n * reconnect), while the inbound watchdog tears down the stream and replays the\n * in-flight transaction — expensive, and self-defeating when the wal sender is\n * legitimately silent for long stretches (e.g. decoding through WAL from\n * unpublished tables, or assembling a large transaction that pgoutput only\n * sends at commit). Operators who don't own the server setting (e.g. managed\n * or operator-provisioned Postgres with an aggressive cluster-wide\n * `wal_sender_timeout`) can widen the client-side fuse independently.\n *\n * The override has no effect when `wal_sender_timeout` is disabled (0): the\n * server then sends no periodic keepalives, so inbound silence is normal even\n * on an idle healthy connection and any silence-based watchdog would\n * false-positive.\n *\n * https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-SENDER-TIMEOUT\n */\nexport function computeLivenessTimings(\n walSenderTimeoutMs: number,\n inboundTimeoutOverrideMs?: number | undefined,\n): {\n enabled: boolean;\n manualKeepaliveTimeout: number;\n inboundTimeoutMs: number;\n timerIntervalMs: number;\n} {\n // Guard with `!(x > 0)` so that 0, negative, and NaN values all disable the\n // timer rather than producing degenerate (zero / NaN) thresholds.\n if (!(walSenderTimeoutMs > 0)) {\n return {\n enabled: false,\n manualKeepaliveTimeout: 0,\n inboundTimeoutMs: 0,\n timerIntervalMs: 0,\n };\n }\n // Send a manual keepalive if nothing has been sent in the last 75% of the\n // wal_sender_timeout, so Postgres never times us out under back-pressure.\n const manualKeepaliveTimeout = Math.floor(walSenderTimeoutMs * 0.75);\n return {\n enabled: true,\n manualKeepaliveTimeout,\n // Force a reconnect after 2x wal_sender_timeout — i.e. two consecutive\n // missed keepalives — without any inbound message, to avoid spurious\n // reconnects from a single delayed keepalive (PG scheduling jitter under\n // load, our own event-loop stalls, etc.). A 0 / negative / NaN override\n // falls back to the default rather than degenerating the threshold.\n inboundTimeoutMs:\n inboundTimeoutOverrideMs !== undefined && inboundTimeoutOverrideMs > 0\n ? inboundTimeoutOverrideMs\n : walSenderTimeoutMs * 2,\n // Poll at 1/5th of the manual keepalive interval.\n timerIntervalMs: manualKeepaliveTimeout / 5,\n };\n}\n\n/**\n * Pure decision for the inbound-liveness watchdog, given the time since the\n * last inbound message, the timeout threshold, and the number of messages\n * currently queued downstream (see {@link SourceWithPendingQueue.queued}).\n *\n * A non-empty downstream queue means we have received data we haven't yet\n * consumed: the reason we aren't receiving *more* is our own back-pressure, not\n * upstream silence. In that case we `resetWindow` (treat the backlog as\n * liveness evidence) rather than counting the stall against the connection.\n * This both suppresses false timeouts during back-pressure and — crucially —\n * keeps `lastReceivedTime` fresh so the drain transition (queue emptying after\n * a long stall) doesn't fire the watchdog against a stale timestamp on the very\n * next tick.\n *\n * Only when the queue is empty (consumption has caught up, so reading — and\n * thus keepalives — should be flowing again) does an over-threshold gap\n * indicate a genuinely dead inbound half.\n */\nexport function evaluateInboundLiveness({\n sinceLastReceived,\n inboundTimeoutMs,\n queued,\n}: {\n sinceLastReceived: number;\n inboundTimeoutMs: number;\n queued: number;\n}): {resetWindow: boolean; timedOut: boolean} {\n if (queued > 0) {\n return {resetWindow: true, timedOut: false};\n }\n return {resetWindow: false, timedOut: sinceLastReceived > inboundTimeoutMs};\n}\n\n/**\n * Formats publication names for the START_REPLICATION command.\n * The replication protocol expects format: publication_names 'pub1,pub2'\n * Each name is escaped to handle any quotes that may have passed validation.\n */\nfunction formatPublicationNames(publications: string[]): string {\n // lit() returns 'escaped_name' with surrounding quotes\n // We strip the quotes since the outer quotes are in the template\n return publications.map(p => lit(p).slice(1, -1)).join(',');\n}\n\nasync function startReplicationStream(\n lc: LogContext,\n session: postgres.Sql,\n slot: string,\n publications: string[],\n lsn: bigint,\n maxAttempts: number,\n) {\n for (let i = 0; i < maxAttempts; i++) {\n try {\n const stream = session\n .unsafe(\n `START_REPLICATION SLOT ${id(slot)} LOGICAL ${fromBigInt(lsn)} (\n proto_version '1',\n publication_names '${formatPublicationNames(publications)}',\n messages 'true'\n )`,\n )\n .execute();\n return await Promise.all([stream.readable(), stream.writable()]);\n } catch (e) {\n if (e instanceof postgres.PostgresError) {\n // error: replication slot \"zero_slot_change_source_test_id\" is active for PID 268\n if (e.code === PG_OBJECT_IN_USE) {\n // The freeing up of the replication slot is not transactional;\n // sometimes it takes time for Postgres to consider the slot\n // inactive.\n lc.warn?.(`attempt ${i + 1}: ${String(e)}`, e);\n await sleep(10);\n continue;\n }\n // error: This slot has been invalidated because it exceeded the maximum reserved size.\n // (This is a different manifestation of a slot being invalidated when\n // the wal exceeds the max_slot_wal_keep_size)\n if (e.code === PG_OBJECT_NOT_IN_PREREQUISITE_STATE) {\n lc.error?.(`error starting replication stream`, e);\n throw new AutoResetSignal(`unable to start replication stream`, {\n cause: e,\n });\n }\n }\n throw e;\n }\n }\n throw new Error(\n `exceeded max attempts (${maxAttempts}) to start the Postgres stream`,\n );\n}\n\n/**\n * Starts a \"dummy\" replication session for the specified `slot` which:\n * * does not consume any records\n * * keeps the session alive by sending status messages at the starting LSN\n *\n * This essentially reserves the replication slot for this process by marking\n * it as \"active\" in pg_replication_slots, allowing replication slot cleanup\n * logic to distinguish a new-but-initializing replication slot from one that\n * has been abandoned / orphaned.\n *\n * When initialization (e.g. initial-sync) has finished, the server should take\n * over the replication slot using pg_terminate_backend, which will close the\n * session.\n *\n * Note that caller should not close the supplied `session`, as that will\n * also terminate the dummy replication session.\n */\nexport async function keepSlotActiveUntilTakenOver(\n lc: LogContext,\n session: postgres.Sql,\n slot: string,\n dummyPublication: string,\n lsn: bigint,\n) {\n const [readable, writeable] = await startReplicationStream(\n lc,\n session,\n slot,\n [dummyPublication],\n lsn,\n 1,\n );\n lc.info?.(`keeping ${slot} active until taken over ...`);\n // Send periodic status messages upstream to indicate that the session is\n // alive, but keep the confirmed_flush_lsn at the initial lsn.\n const keepalive = setInterval(() => writeable.write(makeAck(lsn)), 10_000);\n\n readable.on('close', async () => {\n lc.info?.(`released initial reservation of ${slot}`);\n clearInterval(keepalive);\n try {\n await session.end();\n lc.info?.(`ended session`);\n } catch (e) {\n lc.warn?.(`error ending session`, e);\n }\n });\n readable.once('error', e => {\n lc.info?.(`closing replication session to ${session.options.host}`, e);\n readable.destroy();\n });\n return readable;\n}\n\nfunction parseStreamMessage(\n lc: LogContext,\n buffer: Buffer,\n parser: PgoutputParser,\n): StreamMessage | null {\n // https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-START-REPLICATION\n if (buffer[0] !== 0x77 && buffer[0] !== 0x6b) {\n lc.warn?.('Unknown message', buffer[0]);\n return null;\n }\n const lsn = buffer.readBigUInt64BE(1);\n if (buffer[0] === 0x77) {\n // https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-XLOGDATA\n // (Byte 25 is where the WAL data begins)\n return [lsn, parser.parse(buffer.subarray(25))];\n }\n // https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-PRIMARY-KEEPALIVE-MESSAGE\n // (Byte 17: shouldRespond)\n const shouldRespond = buffer.readInt8(17) !== 0;\n return [lsn, {tag: 'keepalive', shouldRespond}];\n}\n\n// https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-STANDBY-STATUS-UPDATE\nfunction makeAck(lsn: bigint): Buffer {\n const microNow = BigInt(Date.now() - Date.UTC(2000, 0, 1)) * BigInt(1000);\n\n const x = Buffer.alloc(34);\n x[0] = 'r'.charCodeAt(0);\n x.writeBigInt64BE(lsn, 1);\n x.writeBigInt64BE(lsn, 9);\n x.writeBigInt64BE(lsn, 17);\n x.writeBigInt64BE(microNow, 25);\n return x;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stream.js","names":["#lc","#start","#restartLSN","#confirmedFlushLSN","#startTime","#done","#first","#worker","#closedPromise","#sigtermTimer","#stopped"],"sources":["../../../../../../../../zero-cache/src/services/change-source/pg/logical-replication/stream.ts"],"sourcesContent":["import {Readable} from 'node:stream';\nimport {\n PG_ADMIN_SHUTDOWN,\n PG_OBJECT_IN_USE,\n PG_OBJECT_NOT_IN_PREREQUISITE_STATE,\n} from '@drdgvhbh/postgres-error-codes';\nimport type {LogContext} from '@rocicorp/logger';\nimport {defu} from 'defu';\nimport postgres, {type Options, type PostgresType} from 'postgres';\nimport {sleep} from '../../../../../../shared/src/sleep.ts';\nimport {getTypeParsers} from '../../../../db/pg-type-parser.ts';\nimport {getOrCreateHistogram} from '../../../../observability/metrics.ts';\nimport type {SlotKeeperConfig} from '../../../../server/slot-keeper.ts';\nimport {SLOT_KEEPER_URL} from '../../../../server/worker-urls.ts';\nimport {type PostgresDB} from '../../../../types/pg.ts';\nimport {childWorker, type Worker} from '../../../../types/processes.ts';\nimport {id, lit} from '../../../../types/sql.ts';\nimport {pipe, type Sink, type Source} from '../../../../types/streams.ts';\nimport {Subscription} from '../../../../types/subscription.ts';\nimport {AutoResetSignal} from '../../../change-streamer/schema/tables.ts';\nimport {fromBigInt, toBigInt, type LSN} from '../lsn.ts';\nimport {PgoutputParser} from './pgoutput-parser.ts';\nimport type {Message} from './pgoutput.types.ts';\n\nexport const DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE = 5;\n\nexport type StreamMessage = [\n lsn: bigint,\n Message | {tag: 'keepalive'; shouldRespond: boolean},\n];\n\n// Expose the `queued` variable of the Subscription to allow\n// the change-source to determine if there are more messages\n// immediately available.\ntype SourceWithPendingQueue<T> = Source<T> & {\n queued: number;\n};\n\nexport function createReplicationSessionFor(\n db: PostgresDB,\n applicationName: string,\n) {\n return postgres(\n defu(\n {\n max: 1,\n ['fetch_types']: false, // Necessary for the streaming protocol\n ['idle_timeout']: null,\n ['max_lifetime']: null as unknown as number,\n connection: {\n ['application_name']: applicationName,\n replication: 'database', // https://www.postgresql.org/docs/current/protocol-replication.html\n },\n },\n // ParsedOptions are technically compatible with Options, but happen\n // to not be typed that way. The postgres.js author does an equivalent\n // merge of ParsedOptions and Options here:\n // https://github.com/porsager/postgres/blob/089214e85c23c90cf142d47fb30bd03f42874984/src/subscribe.js#L13\n db.options as unknown as Options<Record<string, PostgresType>>,\n ),\n );\n}\n\nexport async function subscribe(\n lc: LogContext,\n db: PostgresDB,\n slot: string,\n publications: string[],\n lsn: bigint,\n retriesIfReplicationSlotActive = DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE,\n applicationName = 'zero-replicator',\n inboundTimeoutOverrideMs?: number | undefined,\n): Promise<{\n messages: SourceWithPendingQueue<StreamMessage>;\n acks: Sink<bigint>;\n}> {\n const session = createReplicationSessionFor(db, applicationName);\n\n // Postgres will send keepalives before timing out a wal_sender. It is possible that\n // these keepalives are not received if there is back-pressure in the replication\n // stream. To keep the connection alive, explicitly send keepalives if none have been\n // sent within the last 75% of the wal_sender_timeout.\n //\n // https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-SENDER-TIMEOUT\n const [{walSenderTimeoutMs}] = await session<\n {walSenderTimeoutMs: number}[]\n >`SELECT EXTRACT(EPOCH FROM (setting || unit)::interval) * 1000 \n AS \"walSenderTimeoutMs\" FROM pg_settings\n WHERE name = 'wal_sender_timeout'`.simple();\n const {\n enabled: livenessEnabled,\n manualKeepaliveTimeout,\n inboundTimeoutMs,\n timerIntervalMs,\n } = computeLivenessTimings(walSenderTimeoutMs, inboundTimeoutOverrideMs);\n lc.info?.(\n livenessEnabled\n ? `wal_sender_timeout: ${walSenderTimeoutMs}ms. ` +\n `Ensuring manual keepalives at least every ${manualKeepaliveTimeout}ms. ` +\n `Inbound timeout: ${inboundTimeoutMs}ms` +\n (inboundTimeoutMs === walSenderTimeoutMs * 2\n ? ''\n : ' (configured override)')\n : `wal_sender_timeout is disabled (0); skipping manual keepalives and ` +\n `inbound liveness detection.`,\n );\n\n const decode = await InitialDecodeTracker.start(lc, session, slot, lsn);\n const [readable, writable] = await startReplicationStream(\n lc,\n session,\n slot,\n publications,\n lsn,\n retriesIfReplicationSlotActive + 1,\n );\n\n let lastAckTime = Date.now();\n function sendAck(lsn: bigint) {\n writable.write(makeAck(lsn));\n lastAckTime = Date.now();\n }\n\n // Tear down the readable to force a reconnect if the inbound half of the\n // connection goes silent (our outbound acks keep flowing into the void,\n // neither side errors, and the change-source would otherwise sit there\n // forever). See computeLivenessTimings for the derivation of these\n // thresholds — and why the whole timer is disabled when wal_sender_timeout\n // is 0.\n let lastReceivedTime = Date.now();\n\n const livenessTimer = livenessEnabled\n ? setInterval(() => {\n const now = Date.now();\n if (now - lastAckTime > manualKeepaliveTimeout) {\n sendAck(0n);\n lc.debug?.(`sent manual keepalive`);\n }\n const sinceLastReceived = now - lastReceivedTime;\n const {resetWindow, timedOut} = evaluateInboundLiveness({\n sinceLastReceived,\n inboundTimeoutMs,\n queued: messages.queued,\n });\n if (resetWindow) {\n // Downstream back-pressure is preventing us from consuming (and thus\n // receiving) upstream messages. Keep the inbound window fresh so that\n // when the backlog finally drains we grant a full inboundTimeoutMs\n // before concluding the connection is dead — otherwise a long stall\n // would leave lastReceivedTime stale and fire this watchdog on the\n // first post-drain tick, tearing down a healthy connection.\n lastReceivedTime = now;\n } else if (timedOut && !readable.destroyed) {\n lc.warn?.(\n `no message received from ${db.options.host} in ${sinceLastReceived}ms ` +\n `(> inbound timeout ${inboundTimeoutMs}ms). Destroying ` +\n `replication stream to force reconnect.`,\n );\n readable.destroy(\n new Error(\n `replication stream inbound timeout after ${sinceLastReceived}ms`,\n ),\n );\n }\n }, timerIntervalMs)\n : undefined;\n\n let destroyed = false;\n const typeParsers = await getTypeParsers(db, {returnJsonAsString: true});\n const parser = new PgoutputParser(typeParsers);\n const messages = Subscription.create<StreamMessage>({\n cleanup: () => {\n destroyed = true;\n readable.destroyed || readable.destroy();\n clearInterval(livenessTimer);\n return session.end();\n },\n });\n\n readable.once(\n 'close',\n () =>\n // Only log a warning if the stream was not manually closed.\n destroyed || lc.warn?.(`replication stream closed by ${db.options.host}`),\n );\n readable.once(\n 'error',\n e =>\n // Don't log the shutdown signal. This is the expected way for upstream\n // to close the connection (and will be logged downstream).\n (e instanceof postgres.PostgresError && e.code === PG_ADMIN_SHUTDOWN) ||\n lc.warn?.(`error from ${db.options.host}`, e),\n );\n\n pipe({\n source: readable,\n sink: messages,\n parse: buffer => {\n lastReceivedTime = Date.now();\n const msg = parseStreamMessage(lc, buffer, parser);\n if (msg) {\n decode.observe(msg, lastReceivedTime);\n }\n return msg;\n },\n // Allow a small buffer of messages to be queued in the subscription so\n // that the change-source loop can check the queue to determine if more\n // messages are immediately available.\n bufferMessages: 5,\n });\n\n return {\n messages,\n acks: {push: sendAck},\n };\n}\n\nconst INITIAL_DECODE_HISTOGRAM_BOUNDARIES_S = [\n 0.1, 0.5, 1, 2, 5, 10, 30, 60, 120, 300, 600, 1200, 2400, 3600, 7200,\n];\n\nfunction initialDecodeHistogram() {\n return getOrCreateHistogram('replication', 'stream_initial_decode', {\n description:\n 'Time from START_REPLICATION until upstream has decoded the WAL ' +\n \"between the slot's restart_lsn and the start of the stream\",\n unit: 's',\n bucketBoundaries: INITIAL_DECODE_HISTOGRAM_BOUNDARIES_S,\n });\n}\n\n/**\n * Measures how long upstream takes to decode the WAL between the slot's\n * `restart_lsn` and the start of the stream, during which the stream\n * delivers nothing but keepalives. This span can be large, e.g. for a slot\n * that was created (or last acked) long before the requested start LSN.\n *\n * The walsender streams from `max(lsn, confirmed_flush_lsn)`, but must\n * decode from `restart_lsn` to rebuild its transaction state. The decode is\n * considered complete upon the first message at or past the start:\n * * any XLogData message, since only transactions committed after the\n * start are sent, or\n * * a keepalive at or past the start. Keepalives report the decoding\n * position, except for the first one of the stream, which reports the\n * slot's `confirmed_flush_lsn` and is thus ignored if it is at or past the\n * start.\n *\n * Note that on an idle upstream, a walsender whose start is already\n * confirmed may not send a keepalive until other WAL is written or the\n * periodic keepalive (`wal_sender_timeout / 2`) is due, so the measured\n * time is an upper bound when completed by a keepalive.\n */\nexport class InitialDecodeTracker {\n static async start(\n lc: LogContext,\n session: postgres.Sql,\n slot: string,\n lsn: bigint,\n ): Promise<InitialDecodeTracker> {\n let restartLSN: bigint | undefined;\n let confirmedFlushLSN: bigint | undefined;\n try {\n // Replication sessions only support the simple query protocol, so the\n // slot name is inlined as a literal.\n const [row] = await session\n .unsafe<{restartLSN: LSN | null; confirmedFlushLSN: LSN | null}[]>(\n `SELECT restart_lsn AS \"restartLSN\",\n confirmed_flush_lsn AS \"confirmedFlushLSN\"\n FROM pg_replication_slots\n WHERE slot_name = ${lit(slot)}`,\n )\n .simple();\n restartLSN = row?.restartLSN ? toBigInt(row.restartLSN) : undefined;\n confirmedFlushLSN = row?.confirmedFlushLSN\n ? toBigInt(row.confirmedFlushLSN)\n : undefined;\n } catch (e) {\n lc.warn?.(`unable to read position of replication slot ${slot}`, e);\n }\n return new InitialDecodeTracker(\n lc,\n lsn,\n restartLSN,\n confirmedFlushLSN,\n Date.now(),\n );\n }\n\n readonly #lc: LogContext;\n readonly #start: bigint;\n readonly #restartLSN: bigint | undefined;\n readonly #confirmedFlushLSN: bigint | undefined;\n readonly #startTime: number;\n #first = true;\n #done = false;\n\n constructor(\n lc: LogContext,\n lsn: bigint,\n restartLSN: bigint | undefined,\n confirmedFlushLSN: bigint | undefined,\n startTime: number,\n ) {\n // The walsender silently starts at confirmed_flush_lsn if the\n // requested lsn is behind it.\n this.#start =\n confirmedFlushLSN !== undefined && confirmedFlushLSN > lsn\n ? confirmedFlushLSN\n : lsn;\n this.#lc = lc.withContext('decodeStart', fromBigInt(this.#start));\n this.#restartLSN = restartLSN;\n this.#confirmedFlushLSN = confirmedFlushLSN;\n this.#startTime = startTime;\n\n if (restartLSN !== undefined) {\n this.#lc.info?.(\n `decoding ${this.#start - restartLSN} bytes of WAL from ` +\n `restart_lsn ${fromBigInt(restartLSN)} to the start of the stream`,\n );\n }\n }\n\n /**\n * Observes a received message, returning the elapsed decode time (ms) if\n * this message completed the initial decode.\n */\n observe([lsn, msg]: StreamMessage, now: number): number | undefined {\n if (this.#done) {\n return undefined;\n }\n const first = this.#first;\n this.#first = false;\n if (msg.tag === 'keepalive') {\n if (\n lsn < this.#start ||\n (first && lsn === this.#confirmedFlushLSN) // reports confirmed_flush\n ) {\n return undefined;\n }\n }\n this.#done = true;\n const elapsed = now - this.#startTime;\n initialDecodeHistogram().recordMs(elapsed);\n this.#lc.info?.(\n `upstream decoded the WAL to the start of the stream in ` +\n `${elapsed} ms (${msg.tag} at ${fromBigInt(lsn)}` +\n (this.#restartLSN === undefined\n ? ')'\n : `, ${this.#start - this.#restartLSN} bytes from restart_lsn)`),\n {elapsed},\n );\n return elapsed;\n }\n}\n\n/**\n * Derives the timings for the replication liveness timer from the server's\n * `wal_sender_timeout` (in milliseconds).\n *\n * Postgres treats `wal_sender_timeout = 0` as \"disabled\": it will neither\n * terminate an idle wal sender nor emit the periodic keepalives it otherwise\n * sends at roughly `wal_sender_timeout / 2`. Every timing below is derived from\n * that interval, so a disabled timeout disables the liveness machinery entirely\n * (`enabled: false`). Otherwise the derived thresholds would all collapse to 0,\n * inverting the intended meaning: the inbound watchdog would fire on the very\n * first tick and destroy the stream, while the timer itself would busy-spin at\n * a 0ms interval — together producing a continuous reconnect storm.\n *\n * An `inboundTimeoutOverrideMs` (when positive) replaces the default\n * `2x wal_sender_timeout` inbound threshold. The two timeouts protect\n * different parties with asymmetric false-positive costs: `wal_sender_timeout`\n * is the server reaping dead clients (a false positive there costs a cheap\n * reconnect), while the inbound watchdog tears down the stream and replays the\n * in-flight transaction — expensive, and self-defeating when the wal sender is\n * legitimately silent for long stretches (e.g. decoding through WAL from\n * unpublished tables, or assembling a large transaction that pgoutput only\n * sends at commit). Operators who don't own the server setting (e.g. managed\n * or operator-provisioned Postgres with an aggressive cluster-wide\n * `wal_sender_timeout`) can widen the client-side fuse independently.\n *\n * The override has no effect when `wal_sender_timeout` is disabled (0): the\n * server then sends no periodic keepalives, so inbound silence is normal even\n * on an idle healthy connection and any silence-based watchdog would\n * false-positive.\n *\n * https://www.postgresql.org/docs/current/runtime-config-replication.html#GUC-WAL-SENDER-TIMEOUT\n */\nexport function computeLivenessTimings(\n walSenderTimeoutMs: number,\n inboundTimeoutOverrideMs?: number | undefined,\n): {\n enabled: boolean;\n manualKeepaliveTimeout: number;\n inboundTimeoutMs: number;\n timerIntervalMs: number;\n} {\n // Guard with `!(x > 0)` so that 0, negative, and NaN values all disable the\n // timer rather than producing degenerate (zero / NaN) thresholds.\n if (!(walSenderTimeoutMs > 0)) {\n return {\n enabled: false,\n manualKeepaliveTimeout: 0,\n inboundTimeoutMs: 0,\n timerIntervalMs: 0,\n };\n }\n // Send a manual keepalive if nothing has been sent in the last 75% of the\n // wal_sender_timeout, so Postgres never times us out under back-pressure.\n const manualKeepaliveTimeout = Math.floor(walSenderTimeoutMs * 0.75);\n return {\n enabled: true,\n manualKeepaliveTimeout,\n // Force a reconnect after 2x wal_sender_timeout — i.e. two consecutive\n // missed keepalives — without any inbound message, to avoid spurious\n // reconnects from a single delayed keepalive (PG scheduling jitter under\n // load, our own event-loop stalls, etc.). A 0 / negative / NaN override\n // falls back to the default rather than degenerating the threshold.\n inboundTimeoutMs:\n inboundTimeoutOverrideMs !== undefined && inboundTimeoutOverrideMs > 0\n ? inboundTimeoutOverrideMs\n : walSenderTimeoutMs * 2,\n // Poll at 1/5th of the manual keepalive interval.\n timerIntervalMs: manualKeepaliveTimeout / 5,\n };\n}\n\n/**\n * Pure decision for the inbound-liveness watchdog, given the time since the\n * last inbound message, the timeout threshold, and the number of messages\n * currently queued downstream (see {@link SourceWithPendingQueue.queued}).\n *\n * A non-empty downstream queue means we have received data we haven't yet\n * consumed: the reason we aren't receiving *more* is our own back-pressure, not\n * upstream silence. In that case we `resetWindow` (treat the backlog as\n * liveness evidence) rather than counting the stall against the connection.\n * This both suppresses false timeouts during back-pressure and — crucially —\n * keeps `lastReceivedTime` fresh so the drain transition (queue emptying after\n * a long stall) doesn't fire the watchdog against a stale timestamp on the very\n * next tick.\n *\n * Only when the queue is empty (consumption has caught up, so reading — and\n * thus keepalives — should be flowing again) does an over-threshold gap\n * indicate a genuinely dead inbound half.\n */\nexport function evaluateInboundLiveness({\n sinceLastReceived,\n inboundTimeoutMs,\n queued,\n}: {\n sinceLastReceived: number;\n inboundTimeoutMs: number;\n queued: number;\n}): {resetWindow: boolean; timedOut: boolean} {\n if (queued > 0) {\n return {resetWindow: true, timedOut: false};\n }\n return {resetWindow: false, timedOut: sinceLastReceived > inboundTimeoutMs};\n}\n\n/**\n * Formats publication names for the START_REPLICATION command.\n * The replication protocol expects format: publication_names 'pub1,pub2'\n * Each name is escaped to handle any quotes that may have passed validation.\n */\nfunction formatPublicationNames(publications: string[]): string {\n // lit() returns 'escaped_name' with surrounding quotes\n // We strip the quotes since the outer quotes are in the template\n return publications.map(p => lit(p).slice(1, -1)).join(',');\n}\n\nexport async function startReplicationStream(\n lc: LogContext,\n session: postgres.Sql,\n slot: string,\n publications: string[],\n lsn: bigint,\n maxAttempts: number = DEFAULT_RETRIES_IF_REPLICATION_SLOT_ACTIVE + 1,\n) {\n for (let i = 0; i < maxAttempts; i++) {\n try {\n const stream = session\n .unsafe(\n `START_REPLICATION SLOT ${id(slot)} LOGICAL ${fromBigInt(lsn)} (\n proto_version '1',\n publication_names '${formatPublicationNames(publications)}',\n messages 'true'\n )`,\n )\n .execute();\n return await Promise.all([stream.readable(), stream.writable()]);\n } catch (e) {\n if (e instanceof postgres.PostgresError) {\n // error: replication slot \"zero_slot_change_source_test_id\" is active for PID 268\n if (e.code === PG_OBJECT_IN_USE) {\n // The freeing up of the replication slot is not transactional;\n // sometimes it takes time for Postgres to consider the slot\n // inactive.\n lc.warn?.(`attempt ${i + 1}: ${String(e)}`, e);\n await sleep(Math.min(10 * 2 ** i, 1000));\n continue;\n }\n // error: This slot has been invalidated because it exceeded the maximum reserved size.\n // (This is a different manifestation of a slot being invalidated when\n // the wal exceeds the max_slot_wal_keep_size)\n if (e.code === PG_OBJECT_NOT_IN_PREREQUISITE_STATE) {\n lc.error?.(`error starting replication stream`, e);\n throw new AutoResetSignal(`unable to start replication stream`, {\n cause: e,\n });\n }\n }\n throw e;\n }\n }\n throw new Error(\n `exceeded max attempts (${maxAttempts}) to start the Postgres stream`,\n );\n}\n\n/**\n * Starts a \"dummy\" replication session for the specified `slot` which:\n * * does not consume any records\n * * keeps the session alive by sending status messages at the starting LSN\n *\n * This essentially reserves the replication slot for this process by marking\n * it as \"active\" in pg_replication_slots, allowing replication slot cleanup\n * logic to distinguish a new-but-initializing replication slot from one that\n * has been abandoned / orphaned.\n *\n * When initialization (e.g. initial-sync) has finished, the server should take\n * over the replication slot using pg_terminate_backend, which will close the\n * session.\n *\n * Note that caller should not close the supplied `session`, as that will\n * also terminate the dummy replication session.\n */\nexport class SlotReservationHandle extends Readable {\n readonly #worker: Worker;\n readonly #closedPromise: Promise<void>;\n #stopped = false;\n #sigtermTimer?: NodeJS.Timeout | undefined;\n\n constructor(worker: Worker) {\n super({read() {}});\n this.#worker = worker;\n this.#closedPromise = new Promise(resolve => {\n worker.once('close', () => {\n clearTimeout(this.#sigtermTimer);\n resolve();\n });\n });\n // Suppress unhandled error events if destroyed with an error\n this.on('error', () => {});\n worker.on('close', () => {\n if (!this.destroyed) {\n this.destroy();\n }\n });\n worker.on('error', err => {\n if (!this.destroyed) {\n this.destroy(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n override _destroy(\n error: Error | null,\n callback: (error?: Error | null) => void,\n ): void {\n if (!this.#stopped) {\n this.#stopped = true;\n try {\n this.#worker.send(['stop', {}]);\n } catch {\n // ignore\n }\n this.#sigtermTimer = setTimeout(() => {\n try {\n this.#worker.kill('SIGTERM');\n } catch {}\n }, 5_000);\n this.#sigtermTimer.unref();\n }\n callback(error);\n }\n\n async end(timeoutMs = 5_000): Promise<void> {\n this.destroy();\n const closed = await Promise.race([\n this.#closedPromise.then(() => true),\n sleep(timeoutMs).then(() => false),\n ]);\n if (!closed) {\n try {\n this.#worker.kill('SIGKILL');\n } catch {}\n // Await worker closure after forced kill so that the replication session\n // is completely terminated before any subsequent slot drop attempt.\n await Promise.race([this.#closedPromise, sleep(2_000)]);\n }\n }\n}\n\nexport async function endSession(session?: Readable): Promise<void> {\n if (!session) {\n return;\n }\n if ('end' in session && typeof session.end === 'function') {\n await (session as {end: () => Promise<void>}).end();\n } else {\n session.destroy();\n }\n}\n\nexport type PgConnectionConfig = {\n host?: string | string[] | undefined;\n port?: number | number[] | undefined;\n path?: string | undefined;\n database?: string | undefined;\n user?: string | undefined;\n pass?: string | null | undefined;\n ssl?:\n | boolean\n | string\n | {rejectUnauthorized?: boolean | undefined}\n | undefined;\n};\n\nexport function extractConnectionConfig(\n session: postgres.Sql,\n): PgConnectionConfig {\n const opts = session.options;\n return {\n host: opts.host,\n port: opts.port,\n path: (opts as {path?: string | undefined}).path,\n database: opts.database,\n user: opts.user,\n pass: opts.pass,\n ssl:\n typeof opts.ssl === 'object' && opts.ssl !== null\n ? {\n rejectUnauthorized: (\n opts.ssl as {rejectUnauthorized?: boolean | undefined}\n ).rejectUnauthorized,\n }\n : (opts.ssl as boolean | string | undefined),\n };\n}\n\n/**\n * Starts a \"dummy\" replication session for the specified `slot` which:\n * * does not consume any records\n * * keeps the session alive by sending status messages at the starting LSN\n *\n * Runs in a separate process with its own event loop and connection reconnect\n * loop to prevent slot drop races during heavy initial sync table copy or\n * SQLite index building.\n */\nexport async function keepSlotActiveUntilTakenOver(\n lc: LogContext,\n config: SlotKeeperConfig,\n): Promise<Readable> {\n const {slot, lsn} = config;\n lc.info?.(`spawning slot-keeper process for ${slot} at lsn ${lsn} ...`);\n const worker = childWorker(SLOT_KEEPER_URL, process.env);\n worker.onMessageType('init', () => {\n worker.send(['start', config]);\n });\n\n // Wait for the slot keeper to establish replication before returning\n await new Promise<void>((resolve, reject) => {\n const onReady = () => {\n cleanup();\n resolve();\n };\n const onError = (err: unknown) => {\n cleanup();\n reject(err);\n };\n const onClose = (code: number) => {\n cleanup();\n reject(\n new Error(\n `slot-keeper for ${slot} exited with code ${code} before becoming ready`,\n ),\n );\n };\n function cleanup() {\n worker.off('error', onError);\n worker.off('close', onClose);\n }\n worker.onceMessageType('ready', onReady);\n worker.once('error', onError);\n worker.once('close', onClose);\n });\n\n lc.info?.(`slot-keeper active for ${slot}`);\n return new SlotReservationHandle(worker);\n}\n\nfunction parseStreamMessage(\n lc: LogContext,\n buffer: Buffer,\n parser: PgoutputParser,\n): StreamMessage | null {\n // https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-START-REPLICATION\n if (buffer[0] !== 0x77 && buffer[0] !== 0x6b) {\n lc.warn?.('Unknown message', buffer[0]);\n return null;\n }\n const lsn = buffer.readBigUInt64BE(1);\n if (buffer[0] === 0x77) {\n // https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-XLOGDATA\n // (Byte 25 is where the WAL data begins)\n return [lsn, parser.parse(buffer.subarray(25))];\n }\n // https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-PRIMARY-KEEPALIVE-MESSAGE\n // (Byte 17: shouldRespond)\n const shouldRespond = buffer.readInt8(17) !== 0;\n return [lsn, {tag: 'keepalive', shouldRespond}];\n}\n\n// https://www.postgresql.org/docs/current/protocol-replication.html#PROTOCOL-REPLICATION-STANDBY-STATUS-UPDATE\nexport function makeAck(lsn: bigint): Buffer {\n const microNow = BigInt(Date.now() - Date.UTC(2000, 0, 1)) * BigInt(1000);\n\n const x = Buffer.alloc(34);\n x[0] = 'r'.charCodeAt(0);\n x.writeBigInt64BE(lsn, 1);\n x.writeBigInt64BE(lsn, 9);\n x.writeBigInt64BE(lsn, 17);\n x.writeBigInt64BE(microNow, 25);\n return x;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { LogContext } from '@rocicorp/logger';
|
|
2
|
+
import type { PostgresDB } from '../../../types/pg.ts';
|
|
3
|
+
import type { ShardID } from '../../../types/shards.ts';
|
|
4
|
+
type Options = {
|
|
5
|
+
inactiveSlotCleanupTimeoutMs?: number | undefined;
|
|
6
|
+
pollIntervalMs?: number | undefined;
|
|
7
|
+
};
|
|
8
|
+
export declare class ReplicationSlotCleanupMonitor {
|
|
9
|
+
#private;
|
|
10
|
+
constructor(lc: LogContext, shard: ShardID, upstream: PostgresDB, upstreamPgServerVersionNum: number, currentSlot: string, { inactiveSlotCleanupTimeoutMs, pollIntervalMs }?: Options);
|
|
11
|
+
start(): void;
|
|
12
|
+
stop(): void;
|
|
13
|
+
getSlotsToCleanup(now: Date): Promise<string[]>;
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=replication-slot-cleanup-monitor.d.ts.map
|
package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replication-slot-cleanup-monitor.d.ts","sourceRoot":"","sources":["../../../../../../../zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,0BAA0B,CAAC;AAItD,KAAK,OAAO,GAAG;IACb,4BAA4B,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClD,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,CAAC;AAKF,qBAAa,6BAA6B;;IAkCxC,YACE,EAAE,EAAE,UAAU,EACd,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,UAAU,EACpB,0BAA0B,EAAE,MAAM,EAClC,WAAW,EAAE,MAAM,EACnB,EAAC,4BAA4B,EAAE,cAAc,EAAC,GAAE,OAAY,EAW7D;IAED,KAAK,SAYJ;IAED,IAAI,SAIH;IAiBK,iBAAiB,CAAC,GAAG,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqEpD;CACF"}
|