@rocicorp/zero 1.11.0-canary.3 → 1.11.0-canary.30
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/base64.d.ts +19 -0
- package/out/shared/src/base64.d.ts.map +1 -0
- package/out/shared/src/base64.js +40 -0
- package/out/shared/src/base64.js.map +1 -0
- 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/packed-boolean-map.d.ts +7 -0
- package/out/shared/src/packed-boolean-map.d.ts.map +1 -0
- package/out/shared/src/packed-boolean-map.js +36 -0
- package/out/shared/src/packed-boolean-map.js.map +1 -0
- 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 +13 -0
- package/out/shared/src/valita.d.ts.map +1 -1
- package/out/shared/src/valita.js +23 -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 +4 -5
- 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 +46 -4
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +116 -24
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +409 -157
- 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 +117 -77
- 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 +8 -1
- 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 +3 -0
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +95 -21
- package/out/zero-cache/src/server/replicator.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/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 +24 -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/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 +92 -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 +27 -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 +206 -19
- 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 +55 -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 +305 -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 +130 -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 +38 -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 +55 -21
- 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 +31 -0
- 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 +102 -3
- 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 +40 -15
- 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 +149 -27
- 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 +32 -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 +50 -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 +98 -34
- 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 +48 -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 +131 -34
- 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 +22 -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 +149 -78
- 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 +38 -16
- 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.map +1 -1
- 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/schema/tables.d.ts +58 -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 +107 -16
- 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 +1 -1
- 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 +16 -4
- 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 +95 -4
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +293 -83
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +446 -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 +76 -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 +58 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +123 -12
- 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 +1 -1
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +3 -1
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +34 -3
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +121 -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/litestream/wal-keeper.d.ts +33 -0
- package/out/zero-cache/src/services/litestream/wal-keeper.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/wal-keeper.js +49 -0
- package/out/zero-cache/src/services/litestream/wal-keeper.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/incremental-sync.d.ts +5 -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 +54 -21
- 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 +4 -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/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/connection-context-manager.d.ts +2 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js +1 -0
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.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 +85 -20
- 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 +76 -11
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +214 -40
- 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-budget.d.ts +33 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js +62 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -0
- 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 +10 -1
- 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 +18 -4
- 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 +80 -6
- 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 +658 -195
- 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/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 +82 -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 +214 -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 +96 -14
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +214 -30
- 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 +11 -1
- 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 +566 -107
- 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 +1 -1
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +39 -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 +18 -1
- package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connect-params.js +25 -1
- package/out/zero-cache/src/workers/connect-params.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +4 -4
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +8 -8
- 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 +15 -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/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 +89 -50
- 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 +5 -0
- package/out/zero-protocol/src/analyze-query-result.d.ts.map +1 -1
- package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +13 -14
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/connect.d.ts +16 -0
- package/out/zero-protocol/src/connect.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.js +27 -1
- package/out/zero-protocol/src/connect.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +31 -31
- package/out/zero-protocol/src/feature-flag-enum.d.ts +14 -0
- package/out/zero-protocol/src/feature-flag-enum.d.ts.map +1 -0
- package/out/zero-protocol/src/feature-flag-enum.js +10 -0
- package/out/zero-protocol/src/feature-flag-enum.js.map +1 -0
- package/out/zero-protocol/src/feature-flag.d.ts +5 -0
- package/out/zero-protocol/src/feature-flag.d.ts.map +1 -0
- package/out/zero-protocol/src/inspect-down.d.ts +16 -16
- package/out/zero-protocol/src/poke.d.ts +17 -10
- package/out/zero-protocol/src/poke.d.ts.map +1 -1
- package/out/zero-protocol/src/poke.js +3 -2
- package/out/zero-protocol/src/poke.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +30 -6
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js +1 -1
- package/out/zero-protocol/src/protocol-version.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-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 +74 -7
- 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 +2 -1
- package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
- package/out/zero-server/src/adapters/drizzle.js +12 -7
- package/out/zero-server/src/adapters/drizzle.js.map +1 -1
- package/out/zero-server/src/adapters/kysely.d.ts +2 -1
- package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
- package/out/zero-server/src/adapters/kysely.js +8 -2
- package/out/zero-server/src/adapters/kysely.js.map +1 -1
- package/out/zero-server/src/adapters/pg.d.ts +5 -1
- package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
- package/out/zero-server/src/adapters/pg.js +28 -7
- package/out/zero-server/src/adapters/pg.js.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
- package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.js +7 -1
- package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
- package/out/zero-server/src/adapters/prisma.d.ts +3 -2
- package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
- package/out/zero-server/src/adapters/prisma.js +8 -2
- 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 +1 -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/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/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/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-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 +22 -5
- 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 +9 -1
- package/out/zqlite/src/db.d.ts.map +1 -1
- package/out/zqlite/src/db.js +62 -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 +52 -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 +4 -5
- 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,67 +1,35 @@
|
|
|
1
|
+
import { AbortError } from "../../../../shared/src/abort-error.js";
|
|
1
2
|
import { sleep } from "../../../../shared/src/sleep.js";
|
|
2
|
-
import {
|
|
3
|
-
import { getShardConfig } from "../../types/shards.js";
|
|
4
|
-
import "../../config/normalize.js";
|
|
5
|
-
import { ChangeStreamerHttpClient } from "./change-streamer-http.js";
|
|
6
|
-
import { resolver } from "@rocicorp/resolver";
|
|
3
|
+
import { promiseOrAbort } from "../../../../shared/src/promise-race.js";
|
|
7
4
|
//#region ../zero-cache/src/services/change-streamer/snapshot.ts
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* The `replicaVersion` of the backup. If a subscriber's restored or
|
|
16
|
-
* existing replica is of a different version, it should delete it and
|
|
17
|
-
* retry the restore from litestream (i.e. equivalent to a
|
|
18
|
-
* `WrongReplicaVersion` response from a `/changes` subscription).
|
|
19
|
-
*/
|
|
20
|
-
replicaVersion: valita_exports.string(),
|
|
21
|
-
/**
|
|
22
|
-
* The earliest watermark from which catchup is possible. If the
|
|
23
|
-
* subscriber's replica is older that this watermark, it should delete it
|
|
24
|
-
* and (retry the) restore from litestream (i.e. equivalent to a
|
|
25
|
-
* `WatermarkTooOld` response from a `/changes` subscription).
|
|
26
|
-
*/
|
|
27
|
-
minWatermark: valita_exports.string()
|
|
28
|
-
});
|
|
29
|
-
var statusMessageSchema = valita_exports.tuple([valita_exports.literal("status"), statusSchema]);
|
|
30
|
-
var snapshotMessageSchema = valita_exports.union(statusMessageSchema);
|
|
31
|
-
function reserveAndGetSnapshotStatus(lc, config) {
|
|
32
|
-
const { promise: status, resolve, reject } = resolver();
|
|
33
|
-
(async function() {
|
|
34
|
-
const abort = new AbortController();
|
|
35
|
-
process.on("SIGINT", () => abort.abort());
|
|
36
|
-
process.on("SIGTERM", () => abort.abort());
|
|
5
|
+
async function reserveAndGetSnapshotStatus(lc, taskID, changeStreamer) {
|
|
6
|
+
const abort = new AbortController();
|
|
7
|
+
const { signal } = abort;
|
|
8
|
+
const onSignal = () => abort.abort(new AbortError("SIGTERM/SIGINT"));
|
|
9
|
+
process.on("SIGINT", onSignal);
|
|
10
|
+
process.on("SIGTERM", onSignal);
|
|
11
|
+
try {
|
|
37
12
|
for (let i = 0;; i++) {
|
|
38
13
|
let err;
|
|
14
|
+
const reservation = changeStreamer.reserveSnapshot(taskID);
|
|
39
15
|
try {
|
|
40
|
-
|
|
41
|
-
const stream = await reserveSnapshot(lc, config);
|
|
42
|
-
for await (const msg of stream) {
|
|
43
|
-
resolve(msg[1]);
|
|
44
|
-
resolved = true;
|
|
45
|
-
}
|
|
46
|
-
if (resolved) break;
|
|
16
|
+
return await promiseOrAbort(reservation, signal);
|
|
47
17
|
} catch (e) {
|
|
48
18
|
err = e;
|
|
49
19
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} catch (e) {
|
|
54
|
-
return reject(e);
|
|
20
|
+
if (signal.aborted) {
|
|
21
|
+
reservation.then(({ followup }) => followup.cancel(), () => {});
|
|
22
|
+
throw err;
|
|
55
23
|
}
|
|
24
|
+
lc.warn?.(`Unable to reserve snapshot (attempt ${i + 1}). Retrying in 5 seconds.`, String(err));
|
|
25
|
+
await sleep(5e3, signal);
|
|
56
26
|
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const { taskID, change, changeStreamer } = config;
|
|
62
|
-
return new ChangeStreamerHttpClient(lc, getShardConfig(config), change.db, changeStreamer.uri).reserveSnapshot(taskID);
|
|
27
|
+
} finally {
|
|
28
|
+
process.off("SIGINT", onSignal);
|
|
29
|
+
process.off("SIGTERM", onSignal);
|
|
30
|
+
}
|
|
63
31
|
}
|
|
64
32
|
//#endregion
|
|
65
|
-
export { reserveAndGetSnapshotStatus
|
|
33
|
+
export { reserveAndGetSnapshotStatus };
|
|
66
34
|
|
|
67
35
|
//# sourceMappingURL=snapshot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","names":[],"sources":["../../../../../../zero-cache/src/services/change-streamer/snapshot.ts"],"sourcesContent":["/**\n * The `snapshot` API serves the purpose of:\n * - informing subscribers (i.e. view-syncers) of the (litestream)\n * backup location from which to restore a replica snapshot\n * - checking whether a restored backup or existing replica is\n * compatible with the change-streamer\n * - preventing change-log cleanup while a snapshot restore is in\n * progress\n * - tracking the approximate time it takes from the beginning of\n * snapshot \"reservation\" to the subsequent subscription, which\n * serves as the minimum interval to wait before cleaning up\n * backed up changes.\n */\n\nimport type {LogContext} from '@rocicorp/logger';\nimport {
|
|
1
|
+
{"version":3,"file":"snapshot.js","names":[],"sources":["../../../../../../zero-cache/src/services/change-streamer/snapshot.ts"],"sourcesContent":["/**\n * The `snapshot` API serves the purpose of:\n * - informing subscribers (i.e. view-syncers) of the (litestream)\n * backup location from which to restore a replica snapshot\n * - checking whether a restored backup or existing replica is\n * compatible with the change-streamer\n * - preventing change-log cleanup while a snapshot restore is in\n * progress\n * - tracking the approximate time it takes from the beginning of\n * snapshot \"reservation\" to the subsequent subscription, which\n * serves as the minimum interval to wait before cleaning up\n * backed up changes.\n */\n\nimport type {LogContext} from '@rocicorp/logger';\nimport {AbortError} from '../../../../shared/src/abort-error.ts';\nimport {promiseOrAbort} from '../../../../shared/src/promise-race.ts';\nimport {sleep} from '../../../../shared/src/sleep.ts';\n\n// The schema definitions live in the pure schema module (with no dependency on\n// the HTTP client) so that subscribe.ts can import them without forming an\n// import cycle through change-streamer-http.ts. Imported here for local use and\n// re-exported for existing consumers.\nimport type {\n ReservationFollowup,\n SnapshotReserver,\n} from './change-streamer-http.ts';\nimport type {SnapshotStatus} from './subscribe.ts';\n\nexport type {SnapshotStatus};\n\nexport async function reserveAndGetSnapshotStatus(\n lc: LogContext,\n taskID: string,\n changeStreamer: SnapshotReserver,\n): Promise<{reserved: SnapshotStatus; followup: ReservationFollowup}> {\n const abort = new AbortController();\n const {signal} = abort;\n // Use our own AbortError as the abort reason (rather than the native\n // DOMException that AbortController.abort() defaults to) so that\n // promiseOrAbort()'s rejection, which propagates `signal.reason` verbatim,\n // is always an instance of the shared AbortError type.\n const onSignal = () => abort.abort(new AbortError('SIGTERM/SIGINT'));\n process.on('SIGINT', onSignal);\n process.on('SIGTERM', onSignal);\n\n try {\n for (let i = 0; ; i++) {\n let err: unknown;\n const reservation = changeStreamer.reserveSnapshot(taskID);\n try {\n return await promiseOrAbort(reservation, signal);\n } catch (e) {\n err = e;\n }\n if (signal.aborted) {\n // promiseOrAbort() does not cancel the loser of the race: the\n // reservation may still resolve later. If it does, cancel its\n // connection rather than leaking it, since this function has already\n // given up and nobody will call followup.subscribe().\n reservation.then(\n ({followup}) => followup.cancel(),\n () => {},\n );\n throw err;\n }\n // Retry in the view-syncer since it cannot proceed until it connects\n // to a (compatible) replication-manager. In particular, a\n // replication-manager that does not support the view-syncer's\n // change-streamer protocol will close the stream with an error; this\n // retry logic essentially delays the startup of a view-syncer until\n // a compatible replication-manager has been rolled out, allowing\n // replication-manager and view-syncer services to be updated in\n // parallel.\n lc.warn?.(\n `Unable to reserve snapshot (attempt ${i + 1}). Retrying in 5 seconds.`,\n String(err),\n );\n await sleep(5000, signal);\n }\n } finally {\n // This function is called repeatedly (e.g. by the replicator's restore\n // loop), so the signal handlers must not outlive the reservation.\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n }\n}\n"],"mappings":";;;;AA+BA,eAAsB,4BACpB,IACA,QACA,gBACoE;CACpE,MAAM,QAAQ,IAAI,gBAAgB;CAClC,MAAM,EAAC,WAAU;CAKjB,MAAM,iBAAiB,MAAM,MAAM,IAAI,WAAW,gBAAgB,CAAC;CACnE,QAAQ,GAAG,UAAU,QAAQ;CAC7B,QAAQ,GAAG,WAAW,QAAQ;CAE9B,IAAI;EACF,KAAK,IAAI,IAAI,IAAK,KAAK;GACrB,IAAI;GACJ,MAAM,cAAc,eAAe,gBAAgB,MAAM;GACzD,IAAI;IACF,OAAO,MAAM,eAAe,aAAa,MAAM;GACjD,SAAS,GAAG;IACV,MAAM;GACR;GACA,IAAI,OAAO,SAAS;IAKlB,YAAY,MACT,EAAC,eAAc,SAAS,OAAO,SAC1B,CAAC,CACT;IACA,MAAM;GACR;GASA,GAAG,OACD,uCAAuC,IAAI,EAAE,4BAC7C,OAAO,GAAG,CACZ;GACA,MAAM,MAAM,KAAM,MAAM;EAC1B;CACF,UAAU;EAGR,QAAQ,IAAI,UAAU,QAAQ;EAC9B,QAAQ,IAAI,WAAW,QAAQ;CACjC;AACF"}
|
|
@@ -25,6 +25,11 @@ export type SQLiteChangeLogWriterOptions = {
|
|
|
25
25
|
onRebuilt?: (() => void) | undefined;
|
|
26
26
|
/** Overridable for tests. */
|
|
27
27
|
now?: (() => number) | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Percentage of transactions that retain the rollout-only per-message
|
|
30
|
+
* timing and source-vs-stored hash validation. Defaults to 1.
|
|
31
|
+
*/
|
|
32
|
+
shadowValidationPercent?: number | undefined;
|
|
28
33
|
};
|
|
29
34
|
/**
|
|
30
35
|
* Appends the canonical change stream to the SQLite change log, from the
|
|
@@ -98,7 +103,7 @@ export declare class SQLiteChangeLogWriter {
|
|
|
98
103
|
* Writes one stream message, committing at transaction boundaries. Never
|
|
99
104
|
* throws: a write failure disables the writer instead of failing the stream.
|
|
100
105
|
*/
|
|
101
|
-
write(change: ChangeStreamData, json: string): void;
|
|
106
|
+
write(change: ChangeStreamData, json: string, storedChange?: string): void;
|
|
102
107
|
/**
|
|
103
108
|
* Discards the open transaction, if any. Called when the change stream is
|
|
104
109
|
* interrupted mid-transaction.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-change-log-writer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/change-streamer/sqlite-change-log-writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"sqlite-change-log-writer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/change-streamer/sqlite-change-log-writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAKjD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,8BAA8B,CAAC;AAM3D,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,iDAAiD,CAAC;AAKtF,OAAO,EAUL,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EAE1B,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAML,KAAK,iCAAiC,EACvC,MAAM,kDAAkD,CAAC;AAG1D,MAAM,MAAM,4BAA4B,GAAG;IACzC,iFAAiF;IACjF,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,QAAQ,EAAE,iBAAiB,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACrD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACtC,6EAA6E;IAC7E,SAAS,CAAC,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;IACrC,6BAA6B;IAC7B,GAAG,CAAC,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,CAAC;IACjC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9C,CAAC;AAIF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,qBAAqB;;IAYhC,YAAY,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,4BAA4B,EAY7D;IAED,qEAAqE;IACrE,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;;;;;OAOG;IACH,IAAI,UAAU,IAAI,QAAQ,GAAG,SAAS,CAErC;IAED,2EAA2E;IAC3E,KAAK,IAAI,iCAAiC,GAAG,SAAS,CAErD;IAED;;;;;;;;;;;;;OAaG;IACH,SAAS,CACP,UAAU,EAAE,oBAAoB,GAC/B,oBAAoB,GAAG,SAAS,CAElC;IAED;;;;;OAKG;IACH,gBAAgB,CACd,IAAI,EAAE,MAAM,oBAAoB,GAC/B,oBAAoB,GAAG,SAAS,CAElC;IA2GD;;;OAGG;IACH,KAAK,CACH,MAAM,EAAE,gBAAgB,EACxB,IAAI,EAAE,MAAM,EACZ,YAAY,SAA8C,GACzD,IAAI,CA4FN;IAeD;;;OAGG;IACH,KAAK,IAAI,IAAI,CAYZ;IAED,KAAK,IAAI,IAAI,CAYZ;CA6BF"}
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
import { assert } from "../../../../shared/src/asserts.js";
|
|
1
2
|
import { must } from "../../../../shared/src/must.js";
|
|
3
|
+
import { h32 } from "../../../../shared/src/hash.js";
|
|
2
4
|
import { readCookieRowCounts, readCookies } from "../replicator/change-log-cookies.js";
|
|
3
5
|
import { StatementRunner } from "../../db/statements.js";
|
|
4
6
|
import { isSQLiteCorruption, logSQLiteCorruptionDiagnostics } from "../../db/sqlite-corruption.js";
|
|
5
7
|
import { ChangeLogRebuildRequired, changeLogFileName, changeLogWipeReason, deleteChangeLogDB, openChangeLogDBForWriting, readChangeLogHead, rebuildChangeLogDBForWriting, reconcileChangeLog } from "../replicator/change-log-db.js";
|
|
8
|
+
import { extractChangeSubstring } from "./change-log-codec.js";
|
|
6
9
|
import { ChangeLogStreamWriter } from "../replicator/change-log-stream-writer.js";
|
|
7
10
|
import { SQLiteChangeLogObserver, getSQLiteChangeLogInfo, logSQLiteChangeLogStartup, recordSQLiteChangeLogReconcile } from "../replicator/sqlite-change-log-observability.js";
|
|
8
11
|
import { SqliteError } from "@rocicorp/zero-sqlite3";
|
|
9
12
|
//#region ../zero-cache/src/services/change-streamer/sqlite-change-log-writer.ts
|
|
13
|
+
var DEFAULT_SHADOW_VALIDATION_PERCENT = 1;
|
|
10
14
|
/**
|
|
11
15
|
* Appends the canonical change stream to the SQLite change log, from the
|
|
12
16
|
* change-streamer's own stream loop.
|
|
@@ -41,14 +45,18 @@ var SQLiteChangeLogWriter = class {
|
|
|
41
45
|
#lc;
|
|
42
46
|
#opts;
|
|
43
47
|
#now;
|
|
48
|
+
#shadowValidationPercent;
|
|
44
49
|
#db;
|
|
45
50
|
#writer;
|
|
46
51
|
#observer;
|
|
47
52
|
#disabled = false;
|
|
53
|
+
#validateTransaction = false;
|
|
48
54
|
constructor(lc, opts) {
|
|
49
55
|
this.#lc = lc.withContext("component", "sqlite-change-log-writer");
|
|
50
56
|
this.#opts = opts;
|
|
51
57
|
this.#now = opts.now ?? Date.now;
|
|
58
|
+
this.#shadowValidationPercent = opts.shadowValidationPercent ?? DEFAULT_SHADOW_VALIDATION_PERCENT;
|
|
59
|
+
assert(Number.isInteger(this.#shadowValidationPercent) && this.#shadowValidationPercent >= 0 && this.#shadowValidationPercent <= 100, "SQLite change-log shadow validation percentage must be an integer between 0 and 100");
|
|
52
60
|
}
|
|
53
61
|
/** False once the writer has failed soft, or after {@link close}. */
|
|
54
62
|
get enabled() {
|
|
@@ -161,26 +169,28 @@ var SQLiteChangeLogWriter = class {
|
|
|
161
169
|
* Writes one stream message, committing at transaction boundaries. Never
|
|
162
170
|
* throws: a write failure disables the writer instead of failing the stream.
|
|
163
171
|
*/
|
|
164
|
-
write(change, json) {
|
|
172
|
+
write(change, json, storedChange = extractChangeSubstring(json, change[1].tag)) {
|
|
165
173
|
const writer = this.#writer;
|
|
166
174
|
const db = this.#db;
|
|
167
175
|
if (this.#disabled || writer === void 0 || db === void 0) return;
|
|
168
|
-
const observer = this.#observer;
|
|
169
|
-
observer?.messageReceived(change, json);
|
|
170
176
|
const [type, msg] = change;
|
|
171
|
-
|
|
177
|
+
if (type === "begin") this.#validateTransaction = this.#isSelectedForShadowValidation(change[2].commitWatermark);
|
|
178
|
+
const validateTransaction = this.#validateTransaction;
|
|
179
|
+
const observer = this.#observer;
|
|
180
|
+
observer?.messageReceived(change, json, validateTransaction, storedChange);
|
|
181
|
+
const startedAt = validateTransaction ? performance.now() : void 0;
|
|
172
182
|
try {
|
|
173
183
|
let commit = null;
|
|
174
184
|
switch (type) {
|
|
175
185
|
case "begin":
|
|
176
|
-
writer.begin(change[2].commitWatermark, json);
|
|
186
|
+
writer.begin(change[2].commitWatermark, json, storedChange, validateTransaction);
|
|
177
187
|
break;
|
|
178
188
|
case "commit": {
|
|
179
189
|
const { watermark } = change[2];
|
|
180
190
|
const commitStart = performance.now();
|
|
181
191
|
commit = {
|
|
182
192
|
watermark,
|
|
183
|
-
stats: writer.commit(watermark, json, this.#now()),
|
|
193
|
+
stats: writer.commit(watermark, json, this.#now(), storedChange),
|
|
184
194
|
logCommitMs: performance.now() - commitStart
|
|
185
195
|
};
|
|
186
196
|
break;
|
|
@@ -189,14 +199,16 @@ var SQLiteChangeLogWriter = class {
|
|
|
189
199
|
writer.rollback();
|
|
190
200
|
break;
|
|
191
201
|
default:
|
|
192
|
-
writer.append(json, msg);
|
|
202
|
+
writer.append(json, msg, storedChange);
|
|
193
203
|
break;
|
|
194
204
|
}
|
|
195
|
-
observer?.messageProcessed(change, commit, performance.now() - startedAt);
|
|
205
|
+
observer?.messageProcessed(change, commit, startedAt === void 0 ? void 0 : performance.now() - startedAt);
|
|
196
206
|
if (commit !== null && commit.stats.cookieMutations.length > 0) observer?.cookiesMutated(commit.stats.cookieMutations, readCookieRowCounts(db));
|
|
197
207
|
if (commit !== null) this.#opts.onCommit?.(commit.watermark);
|
|
208
|
+
if (type === "commit" || type === "rollback") this.#validateTransaction = false;
|
|
198
209
|
} catch (e) {
|
|
199
|
-
observer?.messageFailed(change, e, performance.now() - startedAt);
|
|
210
|
+
observer?.messageFailed(change, e, startedAt === void 0 ? void 0 : performance.now() - startedAt);
|
|
211
|
+
this.#validateTransaction = false;
|
|
200
212
|
if (isConstraintViolation(e)) observer?.invariantFailure("SQLite change-log insert violated a constraint, which means a transaction above the resume watermark was not truncated", {
|
|
201
213
|
tag: msg.tag,
|
|
202
214
|
error: String(e)
|
|
@@ -204,12 +216,17 @@ var SQLiteChangeLogWriter = class {
|
|
|
204
216
|
this.#failSoft("writing to the SQLite change log", e);
|
|
205
217
|
}
|
|
206
218
|
}
|
|
219
|
+
#isSelectedForShadowValidation(watermark) {
|
|
220
|
+
const percent = this.#shadowValidationPercent;
|
|
221
|
+
return percent >= 100 || percent > 0 && h32(`${this.#opts.identity.generation}/${this.#opts.identity.replicaID ?? ""}:${watermark}`) % 100 < percent;
|
|
222
|
+
}
|
|
207
223
|
/**
|
|
208
224
|
* Discards the open transaction, if any. Called when the change stream is
|
|
209
225
|
* interrupted mid-transaction.
|
|
210
226
|
*/
|
|
211
227
|
abort() {
|
|
212
228
|
const writer = this.#writer;
|
|
229
|
+
this.#validateTransaction = false;
|
|
213
230
|
if (this.#disabled || writer === void 0) return;
|
|
214
231
|
this.#observer?.abort();
|
|
215
232
|
try {
|
|
@@ -220,6 +237,7 @@ var SQLiteChangeLogWriter = class {
|
|
|
220
237
|
}
|
|
221
238
|
close() {
|
|
222
239
|
this.#disabled = true;
|
|
240
|
+
this.#validateTransaction = false;
|
|
223
241
|
this.#writer = void 0;
|
|
224
242
|
this.#observer = void 0;
|
|
225
243
|
const db = this.#db;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sqlite-change-log-writer.js","names":["#lc","#opts","#now","#disabled","#db","#observer","#reconcile","#resumeFromLog","#writer","#failSoft"],"sources":["../../../../../../zero-cache/src/services/change-streamer/sqlite-change-log-writer.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {SqliteError} from '@rocicorp/zero-sqlite3';\nimport {must} from '../../../../shared/src/must.ts';\nimport type {Database} from '../../../../zqlite/src/db.ts';\nimport {\n isSQLiteCorruption,\n logSQLiteCorruptionDiagnostics,\n} from '../../db/sqlite-corruption.ts';\nimport {StatementRunner} from '../../db/statements.ts';\nimport type {ChangeStreamData} from '../change-source/protocol/current/downstream.ts';\nimport {\n readCookieRowCounts,\n readCookies,\n} from '../replicator/change-log-cookies.ts';\nimport {\n ChangeLogRebuildRequired,\n changeLogFileName,\n changeLogWipeReason,\n deleteChangeLogDB,\n openChangeLogDBForWriting,\n readChangeLogHead,\n rebuildChangeLogDBForWriting,\n reconcileChangeLog,\n type ChangeLogAnchor,\n type ChangeLogIdentity,\n type ChangeLogResumePoint,\n type ReconcileResult,\n} from '../replicator/change-log-db.ts';\nimport {ChangeLogStreamWriter} from '../replicator/change-log-stream-writer.ts';\nimport {\n getSQLiteChangeLogInfo,\n logSQLiteChangeLogStartup,\n recordSQLiteChangeLogReconcile,\n SQLiteChangeLogObserver,\n type ChangeLogCommit,\n type SQLiteChangeLogObservabilityState,\n} from '../replicator/sqlite-change-log-observability.ts';\n\nexport type SQLiteChangeLogWriterOptions = {\n /** The replica file the log is named after, i.e. `${replicaFile}-change-log`. */\n replicaFile: string;\n /** The replica whose contents this log belongs to. */\n identity: ChangeLogIdentity;\n /**\n * Called after each transaction's log commit, with the log's new head. This\n * is what releases the catchup barrier: after the writer moved in-process,\n * the head advances here rather than at a subscriber's ACK.\n */\n onCommit?: ((watermark: string) => void) | undefined;\n /**\n * Called when the writer disables itself and deletes the file. The reader is\n * cached on the service, so a delete that leaves it open would leave an\n * in-process reader serving an unlinked inode while every new open sees\n * nothing.\n */\n onDisabled?: (() => void) | undefined;\n /** Called when reconciliation replaces the file, to close cached readers. */\n onRebuilt?: (() => void) | undefined;\n /** Overridable for tests. */\n now?: (() => number) | undefined;\n};\n\n/**\n * Appends the canonical change stream to the SQLite change log, from the\n * change-streamer's own stream loop.\n *\n * ### Ordering\n *\n * The log's commit for a transaction precedes the forward of that transaction's\n * `commit` message, and nothing `await`s in between. Everything that can\n * advance the watermark the stream would resume from — the storer's Postgres\n * commit, `lastWatermark`, the upstream ACK — runs strictly after it, so the\n * log's head is always at or above the resume point. A *hole* is therefore\n * unreachable at any crash timing, and a *phantom* is the normal state, which is\n * what makes truncate-above the whole of reconciliation.\n *\n * ### Fail-soft\n *\n * The log is a catchup cache: nothing in it is not either already durable in the\n * replica's litestream backup or re-derivable from the replication slot. A write\n * failure must therefore not stop replication for the shard. Corruption is\n * rebuilt once at open; any other write error — a full disk, an I/O error, a\n * permissions problem — logs, disables the writer, deletes the file, closes the\n * reader, and lets the stream continue. The cost is catchup reach, and reach is\n * recoverable: `too-old` sends a subscriber to a restore.\n *\n * One carve-out keeps that from hiding the bug class this topology introduces. A\n * missed truncate-above surfaces as `SQLITE_CONSTRAINT` on the writer's plain\n * `INSERT`, which is \"any write error other than corruption\" and would be\n * absorbed quietly. It is counted as an invariant failure and alerted on before\n * failing soft.\n */\nexport class SQLiteChangeLogWriter {\n readonly #lc: LogContext;\n readonly #opts: SQLiteChangeLogWriterOptions;\n readonly #now: () => number;\n\n #db: Database | undefined;\n #writer: ChangeLogStreamWriter | undefined;\n #observer: SQLiteChangeLogObserver | undefined;\n #disabled = false;\n\n constructor(lc: LogContext, opts: SQLiteChangeLogWriterOptions) {\n this.#lc = lc.withContext('component', 'sqlite-change-log-writer');\n this.#opts = opts;\n this.#now = opts.now ?? Date.now;\n }\n\n /** False once the writer has failed soft, or after {@link close}. */\n get enabled(): boolean {\n return !this.#disabled;\n }\n\n /**\n * The writer's own connection, which is the one purge runs on (§3.3): one\n * process appends *and* deletes, on one handle, with no second writable\n * connection and no cross-process barrier. `undefined` until the stream\n * loop's first reconcile creates the log, and again once the writer has\n * failed soft and deleted the file — both of which a purge cycle treats as\n * \"skip\", not as an error.\n */\n get connection(): Database | undefined {\n return this.#db;\n }\n\n /** Exposed for tests and for the integration assertions on the metrics. */\n state(): SQLiteChangeLogObservabilityState | undefined {\n return this.#observer?.state();\n }\n\n /**\n * Opens the log if necessary and reconciles it with the Postgres resume\n * point. Returns the resume point stored in the log.\n *\n * Returns `undefined` when the writer is disabled. The caller must then use\n * another source.\n *\n * This runs for every connection because Postgres supplies a new resume point\n * after each reconnect. The log can contain transactions above that point.\n * Reconciliation removes them before Postgres sends them again.\n *\n * `resumeFrom` includes cookies because the cookies must match the resume\n * watermark.\n */\n reconcile(\n resumeFrom: ChangeLogResumePoint,\n ): ChangeLogResumePoint | undefined {\n return this.#reconcile(() => resumeFrom);\n }\n\n /**\n * Reconciles the log without a Postgres resume point.\n *\n * A valid log uses its own head and cookies. A new or invalid log uses the\n * replica values returned by `seed`.\n */\n reconcileFromLog(\n seed: () => ChangeLogResumePoint,\n ): ChangeLogResumePoint | undefined {\n return this.#reconcile(db => this.#resumeFromLog(db, seed));\n }\n\n #reconcile(\n resolve: (db: Database) => ChangeLogResumePoint,\n ): ChangeLogResumePoint | undefined {\n if (this.#disabled) {\n return undefined;\n }\n const {replicaFile, identity} = this.#opts;\n const nowMs = this.#now();\n const anchor = (db: Database): ChangeLogAnchor => ({\n ...resolve(db),\n identity,\n nowMs,\n });\n try {\n const db = this.#db;\n if (db === undefined) {\n const opened = openChangeLogDBForWriting(this.#lc, replicaFile, anchor);\n this.#db = opened.db;\n if (opened.replacedFile) {\n this.#opts.onRebuilt?.();\n }\n recordSQLiteChangeLogReconcile(this.#lc, opened.result);\n const info = getSQLiteChangeLogInfo(opened.db);\n logSQLiteChangeLogStartup(\n this.#lc,\n changeLogFileName(replicaFile),\n info,\n );\n this.#observer = new SQLiteChangeLogObserver(this.#lc, info);\n } else {\n const resolved = anchor(db);\n let result: ReconcileResult;\n try {\n result = reconcileChangeLog(this.#lc, db, resolved, {\n rebuildInsteadOfUnboundedWork: true,\n });\n } catch (e) {\n if (!(e instanceof ChangeLogRebuildRequired)) {\n throw e;\n }\n // Close every handle to the old inode before unlinking it. The writer\n // is reconstructed below against the replacement connection.\n this.#writer = undefined;\n this.#db = undefined;\n db.close();\n this.#opts.onRebuilt?.();\n const rebuilt = rebuildChangeLogDBForWriting(\n this.#lc,\n replicaFile,\n resolved,\n e,\n );\n this.#db = rebuilt.db;\n result = rebuilt.result;\n }\n recordSQLiteChangeLogReconcile(this.#lc, result);\n if (result.action !== 'none') {\n this.#observer?.reconciled(\n getSQLiteChangeLogInfo(\n must(this.#db, 'the SQLite change log is not open'),\n ),\n );\n }\n }\n // A reseed drops and recreates the stream table, so the append statements\n // are prepared fresh against whatever the reconciliation left behind.\n const reconciledDB = must(this.#db, 'the SQLite change log is not open');\n this.#writer = new ChangeLogStreamWriter(\n new StatementRunner(reconciledDB),\n );\n // Read both values after reconciliation. A truncate or reseed updates the\n // head and cookies in the same transaction.\n return {\n resumeWatermark: must(\n readChangeLogHead(reconciledDB),\n 'the SQLite change log has no head after reconciliation',\n ),\n cookies: readCookies(reconciledDB),\n };\n } catch (e) {\n this.#failSoft('reconciling the SQLite change log', e);\n return undefined;\n }\n }\n\n /**\n * Returns the resume point supplied by the log.\n *\n * A valid log uses its own head and cookies. A log that must be recreated uses\n * the replica values returned by `seed`.\n */\n #resumeFromLog(\n db: Database,\n seed: () => ChangeLogResumePoint,\n ): ChangeLogResumePoint {\n if (changeLogWipeReason(db, this.#opts.identity) !== undefined) {\n return seed();\n }\n const head = readChangeLogHead(db);\n // An empty log has no resume point, so use the replica seed.\n return head === null\n ? seed()\n : {resumeWatermark: head, cookies: readCookies(db)};\n }\n\n /**\n * Writes one stream message, committing at transaction boundaries. Never\n * throws: a write failure disables the writer instead of failing the stream.\n */\n write(change: ChangeStreamData, json: string): void {\n const writer = this.#writer;\n const db = this.#db;\n if (this.#disabled || writer === undefined || db === undefined) {\n return;\n }\n const observer = this.#observer;\n observer?.messageReceived(change, json);\n const [type, msg] = change;\n const startedAt = performance.now();\n try {\n let commit: ChangeLogCommit | null = null;\n switch (type) {\n case 'begin':\n writer.begin(change[2].commitWatermark, json);\n break;\n case 'commit': {\n const {watermark} = change[2];\n const commitStart = performance.now();\n const stats = writer.commit(watermark, json, this.#now());\n commit = {\n watermark,\n stats,\n logCommitMs: performance.now() - commitStart,\n };\n break;\n }\n case 'rollback':\n writer.rollback();\n break;\n default:\n writer.append(json, msg);\n break;\n }\n observer?.messageProcessed(change, commit, performance.now() - startedAt);\n if (commit !== null && commit.stats.cookieMutations.length > 0) {\n // Only re-counted when a schema change actually moved the cookie jar,\n // which keeps the count off the forward path of every other\n // transaction. The counts are read after the commit, so they are what\n // a reader of the file would see.\n observer?.cookiesMutated(\n commit.stats.cookieMutations,\n readCookieRowCounts(db),\n );\n }\n if (commit !== null) {\n // The head advanced, and it is durable. Releasing the barrier here is\n // what makes its poll interval a backstop rather than the mechanism.\n this.#opts.onCommit?.(commit.watermark);\n }\n } catch (e) {\n observer?.messageFailed(change, e, performance.now() - startedAt);\n if (isConstraintViolation(e)) {\n // Reconciliation should have truncated whatever this collided with.\n // Report it as an invariant failure before failing soft, so that a\n // truncate-above bug cannot look like a lost cache.\n observer?.invariantFailure(\n 'SQLite change-log insert violated a constraint, which means a ' +\n 'transaction above the resume watermark was not truncated',\n {tag: msg.tag, error: String(e)},\n );\n }\n this.#failSoft('writing to the SQLite change log', e);\n }\n }\n\n /**\n * Discards the open transaction, if any. Called when the change stream is\n * interrupted mid-transaction.\n */\n abort(): void {\n const writer = this.#writer;\n if (this.#disabled || writer === undefined) {\n return;\n }\n this.#observer?.abort();\n try {\n writer.rollback();\n } catch (e) {\n this.#failSoft('rolling back the SQLite change log', e);\n }\n }\n\n close(): void {\n this.#disabled = true;\n this.#writer = undefined;\n this.#observer = undefined;\n const db = this.#db;\n this.#db = undefined;\n try {\n db?.close();\n } catch (e) {\n this.#lc.warn?.('error closing the SQLite change log', e);\n }\n }\n\n /**\n * Logs, disables the writer, deletes the file, and closes the reader, leaving\n * replication running. Disabling is for the life of the process: a log that\n * failed a write is not re-opened until the task restarts, so the behavior a\n * subscriber sees is the same as `sqliteChangeLogMode=off`.\n */\n #failSoft(what: string, e: unknown): void {\n const file = changeLogFileName(this.#opts.replicaFile);\n if (isSQLiteCorruption(e)) {\n // Open-time corruption is rebuilt by openChangeLogDBForWriting. Reaching\n // here means the file went bad under an open handle, which the same\n // delete-and-reseed answers -- on the next process start rather than now.\n logSQLiteCorruptionDiagnostics(this.#lc, 'change-log', file, e);\n }\n this.#lc.error?.(\n `error ${what}: disabling the writer and deleting ${file}. ` +\n `Replication continues; catchup reach is lost until this task restarts.`,\n e,\n );\n this.close();\n try {\n deleteChangeLogDB(this.#opts.replicaFile);\n } catch (deleteError) {\n this.#lc.error?.(`unable to delete ${file}`, deleteError);\n }\n this.#opts.onDisabled?.();\n }\n}\n\nfunction isConstraintViolation(e: unknown): boolean {\n return e instanceof SqliteError && e.code.startsWith('SQLITE_CONSTRAINT');\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sqlite-change-log-writer.js","names":["#lc","#opts","#now","#shadowValidationPercent","#disabled","#db","#observer","#reconcile","#resumeFromLog","#writer","#failSoft","#validateTransaction","#isSelectedForShadowValidation"],"sources":["../../../../../../zero-cache/src/services/change-streamer/sqlite-change-log-writer.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {SqliteError} from '@rocicorp/zero-sqlite3';\nimport {assert} from '../../../../shared/src/asserts.ts';\nimport {h32} from '../../../../shared/src/hash.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport type {Database} from '../../../../zqlite/src/db.ts';\nimport {\n isSQLiteCorruption,\n logSQLiteCorruptionDiagnostics,\n} from '../../db/sqlite-corruption.ts';\nimport {StatementRunner} from '../../db/statements.ts';\nimport type {ChangeStreamData} from '../change-source/protocol/current/downstream.ts';\nimport {\n readCookieRowCounts,\n readCookies,\n} from '../replicator/change-log-cookies.ts';\nimport {\n ChangeLogRebuildRequired,\n changeLogFileName,\n changeLogWipeReason,\n deleteChangeLogDB,\n openChangeLogDBForWriting,\n readChangeLogHead,\n rebuildChangeLogDBForWriting,\n reconcileChangeLog,\n type ChangeLogAnchor,\n type ChangeLogIdentity,\n type ChangeLogResumePoint,\n type ReconcileResult,\n} from '../replicator/change-log-db.ts';\nimport {ChangeLogStreamWriter} from '../replicator/change-log-stream-writer.ts';\nimport {\n getSQLiteChangeLogInfo,\n logSQLiteChangeLogStartup,\n recordSQLiteChangeLogReconcile,\n SQLiteChangeLogObserver,\n type ChangeLogCommit,\n type SQLiteChangeLogObservabilityState,\n} from '../replicator/sqlite-change-log-observability.ts';\nimport {extractChangeSubstring} from './change-log-codec.ts';\n\nexport type SQLiteChangeLogWriterOptions = {\n /** The replica file the log is named after, i.e. `${replicaFile}-change-log`. */\n replicaFile: string;\n /** The replica whose contents this log belongs to. */\n identity: ChangeLogIdentity;\n /**\n * Called after each transaction's log commit, with the log's new head. This\n * is what releases the catchup barrier: after the writer moved in-process,\n * the head advances here rather than at a subscriber's ACK.\n */\n onCommit?: ((watermark: string) => void) | undefined;\n /**\n * Called when the writer disables itself and deletes the file. The reader is\n * cached on the service, so a delete that leaves it open would leave an\n * in-process reader serving an unlinked inode while every new open sees\n * nothing.\n */\n onDisabled?: (() => void) | undefined;\n /** Called when reconciliation replaces the file, to close cached readers. */\n onRebuilt?: (() => void) | undefined;\n /** Overridable for tests. */\n now?: (() => number) | undefined;\n /**\n * Percentage of transactions that retain the rollout-only per-message\n * timing and source-vs-stored hash validation. Defaults to 1.\n */\n shadowValidationPercent?: number | undefined;\n};\n\nconst DEFAULT_SHADOW_VALIDATION_PERCENT = 1;\n\n/**\n * Appends the canonical change stream to the SQLite change log, from the\n * change-streamer's own stream loop.\n *\n * ### Ordering\n *\n * The log's commit for a transaction precedes the forward of that transaction's\n * `commit` message, and nothing `await`s in between. Everything that can\n * advance the watermark the stream would resume from — the storer's Postgres\n * commit, `lastWatermark`, the upstream ACK — runs strictly after it, so the\n * log's head is always at or above the resume point. A *hole* is therefore\n * unreachable at any crash timing, and a *phantom* is the normal state, which is\n * what makes truncate-above the whole of reconciliation.\n *\n * ### Fail-soft\n *\n * The log is a catchup cache: nothing in it is not either already durable in the\n * replica's litestream backup or re-derivable from the replication slot. A write\n * failure must therefore not stop replication for the shard. Corruption is\n * rebuilt once at open; any other write error — a full disk, an I/O error, a\n * permissions problem — logs, disables the writer, deletes the file, closes the\n * reader, and lets the stream continue. The cost is catchup reach, and reach is\n * recoverable: `too-old` sends a subscriber to a restore.\n *\n * One carve-out keeps that from hiding the bug class this topology introduces. A\n * missed truncate-above surfaces as `SQLITE_CONSTRAINT` on the writer's plain\n * `INSERT`, which is \"any write error other than corruption\" and would be\n * absorbed quietly. It is counted as an invariant failure and alerted on before\n * failing soft.\n */\nexport class SQLiteChangeLogWriter {\n readonly #lc: LogContext;\n readonly #opts: SQLiteChangeLogWriterOptions;\n readonly #now: () => number;\n readonly #shadowValidationPercent: number;\n\n #db: Database | undefined;\n #writer: ChangeLogStreamWriter | undefined;\n #observer: SQLiteChangeLogObserver | undefined;\n #disabled = false;\n #validateTransaction = false;\n\n constructor(lc: LogContext, opts: SQLiteChangeLogWriterOptions) {\n this.#lc = lc.withContext('component', 'sqlite-change-log-writer');\n this.#opts = opts;\n this.#now = opts.now ?? Date.now;\n this.#shadowValidationPercent =\n opts.shadowValidationPercent ?? DEFAULT_SHADOW_VALIDATION_PERCENT;\n assert(\n Number.isInteger(this.#shadowValidationPercent) &&\n this.#shadowValidationPercent >= 0 &&\n this.#shadowValidationPercent <= 100,\n 'SQLite change-log shadow validation percentage must be an integer between 0 and 100',\n );\n }\n\n /** False once the writer has failed soft, or after {@link close}. */\n get enabled(): boolean {\n return !this.#disabled;\n }\n\n /**\n * The writer's own connection, which is the one purge runs on (§3.3): one\n * process appends *and* deletes, on one handle, with no second writable\n * connection and no cross-process barrier. `undefined` until the stream\n * loop's first reconcile creates the log, and again once the writer has\n * failed soft and deleted the file — both of which a purge cycle treats as\n * \"skip\", not as an error.\n */\n get connection(): Database | undefined {\n return this.#db;\n }\n\n /** Exposed for tests and for the integration assertions on the metrics. */\n state(): SQLiteChangeLogObservabilityState | undefined {\n return this.#observer?.state();\n }\n\n /**\n * Opens the log if necessary and reconciles it with the Postgres resume\n * point. Returns the resume point stored in the log.\n *\n * Returns `undefined` when the writer is disabled. The caller must then use\n * another source.\n *\n * This runs for every connection because Postgres supplies a new resume point\n * after each reconnect. The log can contain transactions above that point.\n * Reconciliation removes them before Postgres sends them again.\n *\n * `resumeFrom` includes cookies because the cookies must match the resume\n * watermark.\n */\n reconcile(\n resumeFrom: ChangeLogResumePoint,\n ): ChangeLogResumePoint | undefined {\n return this.#reconcile(() => resumeFrom);\n }\n\n /**\n * Reconciles the log without a Postgres resume point.\n *\n * A valid log uses its own head and cookies. A new or invalid log uses the\n * replica values returned by `seed`.\n */\n reconcileFromLog(\n seed: () => ChangeLogResumePoint,\n ): ChangeLogResumePoint | undefined {\n return this.#reconcile(db => this.#resumeFromLog(db, seed));\n }\n\n #reconcile(\n resolve: (db: Database) => ChangeLogResumePoint,\n ): ChangeLogResumePoint | undefined {\n if (this.#disabled) {\n return undefined;\n }\n const {replicaFile, identity} = this.#opts;\n const nowMs = this.#now();\n const anchor = (db: Database): ChangeLogAnchor => ({\n ...resolve(db),\n identity,\n nowMs,\n });\n try {\n const db = this.#db;\n if (db === undefined) {\n const opened = openChangeLogDBForWriting(this.#lc, replicaFile, anchor);\n this.#db = opened.db;\n if (opened.replacedFile) {\n this.#opts.onRebuilt?.();\n }\n recordSQLiteChangeLogReconcile(this.#lc, opened.result);\n const info = getSQLiteChangeLogInfo(opened.db);\n logSQLiteChangeLogStartup(\n this.#lc,\n changeLogFileName(replicaFile),\n info,\n );\n this.#observer = new SQLiteChangeLogObserver(this.#lc, info);\n } else {\n const resolved = anchor(db);\n let result: ReconcileResult;\n try {\n result = reconcileChangeLog(this.#lc, db, resolved, {\n rebuildInsteadOfUnboundedWork: true,\n });\n } catch (e) {\n if (!(e instanceof ChangeLogRebuildRequired)) {\n throw e;\n }\n // Close every handle to the old inode before unlinking it. The writer\n // is reconstructed below against the replacement connection.\n this.#writer = undefined;\n this.#db = undefined;\n db.close();\n this.#opts.onRebuilt?.();\n const rebuilt = rebuildChangeLogDBForWriting(\n this.#lc,\n replicaFile,\n resolved,\n e,\n );\n this.#db = rebuilt.db;\n result = rebuilt.result;\n }\n recordSQLiteChangeLogReconcile(this.#lc, result);\n if (result.action !== 'none') {\n this.#observer?.reconciled(\n getSQLiteChangeLogInfo(\n must(this.#db, 'the SQLite change log is not open'),\n ),\n );\n }\n }\n // A reseed drops and recreates the stream table, so the append statements\n // are prepared fresh against whatever the reconciliation left behind.\n const reconciledDB = must(this.#db, 'the SQLite change log is not open');\n this.#writer = new ChangeLogStreamWriter(\n new StatementRunner(reconciledDB),\n );\n // Read both values after reconciliation. A truncate or reseed updates the\n // head and cookies in the same transaction.\n return {\n resumeWatermark: must(\n readChangeLogHead(reconciledDB),\n 'the SQLite change log has no head after reconciliation',\n ),\n cookies: readCookies(reconciledDB),\n };\n } catch (e) {\n this.#failSoft('reconciling the SQLite change log', e);\n return undefined;\n }\n }\n\n /**\n * Returns the resume point supplied by the log.\n *\n * A valid log uses its own head and cookies. A log that must be recreated uses\n * the replica values returned by `seed`.\n */\n #resumeFromLog(\n db: Database,\n seed: () => ChangeLogResumePoint,\n ): ChangeLogResumePoint {\n if (changeLogWipeReason(db, this.#opts.identity) !== undefined) {\n return seed();\n }\n const head = readChangeLogHead(db);\n // An empty log has no resume point, so use the replica seed.\n return head === null\n ? seed()\n : {resumeWatermark: head, cookies: readCookies(db)};\n }\n\n /**\n * Writes one stream message, committing at transaction boundaries. Never\n * throws: a write failure disables the writer instead of failing the stream.\n */\n write(\n change: ChangeStreamData,\n json: string,\n storedChange = extractChangeSubstring(json, change[1].tag),\n ): void {\n const writer = this.#writer;\n const db = this.#db;\n if (this.#disabled || writer === undefined || db === undefined) {\n return;\n }\n const [type, msg] = change;\n if (type === 'begin') {\n this.#validateTransaction = this.#isSelectedForShadowValidation(\n change[2].commitWatermark,\n );\n }\n const validateTransaction = this.#validateTransaction;\n const observer = this.#observer;\n observer?.messageReceived(change, json, validateTransaction, storedChange);\n const startedAt = validateTransaction ? performance.now() : undefined;\n try {\n let commit: ChangeLogCommit | null = null;\n switch (type) {\n case 'begin':\n writer.begin(\n change[2].commitWatermark,\n json,\n storedChange,\n validateTransaction,\n );\n break;\n case 'commit': {\n const {watermark} = change[2];\n const commitStart = performance.now();\n const stats = writer.commit(\n watermark,\n json,\n this.#now(),\n storedChange,\n );\n commit = {\n watermark,\n stats,\n logCommitMs: performance.now() - commitStart,\n };\n break;\n }\n case 'rollback':\n writer.rollback();\n break;\n default:\n writer.append(json, msg, storedChange);\n break;\n }\n observer?.messageProcessed(\n change,\n commit,\n startedAt === undefined ? undefined : performance.now() - startedAt,\n );\n if (commit !== null && commit.stats.cookieMutations.length > 0) {\n // Only re-counted when a schema change actually moved the cookie jar,\n // which keeps the count off the forward path of every other\n // transaction. The counts are read after the commit, so they are what\n // a reader of the file would see.\n observer?.cookiesMutated(\n commit.stats.cookieMutations,\n readCookieRowCounts(db),\n );\n }\n if (commit !== null) {\n // The head advanced, and it is durable. Releasing the barrier here is\n // what makes its poll interval a backstop rather than the mechanism.\n this.#opts.onCommit?.(commit.watermark);\n }\n if (type === 'commit' || type === 'rollback') {\n this.#validateTransaction = false;\n }\n } catch (e) {\n observer?.messageFailed(\n change,\n e,\n startedAt === undefined ? undefined : performance.now() - startedAt,\n );\n this.#validateTransaction = false;\n if (isConstraintViolation(e)) {\n // Reconciliation should have truncated whatever this collided with.\n // Report it as an invariant failure before failing soft, so that a\n // truncate-above bug cannot look like a lost cache.\n observer?.invariantFailure(\n 'SQLite change-log insert violated a constraint, which means a ' +\n 'transaction above the resume watermark was not truncated',\n {tag: msg.tag, error: String(e)},\n );\n }\n this.#failSoft('writing to the SQLite change log', e);\n }\n }\n\n #isSelectedForShadowValidation(watermark: string): boolean {\n const percent = this.#shadowValidationPercent;\n return (\n percent >= 100 ||\n (percent > 0 &&\n h32(\n `${this.#opts.identity.generation}/${this.#opts.identity.replicaID ?? ''}:${watermark}`,\n ) %\n 100 <\n percent)\n );\n }\n\n /**\n * Discards the open transaction, if any. Called when the change stream is\n * interrupted mid-transaction.\n */\n abort(): void {\n const writer = this.#writer;\n this.#validateTransaction = false;\n if (this.#disabled || writer === undefined) {\n return;\n }\n this.#observer?.abort();\n try {\n writer.rollback();\n } catch (e) {\n this.#failSoft('rolling back the SQLite change log', e);\n }\n }\n\n close(): void {\n this.#disabled = true;\n this.#validateTransaction = false;\n this.#writer = undefined;\n this.#observer = undefined;\n const db = this.#db;\n this.#db = undefined;\n try {\n db?.close();\n } catch (e) {\n this.#lc.warn?.('error closing the SQLite change log', e);\n }\n }\n\n /**\n * Logs, disables the writer, deletes the file, and closes the reader, leaving\n * replication running. Disabling is for the life of the process: a log that\n * failed a write is not re-opened until the task restarts, so the behavior a\n * subscriber sees is the same as `sqliteChangeLogMode=off`.\n */\n #failSoft(what: string, e: unknown): void {\n const file = changeLogFileName(this.#opts.replicaFile);\n if (isSQLiteCorruption(e)) {\n // Open-time corruption is rebuilt by openChangeLogDBForWriting. Reaching\n // here means the file went bad under an open handle, which the same\n // delete-and-reseed answers -- on the next process start rather than now.\n logSQLiteCorruptionDiagnostics(this.#lc, 'change-log', file, e);\n }\n this.#lc.error?.(\n `error ${what}: disabling the writer and deleting ${file}. ` +\n `Replication continues; catchup reach is lost until this task restarts.`,\n e,\n );\n this.close();\n try {\n deleteChangeLogDB(this.#opts.replicaFile);\n } catch (deleteError) {\n this.#lc.error?.(`unable to delete ${file}`, deleteError);\n }\n this.#opts.onDisabled?.();\n }\n}\n\nfunction isConstraintViolation(e: unknown): boolean {\n return e instanceof SqliteError && e.code.startsWith('SQLITE_CONSTRAINT');\n}\n"],"mappings":"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"}
|
|
@@ -9,13 +9,27 @@ import type { UpstreamStatusMessage } from '../change-source/protocol/current/st
|
|
|
9
9
|
import { type CookieSet } from '../replicator/change-log-cookies.ts';
|
|
10
10
|
import type { ReplicatorMode } from '../replicator/replicator.ts';
|
|
11
11
|
import type { Service } from '../service.ts';
|
|
12
|
-
import { type ChangeLogEntry } from './change-log-codec.ts';
|
|
12
|
+
import { type ChangeLogEntry, type SerializedChangeStreamData } from './change-log-codec.ts';
|
|
13
|
+
import { type ChangeLogReinitialization } from './schema/tables.ts';
|
|
13
14
|
import type { Subscriber } from './subscriber.ts';
|
|
14
15
|
/**
|
|
15
16
|
* Factory for creating dynamic connection pools used by the Storer to
|
|
16
17
|
* isolate concurrent transactions into separate pg clients.
|
|
17
18
|
*/
|
|
18
19
|
export type PostgresDBProvider = (applicationName: string, maxConns: number) => PostgresDB;
|
|
20
|
+
export type OwnershipTakeover = {
|
|
21
|
+
/**
|
|
22
|
+
* The lock that prevents the previous owner from purging the change log
|
|
23
|
+
* (from which this change-streamer's replica was restored), released once
|
|
24
|
+
* ownership is assumed.
|
|
25
|
+
*/
|
|
26
|
+
purgeLock: PurgeLock | null;
|
|
27
|
+
/**
|
|
28
|
+
* Requests a restart of the change stream (at a transaction boundary),
|
|
29
|
+
* which is used to start pending backfills once ownership is assumed.
|
|
30
|
+
*/
|
|
31
|
+
requestRestart: (reason: string) => void;
|
|
32
|
+
};
|
|
19
33
|
export type TuningOptions = {
|
|
20
34
|
backPressureLimitHeapProportion: number;
|
|
21
35
|
statementTimeoutMs: number;
|
|
@@ -56,7 +70,65 @@ export declare class Storer implements Service {
|
|
|
56
70
|
#private;
|
|
57
71
|
readonly id = "storer";
|
|
58
72
|
constructor(lc: LogContext, shard: ShardID, taskID: string, discoveryAddress: string, discoveryProtocol: string, dbProvider: PostgresDBProvider, replicaVersion: string, onCommitted: (c: Commit | UpstreamStatusMessage) => void, onFatal: (err: Error) => void, { backPressureLimitHeapProportion, statementTimeoutMs, changeLogBatchSize, drainTimeoutMs, }: TuningOptions);
|
|
59
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Re-initializes a change log that is no longer maintained from the
|
|
75
|
+
* replica's state, taking ownership of it in the process (which is then
|
|
76
|
+
* assumed again at its new head, see {@link assumeOwnershipAtHead}).
|
|
77
|
+
* See {@link reinitializeChangeLog}.
|
|
78
|
+
*/
|
|
79
|
+
reinitializeFromReplica(params: Omit<ChangeLogReinitialization, 'owner' | 'ownerAddress'>): Promise<'reinitialized' | 'maintained'>;
|
|
80
|
+
/**
|
|
81
|
+
* Prepares to assume ownership of the change log at its head, while it may
|
|
82
|
+
* still be owned and maintained by another change-streamer. This allows the
|
|
83
|
+
* previous owner to continue to serve subscribers while this change-source's
|
|
84
|
+
* upstream decodes the WAL to catch up to the head of the change log, which
|
|
85
|
+
* may be many minutes worth of transactions for large DBs.
|
|
86
|
+
*
|
|
87
|
+
* Once the change stream is started from the head of the change log:
|
|
88
|
+
*
|
|
89
|
+
* * Transactions that the change log already contains (i.e. stored by the
|
|
90
|
+
* previous owner) are not stored again, but are otherwise processed
|
|
91
|
+
* normally (e.g. for upstream acks, since they have been stored).
|
|
92
|
+
* * Ownership is assumed in the transaction that stores the first
|
|
93
|
+
* transaction past the head of the change log. The previous owner's
|
|
94
|
+
* (subsequent) transactions fail its ownership check, which makes this
|
|
95
|
+
* transaction the one immediately after the previous owner's last one.
|
|
96
|
+
* * Ownership is also assumed upon a {@link status} at or past the head of
|
|
97
|
+
* the change log (outside of a transaction), which covers an idle
|
|
98
|
+
* upstream: all transactions up to the status position have been
|
|
99
|
+
* received, and any past the head would have been stored.
|
|
100
|
+
*
|
|
101
|
+
* Subscribers are caught up from the change log as usual, as the stream
|
|
102
|
+
* (which is forwarded to them) starts from its head.
|
|
103
|
+
*
|
|
104
|
+
* Backfill transactions are synthesized by each change-streamer's change
|
|
105
|
+
* source, and thus never correspond to those stored by the previous owner.
|
|
106
|
+
* Until ownership is assumed, they are not stored, and no backfills are
|
|
107
|
+
* requested from the change log (see
|
|
108
|
+
* {@link getStartStreamInitializationParameters}). Once ownership is
|
|
109
|
+
* assumed, a restart of the change stream is requested if the change log has
|
|
110
|
+
* pending backfills or if a backfill transaction was skipped.
|
|
111
|
+
*/
|
|
112
|
+
assumeOwnershipAtHead(takeover: OwnershipTakeover): void;
|
|
113
|
+
/**
|
|
114
|
+
* Whether ownership of the change log is pending, i.e. after
|
|
115
|
+
* {@link assumeOwnershipAtHead} and before ownership is assumed.
|
|
116
|
+
*/
|
|
117
|
+
get ownershipPending(): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Relays a status message received outside of a transaction, which is
|
|
120
|
+
* used to assume ownership of the change log on an idle upstream. A no-op
|
|
121
|
+
* unless ownership is pending.
|
|
122
|
+
*/
|
|
123
|
+
status(watermark: string): void;
|
|
124
|
+
/**
|
|
125
|
+
* Assumes ownership of the change log immediately, regardless of its head.
|
|
126
|
+
* This is used for in tests.
|
|
127
|
+
*
|
|
128
|
+
* A production change-streamer instead takes over the change log at its head
|
|
129
|
+
* (see {@link assumeOwnershipAtHead}).
|
|
130
|
+
*/
|
|
131
|
+
assumeOwnership(): Promise<void>;
|
|
60
132
|
/**
|
|
61
133
|
* The whole of what a stream connection starts from: where to resume, what to
|
|
62
134
|
* ask the change source to backfill, and the raw cookie set those requests
|
|
@@ -106,7 +178,7 @@ export declare class Storer implements Service {
|
|
|
106
178
|
/**
|
|
107
179
|
* @returns The JSON stringified stream message to be sent downstream.
|
|
108
180
|
*/
|
|
109
|
-
store(watermark: string, data: ChangeStreamData): string;
|
|
181
|
+
store(watermark: string, data: ChangeStreamData, serialized?: SerializedChangeStreamData): string;
|
|
110
182
|
abort(): void;
|
|
111
183
|
catchup(subscriber: Subscriber, mode: ReplicatorMode): void;
|
|
112
184
|
readyForMore(): Promise<void> | undefined;
|
|
@@ -131,13 +203,32 @@ export declare class PurgeLock {
|
|
|
131
203
|
#private;
|
|
132
204
|
readonly replicaVersion: string;
|
|
133
205
|
readonly minWatermark: string;
|
|
134
|
-
|
|
206
|
+
/**
|
|
207
|
+
* The head of the change log (i.e. its `lastWatermark`) when the lock was
|
|
208
|
+
* acquired. The change log is resumed from its head, which only advances,
|
|
209
|
+
* so a stream cannot (correctly) be started from before it.
|
|
210
|
+
*/
|
|
211
|
+
readonly headWatermark: string;
|
|
212
|
+
constructor(lc: LogContext, tx: TransactionPool, replicaVersion: string, watermark: string, headWatermark: string);
|
|
135
213
|
release(): Promise<void>;
|
|
136
214
|
}
|
|
137
215
|
export declare class PurgeLocker {
|
|
138
216
|
#private;
|
|
139
217
|
constructor(lc: LogContext, shard: ShardID, db: PostgresDB);
|
|
218
|
+
/**
|
|
219
|
+
* Locks the oldest row of the change log, preventing it from being purged.
|
|
220
|
+
*
|
|
221
|
+
* @param slotWatermark The position of the replication slot from which the
|
|
222
|
+
* change log is to be resumed (as a watermark). If specified and the
|
|
223
|
+
* head of the change log is behind it, the change log may be missing
|
|
224
|
+
* transactions that the slot will not stream, in which case nothing is
|
|
225
|
+
* locked and `'behind-slot'` is returned. Conversely, a head at or past
|
|
226
|
+
* the slot's position means that the stream (which resumes from the
|
|
227
|
+
* head) will not skip anything.
|
|
228
|
+
* @returns `null` if the change log is empty.
|
|
229
|
+
*/
|
|
140
230
|
acquire(): Promise<PurgeLock | null>;
|
|
231
|
+
acquire(slotWatermark?: string | undefined): Promise<PurgeLock | null | 'behind-slot'>;
|
|
141
232
|
}
|
|
142
233
|
type TaskKey = JSONObject;
|
|
143
234
|
type TaskDoneFn = () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/change-streamer/storer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAKjD,OAAO,EAEL,KAAK,UAAU,EAChB,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"storer.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/change-streamer/storer.ts"],"names":[],"mappings":"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"}
|