@rocicorp/zero 1.11.0-canary.4 → 1.11.0-canary.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/analyze-query/src/analyze-cli.js +4 -4
- package/out/analyze-query/src/analyze-cli.js.map +1 -1
- package/out/analyze-query/src/bin-analyze.js +13 -12
- package/out/analyze-query/src/bin-analyze.js.map +1 -1
- package/out/analyze-query/src/bin-transform.js +1 -1
- package/out/analyze-query/src/bin-transform.js.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.d.ts +8 -1
- package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.js +25 -25
- package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
- package/out/otel/src/log-options.d.ts +16 -0
- package/out/otel/src/log-options.d.ts.map +1 -1
- package/out/otel/src/log-options.js +60 -6
- package/out/otel/src/log-options.js.map +1 -1
- package/out/replicache/src/bg-interval.d.ts +2 -1
- package/out/replicache/src/bg-interval.d.ts.map +1 -1
- package/out/replicache/src/bg-interval.js +13 -4
- package/out/replicache/src/bg-interval.js.map +1 -1
- package/out/replicache/src/btree/node.d.ts.map +1 -1
- package/out/replicache/src/btree/node.js +3 -6
- package/out/replicache/src/btree/node.js.map +1 -1
- package/out/replicache/src/dag/gc.d.ts.map +1 -1
- package/out/replicache/src/dag/gc.js +8 -11
- package/out/replicache/src/dag/gc.js.map +1 -1
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
- package/out/replicache/src/dag/lazy-store.d.ts +17 -4
- package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
- package/out/replicache/src/dag/lazy-store.js +35 -9
- package/out/replicache/src/dag/lazy-store.js.map +1 -1
- package/out/replicache/src/dag/store-impl.d.ts +12 -2
- package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
- package/out/replicache/src/dag/store-impl.js +29 -9
- package/out/replicache/src/dag/store-impl.js.map +1 -1
- package/out/replicache/src/db/rebase.d.ts +14 -2
- package/out/replicache/src/db/rebase.d.ts.map +1 -1
- package/out/replicache/src/db/rebase.js +27 -5
- package/out/replicache/src/db/rebase.js.map +1 -1
- package/out/replicache/src/get-kv-store-provider.d.ts +1 -1
- package/out/replicache/src/get-kv-store-provider.d.ts.map +1 -1
- package/out/replicache/src/get-kv-store-provider.js +4 -4
- package/out/replicache/src/get-kv-store-provider.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js +28 -5
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/idb-store.d.ts +18 -0
- package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
- package/out/replicache/src/kv/idb-store.js +30 -2
- package/out/replicache/src/kv/idb-store.js.map +1 -1
- package/out/replicache/src/kv/mem-fallback-store.d.ts +54 -0
- package/out/replicache/src/kv/mem-fallback-store.d.ts.map +1 -0
- package/out/replicache/src/kv/mem-fallback-store.js +177 -0
- package/out/replicache/src/kv/mem-fallback-store.js.map +1 -0
- package/out/replicache/src/kv/mem-store.d.ts +1 -0
- package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
- package/out/replicache/src/kv/mem-store.js +3 -0
- package/out/replicache/src/kv/mem-store.js.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.js +4 -4
- package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts +22 -1
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +159 -14
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/kv/store.d.ts +6 -0
- package/out/replicache/src/kv/store.d.ts.map +1 -1
- package/out/replicache/src/new-client-channel.js.map +1 -1
- package/out/replicache/src/persist/client-gc.d.ts +2 -1
- package/out/replicache/src/persist/client-gc.d.ts.map +1 -1
- package/out/replicache/src/persist/client-gc.js +2 -2
- package/out/replicache/src/persist/client-gc.js.map +1 -1
- package/out/replicache/src/persist/client-group-gc.d.ts +2 -1
- package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
- package/out/replicache/src/persist/client-group-gc.js +2 -2
- package/out/replicache/src/persist/client-group-gc.js.map +1 -1
- package/out/replicache/src/persist/clients.d.ts +2 -2
- package/out/replicache/src/persist/collect-idb-databases.d.ts +28 -8
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.js +97 -20
- package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
- package/out/replicache/src/persist/heartbeat.d.ts +2 -1
- package/out/replicache/src/persist/heartbeat.d.ts.map +1 -1
- package/out/replicache/src/persist/heartbeat.js +2 -2
- package/out/replicache/src/persist/heartbeat.js.map +1 -1
- package/out/replicache/src/persist/idb-databases-store-db-name.js +1 -1
- package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
- package/out/replicache/src/persist/persist.d.ts.map +1 -1
- package/out/replicache/src/persist/persist.js +18 -8
- package/out/replicache/src/persist/persist.js.map +1 -1
- package/out/replicache/src/persist/refresh.js +6 -2
- package/out/replicache/src/persist/refresh.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +85 -3
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +321 -29
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/replicache-options.d.ts +9 -0
- package/out/replicache/src/replicache-options.d.ts.map +1 -1
- package/out/replicache/src/storage-failure.d.ts +37 -0
- package/out/replicache/src/storage-failure.d.ts.map +1 -0
- package/out/replicache/src/storage-failure.js +31 -0
- package/out/replicache/src/storage-failure.js.map +1 -0
- package/out/shared/src/arrays.d.ts +5 -0
- package/out/shared/src/arrays.d.ts.map +1 -1
- package/out/shared/src/arrays.js +8 -10
- package/out/shared/src/arrays.js.map +1 -1
- package/out/shared/src/centroid.d.ts +0 -1
- package/out/shared/src/centroid.d.ts.map +1 -1
- package/out/shared/src/centroid.js +1 -4
- package/out/shared/src/centroid.js.map +1 -1
- package/out/shared/src/error.d.ts +11 -0
- package/out/shared/src/error.d.ts.map +1 -1
- package/out/shared/src/error.js +35 -1
- package/out/shared/src/error.js.map +1 -1
- package/out/shared/src/hash.d.ts.map +1 -1
- package/out/shared/src/hash.js +32 -7
- package/out/shared/src/hash.js.map +1 -1
- package/out/shared/src/iterables.d.ts +2 -0
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js +18 -1
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/map.d.ts +24 -2
- package/out/shared/src/map.d.ts.map +1 -1
- package/out/shared/src/map.js +18 -4
- package/out/shared/src/map.js.map +1 -1
- package/out/shared/src/options-types.d.ts +2 -2
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +10 -7
- package/out/shared/src/options.js.map +1 -1
- package/out/shared/src/random-values.js +12 -1
- package/out/shared/src/random-values.js.map +1 -1
- package/out/shared/src/ring-buffer.d.ts +10 -0
- package/out/shared/src/ring-buffer.d.ts.map +1 -1
- package/out/shared/src/ring-buffer.js +26 -1
- package/out/shared/src/ring-buffer.js.map +1 -1
- package/out/shared/src/tdigest.d.ts +10 -0
- package/out/shared/src/tdigest.d.ts.map +1 -1
- package/out/shared/src/tdigest.js +147 -63
- package/out/shared/src/tdigest.js.map +1 -1
- package/out/shared/src/valita.d.ts +88 -0
- package/out/shared/src/valita.d.ts.map +1 -1
- package/out/shared/src/valita.js +141 -23
- package/out/shared/src/valita.js.map +1 -1
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +10 -6
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +9 -5
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +5 -6
- package/out/zero/package.js.map +1 -1
- package/out/zero/src/zero.js +2 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +1 -0
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts +1 -0
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +47 -4
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +148 -25
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +500 -167
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js +3 -4
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
- package/out/zero-cache/src/db/migration-lite.js +5 -3
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/observability/events.js +4 -1
- package/out/zero-cache/src/observability/events.js.map +1 -1
- package/out/zero-cache/src/observability/log-throttle.d.ts +44 -0
- package/out/zero-cache/src/observability/log-throttle.d.ts.map +1 -0
- package/out/zero-cache/src/observability/log-throttle.js +76 -0
- package/out/zero-cache/src/observability/log-throttle.js.map +1 -0
- package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/observability/metrics.js +2 -7
- package/out/zero-cache/src/observability/metrics.js.map +1 -1
- package/out/zero-cache/src/scripts/permissions.d.ts +16 -0
- package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
- package/out/zero-cache/src/scripts/permissions.js +3 -3
- package/out/zero-cache/src/scripts/permissions.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +123 -87
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +28 -2
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +37 -17
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +13 -2
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/mutator.js +2 -0
- package/out/zero-cache/src/server/mutator.js.map +1 -1
- package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
- package/out/zero-cache/src/server/reaper.js +2 -0
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts +7 -0
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +103 -22
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +12 -6
- package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.js +5 -0
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/slot-keeper.d.ts +26 -0
- package/out/zero-cache/src/server/slot-keeper.d.ts.map +1 -0
- package/out/zero-cache/src/server/slot-keeper.js +181 -0
- package/out/zero-cache/src/server/slot-keeper.js.map +1 -0
- package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
- package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
- package/out/zero-cache/src/server/syncer-assigner.js +72 -0
- package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +40 -2
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/worker-urls.d.ts +1 -0
- package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-urls.js +2 -1
- package/out/zero-cache/src/server/worker-urls.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +11 -9
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +198 -24
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +16 -4
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts +24 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.js +44 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +82 -2
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.js +21 -10
- package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js +15 -3
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +7 -3
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +9 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +213 -21
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +65 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js +312 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +31 -18
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +132 -157
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +44 -2
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +65 -28
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +66 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +207 -24
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +66 -21
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +274 -68
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +46 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +68 -27
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +116 -35
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +68 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +141 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +45 -2
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js +10 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +60 -3
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +23 -10
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +17 -7
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current.js +2 -1
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts +72 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js +162 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts +50 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.js +268 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +6 -17
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +59 -8
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +8 -2
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +24 -4
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -4
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js +28 -8
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +17 -0
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +44 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +54 -6
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +145 -35
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +36 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +267 -118
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +161 -17
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js +33 -2
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts +24 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js +67 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +53 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +156 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts +243 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.js +317 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +78 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js +173 -47
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts +92 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js +42 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +14 -2
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +23 -10
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +7 -69
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.js +21 -53
- package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +106 -5
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +299 -86
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +485 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.js +93 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +80 -2
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +157 -20
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +19 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js +23 -3
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
- package/out/zero-cache/src/services/http-service.d.ts +7 -1
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +14 -2
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts +68 -2
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +155 -19
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +35 -3
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +137 -35
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +6 -7
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +51 -24
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +10 -2
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.js +3 -2
- package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts +24 -0
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/restore-progress.js +91 -0
- package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +5 -6
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/plannerz.d.ts +163 -0
- package/out/zero-cache/src/services/plannerz.d.ts.map +1 -0
- package/out/zero-cache/src/services/plannerz.js +267 -0
- package/out/zero-cache/src/services/plannerz.js.map +1 -0
- package/out/zero-cache/src/services/profz.d.ts +30 -0
- package/out/zero-cache/src/services/profz.d.ts.map +1 -0
- package/out/zero-cache/src/services/profz.js +163 -0
- package/out/zero-cache/src/services/profz.js.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-cookies.js +1 -1
- package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +5 -4
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +20 -22
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +51 -5
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/drain-handler.d.ts +74 -0
- package/out/zero-cache/src/services/replicator/drain-handler.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/drain-handler.js +185 -0
- package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -0
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +6 -2
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js +114 -28
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts +35 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.js +99 -8
- package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +5 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js +5 -2
- package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +16 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js +70 -27
- package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +23 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.js +54 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +6 -6
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +19 -14
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +11 -3
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +5 -1
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts +12 -0
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +42 -22
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/runner.d.ts +2 -1
- package/out/zero-cache/src/services/runner.d.ts.map +1 -1
- package/out/zero-cache/src/services/runner.js +10 -2
- package/out/zero-cache/src/services/runner.js.map +1 -1
- package/out/zero-cache/src/services/statz.d.ts +4 -0
- package/out/zero-cache/src/services/statz.d.ts.map +1 -1
- package/out/zero-cache/src/services/statz.js +22 -5
- package/out/zero-cache/src/services/statz.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts +26 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.js +26 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts +79 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.js +249 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +19 -2
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +42 -30
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +27 -2
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +86 -21
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +75 -12
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +234 -43
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +81 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +128 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +12 -2
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +29 -5
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +165 -9
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +953 -209
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +7 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js +35 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.d.ts +132 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.js +164 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts +55 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.js +56 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -6
- package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +25 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js +28 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +89 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js +233 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +2 -107
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +5 -20
- package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +95 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +155 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +229 -16
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +455 -43
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +8 -2
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +788 -71
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.d.ts +2 -0
- package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.js +6 -1
- package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +2 -2
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +50 -0
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +43 -4
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/profiler.d.ts +12 -0
- package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
- package/out/zero-cache/src/types/profiler.js +46 -1
- package/out/zero-cache/src/types/profiler.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts +1 -15
- package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
- package/out/zero-cache/src/types/row-key.js +6 -8
- package/out/zero-cache/src/types/row-key.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts +49 -7
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +190 -58
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +15 -0
- package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
- package/out/zero-cache/src/types/subscription.js +123 -31
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +18 -9
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/types/ws.d.ts.map +1 -1
- package/out/zero-cache/src/types/ws.js +1 -16
- package/out/zero-cache/src/types/ws.js.map +1 -1
- package/out/zero-cache/src/workers/connect-params.d.ts +1 -0
- package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connect-params.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +2 -1
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +9 -1
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +24 -7
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +55 -4
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.js +4 -1
- package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +20 -0
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +77 -13
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
- package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.js +3 -1
- package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +6 -0
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js +2 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +23 -13
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +94 -26
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/crud-impl.d.ts.map +1 -1
- package/out/zero-client/src/client/crud-impl.js +1 -1
- package/out/zero-client/src/client/crud-impl.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts +5 -4
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.js +3 -3
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +1 -1
- package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
- package/out/zero-client/src/client/ivm-branch.js +20 -3
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/keys.d.ts.map +1 -1
- package/out/zero-client/src/client/keys.js +19 -1
- package/out/zero-client/src/client/keys.js.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.d.ts.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts +2 -2
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.js +3 -7
- package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js +9 -4
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +33 -0
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts +9 -0
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.js +47 -14
- package/out/zero-client/src/client/query-manager.js.map +1 -1
- package/out/zero-client/src/client/reload-error-handler.js +2 -2
- package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
- package/out/zero-client/src/client/storage-version.d.ts +23 -0
- package/out/zero-client/src/client/storage-version.d.ts.map +1 -0
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts +1 -0
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +8 -6
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +18 -3
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +86 -48
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +2 -1
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-client/src/mod.js +1 -0
- package/out/zero-client/src/types/query-result.d.ts +2 -0
- package/out/zero-client/src/types/query-result.d.ts.map +1 -1
- package/out/zero-events/src/status.d.ts +64 -0
- package/out/zero-events/src/status.d.ts.map +1 -1
- package/out/zero-protocol/src/analyze-query-result.d.ts +12 -12
- package/out/zero-protocol/src/analyze-query-result.d.ts.map +1 -1
- package/out/zero-protocol/src/analyze-query-result.js +3 -3
- package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
- package/out/zero-protocol/src/ast.d.ts +24 -0
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +39 -16
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +36 -36
- package/out/zero-protocol/src/inspect-down.d.ts +31 -31
- package/out/zero-protocol/src/inspect-up.d.ts +158 -61
- package/out/zero-protocol/src/inspect-up.d.ts.map +1 -1
- package/out/zero-protocol/src/inspect-up.js +12 -6
- package/out/zero-protocol/src/inspect-up.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +4 -1
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/queries-patch.js +2 -2
- package/out/zero-protocol/src/queries-patch.js.map +1 -1
- package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
- package/out/zero-protocol/src/query-hash.js +2 -5
- package/out/zero-protocol/src/query-hash.js.map +1 -1
- package/out/zero-protocol/src/up.d.ts +766 -256
- package/out/zero-protocol/src/up.d.ts.map +1 -1
- package/out/zero-protocol/src/up.js +25 -3
- package/out/zero-protocol/src/up.js.map +1 -1
- package/out/zero-react/src/use-query.d.ts +5 -4
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +75 -8
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-react/src/zero.js +1 -0
- package/out/zero-server/src/adapters/drizzle.d.ts +16 -4
- package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
- package/out/zero-server/src/adapters/drizzle.js +19 -11
- package/out/zero-server/src/adapters/drizzle.js.map +1 -1
- package/out/zero-server/src/adapters/kysely.d.ts +6 -3
- package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
- package/out/zero-server/src/adapters/kysely.js +16 -6
- package/out/zero-server/src/adapters/kysely.js.map +1 -1
- package/out/zero-server/src/adapters/pg.d.ts +7 -2
- package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
- package/out/zero-server/src/adapters/pg.js +34 -10
- package/out/zero-server/src/adapters/pg.js.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.d.ts +4 -2
- package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.js +15 -5
- package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
- package/out/zero-server/src/adapters/prisma.d.ts +17 -5
- package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
- package/out/zero-server/src/adapters/prisma.js +20 -6
- package/out/zero-server/src/adapters/prisma.js.map +1 -1
- package/out/zero-server/src/closable-db-transaction.d.ts +16 -0
- package/out/zero-server/src/closable-db-transaction.d.ts.map +1 -0
- package/out/zero-server/src/closable-db-transaction.js +31 -0
- package/out/zero-server/src/closable-db-transaction.js.map +1 -0
- package/out/zero-server/src/custom.d.ts +10 -4
- package/out/zero-server/src/custom.d.ts.map +1 -1
- package/out/zero-server/src/custom.js +15 -6
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/logging.d.ts +2 -2
- package/out/zero-server/src/logging.d.ts.map +1 -1
- package/out/zero-server/src/logging.js +2 -2
- package/out/zero-server/src/logging.js.map +1 -1
- package/out/zero-server/src/mod.d.ts +2 -1
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.d.ts +2 -2
- package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.js +2 -2
- package/out/zero-server/src/pg-query-executor.js.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +25 -4
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +103 -52
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/push-processor.d.ts +8 -2
- package/out/zero-server/src/push-processor.d.ts.map +1 -1
- package/out/zero-server/src/push-processor.js +12 -4
- package/out/zero-server/src/push-processor.js.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +1 -1
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-server/src/schema.d.ts +2 -2
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +3 -2
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-server/src/transaction-options.d.ts +24 -0
- package/out/zero-server/src/transaction-options.d.ts.map +1 -0
- package/out/zero-server/src/transaction-options.js +11 -0
- package/out/zero-server/src/transaction-options.js.map +1 -0
- package/out/zero-server/src/zql-database.d.ts +21 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js +61 -24
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +17 -0
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +39 -1
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-query.js +1 -2
- package/out/zero-solid/src/use-query.js.map +1 -1
- package/out/zero-solid/src/zero.js +1 -0
- package/out/zql/src/builder/builder.d.ts +25 -0
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +69 -19
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +43 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +1 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.js +161 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -0
- package/out/zql/src/builder/debug-delegate.d.ts +6 -1
- package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
- package/out/zql/src/builder/debug-delegate.js +14 -2
- package/out/zql/src/builder/debug-delegate.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts +29 -0
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +74 -16
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/cap.d.ts +2 -1
- package/out/zql/src/ivm/cap.d.ts.map +1 -1
- package/out/zql/src/ivm/cap.js +14 -4
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +8 -3
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
- package/out/zql/src/ivm/deferred-input.js +3 -2
- package/out/zql/src/ivm/deferred-input.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +3 -1
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +4 -1
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +6 -2
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +13 -5
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +5 -2
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js +4 -0
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +8 -6
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +19 -8
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +5 -2
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +10 -4
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts +9 -4
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +97 -46
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join-index-tap.d.ts +33 -0
- package/out/zql/src/ivm/join-index-tap.d.ts.map +1 -0
- package/out/zql/src/ivm/join-index-tap.js +70 -0
- package/out/zql/src/ivm/join-index-tap.js.map +1 -0
- package/out/zql/src/ivm/join-index.d.ts +35 -0
- package/out/zql/src/ivm/join-index.d.ts.map +1 -0
- package/out/zql/src/ivm/join-index.js +141 -0
- package/out/zql/src/ivm/join-index.js.map +1 -0
- package/out/zql/src/ivm/join-utils.d.ts +6 -0
- package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
- package/out/zql/src/ivm/join-utils.js +22 -1
- package/out/zql/src/ivm/join-utils.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts +19 -1
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +107 -15
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +29 -4
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +70 -34
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/memory-storage.d.ts +1 -0
- package/out/zql/src/ivm/memory-storage.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-storage.js +1 -0
- package/out/zql/src/ivm/memory-storage.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +45 -10
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js +9 -4
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/push-accumulated.d.ts +6 -1
- package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
- package/out/zql/src/ivm/push-accumulated.js +47 -2
- package/out/zql/src/ivm/push-accumulated.js.map +1 -1
- package/out/zql/src/ivm/skip.d.ts +2 -1
- package/out/zql/src/ivm/skip.d.ts.map +1 -1
- package/out/zql/src/ivm/skip.js +3 -0
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/take-gate.d.ts +57 -0
- package/out/zql/src/ivm/take-gate.d.ts.map +1 -0
- package/out/zql/src/ivm/take-gate.js +106 -0
- package/out/zql/src/ivm/take-gate.js.map +1 -0
- package/out/zql/src/ivm/take.d.ts +8 -2
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +139 -103
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +3 -0
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +63 -10
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts +2 -1
- package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js +5 -0
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +9 -4
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/ivm/view.d.ts +15 -0
- package/out/zql/src/ivm/view.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.d.ts +53 -1
- package/out/zql/src/mutate/custom.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +3 -3
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +2 -2
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/planner/planner-builder.d.ts +23 -3
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
- package/out/zql/src/planner/planner-builder.js +34 -17
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-connection.d.ts +58 -2
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
- package/out/zql/src/planner/planner-connection.js +103 -11
- package/out/zql/src/planner/planner-connection.js.map +1 -1
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js +3 -8
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-graph.d.ts +10 -0
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
- package/out/zql/src/planner/planner-graph.js +14 -0
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zql/src/planner/planner-source.d.ts +2 -2
- package/out/zql/src/planner/planner-source.d.ts.map +1 -1
- package/out/zql/src/planner/planner-source.js +2 -2
- package/out/zql/src/planner/planner-source.js.map +1 -1
- package/out/zql/src/planner/planner-warnings.d.ts +83 -0
- package/out/zql/src/planner/planner-warnings.d.ts.map +1 -0
- package/out/zql/src/planner/planner-warnings.js +78 -0
- package/out/zql/src/planner/planner-warnings.js.map +1 -0
- package/out/zql/src/query/expression.d.ts +2 -2
- package/out/zql/src/query/expression.d.ts.map +1 -1
- package/out/zql/src/query/expression.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts +9 -2
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +52 -5
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +4 -2
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +66 -33
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +33 -6
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +1 -0
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +6 -23
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-registry.js +1 -1
- package/out/zql/src/query/query-transitions.d.ts.map +1 -1
- package/out/zql/src/query/query-transitions.js +2 -5
- package/out/zql/src/query/query-transitions.js.map +1 -1
- package/out/zql/src/query/query.d.ts +26 -10
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js +2 -10
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/typed-view.d.ts +1 -1
- package/out/zql/src/query/typed-view.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.js +9 -1
- package/out/zqlite/src/database-storage.js.map +1 -1
- package/out/zqlite/src/db.d.ts +17 -1
- package/out/zqlite/src/db.d.ts.map +1 -1
- package/out/zqlite/src/db.js +73 -30
- package/out/zqlite/src/db.js.map +1 -1
- package/out/zqlite/src/index-usage.d.ts +19 -0
- package/out/zqlite/src/index-usage.d.ts.map +1 -0
- package/out/zqlite/src/index-usage.js +49 -0
- package/out/zqlite/src/index-usage.js.map +1 -0
- package/out/zqlite/src/pending-delta.d.ts +110 -0
- package/out/zqlite/src/pending-delta.d.ts.map +1 -0
- package/out/zqlite/src/pending-delta.js +278 -0
- package/out/zqlite/src/pending-delta.js.map +1 -0
- package/out/zqlite/src/query-builder.d.ts +17 -1
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +111 -20
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-delegate.js +10 -7
- package/out/zqlite/src/query-delegate.js.map +1 -1
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts +3 -1
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
- package/out/zqlite/src/resolve-scalar-subqueries.js +1 -0
- package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +53 -1
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +5 -31
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/sqlite-stat4-sample.d.ts +37 -0
- package/out/zqlite/src/sqlite-stat4-sample.d.ts.map +1 -0
- package/out/zqlite/src/sqlite-stat4-sample.js +61 -0
- package/out/zqlite/src/sqlite-stat4-sample.js.map +1 -0
- package/out/zqlite/src/table-source.d.ts +87 -2
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +276 -42
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +5 -6
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +0 -25
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +0 -1
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js +0 -83
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +0 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +0 -29
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +0 -154
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +0 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { assert, unreachable } from "../../../../shared/src/asserts.js";
|
|
2
|
+
import { getOrInsertComputed } from "../../../../shared/src/map.js";
|
|
3
|
+
import { newArray } from "../../../../shared/src/arrays.js";
|
|
2
4
|
import { must } from "../../../../shared/src/must.js";
|
|
3
5
|
import { h64 } from "../../../../shared/src/hash.js";
|
|
4
6
|
import { Internal, InvalidConnectionRequest, InvalidConnectionRequestBaseCookie, Rehome } from "../../../../zero-protocol/src/error-kind-enum.js";
|
|
@@ -10,24 +12,28 @@ import { manualSpan, startAsyncSpan, startSpan } from "../../../../otel/src/span
|
|
|
10
12
|
import { ZERO_VERSION_COLUMN_NAME } from "../replicator/schema/constants.js";
|
|
11
13
|
import { transformAndHashQuery } from "../../auth/read-authorizer.js";
|
|
12
14
|
import { randInt } from "../../../../shared/src/rand.js";
|
|
15
|
+
import { LogThrottle } from "../../observability/log-throttle.js";
|
|
13
16
|
import { getOrCreateCounter, getOrCreateLatencyHistogram, getOrCreateNativeHistogram, getOrCreateUpDownCounter, getOrCreateValueHistogram } from "../../observability/metrics.js";
|
|
14
17
|
import { rowIDString } from "../../types/row-key.js";
|
|
15
18
|
import "../replicator/schema/replication-state.js";
|
|
16
|
-
import {
|
|
19
|
+
import { planWarningMessage } from "./plan-warnings.js";
|
|
20
|
+
import { shouldCutOffPush } from "./push-cutoff.js";
|
|
21
|
+
import { queryShape } from "./query-shape.js";
|
|
17
22
|
import { ResetPipelinesSignal } from "./snapshotter.js";
|
|
18
|
-
import "./pipeline-driver.js";
|
|
19
23
|
import { Subscription } from "../../types/subscription.js";
|
|
20
24
|
import { CustomKeyMap } from "../../../../shared/src/custom-key-map.js";
|
|
21
25
|
import { ttlClockAsNumber, ttlClockFromNumber } from "./ttl-clock.js";
|
|
22
26
|
import { EMPTY_CVR_VERSION, cmpVersions, versionFromString, versionString, versionToCookie } from "./schema/types.js";
|
|
23
27
|
import { ProtocolErrorWithLevel, getLogLevel, wrapWithProtocolError } from "../../types/error-with-level.js";
|
|
24
28
|
import { isAuthErrorBody } from "../../auth/auth.js";
|
|
29
|
+
import { AdvancementMetrics } from "./advancement-metrics.js";
|
|
25
30
|
import { ClientHandler, startPoke } from "./client-handler.js";
|
|
26
31
|
import { tracer } from "./tracer.js";
|
|
27
32
|
import { CVRStore, ClientNotFoundError } from "./cvr-store.js";
|
|
28
33
|
import { CVRConfigDrivenUpdater, CVRQueryDrivenUpdater, classifyQueriesForHydration, nextEvictionTime } from "./cvr.js";
|
|
29
34
|
import { E2EServingLagTracker } from "./e2e-serving-lag.js";
|
|
30
35
|
import { HydrationBudget } from "./hydration-budget.js";
|
|
36
|
+
import { HydrationCircuitBreaker } from "./hydration-circuit-breaker.js";
|
|
31
37
|
import { handleInspect } from "./inspect-handler.js";
|
|
32
38
|
import { QueryCoveringIndex } from "./query-covering.js";
|
|
33
39
|
import { resolver } from "@rocicorp/resolver";
|
|
@@ -51,6 +57,36 @@ function shutdownBeforeInitializationError() {
|
|
|
51
57
|
* use a timer to update the ttlClock every minute.
|
|
52
58
|
*/
|
|
53
59
|
var TTL_CLOCK_INTERVAL = 6e4;
|
|
60
|
+
/**
|
|
61
|
+
* A slow query is typically slow for every client group that runs it, so
|
|
62
|
+
* slow hydrations are logged at most once per query shape per this window,
|
|
63
|
+
* per process. See {@link LogThrottle}.
|
|
64
|
+
*/
|
|
65
|
+
var SLOW_HYDRATION_LOG_WINDOW_MS = 5 * 6e4;
|
|
66
|
+
/** See `ViewSyncerService.#logRebuilds()`. */
|
|
67
|
+
var REBUILD_LOG_INTERVAL_MS = 6e4;
|
|
68
|
+
var REBUILD_LOG_MIN_MS = 1e3;
|
|
69
|
+
function newRebuildLog() {
|
|
70
|
+
return {
|
|
71
|
+
/** The batches that hydrated queries again. */
|
|
72
|
+
batches: 0,
|
|
73
|
+
/** How many of them were not read, which hydrates every query again. */
|
|
74
|
+
batchesNotRead: 0,
|
|
75
|
+
/** The queries that they abandoned, and why. */
|
|
76
|
+
queries: 0,
|
|
77
|
+
estimate: 0,
|
|
78
|
+
read: 0,
|
|
79
|
+
cutoff: 0,
|
|
80
|
+
/** How many of those were hydrated again, and how long that took. */
|
|
81
|
+
hydrated: 0,
|
|
82
|
+
hydrationTimeMs: 0,
|
|
83
|
+
/** How many were removed instead. */
|
|
84
|
+
timedOut: 0,
|
|
85
|
+
rejectedByCircuitBreaker: 0,
|
|
86
|
+
evictedForHydrationBudget: 0
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
var slowHydrationLogThrottle = new LogThrottle({ windowMs: SLOW_HYDRATION_LOG_WINDOW_MS });
|
|
54
90
|
var ViewSyncerService = class {
|
|
55
91
|
id;
|
|
56
92
|
createdAtMs = Date.now();
|
|
@@ -62,6 +98,7 @@ var ViewSyncerService = class {
|
|
|
62
98
|
#drainCoordinator;
|
|
63
99
|
#keepaliveMs;
|
|
64
100
|
#slowHydrateThreshold;
|
|
101
|
+
#hydrationCircuitBreaker;
|
|
65
102
|
#lastConnectTime = Date.now();
|
|
66
103
|
/**
|
|
67
104
|
* The TTL clock is used to determine the time at which queries are considered
|
|
@@ -89,6 +126,13 @@ var ViewSyncerService = class {
|
|
|
89
126
|
#lock = new Lock();
|
|
90
127
|
#cvrStore;
|
|
91
128
|
#stopped = resolver();
|
|
129
|
+
/**
|
|
130
|
+
* Set when {@link #cleanup} begins. Lock tasks that were in flight when the
|
|
131
|
+
* view-syncer was stopped may still complete after the timers have been
|
|
132
|
+
* cleared; this flag prevents them from scheduling new timers, which would
|
|
133
|
+
* otherwise outlive the service (and retain everything it references).
|
|
134
|
+
*/
|
|
135
|
+
#shuttingDown = false;
|
|
92
136
|
#initialized = resolver();
|
|
93
137
|
#cvr;
|
|
94
138
|
/**
|
|
@@ -103,7 +147,8 @@ var ViewSyncerService = class {
|
|
|
103
147
|
* updates are processed via `#syncQueryPipelineSet`.
|
|
104
148
|
*
|
|
105
149
|
* Resets to `false` if `#advancePipelines` returns a `ResetPipelinesSignal`
|
|
106
|
-
* and pipelines must be reset and rehydrated
|
|
150
|
+
* and pipelines must be reset and rehydrated, or if a reloaded CVR is ahead
|
|
151
|
+
* of the pipelines (see `#resetPipelinesIfBehindCVR`).
|
|
107
152
|
*/
|
|
108
153
|
#pipelinesHydrated = false;
|
|
109
154
|
#servedVersion = null;
|
|
@@ -129,6 +174,7 @@ var ViewSyncerService = class {
|
|
|
129
174
|
description: "Observations of sync.e2e_serving_lag that came out negative and were clamped to zero. Non-zero means the upstream database clock is running ahead of this pod by more than the entire pipeline latency, so sync.e2e_serving_lag is biased low and reads healthier than reality. See replication.upstream_clock_skew for the magnitude.",
|
|
130
175
|
unit: "{observation}"
|
|
131
176
|
});
|
|
177
|
+
#advancementMetrics = new AdvancementMetrics();
|
|
132
178
|
#transactionAdvanceTime = getOrCreateLatencyHistogram("sync", "advance-time", "Time to advance all queries for a given client group after applying a new transaction to the replica.");
|
|
133
179
|
#queryTransformations = getOrCreateCounter("sync", "query.transformations", "Number of query transformations performed");
|
|
134
180
|
#queryTransformationTime = getOrCreateLatencyHistogram("sync", "query.transformation-time", "Time to transform custom queries via API server.");
|
|
@@ -181,14 +227,78 @@ var ViewSyncerService = class {
|
|
|
181
227
|
]
|
|
182
228
|
});
|
|
183
229
|
#queryEvictions = getOrCreateCounter("sync", "query_evictions", {
|
|
184
|
-
description: "Number of
|
|
230
|
+
description: "Number of queries evicted from the CVR ahead of their removal by the client, grouped by reason. Inactive queries are evicted by ttl and hydration-budget; hydration-timeout and hydration-circuit-breaker evict active queries as well.",
|
|
231
|
+
unit: "{query}"
|
|
232
|
+
});
|
|
233
|
+
#hydrationTimeouts = getOrCreateCounter("sync", "hydration_timeouts", {
|
|
234
|
+
description: "Number of query hydrations aborted for exceeding the query hydration timeout.",
|
|
235
|
+
unit: "{query}"
|
|
236
|
+
});
|
|
237
|
+
#hydrationCircuitBreakerRejections = getOrCreateCounter("sync", "hydration_circuit_breaker_rejections", {
|
|
238
|
+
description: "Number of queries rejected without hydration because their hydration circuit breaker was open.",
|
|
185
239
|
unit: "{query}"
|
|
186
240
|
});
|
|
187
241
|
#inspectorDelegate;
|
|
188
242
|
#config;
|
|
243
|
+
/**
|
|
244
|
+
* Set when `costBasedSyncEnabled`: advancements are then bounded by
|
|
245
|
+
* cutting off the queries this says to and hydrating them again in the
|
|
246
|
+
* same poke, instead of by the advancement time limit that resets every
|
|
247
|
+
* pipeline of the client group.
|
|
248
|
+
*/
|
|
249
|
+
#pushCutoff;
|
|
250
|
+
/**
|
|
251
|
+
* Shared by the client groups of the sync worker. Set when
|
|
252
|
+
* `costBasedSyncEnabled`.
|
|
253
|
+
*/
|
|
254
|
+
#pacer;
|
|
255
|
+
/**
|
|
256
|
+
* The time that the pipelines took for the batch being processed, if the
|
|
257
|
+
* pipelines were advanced: reading the changes, pushing them, and
|
|
258
|
+
* hydrating queries again. Unlike the processing time of the advancement,
|
|
259
|
+
* this leaves out the time spent awaiting I/O (e.g. the CVR flush), during
|
|
260
|
+
* which other client groups run.
|
|
261
|
+
*/
|
|
262
|
+
#batchTimeMs;
|
|
263
|
+
#pipelineTime = { ms: 0 };
|
|
264
|
+
/** What the client group's batches have been taking, for pacing. */
|
|
265
|
+
#smoothedBatchTimeMs;
|
|
266
|
+
/** Ends the wait between batches, if the client group is in one. */
|
|
267
|
+
#endBatchWait;
|
|
268
|
+
/** The waits between batches since the last time they were logged. */
|
|
269
|
+
#batchWaitLog = {
|
|
270
|
+
loggedAt: -Infinity,
|
|
271
|
+
waits: 0,
|
|
272
|
+
waitedMs: 0
|
|
273
|
+
};
|
|
274
|
+
/** What batches have hydrated again since that was last logged. */
|
|
275
|
+
#rebuildLog = newRebuildLog();
|
|
276
|
+
#rebuildsLoggedAt = -Infinity;
|
|
277
|
+
#queryRebuilds = getOrCreateCounter("sync", "query-rebuilds", {
|
|
278
|
+
description: "Number of queries hydrated again by an advancement instead of being pushed (all of) its changes, by reason: \"estimate\" if pushing them to it was estimated to cost more, \"read\" if reading them was, for the queries that were left to push them to, or \"cutoff\" if the pushes had taken as long as hydrating the query did",
|
|
279
|
+
unit: "{query}"
|
|
280
|
+
});
|
|
281
|
+
#queryRebuildTime = getOrCreateLatencyHistogram("sync", "query-rebuild-time", "Time to hydrate a query again in an advancement.");
|
|
282
|
+
#pushEstimateRatio = getOrCreateValueHistogram("sync", "push-estimate-ratio", {
|
|
283
|
+
description: "The estimated time to push the changes of an advancement to a query, divided by the time it took, for queries that were pushed all of the changes",
|
|
284
|
+
unit: "1",
|
|
285
|
+
bucketBoundaries: [
|
|
286
|
+
.1,
|
|
287
|
+
.25,
|
|
288
|
+
.5,
|
|
289
|
+
.8,
|
|
290
|
+
1.25,
|
|
291
|
+
2,
|
|
292
|
+
4,
|
|
293
|
+
10
|
|
294
|
+
]
|
|
295
|
+
});
|
|
296
|
+
#batchWaitTime = getOrCreateLatencyHistogram("sync", "batch-wait-time", "Time a client group is made to wait between advancements by pacing.");
|
|
189
297
|
#runPriorityOp;
|
|
190
|
-
constructor(config, lc, shard, taskID, clientGroupID, cvrDb, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, inspectorDelegate, connContextManager, customQueryTransformer, runPriorityOp, keepaliveMs = DEFAULT_KEEPALIVE_MS, setTimeoutFn = setTimeout.bind(globalThis), now = performance.now.bind(performance)) {
|
|
298
|
+
constructor(config, lc, shard, taskID, clientGroupID, cvrDb, pipelineDriver, versionChanges, drainCoordinator, slowHydrateThreshold, inspectorDelegate, connContextManager, customQueryTransformer, runPriorityOp, keepaliveMs = DEFAULT_KEEPALIVE_MS, setTimeoutFn = setTimeout.bind(globalThis), now = performance.now.bind(performance), pushCutoff = shouldCutOffPush, pacer) {
|
|
191
299
|
this.#config = config;
|
|
300
|
+
this.#pushCutoff = config.costBasedSyncEnabled ? pushCutoff : void 0;
|
|
301
|
+
this.#pacer = config.costBasedSyncEnabled ? pacer : void 0;
|
|
192
302
|
this.id = clientGroupID;
|
|
193
303
|
this.connContextManager = connContextManager;
|
|
194
304
|
this.#shard = shard;
|
|
@@ -203,6 +313,7 @@ var ViewSyncerService = class {
|
|
|
203
313
|
this.#cvrStore = new CVRStore(lc, cvrDb, shard, taskID, clientGroupID, () => this.#stateChanges.cancel());
|
|
204
314
|
this.#setTimeout = setTimeoutFn;
|
|
205
315
|
this.#now = now;
|
|
316
|
+
this.#hydrationCircuitBreaker = new HydrationCircuitBreaker(config.viewSyncerQueryHydrationTimeoutMs ?? 0, void 0, now);
|
|
206
317
|
this.#runPriorityOp = runPriorityOp;
|
|
207
318
|
this.keepalive();
|
|
208
319
|
}
|
|
@@ -229,11 +340,13 @@ var ViewSyncerService = class {
|
|
|
229
340
|
this.#stateChanges.cancel();
|
|
230
341
|
return;
|
|
231
342
|
}
|
|
343
|
+
let reloaded = false;
|
|
232
344
|
if (!this.#cvr) {
|
|
233
345
|
this.#lc.debug?.("loading cvr");
|
|
234
346
|
this.#cvr = await this.#runPriorityOp(lc, "loading cvr", () => this.#cvrStore.load(lc, this.#lastConnectTime));
|
|
235
347
|
this.#ttlClock = this.#cvr.ttlClock;
|
|
236
348
|
this.#ttlClockBase = Date.now();
|
|
349
|
+
reloaded = true;
|
|
237
350
|
} else {
|
|
238
351
|
const now = Date.now();
|
|
239
352
|
this.#cvr = {
|
|
@@ -242,6 +355,10 @@ var ViewSyncerService = class {
|
|
|
242
355
|
};
|
|
243
356
|
}
|
|
244
357
|
try {
|
|
358
|
+
if (reloaded && this.#resetPipelinesIfBehindCVR(lc, this.#cvr)) {
|
|
359
|
+
const connCtx = this.connContextManager.getBackgroundConnectionContext();
|
|
360
|
+
if (connCtx) await this.#maybeHydratePipelines(lc, this.#cvr, connCtx);
|
|
361
|
+
}
|
|
245
362
|
await fn(lc, this.#cvr);
|
|
246
363
|
} catch (e) {
|
|
247
364
|
this.#cvr = void 0;
|
|
@@ -251,11 +368,47 @@ var ViewSyncerService = class {
|
|
|
251
368
|
}
|
|
252
369
|
});
|
|
253
370
|
}
|
|
371
|
+
/**
|
|
372
|
+
* The CVR is reloaded after an error clears the cached copy. By then another
|
|
373
|
+
* view-syncer may have taken over the client group and flushed the CVR at a
|
|
374
|
+
* version ahead of this instance's hydrated pipelines (e.g. its replica was
|
|
375
|
+
* further ahead). The pipelines can no longer be diffed against the CVR, so
|
|
376
|
+
* reset them and let `#maybeHydratePipelines` rehydrate once the replica has
|
|
377
|
+
* caught up to the CVR.
|
|
378
|
+
*
|
|
379
|
+
* A CVR behind the pipelines is expected (advancements that do not change
|
|
380
|
+
* the CVR are not flushed) and is handled by the normal update path.
|
|
381
|
+
*
|
|
382
|
+
* Returns whether the pipelines were reset.
|
|
383
|
+
*
|
|
384
|
+
* Must be called from within the #lock.
|
|
385
|
+
*/
|
|
386
|
+
#resetPipelinesIfBehindCVR(lc, cvr) {
|
|
387
|
+
if (!this.#pipelinesHydrated) return false;
|
|
388
|
+
const pipelineVersion = this.#pipelines.currentVersion();
|
|
389
|
+
if (pipelineVersion >= cvr.version.stateVersion) return false;
|
|
390
|
+
lc.info?.(`resetting pipelines: pipelines@${pipelineVersion} are behind reloaded cvr@${versionString(cvr.version)}`);
|
|
391
|
+
this.#pipelineResets.add(1, { reason: "behind-cvr" });
|
|
392
|
+
this.#pipelinesHydrated = false;
|
|
393
|
+
this.connContextManager.setSharedRetransformReady(false);
|
|
394
|
+
this.#pipelines.reset(must(cvr.clientSchema, "cvr.clientSchema missing after initialization"));
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
254
397
|
readyState() {
|
|
255
|
-
return Promise
|
|
398
|
+
return new Promise((resolve, reject) => {
|
|
399
|
+
const unsubscribe = this.#drainCoordinator.onDraining(() => resolve("draining"));
|
|
400
|
+
this.#initialized.promise.then((state) => {
|
|
401
|
+
unsubscribe();
|
|
402
|
+
resolve(state);
|
|
403
|
+
}, (err) => {
|
|
404
|
+
unsubscribe();
|
|
405
|
+
reject(err);
|
|
406
|
+
});
|
|
407
|
+
});
|
|
256
408
|
}
|
|
257
409
|
async run() {
|
|
258
410
|
try {
|
|
411
|
+
this.#scheduleShutdown(this.#keepaliveMs);
|
|
259
412
|
if (await this.readyState() === "draining") {
|
|
260
413
|
this.#lc.debug?.(`draining view-syncer ${this.id} before running`);
|
|
261
414
|
this.stop();
|
|
@@ -268,6 +421,7 @@ var ViewSyncerService = class {
|
|
|
268
421
|
}
|
|
269
422
|
assert(state === "version-ready", "state should be version-ready");
|
|
270
423
|
this.#e2eServingLagTracker.onVersionReady(replicaState);
|
|
424
|
+
this.#batchTimeMs = void 0;
|
|
271
425
|
await this.#runInLockWithCVR(async (lc, cvr) => {
|
|
272
426
|
const clientSchema = must(cvr.clientSchema, "cvr.clientSchema missing after initialization");
|
|
273
427
|
if (!this.#pipelines.initialized()) this.#pipelines.init(clientSchema);
|
|
@@ -276,19 +430,32 @@ var ViewSyncerService = class {
|
|
|
276
430
|
lc.info?.(`resetting CVR: ${message}`);
|
|
277
431
|
throw new ClientNotFoundError(message);
|
|
278
432
|
}
|
|
433
|
+
let previousQueries;
|
|
279
434
|
if (this.#pipelinesHydrated) {
|
|
280
435
|
const result = await this.#advancePipelines(lc, cvr);
|
|
281
436
|
if (result === "success") return;
|
|
282
|
-
lc.info?.(`resetting pipelines: ${result.message}`);
|
|
437
|
+
lc.info?.(`resetting pipelines: ${result.message}${result.breakdown ? ` (${result.breakdown})` : ""}`);
|
|
283
438
|
this.#pipelineResets.add(1, { reason: result.reason });
|
|
439
|
+
switch (result.reason) {
|
|
440
|
+
case "advancement-timeout":
|
|
441
|
+
case "scalar-subquery":
|
|
442
|
+
case "truncation":
|
|
443
|
+
case "schema-change":
|
|
444
|
+
if (!Object.values(cvr.queries).some((q) => q.type === "client")) previousQueries = new Map([...this.#pipelines.queries(), ...this.#pipelines.abandonedQueries()]);
|
|
445
|
+
break;
|
|
446
|
+
case "permissions-change": break;
|
|
447
|
+
default: unreachable(result.reason);
|
|
448
|
+
}
|
|
284
449
|
this.#pipelines.reset(clientSchema);
|
|
285
450
|
this.#pipelinesHydrated = false;
|
|
286
451
|
this.connContextManager.setSharedRetransformReady(false);
|
|
287
452
|
}
|
|
288
453
|
const backgroundConnCtx = this.connContextManager.getBackgroundConnectionContext();
|
|
289
|
-
if (backgroundConnCtx) await this.#maybeHydratePipelines(lc, cvr, backgroundConnCtx);
|
|
454
|
+
if (backgroundConnCtx) await this.#maybeHydratePipelines(lc, cvr, backgroundConnCtx, previousQueries);
|
|
290
455
|
else lc.info?.("No validated background connection; deferring pipeline init");
|
|
456
|
+
if (this.#batchTimeMs !== void 0) this.#batchTimeMs += this.#totalHydrationTimeMs();
|
|
291
457
|
});
|
|
458
|
+
if (this.#pacer && this.#batchTimeMs !== void 0) await this.#paceBatches(this.#pacer, this.#batchTimeMs);
|
|
292
459
|
}
|
|
293
460
|
if (this.#drainCoordinator.shouldDrain()) this.#drainCoordinator.drainNextIn(this.#totalHydrationTimeMs());
|
|
294
461
|
await this.#cleanup();
|
|
@@ -324,9 +491,18 @@ var ViewSyncerService = class {
|
|
|
324
491
|
* - Syncs missing, errored, or drifted queries via `#syncQueryPipelineSet`.
|
|
325
492
|
* - Sets `#pipelinesHydrated = true` and enables shared retransformations.
|
|
326
493
|
*/
|
|
327
|
-
async #maybeHydratePipelines(lc, cvr, connCtx) {
|
|
494
|
+
async #maybeHydratePipelines(lc, cvr, connCtx, previousQueries) {
|
|
328
495
|
if (!this.#pipelines.initialized()) return;
|
|
329
|
-
|
|
496
|
+
let version;
|
|
497
|
+
try {
|
|
498
|
+
version = this.#pipelines.advanceWithoutDiff(this.#pushCutoff !== void 0);
|
|
499
|
+
} catch (e) {
|
|
500
|
+
if (!(e instanceof ResetPipelinesSignal)) throw e;
|
|
501
|
+
lc.info?.(`resetting pipelines: ${e.message}${e.breakdown ? ` (${e.breakdown})` : ""}`);
|
|
502
|
+
this.#pipelineResets.add(1, { reason: e.reason });
|
|
503
|
+
this.#pipelines.reset(must(cvr.clientSchema, "cvr.clientSchema missing after initialization"));
|
|
504
|
+
version = this.#pipelines.currentVersion();
|
|
505
|
+
}
|
|
330
506
|
const cvrVer = versionString(cvr.version);
|
|
331
507
|
if (version < cvr.version.stateVersion) {
|
|
332
508
|
lc.debug?.(`replica@${version} is behind cvr@${cvrVer}`);
|
|
@@ -338,8 +514,8 @@ var ViewSyncerService = class {
|
|
|
338
514
|
activeHydratedQueries: 0,
|
|
339
515
|
inactiveHydratedQueries: 0
|
|
340
516
|
};
|
|
341
|
-
const driftedQueryIDs = await this.#hydrateUnchangedQueries(lc, cvr, connCtx, hydrationPassStats, hydrationBudget);
|
|
342
|
-
await this.#syncQueryPipelineSet(lc, cvr, "missing", connCtx, driftedQueryIDs, hydrationBudget, hydrationPassStats);
|
|
517
|
+
const driftedQueryIDs = await this.#hydrateUnchangedQueries(lc, cvr, connCtx, hydrationPassStats, hydrationBudget, previousQueries);
|
|
518
|
+
await this.#syncQueryPipelineSet(lc, cvr, "missing", connCtx, driftedQueryIDs, hydrationBudget, hydrationPassStats, previousQueries);
|
|
343
519
|
this.#pipelinesHydrated = true;
|
|
344
520
|
this.connContextManager.setSharedRetransformReady(true);
|
|
345
521
|
}
|
|
@@ -433,7 +609,14 @@ var ViewSyncerService = class {
|
|
|
433
609
|
return true;
|
|
434
610
|
}
|
|
435
611
|
#shutdownTimer = null;
|
|
612
|
+
#stopShutdownTimer() {
|
|
613
|
+
if (this.#shutdownTimer !== null) {
|
|
614
|
+
clearTimeout(this.#shutdownTimer);
|
|
615
|
+
this.#shutdownTimer = null;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
436
618
|
#scheduleShutdown(delayMs = 0) {
|
|
619
|
+
if (this.#shuttingDown) return;
|
|
437
620
|
this.#shutdownTimer ??= this.#setTimeout(() => {
|
|
438
621
|
this.#shutdownTimer = null;
|
|
439
622
|
this.#runInLockWithCVR(() => {}).catch((e) => this.#stateChanges.fail(e));
|
|
@@ -480,6 +663,7 @@ var ViewSyncerService = class {
|
|
|
480
663
|
*/
|
|
481
664
|
#scheduleAuthMaintenance(lc) {
|
|
482
665
|
this.#stopAuthMaintenanceTimer();
|
|
666
|
+
if (this.#shuttingDown) return;
|
|
483
667
|
const plan = this.connContextManager.planMaintenance();
|
|
484
668
|
if (plan.earliestDeadlineAt === void 0) {
|
|
485
669
|
lc.debug?.("No auth maintenance wakeup scheduled");
|
|
@@ -585,17 +769,41 @@ var ViewSyncerService = class {
|
|
|
585
769
|
this.#ttlClockBase = now;
|
|
586
770
|
return ttlClock;
|
|
587
771
|
}
|
|
588
|
-
|
|
772
|
+
/**
|
|
773
|
+
* @param patchesPoked Whether patches computed against the updater's CVR
|
|
774
|
+
* have already been poked to clients. If so, the CVR is checked to be
|
|
775
|
+
* current even when the flush has nothing to write: another
|
|
776
|
+
* view-syncer may have already committed identical rows at a newer
|
|
777
|
+
* version, which would otherwise leave this one poking from a stale
|
|
778
|
+
* CVR whose version it cannot advance.
|
|
779
|
+
*/
|
|
780
|
+
#flushUpdater(lc, updater, patchesPoked = false) {
|
|
589
781
|
return startAsyncSpan(tracer, "vs.#flushUpdater", () => this.#runPriorityOp(lc, "flushing cvr", async () => {
|
|
590
782
|
const now = Date.now();
|
|
591
783
|
const ttlClock = this.#getTTLClock(now);
|
|
592
|
-
const { cvr, flushed } = await updater.flush(lc, this.#lastConnectTime, now, ttlClock);
|
|
784
|
+
const { cvr, flushed } = await updater.flush(lc, this.#lastConnectTime, now, ttlClock, patchesPoked);
|
|
593
785
|
if (flushed) this.#startTTLClockInterval(lc);
|
|
594
786
|
return cvr;
|
|
595
787
|
}));
|
|
596
788
|
}
|
|
789
|
+
/**
|
|
790
|
+
* Flushes an updater whose changes have already been poked. If the flush
|
|
791
|
+
* fails (e.g. the CVR was concurrently modified), the poke is cancelled
|
|
792
|
+
* before the error propagates. The error may only fail the client that
|
|
793
|
+
* initiated the operation, and any other client left mid-poke would fail
|
|
794
|
+
* its next pokeStart.
|
|
795
|
+
*/
|
|
796
|
+
async #flushPoked(lc, updater, pokers) {
|
|
797
|
+
try {
|
|
798
|
+
return await this.#flushUpdater(lc, updater, pokers.patchesSent);
|
|
799
|
+
} catch (e) {
|
|
800
|
+
await pokers.cancel();
|
|
801
|
+
throw e;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
597
804
|
#startTTLClockInterval(lc) {
|
|
598
805
|
this.#stopTTLClockInterval();
|
|
806
|
+
if (this.#shuttingDown) return;
|
|
599
807
|
this.#ttlClockInterval = this.#setTimeout(() => {
|
|
600
808
|
this.#updateTTLClockInCVRWithoutLock(lc);
|
|
601
809
|
this.#startTTLClockInterval(lc);
|
|
@@ -624,7 +832,7 @@ var ViewSyncerService = class {
|
|
|
624
832
|
if (cmpVersions(cvr.version, this.#cvr.version) < 0) {
|
|
625
833
|
const newCVR = this.#cvr;
|
|
626
834
|
await startAsyncSpan(tracer, "vs.#updateCVRConfig.pokeClients", async () => {
|
|
627
|
-
const pokers = startPoke(this.#getClients(cvr.version), newCVR.version);
|
|
835
|
+
const pokers = startPoke(lc, this.#getClients(cvr.version), newCVR.version);
|
|
628
836
|
for (const patch of patches) await pokers.addPatch(patch);
|
|
629
837
|
await pokers.end(newCVR.version);
|
|
630
838
|
});
|
|
@@ -726,6 +934,7 @@ var ViewSyncerService = class {
|
|
|
726
934
|
#scheduleExpireEviction(lc, cvr) {
|
|
727
935
|
const { ttlClock } = cvr;
|
|
728
936
|
this.#stopExpireTimer();
|
|
937
|
+
if (this.#shuttingDown) return;
|
|
729
938
|
const next = nextEvictionTime(cvr);
|
|
730
939
|
if (next === void 0) {
|
|
731
940
|
lc.debug?.("no inactive queries with ttl");
|
|
@@ -753,7 +962,7 @@ var ViewSyncerService = class {
|
|
|
753
962
|
*
|
|
754
963
|
* This must be called from within the #lock.
|
|
755
964
|
*/
|
|
756
|
-
async #hydrateUnchangedQueries(lc, cvr, connCtx, hydrationPassStats, hydrationBudget) {
|
|
965
|
+
async #hydrateUnchangedQueries(lc, cvr, connCtx, hydrationPassStats, hydrationBudget, previousQueries) {
|
|
757
966
|
assert(this.#pipelines.initialized(), "pipelines must be initialized");
|
|
758
967
|
const dbVersion = this.#pipelines.currentVersion();
|
|
759
968
|
const cvrVersion = cvr.version;
|
|
@@ -766,9 +975,16 @@ var ViewSyncerService = class {
|
|
|
766
975
|
const customQueries = /* @__PURE__ */ new Map();
|
|
767
976
|
const otherQueries = [];
|
|
768
977
|
const inactivatedCount = gotQueries.length - requiredGotQueries.length;
|
|
769
|
-
for (const query of requiredGotQueries) if (query.type === "custom") customQueries.set(query.id, query);
|
|
770
|
-
else otherQueries.push(query);
|
|
771
978
|
const transformedQueries = [];
|
|
979
|
+
for (const query of requiredGotQueries) if (query.type === "custom") {
|
|
980
|
+
const previous = previousQueries?.get(query.id);
|
|
981
|
+
if (previous && previous.transformationHash === query.transformationHash) transformedQueries.push({
|
|
982
|
+
id: query.id,
|
|
983
|
+
transformationHash: previous.transformationHash,
|
|
984
|
+
transformedAst: previous.originalAst ?? previous.transformedAst
|
|
985
|
+
});
|
|
986
|
+
else customQueries.set(query.id, query);
|
|
987
|
+
} else otherQueries.push(query);
|
|
772
988
|
let customErrorCount = 0;
|
|
773
989
|
let customHashMismatchCount = 0;
|
|
774
990
|
let otherHashMismatchCount = 0;
|
|
@@ -795,33 +1011,58 @@ var ViewSyncerService = class {
|
|
|
795
1011
|
for (const { id: queryID, transformationHash, transformedAst } of transformedQueries) {
|
|
796
1012
|
const query = cvr.queries[queryID];
|
|
797
1013
|
const queryName = query.type === "custom" ? query.name : void 0;
|
|
1014
|
+
if (query.type !== "internal" && this.#hydrationCircuitBreaker.isOpen(transformationHash)) {
|
|
1015
|
+
lc.info?.(`skipping hydration of ${queryID}: hydration circuit breaker open`);
|
|
1016
|
+
continue;
|
|
1017
|
+
}
|
|
798
1018
|
const covered = queryCoveringIndex ? this.#findQueryCoverageShadowHit(queryCoveringIndex, queryID, transformationHash, transformedAst, queryName) : void 0;
|
|
799
1019
|
totalHydratedQueries++;
|
|
800
1020
|
if (covered) {
|
|
801
1021
|
coveredHydratedQueries++;
|
|
802
1022
|
firstCoveredQuery ??= covered;
|
|
803
1023
|
}
|
|
804
|
-
const timer =
|
|
1024
|
+
const timer = this.#timer(lc, "hydration");
|
|
805
1025
|
let count = 0;
|
|
1026
|
+
let timedOut = false;
|
|
806
1027
|
await startAsyncSpan(tracer, "vs.#hydrateUnchangedQueries.addQuery", async (span) => {
|
|
807
1028
|
span.setAttribute("queryHash", queryID);
|
|
808
1029
|
span.setAttribute("transformationHash", transformationHash);
|
|
809
1030
|
span.setAttribute("table", transformedAst.table);
|
|
810
1031
|
if (queryName !== void 0) span.setAttribute("queryName", queryName);
|
|
811
|
-
for (const change of this.#pipelines.addQuery(transformationHash, queryID, transformedAst, await timer.start(), queryName, "unchanged-query-rehydrate")) if (change === "yield")
|
|
812
|
-
|
|
1032
|
+
for (const change of this.#pipelines.addQuery(transformationHash, queryID, transformedAst, await timer.start(), queryName, "unchanged-query-rehydrate")) if (change === "yield") {
|
|
1033
|
+
if (query.type !== "internal" && this.#hydrationCircuitBreaker.exceeded(timer.totalElapsed())) {
|
|
1034
|
+
timedOut = true;
|
|
1035
|
+
await timer.yieldProcess("yield in hydrateUnchangedQueries");
|
|
1036
|
+
break;
|
|
1037
|
+
}
|
|
1038
|
+
await timer.yieldProcess("yield in hydrateUnchangedQueries");
|
|
1039
|
+
} else count++;
|
|
813
1040
|
});
|
|
814
1041
|
const elapsed = timer.totalElapsed();
|
|
1042
|
+
if (timedOut) {
|
|
1043
|
+
this.#recordHydrationTimeout(lc, {
|
|
1044
|
+
id: queryID,
|
|
1045
|
+
ast: transformedAst,
|
|
1046
|
+
transformationHash,
|
|
1047
|
+
name: queryName
|
|
1048
|
+
}, elapsed, count);
|
|
1049
|
+
continue;
|
|
1050
|
+
}
|
|
815
1051
|
hydrationPassStats.activeHydratedQueries++;
|
|
816
1052
|
this.#hydrations.add(1);
|
|
817
1053
|
this.#hydrationTime.recordMs(elapsed);
|
|
818
|
-
this.#addQueryMaterializationServerMetric(
|
|
819
|
-
this.#inspectorDelegate.addQuery(
|
|
1054
|
+
this.#addQueryMaterializationServerMetric(queryID, elapsed);
|
|
1055
|
+
this.#inspectorDelegate.addQuery(queryID, transformedAst);
|
|
820
1056
|
lc.debug?.(`hydrated ${count} rows for ${queryID} (${elapsed} ms)`);
|
|
1057
|
+
if (elapsed > this.#slowHydrateThreshold) this.#logSlowHydration(lc, {
|
|
1058
|
+
id: queryID,
|
|
1059
|
+
ast: transformedAst,
|
|
1060
|
+
transformationHash,
|
|
1061
|
+
name: queryName
|
|
1062
|
+
}, elapsed);
|
|
821
1063
|
let drifted = false;
|
|
822
|
-
const
|
|
823
|
-
if (
|
|
824
|
-
const priorSig = parseSignature(storedSigHex);
|
|
1064
|
+
const priorSig = this.#cvrStore.rowSetSignature(queryID);
|
|
1065
|
+
if (priorSig !== void 0) {
|
|
825
1066
|
const candidateSig = this.#pipelines.rowSetSignature(queryID) ?? 0n;
|
|
826
1067
|
if (priorSig !== candidateSig) {
|
|
827
1068
|
lc.warn?.(`rowSetSignature drift for query ${queryID}: prior=${priorSig.toString(16)} new=${candidateSig.toString(16)} (${count} rows). Removing from pipelines for full re-execution.`);
|
|
@@ -877,11 +1118,7 @@ var ViewSyncerService = class {
|
|
|
877
1118
|
return;
|
|
878
1119
|
}
|
|
879
1120
|
const appErrorGroups = /* @__PURE__ */ new Map();
|
|
880
|
-
for (const err of errorOrErrors) for (const clientId of getAffectedClientIDs([err.id]))
|
|
881
|
-
const group = appErrorGroups.get(clientId) ?? [];
|
|
882
|
-
group.push(err);
|
|
883
|
-
appErrorGroups.set(clientId, group);
|
|
884
|
-
}
|
|
1121
|
+
for (const err of errorOrErrors) for (const clientId of getAffectedClientIDs([err.id])) getOrInsertComputed(appErrorGroups, clientId, newArray).push(err);
|
|
885
1122
|
for (const [clientId, errors] of appErrorGroups) this.#clients.get(clientId)?.sendQueryTransformApplicationErrors(errors);
|
|
886
1123
|
}
|
|
887
1124
|
#addQueryMaterializationServerMetric(queryID, elapsed) {
|
|
@@ -920,7 +1157,7 @@ var ViewSyncerService = class {
|
|
|
920
1157
|
#syncQueryPipelineSet(lc, cvr, customQueryTransformMode, connCtx, driftedQueryIDs = /* @__PURE__ */ new Set(), hydrationBudget = new HydrationBudget(this.#config.viewSyncerHydrationBudgetMs ?? 0, this.#now), hydrationPassStats = {
|
|
921
1158
|
activeHydratedQueries: 0,
|
|
922
1159
|
inactiveHydratedQueries: 0
|
|
923
|
-
}) {
|
|
1160
|
+
}, previousQueries) {
|
|
924
1161
|
return startAsyncSpan(tracer, "vs.#syncQueryPipelineSet", async (span) => {
|
|
925
1162
|
const start = performance.now();
|
|
926
1163
|
span.setAttribute("clientGroupID", this.id);
|
|
@@ -951,7 +1188,13 @@ var ViewSyncerService = class {
|
|
|
951
1188
|
});
|
|
952
1189
|
}
|
|
953
1190
|
};
|
|
954
|
-
const shouldTransformCustomQuery = (query) =>
|
|
1191
|
+
const shouldTransformCustomQuery = (query) => {
|
|
1192
|
+
if (customQueryTransformMode === "all") return true;
|
|
1193
|
+
if (this.#pipelines.queries().has(query.id)) return false;
|
|
1194
|
+
const previous = previousQueries?.get(query.id);
|
|
1195
|
+
if (previous && previous.transformationHash === query.transformationHash) return false;
|
|
1196
|
+
return true;
|
|
1197
|
+
};
|
|
955
1198
|
const transformCustomQueries = async (queries) => {
|
|
956
1199
|
if (!customQueryTransformer || queries.length === 0) return;
|
|
957
1200
|
transformedCustomQueryCount += queries.length;
|
|
@@ -999,8 +1242,35 @@ var ViewSyncerService = class {
|
|
|
999
1242
|
};
|
|
1000
1243
|
const queriesToTransform = [...required, ...optionalToHydrate];
|
|
1001
1244
|
transformOtherQueries(queriesToTransform);
|
|
1245
|
+
if (customQueryTransformMode === "missing" && previousQueries) {
|
|
1246
|
+
for (const query of queriesToTransform) if (query.type === "custom" && !this.#pipelines.queries().has(query.id)) {
|
|
1247
|
+
const previous = previousQueries.get(query.id);
|
|
1248
|
+
if (previous && previous.transformationHash === query.transformationHash) {
|
|
1249
|
+
this.#queryTransformationNoOps.add(1);
|
|
1250
|
+
transformedQueries.push({
|
|
1251
|
+
id: query.id,
|
|
1252
|
+
origQuery: query,
|
|
1253
|
+
transformed: {
|
|
1254
|
+
id: query.id,
|
|
1255
|
+
transformationHash: previous.transformationHash,
|
|
1256
|
+
transformedAst: previous.originalAst ?? previous.transformedAst
|
|
1257
|
+
}
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
}
|
|
1002
1262
|
await transformCustomQueries(queriesToTransform.filter((query) => query.type === "custom" && shouldTransformCustomQuery(query)));
|
|
1003
|
-
const
|
|
1263
|
+
const circuitBrokenQueries = transformedQueries.filter(({ id, origQuery, transformed }) => origQuery.type !== "internal" && this.#pipelines.queries().get(id)?.transformationHash !== transformed.transformationHash && this.#hydrationCircuitBreaker.isOpen(transformed.transformationHash)).map(({ id, origQuery, transformed }) => ({
|
|
1264
|
+
id,
|
|
1265
|
+
transformationHash: transformed.transformationHash,
|
|
1266
|
+
name: origQuery.type === "custom" ? origQuery.name : void 0
|
|
1267
|
+
}));
|
|
1268
|
+
if (circuitBrokenQueries.length > 0) this.#rejectCircuitBrokenQueries(lc, cvr, circuitBrokenQueries);
|
|
1269
|
+
const removeQueriesQueryIds = new Set([
|
|
1270
|
+
...naturallyExpiredQueryIDs,
|
|
1271
|
+
...erroredQueryIDs,
|
|
1272
|
+
...circuitBrokenQueries.map(({ id }) => id)
|
|
1273
|
+
]);
|
|
1004
1274
|
const addQueries = transformedQueries.map(({ id, origQuery, transformed }) => ({
|
|
1005
1275
|
id,
|
|
1006
1276
|
ast: transformed.transformedAst,
|
|
@@ -1011,7 +1281,7 @@ var ViewSyncerService = class {
|
|
|
1011
1281
|
addQueries.sort((a, b) => must(hydrationOrder.get(a.id)) - must(hydrationOrder.get(b.id)));
|
|
1012
1282
|
const requiredAddQueries = addQueries.filter((query) => requiredQueryIDs.has(query.id));
|
|
1013
1283
|
const optionalAddQueries = addQueries.filter((query) => !requiredQueryIDs.has(query.id));
|
|
1014
|
-
lc.info?.(`syncQueryPipelineSet: ${cvrQueryEntires.length} CVR queries, ${transformedCustomQueryCount} custom re-transformed, ${erroredQueryIDs.length} errored, ${removeQueriesQueryIds.size} to remove, ${addQueries.length} to add`);
|
|
1284
|
+
lc.info?.(`syncQueryPipelineSet: ${cvrQueryEntires.length} CVR queries, ${transformedCustomQueryCount} custom re-transformed, ${erroredQueryIDs.length} errored, ${circuitBrokenQueries.length} circuit-broken, ${removeQueriesQueryIds.size} to remove, ${addQueries.length} to add`);
|
|
1015
1285
|
for (const q of addQueries) {
|
|
1016
1286
|
const orig = cvr.queries[q.id];
|
|
1017
1287
|
lc.debug?.("ViewSyncer adding query", q.ast, "transformed from", orig.type === "custom" ? orig.name : orig.ast);
|
|
@@ -1050,6 +1320,107 @@ var ViewSyncerService = class {
|
|
|
1050
1320
|
record.count++;
|
|
1051
1321
|
if (record.count >= THRASH_THRESHOLD) this.#lc.warn?.(`Query thrashing detected for query ${queryID}. ${record.count} replacements in 60s. This may indicate clients with different auth contexts connecting to the same client group.`);
|
|
1052
1322
|
}
|
|
1323
|
+
/**
|
|
1324
|
+
* Records that hydrating `query` was aborted for exceeding the query
|
|
1325
|
+
* hydration timeout, and opens its circuit breaker.
|
|
1326
|
+
*/
|
|
1327
|
+
#recordHydrationTimeout(lc, query, elapsedMs, rowCount) {
|
|
1328
|
+
this.#hydrationCircuitBreaker.trip(query.transformationHash);
|
|
1329
|
+
this.#hydrationTimeouts.add(1);
|
|
1330
|
+
if (!lc.warn) return;
|
|
1331
|
+
const shape = queryShape(query.ast);
|
|
1332
|
+
lc.warn("Query hydration aborted for exceeding the hydration timeout", {
|
|
1333
|
+
clientGroupID: this.id,
|
|
1334
|
+
queryHash: query.id,
|
|
1335
|
+
transformationHash: query.transformationHash,
|
|
1336
|
+
...query.name !== void 0 && { queryName: query.name },
|
|
1337
|
+
queryShape: shape.hash,
|
|
1338
|
+
hydrationTimeoutMs: this.#hydrationCircuitBreaker.timeoutMs,
|
|
1339
|
+
hydrationElapsedMs: elapsedMs,
|
|
1340
|
+
...rowCount !== void 0 && { hydrationRowCount: rowCount },
|
|
1341
|
+
circuitBreakerOpenMs: this.#hydrationCircuitBreaker.openMs,
|
|
1342
|
+
zql: shape.zql
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Logs a hydration that exceeded the slow hydration threshold.
|
|
1347
|
+
*
|
|
1348
|
+
* The query is logged as its {@link queryShape}, with literal values
|
|
1349
|
+
* redacted, and each shape is logged at most once per
|
|
1350
|
+
* {@link SLOW_HYDRATION_LOG_WINDOW_MS}. The next log of a shape reports how
|
|
1351
|
+
* many slow hydrations of it were suppressed in the meantime.
|
|
1352
|
+
*/
|
|
1353
|
+
#logSlowHydration(lc, query, elapsedMs) {
|
|
1354
|
+
if (!lc.warn) return;
|
|
1355
|
+
const stats = this.#pipelines.hydrationStats(query.id);
|
|
1356
|
+
const shape = stats?.shape ?? queryShape(query.ast);
|
|
1357
|
+
const suppressed = slowHydrationLogThrottle.admit(`${query.name ?? ""}:${shape.hash}`);
|
|
1358
|
+
if (suppressed === void 0) return;
|
|
1359
|
+
lc.warn("Slow query materialization", {
|
|
1360
|
+
zeroEvent: "query-slow-hydration",
|
|
1361
|
+
clientGroupID: this.id,
|
|
1362
|
+
queryHash: query.id,
|
|
1363
|
+
transformationHash: query.transformationHash,
|
|
1364
|
+
...query.name !== void 0 && { queryName: query.name },
|
|
1365
|
+
queryShape: shape.hash,
|
|
1366
|
+
hydrationTimeMs: elapsedMs,
|
|
1367
|
+
...stats && {
|
|
1368
|
+
hydrationRowCount: stats.rowCount,
|
|
1369
|
+
hydrationRowsRead: stats.rowsRead
|
|
1370
|
+
},
|
|
1371
|
+
...stats !== void 0 && stats.planWarnings.length > 0 && { planWarnings: stats.planWarnings.map(planWarningMessage) },
|
|
1372
|
+
...suppressed > 0 && { suppressedSinceLastLog: suppressed },
|
|
1373
|
+
zql: shape.zql
|
|
1374
|
+
});
|
|
1375
|
+
}
|
|
1376
|
+
/** Records that `query` was rejected without hydration by its open breaker. */
|
|
1377
|
+
#recordCircuitBreakerRejection(lc, query) {
|
|
1378
|
+
this.#hydrationCircuitBreakerRejections.add(1);
|
|
1379
|
+
lc.warn?.("Query rejected by its open hydration circuit breaker", {
|
|
1380
|
+
clientGroupID: this.id,
|
|
1381
|
+
queryHash: query.id,
|
|
1382
|
+
transformationHash: query.transformationHash,
|
|
1383
|
+
...query.name !== void 0 && { queryName: query.name },
|
|
1384
|
+
hydrationTimeoutMs: this.#hydrationCircuitBreaker.timeoutMs,
|
|
1385
|
+
circuitBreakerOpenMs: this.#hydrationCircuitBreaker.openMs
|
|
1386
|
+
});
|
|
1387
|
+
}
|
|
1388
|
+
/**
|
|
1389
|
+
* Handles queries whose hydration circuit breaker is open: they are counted,
|
|
1390
|
+
* logged, and errored to the affected clients. The caller removes them from
|
|
1391
|
+
* the CVR.
|
|
1392
|
+
*/
|
|
1393
|
+
#rejectCircuitBrokenQueries(lc, cvr, queries) {
|
|
1394
|
+
for (const query of queries) this.#recordCircuitBreakerRejection(lc, query);
|
|
1395
|
+
this.#queryEvictions.add(queries.length, { reason: "hydration-circuit-breaker" });
|
|
1396
|
+
this.#sendHydrationTimeoutErrors(cvr, queries);
|
|
1397
|
+
}
|
|
1398
|
+
/**
|
|
1399
|
+
* Sends a per-query error to every client that desires one of `queries`.
|
|
1400
|
+
* The error goes out as a `transformError` application error, which every
|
|
1401
|
+
* client understands as "this query errored" without affecting the
|
|
1402
|
+
* connection or the client's other queries.
|
|
1403
|
+
*/
|
|
1404
|
+
#sendHydrationTimeoutErrors(cvr, queries) {
|
|
1405
|
+
const timeoutMs = this.#hydrationCircuitBreaker.timeoutMs;
|
|
1406
|
+
const errorsByClient = /* @__PURE__ */ new Map();
|
|
1407
|
+
for (const { id, name } of queries) {
|
|
1408
|
+
const query = cvr.queries[id];
|
|
1409
|
+
if (query === void 0 || query.type === "internal") continue;
|
|
1410
|
+
const error = {
|
|
1411
|
+
error: "app",
|
|
1412
|
+
id,
|
|
1413
|
+
name: name ?? (query.type === "custom" ? query.name : "legacy"),
|
|
1414
|
+
message: `Query hydration exceeded the ${timeoutMs}ms limit (ZERO_VIEW_SYNCER_QUERY_HYDRATION_TIMEOUT_MS) and was aborted`,
|
|
1415
|
+
details: {
|
|
1416
|
+
kind: "HydrationTimeout",
|
|
1417
|
+
timeoutMs
|
|
1418
|
+
}
|
|
1419
|
+
};
|
|
1420
|
+
for (const clientID of Object.keys(query.clientState)) getOrInsertComputed(errorsByClient, clientID, newArray).push(error);
|
|
1421
|
+
}
|
|
1422
|
+
for (const [clientID, errors] of errorsByClient) this.#clients.get(clientID)?.sendQueryTransformApplicationErrors(errors);
|
|
1423
|
+
}
|
|
1053
1424
|
#recordHydrationBudgetExhaustion(lc, hydrationBudget, activeHydratedQueries, inactiveHydratedQueries, inactiveEvictedQueryIDs) {
|
|
1054
1425
|
const elapsedMs = hydrationBudget.exhaustedAtMs;
|
|
1055
1426
|
if (elapsedMs === void 0) return;
|
|
@@ -1076,7 +1447,7 @@ var ViewSyncerService = class {
|
|
|
1076
1447
|
const stateVersion = this.#pipelines.currentVersion();
|
|
1077
1448
|
lc = lc.withContext("stateVersion", stateVersion);
|
|
1078
1449
|
lc.info?.(`hydrating ${addQueries.length} queries`);
|
|
1079
|
-
const updater = new CVRQueryDrivenUpdater(this.#cvrStore, cvr, stateVersion, this.#pipelines.replicaVersion,
|
|
1450
|
+
const updater = new CVRQueryDrivenUpdater(this.#cvrStore, cvr, stateVersion, this.#pipelines.replicaVersion, this.#pipelines);
|
|
1080
1451
|
const sameHashRehydratedQueryIDs = addQueries.filter((q) => cvr.queries[q.id]?.transformationHash === q.transformationHash).map((q) => q.id);
|
|
1081
1452
|
const trackQueriesWillBumpVersion = stateVersion > cvr.version.stateVersion || removeQueries.length > 0 || addQueries.some((q) => cvr.queries[q.id]?.transformationHash !== q.transformationHash);
|
|
1082
1453
|
if (sameHashRehydratedQueryIDs.length > 0 && !trackQueriesWillBumpVersion) {
|
|
@@ -1088,7 +1459,8 @@ var ViewSyncerService = class {
|
|
|
1088
1459
|
}
|
|
1089
1460
|
const { queryPatches, newVersion } = updater.trackQueries(lc, addQueries, removeQueries);
|
|
1090
1461
|
if (hydrationBudget.limitMs !== 0 && optionalQueries.length > 0) assert(cmpVersions(cvr.version, newVersion) < 0, "Optional hydration requires a final poke version before row processing so a removal is actually poked");
|
|
1091
|
-
const
|
|
1462
|
+
const clients = this.#getClients();
|
|
1463
|
+
const pokers = startPoke(lc, clients, newVersion);
|
|
1092
1464
|
for (const patch of queryPatches) await pokers.addPatch(patch);
|
|
1093
1465
|
for (const q of removeQueries) {
|
|
1094
1466
|
this.#pipelines.removeQuery(q.id);
|
|
@@ -1096,7 +1468,7 @@ var ViewSyncerService = class {
|
|
|
1096
1468
|
this.#queryReplacements.delete(q.id);
|
|
1097
1469
|
}
|
|
1098
1470
|
let totalProcessTime = 0;
|
|
1099
|
-
const timer =
|
|
1471
|
+
const timer = this.#timer(lc, "hydration");
|
|
1100
1472
|
const pipelines = this.#pipelines;
|
|
1101
1473
|
const hydrations = this.#hydrations;
|
|
1102
1474
|
const hydrationTime = this.#hydrationTime;
|
|
@@ -1106,8 +1478,11 @@ var ViewSyncerService = class {
|
|
|
1106
1478
|
let firstCoveredQuery;
|
|
1107
1479
|
const hydratedQueryIDs = [];
|
|
1108
1480
|
const budgetEvictedQueryIDs = [];
|
|
1481
|
+
const timedOutQueries = [];
|
|
1482
|
+
const rejectedQueries = [];
|
|
1483
|
+
const circuitBreaker = this.#hydrationCircuitBreaker;
|
|
1109
1484
|
const self = this;
|
|
1110
|
-
await yieldProcess(lc);
|
|
1485
|
+
await (this.#pacer ? this.#pacer.yieldSlice("hydration") : yieldProcess(lc));
|
|
1111
1486
|
function* hydrateQueries(queries, optional, slowHydrateThreshold) {
|
|
1112
1487
|
for (let i = 0; i < queries.length; i++) {
|
|
1113
1488
|
if (optional && hydrationBudget.exhausted()) {
|
|
@@ -1118,15 +1493,34 @@ var ViewSyncerService = class {
|
|
|
1118
1493
|
let queryLC = lc.withContext("hash", q.id).withContext("queryHash", q.id).withContext("transformationHash", q.transformationHash);
|
|
1119
1494
|
if (q.name !== void 0) queryLC = queryLC.withContext("queryName", q.name);
|
|
1120
1495
|
queryLC.debug?.(`adding pipeline for query`, q.ast);
|
|
1496
|
+
const breakable = cvr.queries[q.id]?.type !== "internal";
|
|
1497
|
+
if (breakable && circuitBreaker.isOpen(q.transformationHash)) {
|
|
1498
|
+
rejectedQueries.push(q);
|
|
1499
|
+
self.#recordCircuitBreakerRejection(queryLC, q);
|
|
1500
|
+
continue;
|
|
1501
|
+
}
|
|
1121
1502
|
const covered = queryCoveringIndex ? self.#findQueryCoverageShadowHit(queryCoveringIndex, q.id, q.transformationHash, q.ast, q.name) : void 0;
|
|
1122
1503
|
totalHydratedQueries++;
|
|
1123
1504
|
if (covered) {
|
|
1124
1505
|
coveredHydratedQueries++;
|
|
1125
1506
|
firstCoveredQuery ??= covered;
|
|
1126
1507
|
}
|
|
1127
|
-
|
|
1508
|
+
let timedOut = false;
|
|
1509
|
+
for (const change of pipelines.addQuery(q.transformationHash, q.id, q.ast, timer.startWithoutYielding(), q.name, "query-set-sync")) {
|
|
1510
|
+
if (change === "yield" && breakable && circuitBreaker.exceeded(timer.totalElapsed())) {
|
|
1511
|
+
timedOut = true;
|
|
1512
|
+
yield change;
|
|
1513
|
+
break;
|
|
1514
|
+
}
|
|
1515
|
+
yield change;
|
|
1516
|
+
}
|
|
1128
1517
|
const elapsed = timer.stop();
|
|
1129
1518
|
totalProcessTime += elapsed;
|
|
1519
|
+
if (timedOut) {
|
|
1520
|
+
timedOutQueries.push(q);
|
|
1521
|
+
self.#recordHydrationTimeout(queryLC, q, elapsed);
|
|
1522
|
+
continue;
|
|
1523
|
+
}
|
|
1130
1524
|
hydratedQueryIDs.push(q.id);
|
|
1131
1525
|
if (optional) hydrationPassStats.inactiveHydratedQueries++;
|
|
1132
1526
|
else hydrationPassStats.activeHydratedQueries++;
|
|
@@ -1137,7 +1531,7 @@ var ViewSyncerService = class {
|
|
|
1137
1531
|
transformationHash: q.transformationHash,
|
|
1138
1532
|
...q.name !== void 0 && { queryName: q.name }
|
|
1139
1533
|
});
|
|
1140
|
-
if (elapsed > slowHydrateThreshold) queryLC
|
|
1534
|
+
if (elapsed > slowHydrateThreshold) self.#logSlowHydration(queryLC, q, elapsed);
|
|
1141
1535
|
manualSpan(tracer, "vs.addAndConsumeQuery", elapsed, {
|
|
1142
1536
|
hash: q.id,
|
|
1143
1537
|
transformationHash: q.transformationHash,
|
|
@@ -1151,7 +1545,20 @@ var ViewSyncerService = class {
|
|
|
1151
1545
|
yield* hydrateQueries(requiredQueries, false, slowHydrateThreshold);
|
|
1152
1546
|
yield* hydrateQueries(optionalQueries, true, slowHydrateThreshold);
|
|
1153
1547
|
}
|
|
1154
|
-
await this.#processChanges(lc, timer, generateRowChanges(this.#slowHydrateThreshold), updater, pokers);
|
|
1548
|
+
await this.#processChanges(lc, timer, generateRowChanges(this.#slowHydrateThreshold), (rows) => updater.received(lc, rows), pokers);
|
|
1549
|
+
const abortedQueries = [...timedOutQueries, ...rejectedQueries];
|
|
1550
|
+
if (abortedQueries.length > 0) {
|
|
1551
|
+
const abortedQueryIDs = abortedQueries.map(({ id }) => id);
|
|
1552
|
+
for (const patch of await updater.abortExecutedQueries(lc, abortedQueryIDs)) await pokers.addPatch(patch);
|
|
1553
|
+
for (const queryID of abortedQueryIDs) {
|
|
1554
|
+
this.#pipelines.removeQuery(queryID);
|
|
1555
|
+
this.#inspectorDelegate.removeQuery(queryID);
|
|
1556
|
+
this.#queryReplacements.delete(queryID);
|
|
1557
|
+
}
|
|
1558
|
+
if (timedOutQueries.length > 0) this.#queryEvictions.add(timedOutQueries.length, { reason: "hydration-timeout" });
|
|
1559
|
+
if (rejectedQueries.length > 0) this.#queryEvictions.add(rejectedQueries.length, { reason: "hydration-circuit-breaker" });
|
|
1560
|
+
this.#sendHydrationTimeoutErrors(cvr, abortedQueries);
|
|
1561
|
+
}
|
|
1155
1562
|
for (const patch of updater.removeTrackedQueries(budgetEvictedQueryIDs)) await pokers.addPatch(patch);
|
|
1156
1563
|
for (const queryID of budgetEvictedQueryIDs) {
|
|
1157
1564
|
this.#pipelines.removeQuery(queryID);
|
|
@@ -1163,7 +1570,7 @@ var ViewSyncerService = class {
|
|
|
1163
1570
|
await startAsyncSpan(tracer, "vs.#syncQueryPipelineSet.deleteUnreferencedRows", async () => {
|
|
1164
1571
|
for (const patch of await updater.deleteUnreferencedRows(lc)) await pokers.addPatch(patch);
|
|
1165
1572
|
});
|
|
1166
|
-
this.#cvr = await this.#
|
|
1573
|
+
this.#cvr = await this.#flushPoked(lc, updater, pokers);
|
|
1167
1574
|
if (budgetEvictedQueryIDs.length > 0) this.#scheduleExpireEviction(lc, this.#cvr);
|
|
1168
1575
|
const finalVersion = this.#cvr.version;
|
|
1169
1576
|
await this.#catchupClients(lc, cvr, finalVersion, hydratedQueryIDs, pokers);
|
|
@@ -1195,7 +1602,7 @@ var ViewSyncerService = class {
|
|
|
1195
1602
|
return startAsyncSpan(tracer, "vs.#catchupClients", async (span) => {
|
|
1196
1603
|
current ??= cvr.version;
|
|
1197
1604
|
const clients = this.#getClients();
|
|
1198
|
-
const pokers = usePokers ?? startPoke(clients, cvr.version);
|
|
1605
|
+
const pokers = usePokers ?? startPoke(lc, clients, cvr.version);
|
|
1199
1606
|
span.setAttribute("numClients", clients.length);
|
|
1200
1607
|
const catchupFrom = clients.map((c) => c.version()).reduce((a, b) => cmpVersions(a, b) < 0 ? a : b, cvr.version);
|
|
1201
1608
|
const rowPatches = this.#cvrStore.catchupRowPatches(lc, catchupFrom, cvr, current, excludeQueryHashes);
|
|
@@ -1242,7 +1649,7 @@ var ViewSyncerService = class {
|
|
|
1242
1649
|
}
|
|
1243
1650
|
});
|
|
1244
1651
|
}
|
|
1245
|
-
#processChanges(lc, timer, changes,
|
|
1652
|
+
#processChanges(lc, timer, changes, onBatch, pokers) {
|
|
1246
1653
|
return startAsyncSpan(tracer, "vs.#processChanges", async () => {
|
|
1247
1654
|
const start = performance.now();
|
|
1248
1655
|
const rows = new CustomKeyMap(rowIDString);
|
|
@@ -1251,7 +1658,7 @@ var ViewSyncerService = class {
|
|
|
1251
1658
|
const wallElapsed = performance.now() - start;
|
|
1252
1659
|
total += rows.size;
|
|
1253
1660
|
lc.debug?.(`processing ${rows.size} (of ${total}) rows (${wallElapsed} ms)`);
|
|
1254
|
-
const patches = await
|
|
1661
|
+
const patches = await onBatch(rows);
|
|
1255
1662
|
await startAsyncSpan(tracer, "processBatch.flushToClient", async (span) => {
|
|
1256
1663
|
span.setAttribute("patches", patches.length);
|
|
1257
1664
|
for (const patch of patches) await pokers.addPatch(patch);
|
|
@@ -1316,32 +1723,304 @@ var ViewSyncerService = class {
|
|
|
1316
1723
|
span.setAttribute("clientGroupID", this.id);
|
|
1317
1724
|
assert(this.#pipelines.initialized(), "pipelines must be initialized (advancePipelines");
|
|
1318
1725
|
const start = performance.now();
|
|
1319
|
-
const timer =
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1726
|
+
const timer = this.#timer(lc, "batch");
|
|
1727
|
+
let outcome = { outcome: "error" };
|
|
1728
|
+
let setupTimeMs;
|
|
1729
|
+
let rebuildTimeMs = 0;
|
|
1730
|
+
let evictedQueries = false;
|
|
1731
|
+
this.#pipelineTime.ms = 0;
|
|
1325
1732
|
try {
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1733
|
+
let pokers;
|
|
1734
|
+
let updater;
|
|
1735
|
+
let version;
|
|
1736
|
+
let numChanges = 0;
|
|
1737
|
+
try {
|
|
1738
|
+
const advancement = this.#pipelines.advance(timer, this.#costBasedAdvance(cvr));
|
|
1739
|
+
version = advancement.version;
|
|
1740
|
+
numChanges = advancement.numChanges;
|
|
1741
|
+
lc = lc.withContext("newVersion", version);
|
|
1742
|
+
const targetVersion = cmpVersions(cvr.version, { stateVersion: version }) < 0 ? { stateVersion: version } : cvr.version;
|
|
1743
|
+
pokers = startPoke(lc, this.#getClients(cvr.version), targetVersion);
|
|
1744
|
+
lc.debug?.(`applying ${numChanges} to advance to ${version}`);
|
|
1745
|
+
setupTimeMs = performance.now() - start;
|
|
1746
|
+
await this.#processChanges(lc, await timer.start(), this.#timed(advancement.changes), (rows) => {
|
|
1747
|
+
updater ??= new CVRQueryDrivenUpdater(this.#cvrStore, cvr, version, this.#pipelines.replicaVersion, this.#pipelines);
|
|
1748
|
+
return updater.received(lc, rows);
|
|
1749
|
+
}, pokers);
|
|
1750
|
+
for (const { estimatedPushMs, pushTimeMs } of advancement.estimates()) if (pushTimeMs > 0) this.#pushEstimateRatio.record(estimatedPushMs / pushTimeMs);
|
|
1751
|
+
const abandoned = advancement.abandoned();
|
|
1752
|
+
if (abandoned.length > 0) {
|
|
1753
|
+
updater ??= new CVRQueryDrivenUpdater(this.#cvrStore, cvr, version, this.#pipelines.replicaVersion, this.#pipelines);
|
|
1754
|
+
timer.stop();
|
|
1755
|
+
({rebuildTimeMs, evictedQueries} = await this.#rebuildAbandonedQueries(lc, cvr, abandoned, updater, pokers));
|
|
1756
|
+
}
|
|
1757
|
+
} catch (e) {
|
|
1758
|
+
setupTimeMs ??= performance.now() - start;
|
|
1759
|
+
if (e instanceof ResetPipelinesSignal) {
|
|
1760
|
+
await pokers?.cancel();
|
|
1761
|
+
this.#cvrStore.discardPending();
|
|
1762
|
+
outcome = {
|
|
1763
|
+
outcome: "reset",
|
|
1764
|
+
reason: e.reason
|
|
1765
|
+
};
|
|
1766
|
+
return e;
|
|
1767
|
+
}
|
|
1768
|
+
throw e;
|
|
1331
1769
|
}
|
|
1332
|
-
|
|
1770
|
+
assert(pokers && version !== void 0, "advancement state missing");
|
|
1771
|
+
if (updater) {
|
|
1772
|
+
this.#cvr = await this.#flushPoked(lc, updater, pokers);
|
|
1773
|
+
if (evictedQueries) this.#scheduleExpireEviction(lc, this.#cvr);
|
|
1774
|
+
}
|
|
1775
|
+
const finalVersion = (this.#cvr ?? cvr).version;
|
|
1776
|
+
await startAsyncSpan(tracer, "vs.#advancePipelines.pokeEnd", () => pokers.end(finalVersion));
|
|
1777
|
+
this.#markVersionServed(version);
|
|
1778
|
+
const wallTime = performance.now() - start;
|
|
1779
|
+
const totalProcessTime = timer.totalElapsed() + rebuildTimeMs;
|
|
1780
|
+
lc.debug?.(`finished processing advancement of ${numChanges} changes ((process: ${totalProcessTime} ms, wall: ${wallTime} ms))`);
|
|
1781
|
+
this.#transactionAdvanceTime.recordMs(totalProcessTime);
|
|
1782
|
+
outcome = { outcome: "success" };
|
|
1783
|
+
return "success";
|
|
1784
|
+
} finally {
|
|
1785
|
+
const setupMs = must(setupTimeMs);
|
|
1786
|
+
const processingTimeMs = setupMs + timer.totalElapsed() + rebuildTimeMs;
|
|
1787
|
+
this.#batchTimeMs = setupMs + this.#pipelineTime.ms;
|
|
1788
|
+
const wallTimeMs = performance.now() - start;
|
|
1789
|
+
this.#advancementMetrics.record({
|
|
1790
|
+
processingTimeMs,
|
|
1791
|
+
setupTimeMs: setupMs,
|
|
1792
|
+
wallTimeMs
|
|
1793
|
+
}, outcome);
|
|
1333
1794
|
}
|
|
1334
|
-
this.#cvr = await this.#flushUpdater(lc, updater);
|
|
1335
|
-
const finalVersion = this.#cvr.version;
|
|
1336
|
-
await startAsyncSpan(tracer, "vs.#advancePipelines.pokeEnd", () => pokers.end(finalVersion));
|
|
1337
|
-
this.#markVersionServed(version);
|
|
1338
|
-
const wallTime = performance.now() - start;
|
|
1339
|
-
const totalProcessTime = timer.totalElapsed();
|
|
1340
|
-
lc.debug?.(`finished processing advancement of ${numChanges} changes ((process: ${totalProcessTime} ms, wall: ${wallTime} ms))`);
|
|
1341
|
-
this.#transactionAdvanceTime.recordMs(totalProcessTime);
|
|
1342
|
-
return "success";
|
|
1343
1795
|
});
|
|
1344
1796
|
}
|
|
1797
|
+
/**
|
|
1798
|
+
* What a cost-based advancement needs, or `undefined` if advancements are
|
|
1799
|
+
* bounded by the advancement time limit.
|
|
1800
|
+
*/
|
|
1801
|
+
#costBasedAdvance(cvr) {
|
|
1802
|
+
const shouldCutOff = this.#pushCutoff;
|
|
1803
|
+
if (shouldCutOff === void 0) return;
|
|
1804
|
+
if (this.#pipelines.currentVersion() < cvr.version.stateVersion) return;
|
|
1805
|
+
return {
|
|
1806
|
+
shouldCutOff,
|
|
1807
|
+
rebuildMargin: this.#config.syncRebuildMargin ?? 2
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Hydrates the queries whose pipelines an advancement abandoned, at the
|
|
1812
|
+
* snapshot it advanced to, within the advancement's CVR update and poke.
|
|
1813
|
+
* What the queries contributed to the update before they were abandoned
|
|
1814
|
+
* is retracted first.
|
|
1815
|
+
*
|
|
1816
|
+
* The hydrations are protected as they are in a hydration pass (see
|
|
1817
|
+
* {@link #addAndRemoveQueries}). A query that exceeds the query hydration
|
|
1818
|
+
* timeout, or whose circuit breaker is open, is removed and errored to its
|
|
1819
|
+
* clients. Inactive queries are hydrated last, and those not reached
|
|
1820
|
+
* before the hydration budget is spent are evicted.
|
|
1821
|
+
*
|
|
1822
|
+
* @returns the time spent hydrating, and whether inactive queries were
|
|
1823
|
+
* evicted.
|
|
1824
|
+
*/
|
|
1825
|
+
async #rebuildAbandonedQueries(lc, cvr, abandoned, updater, pokers) {
|
|
1826
|
+
for (const patch of await updater.retractQueries(lc, abandoned.map((q) => q.queryID))) await pokers.addPatch(patch);
|
|
1827
|
+
const hydrationBudget = new HydrationBudget(this.#config.viewSyncerHydrationBudgetMs ?? 0, this.#now);
|
|
1828
|
+
const abandonedByID = new Map(abandoned.map((q) => [q.queryID, q]));
|
|
1829
|
+
const { required, optional } = classifyQueriesForHydration(abandoned.map((q) => must(cvr.queries[q.queryID])));
|
|
1830
|
+
const byRecord = (queries) => queries.map(({ id }) => must(abandonedByID.get(id)));
|
|
1831
|
+
const timer = this.#timer(lc, "batch");
|
|
1832
|
+
const pipelines = this.#pipelines;
|
|
1833
|
+
const circuitBreaker = this.#hydrationCircuitBreaker;
|
|
1834
|
+
const budgetEvicted = [];
|
|
1835
|
+
const timedOut = [];
|
|
1836
|
+
const rejected = [];
|
|
1837
|
+
const rebuilt = {
|
|
1838
|
+
active: 0,
|
|
1839
|
+
inactive: 0
|
|
1840
|
+
};
|
|
1841
|
+
const self = this;
|
|
1842
|
+
let total = 0;
|
|
1843
|
+
function* rebuild(queries, inactive) {
|
|
1844
|
+
for (let i = 0; i < queries.length; i++) {
|
|
1845
|
+
if (inactive && hydrationBudget.exhausted()) {
|
|
1846
|
+
budgetEvicted.push(...queries.slice(i));
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
const q = must(queries[i]);
|
|
1850
|
+
const hydrationQuery = {
|
|
1851
|
+
id: q.queryID,
|
|
1852
|
+
ast: q.originalAst,
|
|
1853
|
+
transformationHash: q.transformationHash,
|
|
1854
|
+
name: q.queryName
|
|
1855
|
+
};
|
|
1856
|
+
const breakable = cvr.queries[q.queryID]?.type !== "internal";
|
|
1857
|
+
if (breakable && circuitBreaker.isOpen(q.transformationHash)) {
|
|
1858
|
+
rejected.push(q);
|
|
1859
|
+
self.#recordCircuitBreakerRejection(lc, hydrationQuery);
|
|
1860
|
+
continue;
|
|
1861
|
+
}
|
|
1862
|
+
let aborted = false;
|
|
1863
|
+
for (const change of pipelines.addQuery(q.transformationHash, q.queryID, q.originalAst, timer.startWithoutYielding(), q.queryName, "unchanged-query-rehydrate")) {
|
|
1864
|
+
if (change === "yield" && breakable && circuitBreaker.exceeded(timer.totalElapsed())) {
|
|
1865
|
+
aborted = true;
|
|
1866
|
+
yield change;
|
|
1867
|
+
break;
|
|
1868
|
+
}
|
|
1869
|
+
yield change;
|
|
1870
|
+
}
|
|
1871
|
+
const elapsed = timer.stop();
|
|
1872
|
+
total += elapsed;
|
|
1873
|
+
if (aborted) {
|
|
1874
|
+
timedOut.push(q);
|
|
1875
|
+
self.#recordHydrationTimeout(lc, hydrationQuery, elapsed);
|
|
1876
|
+
continue;
|
|
1877
|
+
}
|
|
1878
|
+
if (inactive) rebuilt.inactive++;
|
|
1879
|
+
else rebuilt.active++;
|
|
1880
|
+
self.#queryRebuilds.add(1, { reason: q.reason });
|
|
1881
|
+
self.#queryRebuildTime.recordMs(elapsed);
|
|
1882
|
+
self.#addQueryMaterializationServerMetric(q.queryID, elapsed);
|
|
1883
|
+
if (elapsed > self.#slowHydrateThreshold) self.#logSlowHydration(lc, hydrationQuery, elapsed);
|
|
1884
|
+
}
|
|
1885
|
+
}
|
|
1886
|
+
function* rebuildAll() {
|
|
1887
|
+
yield* rebuild(byRecord(required), false);
|
|
1888
|
+
yield* rebuild(byRecord(optional), true);
|
|
1889
|
+
}
|
|
1890
|
+
await this.#processChanges(lc, timer, this.#timed(rebuildAll()), (rows) => updater.received(lc, rows), pokers);
|
|
1891
|
+
const abortedQueries = [...timedOut, ...rejected];
|
|
1892
|
+
if (abortedQueries.length > 0) {
|
|
1893
|
+
for (const patch of await updater.abortExecutedQueries(lc, abortedQueries.map((q) => q.queryID))) await pokers.addPatch(patch);
|
|
1894
|
+
if (timedOut.length > 0) this.#queryEvictions.add(timedOut.length, { reason: "hydration-timeout" });
|
|
1895
|
+
if (rejected.length > 0) this.#queryEvictions.add(rejected.length, { reason: "hydration-circuit-breaker" });
|
|
1896
|
+
this.#sendHydrationTimeoutErrors(cvr, abortedQueries.map((q) => ({
|
|
1897
|
+
id: q.queryID,
|
|
1898
|
+
name: q.queryName
|
|
1899
|
+
})));
|
|
1900
|
+
}
|
|
1901
|
+
const evictedQueryIDs = budgetEvicted.map((q) => q.queryID);
|
|
1902
|
+
for (const patch of updater.removeTrackedQueries(evictedQueryIDs)) await pokers.addPatch(patch);
|
|
1903
|
+
for (const { queryID } of [...abortedQueries, ...budgetEvicted]) {
|
|
1904
|
+
this.#pipelines.removeQuery(queryID);
|
|
1905
|
+
this.#inspectorDelegate.removeQuery(queryID);
|
|
1906
|
+
this.#queryReplacements.delete(queryID);
|
|
1907
|
+
}
|
|
1908
|
+
this.#recordHydrationBudgetExhaustion(lc, hydrationBudget, rebuilt.active, rebuilt.inactive, evictedQueryIDs);
|
|
1909
|
+
for (const patch of await updater.deleteUnreferencedRows(lc)) await pokers.addPatch(patch);
|
|
1910
|
+
this.#logRebuilds(lc, abandoned, {
|
|
1911
|
+
hydrated: rebuilt.active + rebuilt.inactive,
|
|
1912
|
+
hydrationTimeMs: total,
|
|
1913
|
+
timedOut: timedOut.length,
|
|
1914
|
+
rejectedByCircuitBreaker: rejected.length,
|
|
1915
|
+
evictedForHydrationBudget: budgetEvicted.length
|
|
1916
|
+
});
|
|
1917
|
+
return {
|
|
1918
|
+
rebuildTimeMs: total,
|
|
1919
|
+
evictedQueries: evictedQueryIDs.length > 0
|
|
1920
|
+
};
|
|
1921
|
+
}
|
|
1922
|
+
/**
|
|
1923
|
+
* Says in the log that this client group's batches hydrate queries again,
|
|
1924
|
+
* which can be every batch. Nothing else is logged at `info` for a batch,
|
|
1925
|
+
* so this is at most once a minute, for the batches since the last time,
|
|
1926
|
+
* and not before their hydrations add up to a second. Which queries they
|
|
1927
|
+
* were is in the query stats, by query shape (see `QueryStats`).
|
|
1928
|
+
*/
|
|
1929
|
+
#logRebuilds(lc, abandoned, batch) {
|
|
1930
|
+
const log = this.#rebuildLog;
|
|
1931
|
+
log.batches++;
|
|
1932
|
+
log.queries += abandoned.length;
|
|
1933
|
+
for (const { reason } of abandoned) log[reason]++;
|
|
1934
|
+
if (abandoned.some((q) => q.reason === "read")) log.batchesNotRead++;
|
|
1935
|
+
log.hydrated += batch.hydrated;
|
|
1936
|
+
log.hydrationTimeMs += batch.hydrationTimeMs;
|
|
1937
|
+
log.timedOut += batch.timedOut;
|
|
1938
|
+
log.rejectedByCircuitBreaker += batch.rejectedByCircuitBreaker;
|
|
1939
|
+
log.evictedForHydrationBudget += batch.evictedForHydrationBudget;
|
|
1940
|
+
const now = this.#now();
|
|
1941
|
+
if (log.hydrationTimeMs < REBUILD_LOG_MIN_MS || now - this.#rebuildsLoggedAt < REBUILD_LOG_INTERVAL_MS) return;
|
|
1942
|
+
lc.info?.("Client group hydrated queries again in its batches of changes instead of pushing the changes to them", {
|
|
1943
|
+
clientGroupID: this.id,
|
|
1944
|
+
...log
|
|
1945
|
+
});
|
|
1946
|
+
this.#rebuildsLoggedAt = now;
|
|
1947
|
+
this.#rebuildLog = newRebuildLog();
|
|
1948
|
+
}
|
|
1949
|
+
/**
|
|
1950
|
+
* Adds the time that the pipelines take to produce `values` to the time
|
|
1951
|
+
* of the batch being processed (see {@link #batchTimeMs}).
|
|
1952
|
+
*/
|
|
1953
|
+
#timed(values) {
|
|
1954
|
+
return this.#pacer ? timeIteration(values, this.#pipelineTime) : values;
|
|
1955
|
+
}
|
|
1956
|
+
/**
|
|
1957
|
+
* A timer for a batch, or for the hydration of new queries, which has
|
|
1958
|
+
* priority over batches for the worker's time slices (see
|
|
1959
|
+
* `BatchPacer.yieldSlice()`).
|
|
1960
|
+
*/
|
|
1961
|
+
#timer(lc, kind) {
|
|
1962
|
+
const pacer = this.#pacer;
|
|
1963
|
+
return new TimeSliceTimer(lc, pacer && (() => pacer.yieldSlice(kind)));
|
|
1964
|
+
}
|
|
1965
|
+
/**
|
|
1966
|
+
* Waits as long as the worker's pacer says before the next batch, after
|
|
1967
|
+
* one that took `batchTimeMs`. The wait is outside of the
|
|
1968
|
+
* lock, so connections and query changes are served as usual, at the
|
|
1969
|
+
* pipelines' current snapshot. `version-ready` notifications received in
|
|
1970
|
+
* the meantime are coalesced by the subscription, so the next batch covers
|
|
1971
|
+
* all of them.
|
|
1972
|
+
*/
|
|
1973
|
+
async #paceBatches(pacer, batchTimeMs) {
|
|
1974
|
+
this.#smoothedBatchTimeMs = this.#smoothedBatchTimeMs === void 0 ? batchTimeMs : this.#smoothedBatchTimeMs + BATCH_TIME_SMOOTHING * (batchTimeMs - this.#smoothedBatchTimeMs);
|
|
1975
|
+
const processingMs = this.#smoothedBatchTimeMs * (1 + BATCH_WAIT_JITTER * (Math.random() * 2 - 1));
|
|
1976
|
+
const start = performance.now();
|
|
1977
|
+
let waited = false;
|
|
1978
|
+
for (;;) {
|
|
1979
|
+
const remaining = pacer.waitMs(processingMs) - (performance.now() - start);
|
|
1980
|
+
if (remaining <= 0 || !this.#stateChanges.active) break;
|
|
1981
|
+
waited = true;
|
|
1982
|
+
await new Promise((resolve) => {
|
|
1983
|
+
const timer = setTimeout(resolve, Math.min(remaining, BATCH_WAIT_STEP_MS));
|
|
1984
|
+
this.#endBatchWait = () => {
|
|
1985
|
+
clearTimeout(timer);
|
|
1986
|
+
resolve();
|
|
1987
|
+
};
|
|
1988
|
+
});
|
|
1989
|
+
this.#endBatchWait = void 0;
|
|
1990
|
+
}
|
|
1991
|
+
if (waited) {
|
|
1992
|
+
const waitedMs = performance.now() - start;
|
|
1993
|
+
this.#batchWaitTime.recordMs(waitedMs);
|
|
1994
|
+
this.#logBatchWait(pacer, waitedMs);
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
/**
|
|
1998
|
+
* Says in the log that this client group is being held back, which the
|
|
1999
|
+
* worker's metrics do not tell one client group from another by. A client
|
|
2000
|
+
* group that is held back is after every batch, so this is at most once
|
|
2001
|
+
* a minute, for the waits since the last time, and not for waits that add
|
|
2002
|
+
* up to less than a second.
|
|
2003
|
+
*/
|
|
2004
|
+
#logBatchWait(pacer, waitedMs) {
|
|
2005
|
+
const log = this.#batchWaitLog;
|
|
2006
|
+
log.waits++;
|
|
2007
|
+
log.waitedMs += waitedMs;
|
|
2008
|
+
const now = this.#now();
|
|
2009
|
+
if (log.waitedMs < BATCH_WAIT_LOG_MIN_MS || now - log.loggedAt < BATCH_WAIT_LOG_INTERVAL_MS) return;
|
|
2010
|
+
this.#lc.info?.("Client group is waiting between batches: its sync worker is over its share target", {
|
|
2011
|
+
clientGroupID: this.id,
|
|
2012
|
+
waits: log.waits,
|
|
2013
|
+
waitedMs: log.waitedMs,
|
|
2014
|
+
lastWaitMs: waitedMs,
|
|
2015
|
+
batchTimeMs: this.#smoothedBatchTimeMs,
|
|
2016
|
+
waitMultiplier: pacer.multiplier
|
|
2017
|
+
});
|
|
2018
|
+
this.#batchWaitLog = {
|
|
2019
|
+
loggedAt: now,
|
|
2020
|
+
waits: 0,
|
|
2021
|
+
waitedMs: 0
|
|
2022
|
+
};
|
|
2023
|
+
}
|
|
1345
2024
|
async inspect(selector, msg) {
|
|
1346
2025
|
await this.#runInLockForClient(selector, msg, this.#handleInspect);
|
|
1347
2026
|
}
|
|
@@ -1351,7 +2030,7 @@ var ViewSyncerService = class {
|
|
|
1351
2030
|
clientID,
|
|
1352
2031
|
wsID: client.wsID
|
|
1353
2032
|
});
|
|
1354
|
-
return handleInspect(lc, body, cvr, client, this.#inspectorDelegate, this.id, this.#cvrStore, this.#config, connCtx);
|
|
2033
|
+
return handleInspect(lc, body, cvr, client, this.#inspectorDelegate, this.id, this, this.#cvrStore, this.#config, connCtx);
|
|
1355
2034
|
};
|
|
1356
2035
|
async #runBackgroundRetransform(lc) {
|
|
1357
2036
|
const attemptRetransform = async (connCtx) => {
|
|
@@ -1435,18 +2114,22 @@ var ViewSyncerService = class {
|
|
|
1435
2114
|
this.connContextManager.setSharedRetransformReady(false);
|
|
1436
2115
|
this.#initialized.reject(shutdownBeforeInitializationError());
|
|
1437
2116
|
this.#stateChanges.cancel();
|
|
2117
|
+
this.#endBatchWait?.();
|
|
1438
2118
|
return this.#stopped.promise;
|
|
1439
2119
|
}
|
|
1440
2120
|
async #cleanup(err) {
|
|
2121
|
+
this.#shuttingDown = true;
|
|
1441
2122
|
this.connContextManager.setSharedRetransformReady(false);
|
|
1442
2123
|
this.#stopTTLClockInterval();
|
|
1443
2124
|
this.#stopExpireTimer();
|
|
1444
2125
|
this.#stopAuthMaintenanceTimer();
|
|
2126
|
+
this.#stopShutdownTimer();
|
|
1445
2127
|
this.#customQueryTransformer?.destroy();
|
|
1446
2128
|
for (const client of this.#clients.values()) if (err) client.fail(err);
|
|
1447
2129
|
else client.close(`closed clientGroupID=${this.id}`);
|
|
1448
2130
|
await this.#lock.withLock(() => {});
|
|
1449
2131
|
this.#pipelines.destroy();
|
|
2132
|
+
this.#inspectorDelegate.clearAuthenticated(this.id, this);
|
|
1450
2133
|
}
|
|
1451
2134
|
/**
|
|
1452
2135
|
* Test helper: Manually mark initialization as complete.
|
|
@@ -1502,15 +2185,49 @@ function hasExpiredQueries(cvr) {
|
|
|
1502
2185
|
for (const q of Object.values(cvr.queries)) if (expired(ttlClock, q)) return true;
|
|
1503
2186
|
return false;
|
|
1504
2187
|
}
|
|
2188
|
+
/**
|
|
2189
|
+
* Iterates over `values`, adding the time spent producing them to
|
|
2190
|
+
* `total.ms`. The time that the consumer takes between values, including
|
|
2191
|
+
* any that it spends awaiting, is not counted.
|
|
2192
|
+
*/
|
|
2193
|
+
function* timeIteration(values, total) {
|
|
2194
|
+
const iterator = values[Symbol.iterator]();
|
|
2195
|
+
try {
|
|
2196
|
+
for (;;) {
|
|
2197
|
+
const start = performance.now();
|
|
2198
|
+
const result = iterator.next();
|
|
2199
|
+
total.ms += performance.now() - start;
|
|
2200
|
+
if (result.done) return;
|
|
2201
|
+
yield result.value;
|
|
2202
|
+
}
|
|
2203
|
+
} finally {
|
|
2204
|
+
iterator.return?.();
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
/** How often a client group that is waiting between batches asks again. */
|
|
2208
|
+
var BATCH_WAIT_STEP_MS = 250;
|
|
2209
|
+
/** See `ViewSyncerService.#logBatchWait()`. */
|
|
2210
|
+
var BATCH_WAIT_LOG_INTERVAL_MS = 6e4;
|
|
2211
|
+
var BATCH_WAIT_LOG_MIN_MS = 1e3;
|
|
2212
|
+
/** The weight of the latest batch in a client group's smoothed batch time. */
|
|
2213
|
+
var BATCH_TIME_SMOOTHING = .3;
|
|
2214
|
+
/** How far, as a fraction, a client group's wait is varied at random. */
|
|
2215
|
+
var BATCH_WAIT_JITTER = .3;
|
|
1505
2216
|
var TimeSliceTimer = class {
|
|
1506
2217
|
#total = 0;
|
|
1507
2218
|
#start = 0;
|
|
1508
2219
|
#lc;
|
|
1509
|
-
|
|
2220
|
+
#yieldSlice;
|
|
2221
|
+
/**
|
|
2222
|
+
* @param yieldSlice How the timer yields the process, if not by taking
|
|
2223
|
+
* turns with the rest of the worker's work (see `yieldProcess()`).
|
|
2224
|
+
*/
|
|
2225
|
+
constructor(lc, yieldSlice) {
|
|
1510
2226
|
this.#lc = lc;
|
|
2227
|
+
this.#yieldSlice = yieldSlice;
|
|
1511
2228
|
}
|
|
1512
2229
|
async start() {
|
|
1513
|
-
await yieldProcess(this.#lc);
|
|
2230
|
+
await (this.#yieldSlice ? this.#yieldSlice() : yieldProcess(this.#lc));
|
|
1514
2231
|
return this.startWithoutYielding();
|
|
1515
2232
|
}
|
|
1516
2233
|
startWithoutYielding() {
|
|
@@ -1520,7 +2237,7 @@ var TimeSliceTimer = class {
|
|
|
1520
2237
|
}
|
|
1521
2238
|
async yieldProcess(_msgForTesting) {
|
|
1522
2239
|
this.#stopLap();
|
|
1523
|
-
await yieldProcess(this.#lc);
|
|
2240
|
+
await (this.#yieldSlice ? this.#yieldSlice() : yieldProcess(this.#lc));
|
|
1524
2241
|
this.#startLap();
|
|
1525
2242
|
}
|
|
1526
2243
|
#startLap() {
|