@rocicorp/zero 1.11.0-canary.2 → 1.11.0-canary.20
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/bin-analyze.js +9 -8
- package/out/analyze-query/src/bin-analyze.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 +54 -1
- 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/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/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/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/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/z2s/src/compiler.js +1 -1
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +2 -2
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +3 -4
- 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.map +1 -1
- package/out/zero-cache/src/config/normalize.js +26 -2
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +102 -6
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +254 -57
- package/out/zero-cache/src/config/zero-config.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/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/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +27 -10
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +28 -2
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +37 -17
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +8 -1
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/mutator.js +2 -0
- package/out/zero-cache/src/server/mutator.js.map +1 -1
- package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
- package/out/zero-cache/src/server/reaper.js +2 -0
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts +3 -0
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +79 -15
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.js +5 -0
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
- package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
- package/out/zero-cache/src/server/syncer-assigner.js +72 -0
- package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +24 -2
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +11 -9
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +198 -24
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +15 -3
- 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/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/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 +204 -18
- 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 +25 -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 +202 -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 +14 -16
- 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 +64 -143
- 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 +37 -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 +53 -21
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/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 +21 -15
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +86 -23
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +32 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +50 -27
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +100 -34
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +68 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +141 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +43 -0
- 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 +57 -0
- 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 +20 -6
- 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 +66 -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 +154 -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 +2 -0
- 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 +58 -7
- 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-streamer-http.d.ts +48 -6
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +130 -34
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +11 -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 +118 -68
- 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 +37 -15
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +51 -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 +132 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +1 -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 +19 -8
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts +92 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js +42 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +16 -4
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +7 -69
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.js +21 -53
- package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +2 -2
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +9 -6
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +446 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.js +76 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +33 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +76 -0
- 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 +17 -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 +19 -3
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +5 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +35 -5
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +3 -1
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +15 -3
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +24 -7
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +11 -4
- 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 +145 -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 +49 -5
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +3 -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 +50 -20
- 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 +96 -6
- package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +2 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js +2 -2
- package/out/zero-cache/src/services/replicator/replicator.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 +26 -14
- 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/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 +19 -1
- 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 +34 -11
- 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 +51 -2
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +142 -6
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +81 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +128 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +33 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js +62 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +3 -3
- 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 +50 -2
- 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 +471 -62
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +7 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js +35 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -6
- package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +25 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js +28 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +77 -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 +206 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -0
- 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 +78 -4
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +158 -28
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +11 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +587 -103
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +39 -0
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +43 -4
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/profiler.d.ts +12 -0
- package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
- package/out/zero-cache/src/types/profiler.js +46 -1
- package/out/zero-cache/src/types/profiler.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
- package/out/zero-cache/src/types/row-key.js +5 -5
- 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/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 +22 -12
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +92 -25
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/custom.js +2 -2
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/error.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/mutator-proxy.d.ts.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js +5 -2
- 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.map +1 -1
- package/out/zero-client/src/client/query-manager.js +44 -11
- package/out/zero-client/src/client/query-manager.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts +1 -0
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +8 -6
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +18 -3
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +83 -46
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +1 -0
- 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 +58 -0
- package/out/zero-events/src/status.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +13 -14
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +29 -29
- package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
- package/out/zero-protocol/src/query-hash.js +2 -5
- package/out/zero-protocol/src/query-hash.js.map +1 -1
- package/out/zero-react/src/use-query.d.ts +5 -4
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +62 -4
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-react/src/zero.js +1 -0
- package/out/zero-server/src/adapters/drizzle.d.ts +2 -1
- package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
- package/out/zero-server/src/adapters/drizzle.js +12 -7
- package/out/zero-server/src/adapters/drizzle.js.map +1 -1
- package/out/zero-server/src/adapters/kysely.d.ts +2 -1
- package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
- package/out/zero-server/src/adapters/kysely.js +8 -2
- package/out/zero-server/src/adapters/kysely.js.map +1 -1
- package/out/zero-server/src/adapters/pg.d.ts +1 -0
- package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
- package/out/zero-server/src/adapters/pg.js +8 -2
- package/out/zero-server/src/adapters/pg.js.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
- package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.js +7 -1
- package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
- package/out/zero-server/src/adapters/prisma.d.ts +3 -2
- package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
- package/out/zero-server/src/adapters/prisma.js +8 -2
- package/out/zero-server/src/adapters/prisma.js.map +1 -1
- package/out/zero-server/src/custom.d.ts +5 -1
- package/out/zero-server/src/custom.d.ts.map +1 -1
- package/out/zero-server/src/custom.js +6 -3
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/logging.d.ts +2 -2
- package/out/zero-server/src/logging.d.ts.map +1 -1
- package/out/zero-server/src/logging.js +2 -2
- package/out/zero-server/src/logging.js.map +1 -1
- package/out/zero-server/src/mod.d.ts +1 -1
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.d.ts +2 -2
- package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.js +2 -2
- package/out/zero-server/src/pg-query-executor.js.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +12 -3
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +13 -8
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/push-processor.d.ts +8 -2
- package/out/zero-server/src/push-processor.d.ts.map +1 -1
- package/out/zero-server/src/push-processor.js +12 -4
- package/out/zero-server/src/push-processor.js.map +1 -1
- package/out/zero-server/src/schema.d.ts +2 -2
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +2 -2
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-server/src/zql-database.d.ts +21 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js +33 -2
- 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 +58 -9
- 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/connection-index.d.ts +68 -0
- package/out/zql/src/ivm/connection-index.d.ts.map +1 -0
- package/out/zql/src/ivm/connection-index.js +149 -0
- package/out/zql/src/ivm/connection-index.js.map +1 -0
- 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 +28 -3
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +69 -33
- 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 +24 -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 +2 -2
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/planner/planner-builder.d.ts +23 -3
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
- package/out/zql/src/planner/planner-builder.js +34 -17
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-connection.d.ts +58 -2
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
- package/out/zql/src/planner/planner-connection.js +103 -11
- package/out/zql/src/planner/planner-connection.js.map +1 -1
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js +3 -8
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-graph.d.ts +10 -0
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
- package/out/zql/src/planner/planner-graph.js +14 -0
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zql/src/planner/planner-source.d.ts +2 -2
- package/out/zql/src/planner/planner-source.d.ts.map +1 -1
- package/out/zql/src/planner/planner-source.js +2 -2
- package/out/zql/src/planner/planner-source.js.map +1 -1
- package/out/zql/src/planner/planner-warnings.d.ts +83 -0
- package/out/zql/src/planner/planner-warnings.d.ts.map +1 -0
- package/out/zql/src/planner/planner-warnings.js +78 -0
- package/out/zql/src/planner/planner-warnings.js.map +1 -0
- package/out/zql/src/query/measure-push-operator.d.ts +2 -1
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +33 -4
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +4 -2
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +66 -33
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +33 -6
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +1 -0
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +6 -23
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-transitions.d.ts.map +1 -1
- package/out/zql/src/query/query-transitions.js +2 -5
- package/out/zql/src/query/query-transitions.js.map +1 -1
- package/out/zql/src/query/query.d.ts +11 -2
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js +2 -10
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/typed-view.d.ts +1 -1
- package/out/zql/src/query/typed-view.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.js +9 -1
- package/out/zqlite/src/database-storage.js.map +1 -1
- package/out/zqlite/src/db.d.ts +9 -1
- package/out/zqlite/src/db.d.ts.map +1 -1
- package/out/zqlite/src/db.js +31 -27
- package/out/zqlite/src/db.js.map +1 -1
- 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/sqlite-cost-model.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +52 -1
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +5 -31
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/sqlite-stat4-sample.d.ts +37 -0
- package/out/zqlite/src/sqlite-stat4-sample.d.ts.map +1 -0
- package/out/zqlite/src/sqlite-stat4-sample.js +61 -0
- package/out/zqlite/src/sqlite-stat4-sample.js.map +1 -0
- package/out/zqlite/src/table-source.d.ts +83 -2
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +264 -38
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +3 -4
- 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
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { assert } from "../../../../shared/src/asserts.js";
|
|
2
|
+
import { getHeapStatistics } from "node:v8";
|
|
3
|
+
//#region ../zero-cache/src/services/view-syncer/deferred-writes-budget.ts
|
|
4
|
+
/**
|
|
5
|
+
* The bytes assumed for each row held in memory, which converts the memory
|
|
6
|
+
* given to deferred writes into rows. The width of the rows an advancement
|
|
7
|
+
* will hold is not known before it starts.
|
|
8
|
+
*/
|
|
9
|
+
var BYTES_PER_ROW = 1024;
|
|
10
|
+
/**
|
|
11
|
+
* Bounds the memory that deferred IVM writes (see `deferIvmWrites`) use
|
|
12
|
+
* across the client groups of one syncer process.
|
|
13
|
+
*
|
|
14
|
+
* Each client group holds its own in-memory copy of the changes of the
|
|
15
|
+
* advancement it is processing, so the copies add up across the groups that
|
|
16
|
+
* advance at the same time. Before an advancement starts, its pipeline driver
|
|
17
|
+
* reserves the number of change log entries it advances through (of every
|
|
18
|
+
* table, since counting only the tables it reads would take a scan of the
|
|
19
|
+
* entries). That number bounds the rows its sources can hold: the change log
|
|
20
|
+
* has one entry per row key (a truncation, which does not, resets the
|
|
21
|
+
* pipelines instead), and a row displaced through a unique key must itself
|
|
22
|
+
* have changed in the same interval, so it has its own entry. (An entry that
|
|
23
|
+
* sets a row of a table whose primary key in the client schema is not the key
|
|
24
|
+
* the change log uses can change the row's primary key, which is two rows, so
|
|
25
|
+
* the driver reserves a second row for it as it gets to it.) An advancement that does
|
|
26
|
+
* not fit is written through to the replica snapshot instead, which SQLite
|
|
27
|
+
* bounds with its page cache and spills to disk.
|
|
28
|
+
*
|
|
29
|
+
* The rows are reserved at an assumed {@link BYTES_PER_ROW}, but their width
|
|
30
|
+
* is not known until they are held. So the advancements also add up the
|
|
31
|
+
* bytes they are estimated to hold as they go, and the one that takes the
|
|
32
|
+
* total past the budget writes what it holds through to the replica snapshot,
|
|
33
|
+
* and the rest of its changes after them.
|
|
34
|
+
*
|
|
35
|
+
* The budget is a share of the heap, so it does not depend on how many
|
|
36
|
+
* client groups are connected: when advancements do not overlap, each one
|
|
37
|
+
* can use all of it, and when many do, each gets less and the rest write
|
|
38
|
+
* through.
|
|
39
|
+
*/
|
|
40
|
+
var DeferredWritesBudget = class DeferredWritesBudget {
|
|
41
|
+
#maxRows;
|
|
42
|
+
#maxBytes;
|
|
43
|
+
#reservedRows = 0;
|
|
44
|
+
#heldBytes = 0;
|
|
45
|
+
#rowOverruns = 0;
|
|
46
|
+
/**
|
|
47
|
+
* A budget of `proportion` of the heap limit, and the rows that fit in it
|
|
48
|
+
* at {@link BYTES_PER_ROW}.
|
|
49
|
+
*/
|
|
50
|
+
static forHeapProportion(proportion) {
|
|
51
|
+
return DeferredWritesBudget.forBytes(Math.floor(getHeapStatistics().heap_size_limit * proportion));
|
|
52
|
+
}
|
|
53
|
+
/** A budget of `bytes`, and the rows that fit in it at {@link BYTES_PER_ROW}. */
|
|
54
|
+
static forBytes(bytes) {
|
|
55
|
+
return new DeferredWritesBudget(Math.floor(bytes / BYTES_PER_ROW), bytes);
|
|
56
|
+
}
|
|
57
|
+
constructor(maxRows, maxBytes) {
|
|
58
|
+
this.#maxRows = maxRows;
|
|
59
|
+
this.#maxBytes = maxBytes;
|
|
60
|
+
}
|
|
61
|
+
get maxRows() {
|
|
62
|
+
return this.#maxRows;
|
|
63
|
+
}
|
|
64
|
+
get maxBytes() {
|
|
65
|
+
return this.#maxBytes;
|
|
66
|
+
}
|
|
67
|
+
get reservedRows() {
|
|
68
|
+
return this.#reservedRows;
|
|
69
|
+
}
|
|
70
|
+
/** The estimated bytes held by the advancements that hold rows. */
|
|
71
|
+
get heldBytes() {
|
|
72
|
+
return this.#heldBytes;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reserves `rows` if they fit in what is left of the budget, and returns
|
|
76
|
+
* whether they did. A successful reservation must be {@link release}d.
|
|
77
|
+
*/
|
|
78
|
+
tryReserve(rows) {
|
|
79
|
+
return this.#tryReserve(rows);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Reserves `rows` more for an advancement that is already holding rows, if
|
|
83
|
+
* they fit. An advancement reserves a row this way for each change log entry
|
|
84
|
+
* that can change the primary key of the row it sets, as it gets to it, and
|
|
85
|
+
* writes through if it does not fit. The rows are {@link release}d with the rest.
|
|
86
|
+
*/
|
|
87
|
+
tryReserveMore(rows) {
|
|
88
|
+
return this.#tryReserve(rows);
|
|
89
|
+
}
|
|
90
|
+
#tryReserve(rows) {
|
|
91
|
+
if (this.#reservedRows + rows > this.#maxRows) return false;
|
|
92
|
+
this.#reservedRows += rows;
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Adds `bytes` (fewer if negative) to the estimated bytes held by an
|
|
97
|
+
* advancement that has reserved rows, and returns whether the total is
|
|
98
|
+
* still within the budget. If it is not, the advancement is expected to
|
|
99
|
+
* stop holding rows and {@link release} them.
|
|
100
|
+
*/
|
|
101
|
+
holdBytes(bytes) {
|
|
102
|
+
this.#heldBytes += bytes;
|
|
103
|
+
assert(this.#heldBytes >= 0, () => `Holding ${this.#heldBytes} bytes`);
|
|
104
|
+
return this.#heldBytes <= this.#maxBytes;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* The advancements that have held more rows than they reserved, which the
|
|
108
|
+
* reservation is supposed to rule out. Each writes through the rest of its
|
|
109
|
+
* changes instead.
|
|
110
|
+
*/
|
|
111
|
+
get rowOverruns() {
|
|
112
|
+
return this.#rowOverruns;
|
|
113
|
+
}
|
|
114
|
+
recordRowOverrun() {
|
|
115
|
+
this.#rowOverruns++;
|
|
116
|
+
}
|
|
117
|
+
/** Returns an advancement's reserved `rows` and the `bytes` it held. */
|
|
118
|
+
release(rows, bytes) {
|
|
119
|
+
assert(rows <= this.#reservedRows, () => `Releasing ${rows} rows but only ${this.#reservedRows} are reserved`);
|
|
120
|
+
assert(bytes <= this.#heldBytes, () => `Releasing ${bytes} bytes but only ${this.#heldBytes} are held`);
|
|
121
|
+
this.#reservedRows -= rows;
|
|
122
|
+
this.#heldBytes -= bytes;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
//#endregion
|
|
126
|
+
export { DeferredWritesBudget };
|
|
127
|
+
|
|
128
|
+
//# sourceMappingURL=deferred-writes-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deferred-writes-budget.js","names":["#maxRows","#maxBytes","#reservedRows","#heldBytes","#tryReserve","#rowOverruns"],"sources":["../../../../../../zero-cache/src/services/view-syncer/deferred-writes-budget.ts"],"sourcesContent":["import {getHeapStatistics} from 'node:v8';\nimport {assert} from '../../../../shared/src/asserts.ts';\n\n/**\n * The bytes assumed for each row held in memory, which converts the memory\n * given to deferred writes into rows. The width of the rows an advancement\n * will hold is not known before it starts.\n */\nexport const BYTES_PER_ROW = 1024;\n\n/**\n * Bounds the memory that deferred IVM writes (see `deferIvmWrites`) use\n * across the client groups of one syncer process.\n *\n * Each client group holds its own in-memory copy of the changes of the\n * advancement it is processing, so the copies add up across the groups that\n * advance at the same time. Before an advancement starts, its pipeline driver\n * reserves the number of change log entries it advances through (of every\n * table, since counting only the tables it reads would take a scan of the\n * entries). That number bounds the rows its sources can hold: the change log\n * has one entry per row key (a truncation, which does not, resets the\n * pipelines instead), and a row displaced through a unique key must itself\n * have changed in the same interval, so it has its own entry. (An entry that\n * sets a row of a table whose primary key in the client schema is not the key\n * the change log uses can change the row's primary key, which is two rows, so\n * the driver reserves a second row for it as it gets to it.) An advancement that does\n * not fit is written through to the replica snapshot instead, which SQLite\n * bounds with its page cache and spills to disk.\n *\n * The rows are reserved at an assumed {@link BYTES_PER_ROW}, but their width\n * is not known until they are held. So the advancements also add up the\n * bytes they are estimated to hold as they go, and the one that takes the\n * total past the budget writes what it holds through to the replica snapshot,\n * and the rest of its changes after them.\n *\n * The budget is a share of the heap, so it does not depend on how many\n * client groups are connected: when advancements do not overlap, each one\n * can use all of it, and when many do, each gets less and the rest write\n * through.\n */\nexport class DeferredWritesBudget {\n readonly #maxRows: number;\n readonly #maxBytes: number;\n #reservedRows = 0;\n #heldBytes = 0;\n #rowOverruns = 0;\n\n /**\n * A budget of `proportion` of the heap limit, and the rows that fit in it\n * at {@link BYTES_PER_ROW}.\n */\n static forHeapProportion(proportion: number): DeferredWritesBudget {\n return DeferredWritesBudget.forBytes(\n Math.floor(getHeapStatistics().heap_size_limit * proportion),\n );\n }\n\n /** A budget of `bytes`, and the rows that fit in it at {@link BYTES_PER_ROW}. */\n static forBytes(bytes: number): DeferredWritesBudget {\n return new DeferredWritesBudget(Math.floor(bytes / BYTES_PER_ROW), bytes);\n }\n\n constructor(maxRows: number, maxBytes: number) {\n this.#maxRows = maxRows;\n this.#maxBytes = maxBytes;\n }\n\n get maxRows(): number {\n return this.#maxRows;\n }\n\n get maxBytes(): number {\n return this.#maxBytes;\n }\n\n get reservedRows(): number {\n return this.#reservedRows;\n }\n\n /** The estimated bytes held by the advancements that hold rows. */\n get heldBytes(): number {\n return this.#heldBytes;\n }\n\n /**\n * Reserves `rows` if they fit in what is left of the budget, and returns\n * whether they did. A successful reservation must be {@link release}d.\n */\n tryReserve(rows: number): boolean {\n return this.#tryReserve(rows);\n }\n\n /**\n * Reserves `rows` more for an advancement that is already holding rows, if\n * they fit. An advancement reserves a row this way for each change log entry\n * that can change the primary key of the row it sets, as it gets to it, and\n * writes through if it does not fit. The rows are {@link release}d with the rest.\n */\n tryReserveMore(rows: number): boolean {\n return this.#tryReserve(rows);\n }\n\n #tryReserve(rows: number): boolean {\n if (this.#reservedRows + rows > this.#maxRows) {\n return false;\n }\n this.#reservedRows += rows;\n return true;\n }\n\n /**\n * Adds `bytes` (fewer if negative) to the estimated bytes held by an\n * advancement that has reserved rows, and returns whether the total is\n * still within the budget. If it is not, the advancement is expected to\n * stop holding rows and {@link release} them.\n */\n holdBytes(bytes: number): boolean {\n this.#heldBytes += bytes;\n assert(this.#heldBytes >= 0, () => `Holding ${this.#heldBytes} bytes`);\n return this.#heldBytes <= this.#maxBytes;\n }\n\n /**\n * The advancements that have held more rows than they reserved, which the\n * reservation is supposed to rule out. Each writes through the rest of its\n * changes instead.\n */\n get rowOverruns(): number {\n return this.#rowOverruns;\n }\n\n recordRowOverrun(): void {\n this.#rowOverruns++;\n }\n\n /** Returns an advancement's reserved `rows` and the `bytes` it held. */\n release(rows: number, bytes: number): void {\n assert(\n rows <= this.#reservedRows,\n () =>\n `Releasing ${rows} rows but only ${this.#reservedRows} are reserved`,\n );\n assert(\n bytes <= this.#heldBytes,\n () => `Releasing ${bytes} bytes but only ${this.#heldBytes} are held`,\n );\n this.#reservedRows -= rows;\n this.#heldBytes -= bytes;\n }\n}\n"],"mappings":";;;;;;;;AAQA,IAAa,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgC7B,IAAa,uBAAb,MAAa,qBAAqB;CAChC;CACA;CACA,gBAAgB;CAChB,aAAa;CACb,eAAe;;;;;CAMf,OAAO,kBAAkB,YAA0C;EACjE,OAAO,qBAAqB,SAC1B,KAAK,MAAM,kBAAkB,EAAE,kBAAkB,UAAU,CAC7D;CACF;;CAGA,OAAO,SAAS,OAAqC;EACnD,OAAO,IAAI,qBAAqB,KAAK,MAAM,QAAQ,aAAa,GAAG,KAAK;CAC1E;CAEA,YAAY,SAAiB,UAAkB;EAC7C,KAAKA,WAAW;EAChB,KAAKC,YAAY;CACnB;CAEA,IAAI,UAAkB;EACpB,OAAO,KAAKD;CACd;CAEA,IAAI,WAAmB;EACrB,OAAO,KAAKC;CACd;CAEA,IAAI,eAAuB;EACzB,OAAO,KAAKC;CACd;;CAGA,IAAI,YAAoB;EACtB,OAAO,KAAKC;CACd;;;;;CAMA,WAAW,MAAuB;EAChC,OAAO,KAAKC,YAAY,IAAI;CAC9B;;;;;;;CAQA,eAAe,MAAuB;EACpC,OAAO,KAAKA,YAAY,IAAI;CAC9B;CAEA,YAAY,MAAuB;EACjC,IAAI,KAAKF,gBAAgB,OAAO,KAAKF,UACnC,OAAO;EAET,KAAKE,iBAAiB;EACtB,OAAO;CACT;;;;;;;CAQA,UAAU,OAAwB;EAChC,KAAKC,cAAc;EACnB,OAAO,KAAKA,cAAc,SAAS,WAAW,KAAKA,WAAW,OAAO;EACrE,OAAO,KAAKA,cAAc,KAAKF;CACjC;;;;;;CAOA,IAAI,cAAsB;EACxB,OAAO,KAAKI;CACd;CAEA,mBAAyB;EACvB,KAAKA;CACP;;CAGA,QAAQ,MAAc,OAAqB;EACzC,OACE,QAAQ,KAAKH,qBAEX,aAAa,KAAK,iBAAiB,KAAKA,cAAc,cAC1D;EACA,OACE,SAAS,KAAKC,kBACR,aAAa,MAAM,kBAAkB,KAAKA,WAAW,UAC7D;EACA,KAAKD,iBAAiB;EACtB,KAAKC,cAAc;CACrB;AACF"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
type DrainListener = () => void;
|
|
1
2
|
/**
|
|
2
3
|
* There are two types of drains:
|
|
3
4
|
* 1. Elective drains happen when a view-syncer is about to process
|
|
@@ -23,10 +24,22 @@
|
|
|
23
24
|
*/
|
|
24
25
|
export declare class DrainCoordinator {
|
|
25
26
|
#private;
|
|
26
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Calls `listener` once draining has started (immediately if it already
|
|
29
|
+
* has) and returns a function that unsubscribes it.
|
|
30
|
+
*
|
|
31
|
+
* This is a subscription rather than a Promise so that a caller that stops
|
|
32
|
+
* caring (e.g. a view-syncer that finished initializing) can let go of it.
|
|
33
|
+
* A reaction attached to a Promise that may never settle would otherwise
|
|
34
|
+
* be retained by the coordinator for the lifetime of the server, once per
|
|
35
|
+
* view-syncer ever created.
|
|
36
|
+
*/
|
|
37
|
+
onDraining(listener: DrainListener): () => void;
|
|
38
|
+
get drainListenerCount(): number;
|
|
27
39
|
shouldDrain(): 0 | boolean;
|
|
28
40
|
drainNextIn(interval: number): void;
|
|
29
41
|
get forceDrainTimeout(): Promise<void>;
|
|
30
42
|
get nextDrainTime(): number;
|
|
31
43
|
}
|
|
44
|
+
export {};
|
|
32
45
|
//# sourceMappingURL=drain-coordinator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drain-coordinator.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/drain-coordinator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"drain-coordinator.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/drain-coordinator.ts"],"names":[],"mappings":"AAGA,KAAK,aAAa,GAAG,MAAM,IAAI,CAAC;AAMhC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,gBAAgB;;IAO3B;;;;;;;;;OASG;IACH,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,IAAI,CAS9C;IAGD,IAAI,kBAAkB,WAErB;IAED,WAAW,gBAEV;IAED,WAAW,CAAC,QAAQ,EAAE,MAAM,QA0B3B;IAED,IAAI,iBAAiB,kBAEpB;IAGD,IAAI,aAAa,WAEhB;CACF"}
|
|
@@ -26,18 +26,44 @@ var TARGET_UTILIZATION = .6;
|
|
|
26
26
|
* for the next elective or forced drain.
|
|
27
27
|
*/
|
|
28
28
|
var DrainCoordinator = class {
|
|
29
|
-
#draining =
|
|
29
|
+
#draining = false;
|
|
30
|
+
#drainListeners = /* @__PURE__ */ new Set();
|
|
30
31
|
#nextDrainTime = 0;
|
|
31
32
|
#timeout = resolver();
|
|
32
33
|
#timeoutID;
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Calls `listener` once draining has started (immediately if it already
|
|
36
|
+
* has) and returns a function that unsubscribes it.
|
|
37
|
+
*
|
|
38
|
+
* This is a subscription rather than a Promise so that a caller that stops
|
|
39
|
+
* caring (e.g. a view-syncer that finished initializing) can let go of it.
|
|
40
|
+
* A reaction attached to a Promise that may never settle would otherwise
|
|
41
|
+
* be retained by the coordinator for the lifetime of the server, once per
|
|
42
|
+
* view-syncer ever created.
|
|
43
|
+
*/
|
|
44
|
+
onDraining(listener) {
|
|
45
|
+
if (this.#draining) {
|
|
46
|
+
listener();
|
|
47
|
+
return () => {};
|
|
48
|
+
}
|
|
49
|
+
this.#drainListeners.add(listener);
|
|
50
|
+
return () => {
|
|
51
|
+
this.#drainListeners.delete(listener);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
get drainListenerCount() {
|
|
55
|
+
return this.#drainListeners.size;
|
|
35
56
|
}
|
|
36
57
|
shouldDrain() {
|
|
37
58
|
return this.#nextDrainTime && this.#nextDrainTime <= Date.now();
|
|
38
59
|
}
|
|
39
60
|
drainNextIn(interval) {
|
|
40
|
-
this.#draining
|
|
61
|
+
if (!this.#draining) {
|
|
62
|
+
this.#draining = true;
|
|
63
|
+
const listeners = [...this.#drainListeners];
|
|
64
|
+
this.#drainListeners.clear();
|
|
65
|
+
for (const listener of listeners) listener();
|
|
66
|
+
}
|
|
41
67
|
interval /= TARGET_UTILIZATION;
|
|
42
68
|
const now = Date.now();
|
|
43
69
|
assert(this.#nextDrainTime <= now, `drainNextIn() should only be called if shouldDrain()`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"drain-coordinator.js","names":["#draining","#nextDrainTime","#timeoutID","#timeout"],"sources":["../../../../../../zero-cache/src/services/view-syncer/drain-coordinator.ts"],"sourcesContent":["import {resolver} from '@rocicorp/resolver';\nimport {assert} from '../../../../shared/src/asserts.ts';\n\n// The target (additional) utilization to impose on the server\n// that receives the drained connections.\nconst TARGET_UTILIZATION = 0.6;\n\n/**\n * There are two types of drains:\n * 1. Elective drains happen when a view-syncer is about to process\n * a replication event and drains instead because {@link shouldDrain()}\n * returned true. In this case, it exits its processing loop and\n * calls {@link drainNextIn()} immediately.\n * 2. Force drains are performed by the Syncer, which picks a random\n * view-syncer and calls {@link stop()}.\n *\n * In the case of a forced drain, the view-syncer may be queued up\n * behind a large amount of CPU-consuming events, and thus it may take\n * a long time before it actually stops. Elective drains are preferred because\n * they are less subject to that variance. However, elective drains only happen\n * if there is a task to be processed, so forced drains are still necessary\n * for draining servers with no work / tasks.\n *\n * The Syncer kicks off the drain process by calling {@link drainNextIn drainNextIn(0)},\n * which sets off a short {@link forceDrainTimeout} but starts returning `true` for\n * {@link shouldDrain()} for elective drains. In the latter case, the drained\n * view-syncer immediately exiting its processing loop and calls\n * {@link drainNextIn drainNextIn(myHydrationTime)} to reset the timeout\n * for the next elective or forced drain.\n */\nexport class DrainCoordinator {\n readonly #
|
|
1
|
+
{"version":3,"file":"drain-coordinator.js","names":["#drainListeners","#draining","#nextDrainTime","#timeoutID","#timeout"],"sources":["../../../../../../zero-cache/src/services/view-syncer/drain-coordinator.ts"],"sourcesContent":["import {resolver} from '@rocicorp/resolver';\nimport {assert} from '../../../../shared/src/asserts.ts';\n\ntype DrainListener = () => void;\n\n// The target (additional) utilization to impose on the server\n// that receives the drained connections.\nconst TARGET_UTILIZATION = 0.6;\n\n/**\n * There are two types of drains:\n * 1. Elective drains happen when a view-syncer is about to process\n * a replication event and drains instead because {@link shouldDrain()}\n * returned true. In this case, it exits its processing loop and\n * calls {@link drainNextIn()} immediately.\n * 2. Force drains are performed by the Syncer, which picks a random\n * view-syncer and calls {@link stop()}.\n *\n * In the case of a forced drain, the view-syncer may be queued up\n * behind a large amount of CPU-consuming events, and thus it may take\n * a long time before it actually stops. Elective drains are preferred because\n * they are less subject to that variance. However, elective drains only happen\n * if there is a task to be processed, so forced drains are still necessary\n * for draining servers with no work / tasks.\n *\n * The Syncer kicks off the drain process by calling {@link drainNextIn drainNextIn(0)},\n * which sets off a short {@link forceDrainTimeout} but starts returning `true` for\n * {@link shouldDrain()} for elective drains. In the latter case, the drained\n * view-syncer immediately exiting its processing loop and calls\n * {@link drainNextIn drainNextIn(myHydrationTime)} to reset the timeout\n * for the next elective or forced drain.\n */\nexport class DrainCoordinator {\n #draining = false;\n readonly #drainListeners = new Set<DrainListener>();\n #nextDrainTime = 0;\n #timeout = resolver();\n #timeoutID: NodeJS.Timeout | undefined;\n\n /**\n * Calls `listener` once draining has started (immediately if it already\n * has) and returns a function that unsubscribes it.\n *\n * This is a subscription rather than a Promise so that a caller that stops\n * caring (e.g. a view-syncer that finished initializing) can let go of it.\n * A reaction attached to a Promise that may never settle would otherwise\n * be retained by the coordinator for the lifetime of the server, once per\n * view-syncer ever created.\n */\n onDraining(listener: DrainListener): () => void {\n if (this.#draining) {\n listener();\n return () => {};\n }\n this.#drainListeners.add(listener);\n return () => {\n this.#drainListeners.delete(listener);\n };\n }\n\n // Exposed for testing.\n get drainListenerCount() {\n return this.#drainListeners.size;\n }\n\n shouldDrain() {\n return this.#nextDrainTime && this.#nextDrainTime <= Date.now();\n }\n\n drainNextIn(interval: number) {\n if (!this.#draining) {\n this.#draining = true;\n const listeners = [...this.#drainListeners];\n this.#drainListeners.clear();\n for (const listener of listeners) {\n listener();\n }\n }\n // Increase the timeout between drains to give the receiving\n // server space to perform normal processing.\n interval /= TARGET_UTILIZATION;\n\n const now = Date.now();\n assert(\n this.#nextDrainTime <= now,\n `drainNextIn() should only be called if shouldDrain()`,\n );\n this.#nextDrainTime = now + interval;\n\n // Push the forceDrainTimeout forward.\n clearTimeout(this.#timeoutID);\n this.#timeoutID = setTimeout(() => {\n this.#timeout.resolve();\n this.#timeout = resolver();\n }, interval + FORCE_DRAIN_PADDING);\n }\n\n get forceDrainTimeout() {\n return this.#timeout.promise;\n }\n\n // Exposed for testing.\n get nextDrainTime() {\n return this.#nextDrainTime;\n }\n}\n\nconst FORCE_DRAIN_PADDING = 2;\n"],"mappings":";;;AAOA,IAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;AAyB3B,IAAa,mBAAb,MAA8B;CAC5B,YAAY;CACZ,kCAA2B,IAAI,IAAmB;CAClD,iBAAiB;CACjB,WAAW,SAAS;CACpB;;;;;;;;;;;CAYA,WAAW,UAAqC;EAC9C,IAAI,KAAKC,WAAW;GAClB,SAAS;GACT,aAAa,CAAC;EAChB;EACA,KAAKD,gBAAgB,IAAI,QAAQ;EACjC,aAAa;GACX,KAAKA,gBAAgB,OAAO,QAAQ;EACtC;CACF;CAGA,IAAI,qBAAqB;EACvB,OAAO,KAAKA,gBAAgB;CAC9B;CAEA,cAAc;EACZ,OAAO,KAAKE,kBAAkB,KAAKA,kBAAkB,KAAK,IAAI;CAChE;CAEA,YAAY,UAAkB;EAC5B,IAAI,CAAC,KAAKD,WAAW;GACnB,KAAKA,YAAY;GACjB,MAAM,YAAY,CAAC,GAAG,KAAKD,eAAe;GAC1C,KAAKA,gBAAgB,MAAM;GAC3B,KAAK,MAAM,YAAY,WACrB,SAAS;EAEb;EAGA,YAAY;EAEZ,MAAM,MAAM,KAAK,IAAI;EACrB,OACE,KAAKE,kBAAkB,KACvB,sDACF;EACA,KAAKA,iBAAiB,MAAM;EAG5B,aAAa,KAAKC,UAAU;EAC5B,KAAKA,aAAa,iBAAiB;GACjC,KAAKC,SAAS,QAAQ;GACtB,KAAKA,WAAW,SAAS;EAC3B,GAAG,WAAW,mBAAmB;CACnC;CAEA,IAAI,oBAAoB;EACtB,OAAO,KAAKA,SAAS;CACvB;CAGA,IAAI,gBAAgB;EAClB,OAAO,KAAKF;CACd;AACF;AAEA,IAAM,sBAAsB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type MonotonicClock = () => number;
|
|
2
|
+
/**
|
|
3
|
+
* A soft wall-clock budget for one view-syncer hydration pass.
|
|
4
|
+
*
|
|
5
|
+
* Callers check the budget only at query boundaries. Consequently, a query
|
|
6
|
+
* that starts before the limit is reached is always allowed to finish.
|
|
7
|
+
*
|
|
8
|
+
* The budget measures hydration work. Intervals that are not hydration --
|
|
9
|
+
* notably the remote custom-query transform round trips -- are discounted via
|
|
10
|
+
* {@link excluding}, so that endpoint latency cannot spend a budget that only
|
|
11
|
+
* evicting queries could recover.
|
|
12
|
+
*/
|
|
13
|
+
export declare class HydrationBudget {
|
|
14
|
+
#private;
|
|
15
|
+
readonly limitMs: number;
|
|
16
|
+
constructor(limitMs: number, now?: MonotonicClock);
|
|
17
|
+
/**
|
|
18
|
+
* Runs `fn`, discounting the time it takes as non-hydration work. The
|
|
19
|
+
* interval is measured with this budget's own clock, so an injected clock
|
|
20
|
+
* governs both the elapsed time and what is excluded from it.
|
|
21
|
+
*/
|
|
22
|
+
excluding<T>(fn: () => Promise<T>): Promise<T>;
|
|
23
|
+
elapsedMs(): number;
|
|
24
|
+
/**
|
|
25
|
+
* Whether the budget is spent. A disabled budget (`limitMs === 0`) is never
|
|
26
|
+
* exhausted. The elapsed time at the first exhausted check is retained in
|
|
27
|
+
* {@link exhaustedAtMs} so that reporting does not re-read the clock.
|
|
28
|
+
*/
|
|
29
|
+
exhausted(): boolean;
|
|
30
|
+
/** The elapsed time at which {@link exhausted} first returned true. */
|
|
31
|
+
get exhaustedAtMs(): number | undefined;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=hydration-budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydration-budget.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/hydration-budget.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC;AAE1C;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAMzB,YACE,OAAO,EAAE,MAAM,EACf,GAAG,GAAE,cAAkD,EASxD;IAED;;;;OAIG;IACG,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAOnD;IAED,SAAS,IAAI,MAAM,CAElB;IAED;;;;OAIG;IACH,SAAS,IAAI,OAAO,CAUnB;IAED,uEAAuE;IACvE,IAAI,aAAa,IAAI,MAAM,GAAG,SAAS,CAEtC;CACF"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { assert } from "../../../../shared/src/asserts.js";
|
|
2
|
+
//#region ../zero-cache/src/services/view-syncer/hydration-budget.ts
|
|
3
|
+
/**
|
|
4
|
+
* A soft wall-clock budget for one view-syncer hydration pass.
|
|
5
|
+
*
|
|
6
|
+
* Callers check the budget only at query boundaries. Consequently, a query
|
|
7
|
+
* that starts before the limit is reached is always allowed to finish.
|
|
8
|
+
*
|
|
9
|
+
* The budget measures hydration work. Intervals that are not hydration --
|
|
10
|
+
* notably the remote custom-query transform round trips -- are discounted via
|
|
11
|
+
* {@link excluding}, so that endpoint latency cannot spend a budget that only
|
|
12
|
+
* evicting queries could recover.
|
|
13
|
+
*/
|
|
14
|
+
var HydrationBudget = class {
|
|
15
|
+
limitMs;
|
|
16
|
+
#now;
|
|
17
|
+
#startedAt;
|
|
18
|
+
#excludedMs = 0;
|
|
19
|
+
#exhaustedAtMs;
|
|
20
|
+
constructor(limitMs, now = performance.now.bind(performance)) {
|
|
21
|
+
assert(Number.isSafeInteger(limitMs) && limitMs >= 0, "Hydration budget must be a nonnegative integer");
|
|
22
|
+
this.limitMs = limitMs;
|
|
23
|
+
this.#now = now;
|
|
24
|
+
this.#startedAt = now();
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Runs `fn`, discounting the time it takes as non-hydration work. The
|
|
28
|
+
* interval is measured with this budget's own clock, so an injected clock
|
|
29
|
+
* governs both the elapsed time and what is excluded from it.
|
|
30
|
+
*/
|
|
31
|
+
async excluding(fn) {
|
|
32
|
+
const start = this.#now();
|
|
33
|
+
try {
|
|
34
|
+
return await fn();
|
|
35
|
+
} finally {
|
|
36
|
+
this.#excludedMs += this.#now() - start;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
elapsedMs() {
|
|
40
|
+
return this.#now() - this.#startedAt - this.#excludedMs;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Whether the budget is spent. A disabled budget (`limitMs === 0`) is never
|
|
44
|
+
* exhausted. The elapsed time at the first exhausted check is retained in
|
|
45
|
+
* {@link exhaustedAtMs} so that reporting does not re-read the clock.
|
|
46
|
+
*/
|
|
47
|
+
exhausted() {
|
|
48
|
+
if (this.limitMs === 0) return false;
|
|
49
|
+
const elapsed = this.elapsedMs();
|
|
50
|
+
if (elapsed < this.limitMs) return false;
|
|
51
|
+
this.#exhaustedAtMs ??= elapsed;
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
/** The elapsed time at which {@link exhausted} first returned true. */
|
|
55
|
+
get exhaustedAtMs() {
|
|
56
|
+
return this.#exhaustedAtMs;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
export { HydrationBudget };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=hydration-budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydration-budget.js","names":["#now","#startedAt","#excludedMs","#exhaustedAtMs"],"sources":["../../../../../../zero-cache/src/services/view-syncer/hydration-budget.ts"],"sourcesContent":["import {assert} from '../../../../shared/src/asserts.ts';\n\nexport type MonotonicClock = () => number;\n\n/**\n * A soft wall-clock budget for one view-syncer hydration pass.\n *\n * Callers check the budget only at query boundaries. Consequently, a query\n * that starts before the limit is reached is always allowed to finish.\n *\n * The budget measures hydration work. Intervals that are not hydration --\n * notably the remote custom-query transform round trips -- are discounted via\n * {@link excluding}, so that endpoint latency cannot spend a budget that only\n * evicting queries could recover.\n */\nexport class HydrationBudget {\n readonly limitMs: number;\n readonly #now: MonotonicClock;\n readonly #startedAt: number;\n #excludedMs = 0;\n #exhaustedAtMs: number | undefined;\n\n constructor(\n limitMs: number,\n now: MonotonicClock = performance.now.bind(performance),\n ) {\n assert(\n Number.isSafeInteger(limitMs) && limitMs >= 0,\n 'Hydration budget must be a nonnegative integer',\n );\n this.limitMs = limitMs;\n this.#now = now;\n this.#startedAt = now();\n }\n\n /**\n * Runs `fn`, discounting the time it takes as non-hydration work. The\n * interval is measured with this budget's own clock, so an injected clock\n * governs both the elapsed time and what is excluded from it.\n */\n async excluding<T>(fn: () => Promise<T>): Promise<T> {\n const start = this.#now();\n try {\n return await fn();\n } finally {\n this.#excludedMs += this.#now() - start;\n }\n }\n\n elapsedMs(): number {\n return this.#now() - this.#startedAt - this.#excludedMs;\n }\n\n /**\n * Whether the budget is spent. A disabled budget (`limitMs === 0`) is never\n * exhausted. The elapsed time at the first exhausted check is retained in\n * {@link exhaustedAtMs} so that reporting does not re-read the clock.\n */\n exhausted(): boolean {\n if (this.limitMs === 0) {\n return false;\n }\n const elapsed = this.elapsedMs();\n if (elapsed < this.limitMs) {\n return false;\n }\n this.#exhaustedAtMs ??= elapsed;\n return true;\n }\n\n /** The elapsed time at which {@link exhausted} first returned true. */\n get exhaustedAtMs(): number | undefined {\n return this.#exhaustedAtMs;\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAeA,IAAa,kBAAb,MAA6B;CAC3B;CACA;CACA;CACA,cAAc;CACd;CAEA,YACE,SACA,MAAsB,YAAY,IAAI,KAAK,WAAW,GACtD;EACA,OACE,OAAO,cAAc,OAAO,KAAK,WAAW,GAC5C,gDACF;EACA,KAAK,UAAU;EACf,KAAKA,OAAO;EACZ,KAAKC,aAAa,IAAI;CACxB;;;;;;CAOA,MAAM,UAAa,IAAkC;EACnD,MAAM,QAAQ,KAAKD,KAAK;EACxB,IAAI;GACF,OAAO,MAAM,GAAG;EAClB,UAAU;GACR,KAAKE,eAAe,KAAKF,KAAK,IAAI;EACpC;CACF;CAEA,YAAoB;EAClB,OAAO,KAAKA,KAAK,IAAI,KAAKC,aAAa,KAAKC;CAC9C;;;;;;CAOA,YAAqB;EACnB,IAAI,KAAK,YAAY,GACnB,OAAO;EAET,MAAM,UAAU,KAAK,UAAU;EAC/B,IAAI,UAAU,KAAK,SACjB,OAAO;EAET,KAAKC,mBAAmB;EACxB,OAAO;CACT;;CAGA,IAAI,gBAAoC;EACtC,OAAO,KAAKA;CACd;AACF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { MonotonicClock } from './hydration-budget.ts';
|
|
2
|
+
/**
|
|
3
|
+
* How long a tripped query stays rejected before a retry is allowed.
|
|
4
|
+
*
|
|
5
|
+
* A query that blows the timeout is almost always slow because of the shape
|
|
6
|
+
* of its data rather than because of transient load, so retrying it on every
|
|
7
|
+
* reconnect would burn a full timeout each time. The cooldown keeps that cost
|
|
8
|
+
* to at most one timeout per cooldown period per query.
|
|
9
|
+
*/
|
|
10
|
+
export declare const DEFAULT_CIRCUIT_BREAKER_OPEN_MS: number;
|
|
11
|
+
/**
|
|
12
|
+
* A per-query circuit breaker for view-syncer hydration.
|
|
13
|
+
*
|
|
14
|
+
* Hydration of a single query is aborted once its processing time exceeds
|
|
15
|
+
* {@link timeoutMs}. Callers check {@link exceeded} at the yield points of a
|
|
16
|
+
* hydration, so a query is only ever aborted between time slices.
|
|
17
|
+
*
|
|
18
|
+
* Once a query has been aborted the breaker is "open" for its transformation
|
|
19
|
+
* hash: {@link isOpen} reports true for {@link openMs}, and callers reject the
|
|
20
|
+
* query up front instead of hydrating it again. After that the breaker is
|
|
21
|
+
* implicitly half-open: the next hydration attempt runs, and either succeeds
|
|
22
|
+
* or trips the breaker again.
|
|
23
|
+
*
|
|
24
|
+
* The breaker is keyed by transformation hash rather than query hash because
|
|
25
|
+
* the transformation (permissions, auth context) determines the pipeline that
|
|
26
|
+
* runs, and a different transformation of the same query may well be fast.
|
|
27
|
+
*/
|
|
28
|
+
export declare class HydrationCircuitBreaker {
|
|
29
|
+
#private;
|
|
30
|
+
readonly timeoutMs: number;
|
|
31
|
+
readonly openMs: number;
|
|
32
|
+
constructor(timeoutMs: number, openMs?: number, now?: MonotonicClock);
|
|
33
|
+
/** Whether the breaker does anything at all. */
|
|
34
|
+
get enabled(): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Whether a hydration that has consumed `elapsedMs` of processing time must
|
|
37
|
+
* be aborted. Always false when the breaker is disabled.
|
|
38
|
+
*/
|
|
39
|
+
exceeded(elapsedMs: number): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Records that hydrating `transformationHash` was aborted.
|
|
42
|
+
*
|
|
43
|
+
* Trips are rare, so this is also when expired entries are swept, which
|
|
44
|
+
* keeps the map bounded by the number of hashes tripped within one cooldown
|
|
45
|
+
* rather than by every hash ever tripped.
|
|
46
|
+
*/
|
|
47
|
+
trip(transformationHash: string): void;
|
|
48
|
+
/** Whether `transformationHash` is currently rejected. */
|
|
49
|
+
isOpen(transformationHash: string): boolean;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=hydration-circuit-breaker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydration-circuit-breaker.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/hydration-circuit-breaker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,QAAa,CAAC;AAE1D;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,uBAAuB;;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAIxB,YACE,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAAwC,EAChD,GAAG,GAAE,cAAkD,EAUxD;IAED,gDAAgD;IAChD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEnC;IAED;;;;;;OAMG;IACH,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAQrC;IAED,0DAA0D;IAC1D,MAAM,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO,CAU1C;CACF"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { assert } from "../../../../shared/src/asserts.js";
|
|
2
|
+
//#region ../zero-cache/src/services/view-syncer/hydration-circuit-breaker.ts
|
|
3
|
+
/**
|
|
4
|
+
* How long a tripped query stays rejected before a retry is allowed.
|
|
5
|
+
*
|
|
6
|
+
* A query that blows the timeout is almost always slow because of the shape
|
|
7
|
+
* of its data rather than because of transient load, so retrying it on every
|
|
8
|
+
* reconnect would burn a full timeout each time. The cooldown keeps that cost
|
|
9
|
+
* to at most one timeout per cooldown period per query.
|
|
10
|
+
*/
|
|
11
|
+
var DEFAULT_CIRCUIT_BREAKER_OPEN_MS = 5 * 6e4;
|
|
12
|
+
/**
|
|
13
|
+
* A per-query circuit breaker for view-syncer hydration.
|
|
14
|
+
*
|
|
15
|
+
* Hydration of a single query is aborted once its processing time exceeds
|
|
16
|
+
* {@link timeoutMs}. Callers check {@link exceeded} at the yield points of a
|
|
17
|
+
* hydration, so a query is only ever aborted between time slices.
|
|
18
|
+
*
|
|
19
|
+
* Once a query has been aborted the breaker is "open" for its transformation
|
|
20
|
+
* hash: {@link isOpen} reports true for {@link openMs}, and callers reject the
|
|
21
|
+
* query up front instead of hydrating it again. After that the breaker is
|
|
22
|
+
* implicitly half-open: the next hydration attempt runs, and either succeeds
|
|
23
|
+
* or trips the breaker again.
|
|
24
|
+
*
|
|
25
|
+
* The breaker is keyed by transformation hash rather than query hash because
|
|
26
|
+
* the transformation (permissions, auth context) determines the pipeline that
|
|
27
|
+
* runs, and a different transformation of the same query may well be fast.
|
|
28
|
+
*/
|
|
29
|
+
var HydrationCircuitBreaker = class {
|
|
30
|
+
timeoutMs;
|
|
31
|
+
openMs;
|
|
32
|
+
#now;
|
|
33
|
+
#openedAt = /* @__PURE__ */ new Map();
|
|
34
|
+
constructor(timeoutMs, openMs = DEFAULT_CIRCUIT_BREAKER_OPEN_MS, now = performance.now.bind(performance)) {
|
|
35
|
+
assert(Number.isSafeInteger(timeoutMs) && timeoutMs >= 0, "Hydration timeout must be a nonnegative integer");
|
|
36
|
+
assert(openMs >= 0, "Circuit breaker open duration must be nonnegative");
|
|
37
|
+
this.timeoutMs = timeoutMs;
|
|
38
|
+
this.openMs = openMs;
|
|
39
|
+
this.#now = now;
|
|
40
|
+
}
|
|
41
|
+
/** Whether the breaker does anything at all. */
|
|
42
|
+
get enabled() {
|
|
43
|
+
return this.timeoutMs > 0;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Whether a hydration that has consumed `elapsedMs` of processing time must
|
|
47
|
+
* be aborted. Always false when the breaker is disabled.
|
|
48
|
+
*/
|
|
49
|
+
exceeded(elapsedMs) {
|
|
50
|
+
return this.enabled && elapsedMs >= this.timeoutMs;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Records that hydrating `transformationHash` was aborted.
|
|
54
|
+
*
|
|
55
|
+
* Trips are rare, so this is also when expired entries are swept, which
|
|
56
|
+
* keeps the map bounded by the number of hashes tripped within one cooldown
|
|
57
|
+
* rather than by every hash ever tripped.
|
|
58
|
+
*/
|
|
59
|
+
trip(transformationHash) {
|
|
60
|
+
const now = this.#now();
|
|
61
|
+
for (const [hash, openedAt] of this.#openedAt) if (now - openedAt >= this.openMs) this.#openedAt.delete(hash);
|
|
62
|
+
this.#openedAt.set(transformationHash, now);
|
|
63
|
+
}
|
|
64
|
+
/** Whether `transformationHash` is currently rejected. */
|
|
65
|
+
isOpen(transformationHash) {
|
|
66
|
+
const openedAt = this.#openedAt.get(transformationHash);
|
|
67
|
+
if (openedAt === void 0) return false;
|
|
68
|
+
if (this.#now() - openedAt >= this.openMs) {
|
|
69
|
+
this.#openedAt.delete(transformationHash);
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
//#endregion
|
|
76
|
+
export { HydrationCircuitBreaker };
|
|
77
|
+
|
|
78
|
+
//# sourceMappingURL=hydration-circuit-breaker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hydration-circuit-breaker.js","names":["#now","#openedAt"],"sources":["../../../../../../zero-cache/src/services/view-syncer/hydration-circuit-breaker.ts"],"sourcesContent":["import {assert} from '../../../../shared/src/asserts.ts';\nimport type {MonotonicClock} from './hydration-budget.ts';\n\n/**\n * How long a tripped query stays rejected before a retry is allowed.\n *\n * A query that blows the timeout is almost always slow because of the shape\n * of its data rather than because of transient load, so retrying it on every\n * reconnect would burn a full timeout each time. The cooldown keeps that cost\n * to at most one timeout per cooldown period per query.\n */\nexport const DEFAULT_CIRCUIT_BREAKER_OPEN_MS = 5 * 60_000;\n\n/**\n * A per-query circuit breaker for view-syncer hydration.\n *\n * Hydration of a single query is aborted once its processing time exceeds\n * {@link timeoutMs}. Callers check {@link exceeded} at the yield points of a\n * hydration, so a query is only ever aborted between time slices.\n *\n * Once a query has been aborted the breaker is \"open\" for its transformation\n * hash: {@link isOpen} reports true for {@link openMs}, and callers reject the\n * query up front instead of hydrating it again. After that the breaker is\n * implicitly half-open: the next hydration attempt runs, and either succeeds\n * or trips the breaker again.\n *\n * The breaker is keyed by transformation hash rather than query hash because\n * the transformation (permissions, auth context) determines the pipeline that\n * runs, and a different transformation of the same query may well be fast.\n */\nexport class HydrationCircuitBreaker {\n readonly timeoutMs: number;\n readonly openMs: number;\n readonly #now: MonotonicClock;\n readonly #openedAt = new Map<string, number>();\n\n constructor(\n timeoutMs: number,\n openMs: number = DEFAULT_CIRCUIT_BREAKER_OPEN_MS,\n now: MonotonicClock = performance.now.bind(performance),\n ) {\n assert(\n Number.isSafeInteger(timeoutMs) && timeoutMs >= 0,\n 'Hydration timeout must be a nonnegative integer',\n );\n assert(openMs >= 0, 'Circuit breaker open duration must be nonnegative');\n this.timeoutMs = timeoutMs;\n this.openMs = openMs;\n this.#now = now;\n }\n\n /** Whether the breaker does anything at all. */\n get enabled(): boolean {\n return this.timeoutMs > 0;\n }\n\n /**\n * Whether a hydration that has consumed `elapsedMs` of processing time must\n * be aborted. Always false when the breaker is disabled.\n */\n exceeded(elapsedMs: number): boolean {\n return this.enabled && elapsedMs >= this.timeoutMs;\n }\n\n /**\n * Records that hydrating `transformationHash` was aborted.\n *\n * Trips are rare, so this is also when expired entries are swept, which\n * keeps the map bounded by the number of hashes tripped within one cooldown\n * rather than by every hash ever tripped.\n */\n trip(transformationHash: string): void {\n const now = this.#now();\n for (const [hash, openedAt] of this.#openedAt) {\n if (now - openedAt >= this.openMs) {\n this.#openedAt.delete(hash);\n }\n }\n this.#openedAt.set(transformationHash, now);\n }\n\n /** Whether `transformationHash` is currently rejected. */\n isOpen(transformationHash: string): boolean {\n const openedAt = this.#openedAt.get(transformationHash);\n if (openedAt === undefined) {\n return false;\n }\n if (this.#now() - openedAt >= this.openMs) {\n this.#openedAt.delete(transformationHash);\n return false;\n }\n return true;\n }\n}\n"],"mappings":";;;;;;;;;;AAWA,IAAa,kCAAkC,IAAI;;;;;;;;;;;;;;;;;;AAmBnD,IAAa,0BAAb,MAAqC;CACnC;CACA;CACA;CACA,4BAAqB,IAAI,IAAoB;CAE7C,YACE,WACA,SAAiB,iCACjB,MAAsB,YAAY,IAAI,KAAK,WAAW,GACtD;EACA,OACE,OAAO,cAAc,SAAS,KAAK,aAAa,GAChD,iDACF;EACA,OAAO,UAAU,GAAG,mDAAmD;EACvE,KAAK,YAAY;EACjB,KAAK,SAAS;EACd,KAAKA,OAAO;CACd;;CAGA,IAAI,UAAmB;EACrB,OAAO,KAAK,YAAY;CAC1B;;;;;CAMA,SAAS,WAA4B;EACnC,OAAO,KAAK,WAAW,aAAa,KAAK;CAC3C;;;;;;;;CASA,KAAK,oBAAkC;EACrC,MAAM,MAAM,KAAKA,KAAK;EACtB,KAAK,MAAM,CAAC,MAAM,aAAa,KAAKC,WAClC,IAAI,MAAM,YAAY,KAAK,QACzB,KAAKA,UAAU,OAAO,IAAI;EAG9B,KAAKA,UAAU,IAAI,oBAAoB,GAAG;CAC5C;;CAGA,OAAO,oBAAqC;EAC1C,MAAM,WAAW,KAAKA,UAAU,IAAI,kBAAkB;EACtD,IAAI,aAAa,KAAA,GACf,OAAO;EAET,IAAI,KAAKD,KAAK,IAAI,YAAY,KAAK,QAAQ;GACzC,KAAKC,UAAU,OAAO,kBAAkB;GACxC,OAAO;EACT;EACA,OAAO;CACT;AACF"}
|
|
@@ -7,7 +7,7 @@ import type { ClientHandler } from './client-handler.ts';
|
|
|
7
7
|
import type { ConnectionContext } from './connection-context-manager.ts';
|
|
8
8
|
import type { CVRStore } from './cvr-store.ts';
|
|
9
9
|
import type { CVRSnapshot } from './cvr.ts';
|
|
10
|
-
export declare function handleInspect(lc: LogContext, body: UnparsedInspectUpBody, cvr: CVRSnapshot, client: ClientHandler, inspectorDelegate: InspectorDelegate, clientGroupID: string, cvrStore: CVRStore, config: NormalizedZeroConfig, ctx: ConnectionContext): Promise<void>;
|
|
10
|
+
export declare function handleInspect(lc: LogContext, body: UnparsedInspectUpBody, cvr: CVRSnapshot, client: ClientHandler, inspectorDelegate: InspectorDelegate, clientGroupID: string, authOwner: object, cvrStore: CVRStore, config: NormalizedZeroConfig, ctx: ConnectionContext): Promise<void>;
|
|
11
11
|
/**
|
|
12
12
|
* Converts per-query server metrics to the appropriate wire format based on the
|
|
13
13
|
* client's protocol version.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect-handler.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/inspect-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAKjD,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,6CAA6C,CAAC;AAGrD,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAMpE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,oCAAoC,CAAC;AAE1E,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,UAAU,CAAC;AAE1C,wBAAsB,aAAa,CACjC,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,qBAAqB,EAC3B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,aAAa,EACrB,iBAAiB,EAAE,iBAAiB,EACpC,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"inspect-handler.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/inspect-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAKjD,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,6CAA6C,CAAC;AAGrD,OAAO,KAAK,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAMpE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,oCAAoC,CAAC;AAE1E,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,iCAAiC,CAAC;AACvE,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAC7C,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,UAAU,CAAC;AAE1C,wBAAsB,aAAa,CACjC,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,qBAAqB,EAC3B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,aAAa,EACrB,iBAAiB,EAAE,iBAAiB,EACpC,aAAa,EAAE,MAAM,EAGrB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,IAAI,CAAC,CAiJf;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,kBAAkB,GAAG,IAAI,EAClC,eAAe,EAAE,MAAM,GACtB,kBAAkB,GAAG,IAAI,CAmB3B"}
|
|
@@ -6,11 +6,11 @@ import { getServerVersion, isAdminPasswordValid } from "../../config/zero-config
|
|
|
6
6
|
import { Database } from "../../../../zqlite/src/db.js";
|
|
7
7
|
import { loadPermissions } from "../../auth/load-permissions.js";
|
|
8
8
|
import { StatementRunner } from "../../db/statements.js";
|
|
9
|
-
import { inspectAnalyzeQueryUpSchema } from "../../../../zero-protocol/src/inspect-up.js";
|
|
10
9
|
import { _usingCtx } from "../../../../_virtual/_@oxc-project_runtime@0.130.0/helpers/usingCtx.js";
|
|
10
|
+
import { inspectAnalyzeQueryUpSchema } from "../../../../zero-protocol/src/inspect-up.js";
|
|
11
11
|
import { analyzeQuery } from "../analyze.js";
|
|
12
12
|
//#region ../zero-cache/src/services/view-syncer/inspect-handler.ts
|
|
13
|
-
async function handleInspect(lc, body, cvr, client, inspectorDelegate, clientGroupID, cvrStore, config, ctx) {
|
|
13
|
+
async function handleInspect(lc, body, cvr, client, inspectorDelegate, clientGroupID, authOwner, cvrStore, config, ctx) {
|
|
14
14
|
if (body.op !== "authenticate" && !inspectorDelegate.isAuthenticated(clientGroupID)) {
|
|
15
15
|
lc.info?.("Client not authenticated to access the inspector protocol. Sending authentication challenge");
|
|
16
16
|
client.sendInspectResponse(lc, {
|
|
@@ -52,7 +52,7 @@ async function handleInspect(lc, body, cvr, client, inspectorDelegate, clientGro
|
|
|
52
52
|
case "authenticate": {
|
|
53
53
|
const password = body.value;
|
|
54
54
|
const ok = isAdminPasswordValid(lc, config, password);
|
|
55
|
-
if (ok) inspectorDelegate.setAuthenticated(clientGroupID);
|
|
55
|
+
if (ok) inspectorDelegate.setAuthenticated(clientGroupID, authOwner);
|
|
56
56
|
else inspectorDelegate.clearAuthenticated(clientGroupID);
|
|
57
57
|
client.sendInspectResponse(lc, {
|
|
58
58
|
op: "authenticated",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspect-handler.js","names":[],"sources":["../../../../../../zero-cache/src/services/view-syncer/inspect-handler.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {unreachable} from '../../../../shared/src/asserts.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport {TDigest} from '../../../../shared/src/tdigest.ts';\nimport * as v from '../../../../shared/src/valita.ts';\nimport type {\n QueryServerMetrics,\n ServerMetrics,\n} from '../../../../zero-protocol/src/inspect-down.ts';\nimport {\n inspectAnalyzeQueryUpSchema,\n type UnparsedInspectUpBody,\n} from '../../../../zero-protocol/src/inspect-up.ts';\nimport {Database} from '../../../../zqlite/src/db.ts';\nimport {loadPermissions} from '../../auth/load-permissions.ts';\nimport type {NormalizedZeroConfig} from '../../config/normalize.ts';\nimport {\n getServerVersion,\n isAdminPasswordValid,\n} from '../../config/zero-config.ts';\nimport {StatementRunner} from '../../db/statements.ts';\nimport type {InspectorDelegate} from '../../server/inspector-delegate.ts';\nimport {analyzeQuery} from '../analyze.ts';\nimport type {ClientHandler} from './client-handler.ts';\nimport type {ConnectionContext} from './connection-context-manager.ts';\nimport type {CVRStore} from './cvr-store.ts';\nimport type {CVRSnapshot} from './cvr.ts';\n\nexport async function handleInspect(\n lc: LogContext,\n body: UnparsedInspectUpBody,\n cvr: CVRSnapshot,\n client: ClientHandler,\n inspectorDelegate: InspectorDelegate,\n clientGroupID: string,\n cvrStore: CVRStore,\n config: NormalizedZeroConfig,\n ctx: ConnectionContext,\n): Promise<void> {\n // Check if the client is already authenticated. We only authenticate the clientGroup\n // once per \"worker\".\n if (\n body.op !== 'authenticate' &&\n !inspectorDelegate.isAuthenticated(clientGroupID)\n ) {\n lc.info?.(\n 'Client not authenticated to access the inspector protocol. Sending authentication challenge',\n );\n client.sendInspectResponse(lc, {\n op: 'authenticated',\n id: body.id,\n value: false,\n });\n return;\n }\n\n try {\n switch (body.op) {\n case 'queries': {\n const queryRows = await cvrStore.inspectQueries(\n lc,\n cvr.ttlClock,\n body.clientID,\n );\n\n // Enhance query rows with server-side materialization metrics\n const enhancedRows = queryRows.map(row => ({\n ...row,\n ast: row.ast ?? inspectorDelegate.getASTForQuery(row.queryID) ?? null,\n metrics: metricsForProtocol(\n inspectorDelegate.getMetricsJSONForQuery(row.queryID),\n ctx.protocolVersion,\n ),\n }));\n\n client.sendInspectResponse(lc, {\n op: 'queries',\n id: body.id,\n value: enhancedRows,\n });\n break;\n }\n\n case 'metrics': {\n client.sendInspectResponse(lc, {\n op: 'metrics',\n id: body.id,\n value: inspectorDelegate.getMetricsJSON(),\n });\n break;\n }\n\n case 'version':\n client.sendInspectResponse(lc, {\n op: 'version',\n id: body.id,\n value: getServerVersion(config),\n });\n break;\n\n case 'authenticate': {\n const password = body.value;\n const ok = isAdminPasswordValid(lc, config, password);\n if (ok) {\n inspectorDelegate.setAuthenticated(clientGroupID);\n } else {\n inspectorDelegate.clearAuthenticated(clientGroupID);\n }\n\n client.sendInspectResponse(lc, {\n op: 'authenticated',\n id: body.id,\n value: ok,\n });\n\n break;\n }\n\n case 'analyze-query': {\n const parsedBody = v.parse(body, inspectAnalyzeQueryUpSchema);\n let ast = parsedBody.ast ?? parsedBody.value;\n let legacyQuery = true;\n\n if (parsedBody.name && parsedBody.args) {\n // Get the AST from the API server by transforming the named query\n ast = await inspectorDelegate.transformCustomQuery(\n parsedBody.name,\n parsedBody.args,\n ctx,\n );\n legacyQuery = false;\n }\n\n if (ast === undefined) {\n throw new Error(\n 'AST is required for analyze-query operation. Either provide an AST directly or ensure custom query transformation is configured.',\n );\n }\n\n let permissions;\n if (legacyQuery) {\n using db = new Database(lc, config.replica.file);\n const dbRunner = new StatementRunner(db);\n const loaded = loadPermissions(lc, dbRunner, config.app.id, config);\n if (loaded.permissions) {\n permissions = loaded.permissions;\n } else {\n lc.info?.(\n 'No permissions loaded; analyze-query will run without applying permissions.',\n );\n }\n }\n\n const result = await analyzeQuery(\n lc,\n config,\n must(cvr.clientSchema),\n ast,\n parsedBody.options?.syncedRows,\n parsedBody.options?.vendedRows,\n permissions,\n ctx.auth?.type === 'jwt' ? ctx.auth : undefined,\n parsedBody.options?.joinPlans,\n );\n client.sendInspectResponse(lc, {\n op: 'analyze-query',\n id: body.id,\n value: result,\n });\n break;\n }\n\n default:\n unreachable(body);\n }\n } catch (e) {\n lc.warn?.('Error handling inspect message', e);\n client.sendInspectResponse(lc, {\n op: 'error',\n id: body.id,\n value: (e as Error).message,\n });\n }\n}\n\n/**\n * Converts per-query server metrics to the appropriate wire format based on the\n * client's protocol version.\n *\n * Protocol >= 51: new format — `query-hydration-server-ms` (plain number) +\n * `query-update-server` (TDigest).\n * Protocol < 51: old format — `query-materialization-server` (TDigest) +\n * `query-update-server` (TDigest). The scalar hydration time is wrapped into a\n * one-point TDigest for backward compatibility.\n *\n * @visibleForTesting\n */\nexport function metricsForProtocol(\n metrics: QueryServerMetrics | null,\n protocolVersion: number,\n): QueryServerMetrics | null {\n if (protocolVersion >= 51 || metrics === null) {\n return metrics;\n }\n // Backward compat: wrap the scalar hydration ms into a one-point TDigest\n // under the old field name so that 1.5 clients can parse the response.\n const hydrateDigest = new TDigest();\n const hydrateMs = metrics['query-hydration-server-ms'];\n if (hydrateMs !== undefined) {\n hydrateDigest.add(hydrateMs);\n }\n const legacyMetrics: ServerMetrics = {\n 'query-materialization-server': hydrateDigest.toJSON(),\n 'query-update-server': metrics['query-update-server'],\n };\n // Cast to QueryServerMetrics: this is intentional — for old-protocol clients\n // we send the legacy ServerMetrics wire shape under the QueryServerMetrics type\n // to satisfy TypeScript while preserving backward compatibility.\n return legacyMetrics as unknown as QueryServerMetrics;\n}\n"],"mappings":";;;;;;;;;;;;AA4BA,eAAsB,cACpB,IACA,MACA,KACA,QACA,mBACA,
|
|
1
|
+
{"version":3,"file":"inspect-handler.js","names":[],"sources":["../../../../../../zero-cache/src/services/view-syncer/inspect-handler.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {unreachable} from '../../../../shared/src/asserts.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport {TDigest} from '../../../../shared/src/tdigest.ts';\nimport * as v from '../../../../shared/src/valita.ts';\nimport type {\n QueryServerMetrics,\n ServerMetrics,\n} from '../../../../zero-protocol/src/inspect-down.ts';\nimport {\n inspectAnalyzeQueryUpSchema,\n type UnparsedInspectUpBody,\n} from '../../../../zero-protocol/src/inspect-up.ts';\nimport {Database} from '../../../../zqlite/src/db.ts';\nimport {loadPermissions} from '../../auth/load-permissions.ts';\nimport type {NormalizedZeroConfig} from '../../config/normalize.ts';\nimport {\n getServerVersion,\n isAdminPasswordValid,\n} from '../../config/zero-config.ts';\nimport {StatementRunner} from '../../db/statements.ts';\nimport type {InspectorDelegate} from '../../server/inspector-delegate.ts';\nimport {analyzeQuery} from '../analyze.ts';\nimport type {ClientHandler} from './client-handler.ts';\nimport type {ConnectionContext} from './connection-context-manager.ts';\nimport type {CVRStore} from './cvr-store.ts';\nimport type {CVRSnapshot} from './cvr.ts';\n\nexport async function handleInspect(\n lc: LogContext,\n body: UnparsedInspectUpBody,\n cvr: CVRSnapshot,\n client: ClientHandler,\n inspectorDelegate: InspectorDelegate,\n clientGroupID: string,\n // The service handling the request, on whose behalf authentication is\n // recorded (see InspectorDelegate.clearAuthenticated).\n authOwner: object,\n cvrStore: CVRStore,\n config: NormalizedZeroConfig,\n ctx: ConnectionContext,\n): Promise<void> {\n // Check if the client is already authenticated. We only authenticate the clientGroup\n // once per \"worker\".\n if (\n body.op !== 'authenticate' &&\n !inspectorDelegate.isAuthenticated(clientGroupID)\n ) {\n lc.info?.(\n 'Client not authenticated to access the inspector protocol. Sending authentication challenge',\n );\n client.sendInspectResponse(lc, {\n op: 'authenticated',\n id: body.id,\n value: false,\n });\n return;\n }\n\n try {\n switch (body.op) {\n case 'queries': {\n const queryRows = await cvrStore.inspectQueries(\n lc,\n cvr.ttlClock,\n body.clientID,\n );\n\n // Enhance query rows with server-side materialization metrics\n const enhancedRows = queryRows.map(row => ({\n ...row,\n ast: row.ast ?? inspectorDelegate.getASTForQuery(row.queryID) ?? null,\n metrics: metricsForProtocol(\n inspectorDelegate.getMetricsJSONForQuery(row.queryID),\n ctx.protocolVersion,\n ),\n }));\n\n client.sendInspectResponse(lc, {\n op: 'queries',\n id: body.id,\n value: enhancedRows,\n });\n break;\n }\n\n case 'metrics': {\n client.sendInspectResponse(lc, {\n op: 'metrics',\n id: body.id,\n value: inspectorDelegate.getMetricsJSON(),\n });\n break;\n }\n\n case 'version':\n client.sendInspectResponse(lc, {\n op: 'version',\n id: body.id,\n value: getServerVersion(config),\n });\n break;\n\n case 'authenticate': {\n const password = body.value;\n const ok = isAdminPasswordValid(lc, config, password);\n if (ok) {\n inspectorDelegate.setAuthenticated(clientGroupID, authOwner);\n } else {\n inspectorDelegate.clearAuthenticated(clientGroupID);\n }\n\n client.sendInspectResponse(lc, {\n op: 'authenticated',\n id: body.id,\n value: ok,\n });\n\n break;\n }\n\n case 'analyze-query': {\n const parsedBody = v.parse(body, inspectAnalyzeQueryUpSchema);\n let ast = parsedBody.ast ?? parsedBody.value;\n let legacyQuery = true;\n\n if (parsedBody.name && parsedBody.args) {\n // Get the AST from the API server by transforming the named query\n ast = await inspectorDelegate.transformCustomQuery(\n parsedBody.name,\n parsedBody.args,\n ctx,\n );\n legacyQuery = false;\n }\n\n if (ast === undefined) {\n throw new Error(\n 'AST is required for analyze-query operation. Either provide an AST directly or ensure custom query transformation is configured.',\n );\n }\n\n let permissions;\n if (legacyQuery) {\n using db = new Database(lc, config.replica.file);\n const dbRunner = new StatementRunner(db);\n const loaded = loadPermissions(lc, dbRunner, config.app.id, config);\n if (loaded.permissions) {\n permissions = loaded.permissions;\n } else {\n lc.info?.(\n 'No permissions loaded; analyze-query will run without applying permissions.',\n );\n }\n }\n\n const result = await analyzeQuery(\n lc,\n config,\n must(cvr.clientSchema),\n ast,\n parsedBody.options?.syncedRows,\n parsedBody.options?.vendedRows,\n permissions,\n ctx.auth?.type === 'jwt' ? ctx.auth : undefined,\n parsedBody.options?.joinPlans,\n );\n client.sendInspectResponse(lc, {\n op: 'analyze-query',\n id: body.id,\n value: result,\n });\n break;\n }\n\n default:\n unreachable(body);\n }\n } catch (e) {\n lc.warn?.('Error handling inspect message', e);\n client.sendInspectResponse(lc, {\n op: 'error',\n id: body.id,\n value: (e as Error).message,\n });\n }\n}\n\n/**\n * Converts per-query server metrics to the appropriate wire format based on the\n * client's protocol version.\n *\n * Protocol >= 51: new format — `query-hydration-server-ms` (plain number) +\n * `query-update-server` (TDigest).\n * Protocol < 51: old format — `query-materialization-server` (TDigest) +\n * `query-update-server` (TDigest). The scalar hydration time is wrapped into a\n * one-point TDigest for backward compatibility.\n *\n * @visibleForTesting\n */\nexport function metricsForProtocol(\n metrics: QueryServerMetrics | null,\n protocolVersion: number,\n): QueryServerMetrics | null {\n if (protocolVersion >= 51 || metrics === null) {\n return metrics;\n }\n // Backward compat: wrap the scalar hydration ms into a one-point TDigest\n // under the old field name so that 1.5 clients can parse the response.\n const hydrateDigest = new TDigest();\n const hydrateMs = metrics['query-hydration-server-ms'];\n if (hydrateMs !== undefined) {\n hydrateDigest.add(hydrateMs);\n }\n const legacyMetrics: ServerMetrics = {\n 'query-materialization-server': hydrateDigest.toJSON(),\n 'query-update-server': metrics['query-update-server'],\n };\n // Cast to QueryServerMetrics: this is intentional — for old-protocol clients\n // we send the legacy ServerMetrics wire shape under the QueryServerMetrics type\n // to satisfy TypeScript while preserving backward compatibility.\n return legacyMetrics as unknown as QueryServerMetrics;\n}\n"],"mappings":";;;;;;;;;;;;AA4BA,eAAsB,cACpB,IACA,MACA,KACA,QACA,mBACA,eAGA,WACA,UACA,QACA,KACe;CAGf,IACE,KAAK,OAAO,kBACZ,CAAC,kBAAkB,gBAAgB,aAAa,GAChD;EACA,GAAG,OACD,6FACF;EACA,OAAO,oBAAoB,IAAI;GAC7B,IAAI;GACJ,IAAI,KAAK;GACT,OAAO;EACT,CAAC;EACD;CACF;CAEA,IAAI;EACF,QAAQ,KAAK,IAAb;GACE,KAAK,WAAW;IAQd,MAAM,gBAAe,MAPG,SAAS,eAC/B,IACA,IAAI,UACJ,KAAK,QACP,GAG+B,KAAI,SAAQ;KACzC,GAAG;KACH,KAAK,IAAI,OAAO,kBAAkB,eAAe,IAAI,OAAO,KAAK;KACjE,SAAS,mBACP,kBAAkB,uBAAuB,IAAI,OAAO,GACpD,IAAI,eACN;IACF,EAAE;IAEF,OAAO,oBAAoB,IAAI;KAC7B,IAAI;KACJ,IAAI,KAAK;KACT,OAAO;IACT,CAAC;IACD;GACF;GAEA,KAAK;IACH,OAAO,oBAAoB,IAAI;KAC7B,IAAI;KACJ,IAAI,KAAK;KACT,OAAO,kBAAkB,eAAe;IAC1C,CAAC;IACD;GAGF,KAAK;IACH,OAAO,oBAAoB,IAAI;KAC7B,IAAI;KACJ,IAAI,KAAK;KACT,OAAO,iBAAiB,MAAM;IAChC,CAAC;IACD;GAEF,KAAK,gBAAgB;IACnB,MAAM,WAAW,KAAK;IACtB,MAAM,KAAK,qBAAqB,IAAI,QAAQ,QAAQ;IACpD,IAAI,IACF,kBAAkB,iBAAiB,eAAe,SAAS;SAE3D,kBAAkB,mBAAmB,aAAa;IAGpD,OAAO,oBAAoB,IAAI;KAC7B,IAAI;KACJ,IAAI,KAAK;KACT,OAAO;IACT,CAAC;IAED;GACF;GAEA,KAAK,iBAAiB;IACpB,MAAM,aAAa,MAAQ,MAAM,2BAA2B;IAC5D,IAAI,MAAM,WAAW,OAAO,WAAW;IACvC,IAAI,cAAc;IAElB,IAAI,WAAW,QAAQ,WAAW,MAAM;KAEtC,MAAM,MAAM,kBAAkB,qBAC5B,WAAW,MACX,WAAW,MACX,GACF;KACA,cAAc;IAChB;IAEA,IAAI,QAAQ,KAAA,GACV,MAAM,IAAI,MACR,kIACF;IAGF,IAAI;IACJ,IAAI,aAAa,IAAA;;KAGf,MAAM,SAAS,gBAAgB,IAAI,IADd,gBAAA,YAAA,EADV,IAAI,SAAS,IAAI,OAAO,QAAQ,IAAI,CACV,CACF,GAAU,OAAO,IAAI,IAAI,MAAM;KAClE,IAAI,OAAO,aACT,cAAc,OAAO;UAErB,GAAG,OACD,6EACF;;;;;;IAIJ,MAAM,SAAS,MAAM,aACnB,IACA,QACA,KAAK,IAAI,YAAY,GACrB,KACA,WAAW,SAAS,YACpB,WAAW,SAAS,YACpB,aACA,IAAI,MAAM,SAAS,QAAQ,IAAI,OAAO,KAAA,GACtC,WAAW,SAAS,SACtB;IACA,OAAO,oBAAoB,IAAI;KAC7B,IAAI;KACJ,IAAI,KAAK;KACT,OAAO;IACT,CAAC;IACD;GACF;GAEA,SACE,YAAY,IAAI;EACpB;CACF,SAAS,GAAG;EACV,GAAG,OAAO,kCAAkC,CAAC;EAC7C,OAAO,oBAAoB,IAAI;GAC7B,IAAI;GACJ,IAAI,KAAK;GACT,OAAQ,EAAY;EACtB,CAAC;CACH;AACF;;;;;;;;;;;;;AAcA,SAAgB,mBACd,SACA,iBAC2B;CAC3B,IAAI,mBAAmB,MAAM,YAAY,MACvC,OAAO;CAIT,MAAM,gBAAgB,IAAI,QAAQ;CAClC,MAAM,YAAY,QAAQ;CAC1B,IAAI,cAAc,KAAA,GAChB,cAAc,IAAI,SAAS;CAS7B,OAAO;EANL,gCAAgC,cAAc,OAAO;EACrD,uBAAuB,QAAQ;CAK1B;AACT"}
|