@rocicorp/zero 1.11.0-canary.4 → 1.11.0-canary.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/analyze-query/src/analyze-cli.js +4 -4
- package/out/analyze-query/src/analyze-cli.js.map +1 -1
- package/out/analyze-query/src/bin-analyze.js +13 -12
- package/out/analyze-query/src/bin-analyze.js.map +1 -1
- package/out/analyze-query/src/bin-transform.js +1 -1
- package/out/analyze-query/src/bin-transform.js.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.d.ts +8 -1
- package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.js +25 -25
- package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
- package/out/otel/src/log-options.d.ts +16 -0
- package/out/otel/src/log-options.d.ts.map +1 -1
- package/out/otel/src/log-options.js +60 -6
- package/out/otel/src/log-options.js.map +1 -1
- package/out/replicache/src/bg-interval.d.ts +2 -1
- package/out/replicache/src/bg-interval.d.ts.map +1 -1
- package/out/replicache/src/bg-interval.js +13 -4
- package/out/replicache/src/bg-interval.js.map +1 -1
- package/out/replicache/src/btree/node.d.ts.map +1 -1
- package/out/replicache/src/btree/node.js +3 -6
- package/out/replicache/src/btree/node.js.map +1 -1
- package/out/replicache/src/dag/gc.d.ts.map +1 -1
- package/out/replicache/src/dag/gc.js +8 -11
- package/out/replicache/src/dag/gc.js.map +1 -1
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
- package/out/replicache/src/dag/lazy-store.d.ts +17 -4
- package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
- package/out/replicache/src/dag/lazy-store.js +35 -9
- package/out/replicache/src/dag/lazy-store.js.map +1 -1
- package/out/replicache/src/dag/store-impl.d.ts +12 -2
- package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
- package/out/replicache/src/dag/store-impl.js +29 -9
- package/out/replicache/src/dag/store-impl.js.map +1 -1
- package/out/replicache/src/db/rebase.d.ts +14 -2
- package/out/replicache/src/db/rebase.d.ts.map +1 -1
- package/out/replicache/src/db/rebase.js +27 -5
- package/out/replicache/src/db/rebase.js.map +1 -1
- package/out/replicache/src/get-kv-store-provider.d.ts +1 -1
- package/out/replicache/src/get-kv-store-provider.d.ts.map +1 -1
- package/out/replicache/src/get-kv-store-provider.js +4 -4
- package/out/replicache/src/get-kv-store-provider.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js +28 -5
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/idb-store.d.ts +18 -0
- package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
- package/out/replicache/src/kv/idb-store.js +30 -2
- package/out/replicache/src/kv/idb-store.js.map +1 -1
- package/out/replicache/src/kv/mem-fallback-store.d.ts +54 -0
- package/out/replicache/src/kv/mem-fallback-store.d.ts.map +1 -0
- package/out/replicache/src/kv/mem-fallback-store.js +177 -0
- package/out/replicache/src/kv/mem-fallback-store.js.map +1 -0
- package/out/replicache/src/kv/mem-store.d.ts +1 -0
- package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
- package/out/replicache/src/kv/mem-store.js +3 -0
- package/out/replicache/src/kv/mem-store.js.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.js +4 -4
- package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts +22 -1
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +159 -14
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/kv/store.d.ts +6 -0
- package/out/replicache/src/kv/store.d.ts.map +1 -1
- package/out/replicache/src/new-client-channel.js.map +1 -1
- package/out/replicache/src/persist/client-gc.d.ts +2 -1
- package/out/replicache/src/persist/client-gc.d.ts.map +1 -1
- package/out/replicache/src/persist/client-gc.js +2 -2
- package/out/replicache/src/persist/client-gc.js.map +1 -1
- package/out/replicache/src/persist/client-group-gc.d.ts +2 -1
- package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
- package/out/replicache/src/persist/client-group-gc.js +2 -2
- package/out/replicache/src/persist/client-group-gc.js.map +1 -1
- package/out/replicache/src/persist/clients.d.ts +2 -2
- package/out/replicache/src/persist/collect-idb-databases.d.ts +28 -8
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.js +97 -20
- package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
- package/out/replicache/src/persist/heartbeat.d.ts +2 -1
- package/out/replicache/src/persist/heartbeat.d.ts.map +1 -1
- package/out/replicache/src/persist/heartbeat.js +2 -2
- package/out/replicache/src/persist/heartbeat.js.map +1 -1
- package/out/replicache/src/persist/idb-databases-store-db-name.js +1 -1
- package/out/replicache/src/persist/idb-databases-store-db-name.js.map +1 -1
- package/out/replicache/src/persist/persist.d.ts.map +1 -1
- package/out/replicache/src/persist/persist.js +18 -8
- package/out/replicache/src/persist/persist.js.map +1 -1
- package/out/replicache/src/persist/refresh.js +6 -2
- package/out/replicache/src/persist/refresh.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +85 -3
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +321 -29
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/replicache-options.d.ts +9 -0
- package/out/replicache/src/replicache-options.d.ts.map +1 -1
- package/out/replicache/src/storage-failure.d.ts +37 -0
- package/out/replicache/src/storage-failure.d.ts.map +1 -0
- package/out/replicache/src/storage-failure.js +31 -0
- package/out/replicache/src/storage-failure.js.map +1 -0
- package/out/shared/src/arrays.d.ts +5 -0
- package/out/shared/src/arrays.d.ts.map +1 -1
- package/out/shared/src/arrays.js +8 -10
- package/out/shared/src/arrays.js.map +1 -1
- package/out/shared/src/centroid.d.ts +0 -1
- package/out/shared/src/centroid.d.ts.map +1 -1
- package/out/shared/src/centroid.js +1 -4
- package/out/shared/src/centroid.js.map +1 -1
- package/out/shared/src/error.d.ts +11 -0
- package/out/shared/src/error.d.ts.map +1 -1
- package/out/shared/src/error.js +35 -1
- package/out/shared/src/error.js.map +1 -1
- package/out/shared/src/hash.d.ts.map +1 -1
- package/out/shared/src/hash.js +32 -7
- package/out/shared/src/hash.js.map +1 -1
- package/out/shared/src/iterables.d.ts +2 -0
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js +18 -1
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/map.d.ts +24 -2
- package/out/shared/src/map.d.ts.map +1 -1
- package/out/shared/src/map.js +18 -4
- package/out/shared/src/map.js.map +1 -1
- package/out/shared/src/options-types.d.ts +2 -2
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +10 -7
- package/out/shared/src/options.js.map +1 -1
- package/out/shared/src/random-values.js +12 -1
- package/out/shared/src/random-values.js.map +1 -1
- package/out/shared/src/ring-buffer.d.ts +10 -0
- package/out/shared/src/ring-buffer.d.ts.map +1 -1
- package/out/shared/src/ring-buffer.js +26 -1
- package/out/shared/src/ring-buffer.js.map +1 -1
- package/out/shared/src/tdigest.d.ts +10 -0
- package/out/shared/src/tdigest.d.ts.map +1 -1
- package/out/shared/src/tdigest.js +147 -63
- package/out/shared/src/tdigest.js.map +1 -1
- package/out/shared/src/valita.d.ts +88 -0
- package/out/shared/src/valita.d.ts.map +1 -1
- package/out/shared/src/valita.js +141 -23
- package/out/shared/src/valita.js.map +1 -1
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +10 -6
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +9 -5
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +5 -6
- package/out/zero/package.js.map +1 -1
- package/out/zero/src/zero.js +2 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +1 -0
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts +1 -0
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +46 -4
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +146 -24
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +494 -158
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js +3 -4
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/db/migration-lite.d.ts.map +1 -1
- package/out/zero-cache/src/db/migration-lite.js +5 -3
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/observability/events.js +4 -1
- package/out/zero-cache/src/observability/events.js.map +1 -1
- package/out/zero-cache/src/observability/log-throttle.d.ts +44 -0
- package/out/zero-cache/src/observability/log-throttle.d.ts.map +1 -0
- package/out/zero-cache/src/observability/log-throttle.js +76 -0
- package/out/zero-cache/src/observability/log-throttle.js.map +1 -0
- package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/observability/metrics.js +2 -7
- package/out/zero-cache/src/observability/metrics.js.map +1 -1
- package/out/zero-cache/src/scripts/permissions.d.ts +16 -0
- package/out/zero-cache/src/scripts/permissions.d.ts.map +1 -1
- package/out/zero-cache/src/scripts/permissions.js +3 -3
- package/out/zero-cache/src/scripts/permissions.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +123 -87
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +28 -2
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +37 -17
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +13 -2
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/mutator.js +2 -0
- package/out/zero-cache/src/server/mutator.js.map +1 -1
- package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
- package/out/zero-cache/src/server/reaper.js +2 -0
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts +7 -0
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +103 -22
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +12 -6
- package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.js +5 -0
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/slot-keeper.d.ts +26 -0
- package/out/zero-cache/src/server/slot-keeper.d.ts.map +1 -0
- package/out/zero-cache/src/server/slot-keeper.js +181 -0
- package/out/zero-cache/src/server/slot-keeper.js.map +1 -0
- package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
- package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
- package/out/zero-cache/src/server/syncer-assigner.js +72 -0
- package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +40 -2
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/worker-urls.d.ts +1 -0
- package/out/zero-cache/src/server/worker-urls.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-urls.js +2 -1
- package/out/zero-cache/src/server/worker-urls.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +11 -9
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +198 -24
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +16 -4
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts +24 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.js +44 -0
- package/out/zero-cache/src/services/change-source/common/init-cleanup.js.map +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +82 -2
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.js +21 -10
- package/out/zero-cache/src/services/change-source/common/replica-restore.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +1 -0
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js +15 -3
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +7 -3
- package/out/zero-cache/src/services/change-source/custom/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +9 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +207 -20
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +65 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js +312 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +31 -18
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +132 -157
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +44 -2
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +60 -23
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +66 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +207 -24
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +66 -21
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +274 -68
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +46 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +68 -27
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +116 -35
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +68 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +141 -0
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +45 -2
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js +10 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +60 -3
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +23 -10
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.js +17 -7
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current.js +2 -1
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts +72 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js +162 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts +50 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.js +268 -0
- package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +6 -17
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +59 -8
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +8 -2
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +24 -4
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -4
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js +28 -8
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +17 -0
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js +44 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +54 -6
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +145 -35
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +36 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +252 -111
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +161 -17
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js +33 -2
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts +24 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js +67 -0
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +53 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +156 -0
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts +243 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.js +317 -0
- package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +58 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js +107 -16
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts +92 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js +42 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +14 -2
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +23 -10
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +7 -69
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.js +21 -53
- package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +95 -4
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +294 -84
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +485 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.js +93 -0
- package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +80 -2
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +157 -20
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +19 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js +23 -3
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
- package/out/zero-cache/src/services/http-service.d.ts +7 -1
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +14 -2
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts +68 -2
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +155 -19
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +35 -3
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +137 -35
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +6 -7
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +51 -24
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +10 -2
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.js +3 -2
- package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts +24 -0
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/restore-progress.js +91 -0
- package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +5 -6
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/plannerz.d.ts +163 -0
- package/out/zero-cache/src/services/plannerz.d.ts.map +1 -0
- package/out/zero-cache/src/services/plannerz.js +267 -0
- package/out/zero-cache/src/services/plannerz.js.map +1 -0
- package/out/zero-cache/src/services/profz.d.ts +30 -0
- package/out/zero-cache/src/services/profz.d.ts.map +1 -0
- package/out/zero-cache/src/services/profz.js +163 -0
- package/out/zero-cache/src/services/profz.js.map +1 -0
- package/out/zero-cache/src/services/replicator/change-log-cookies.js +1 -1
- package/out/zero-cache/src/services/replicator/change-log-cookies.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +5 -4
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +20 -22
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +51 -5
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/drain-handler.d.ts +74 -0
- package/out/zero-cache/src/services/replicator/drain-handler.d.ts.map +1 -0
- package/out/zero-cache/src/services/replicator/drain-handler.js +185 -0
- package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -0
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +6 -2
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js +114 -28
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts +35 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.js +99 -8
- package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +5 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js +5 -2
- package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +16 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js +70 -27
- package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts +23 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.js +54 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +6 -6
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +19 -14
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +11 -3
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +5 -1
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts +12 -0
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +42 -22
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/runner.d.ts +2 -1
- package/out/zero-cache/src/services/runner.d.ts.map +1 -1
- package/out/zero-cache/src/services/runner.js +10 -2
- package/out/zero-cache/src/services/runner.js.map +1 -1
- package/out/zero-cache/src/services/statz.d.ts +4 -0
- package/out/zero-cache/src/services/statz.d.ts.map +1 -1
- package/out/zero-cache/src/services/statz.js +22 -5
- package/out/zero-cache/src/services/statz.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts +26 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.js +26 -0
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts +79 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.js +249 -0
- package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +19 -2
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +42 -30
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +27 -2
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +86 -21
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +75 -12
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +234 -43
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +81 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +128 -0
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +14 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +12 -2
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +29 -5
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +165 -9
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +953 -209
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +7 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js +35 -0
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.d.ts +132 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.js +164 -0
- package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts +55 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.js +56 -0
- package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -6
- package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +25 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js +28 -0
- package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +89 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js +233 -0
- package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +2 -107
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +5 -20
- package/out/zero-cache/src/services/view-syncer/schema/types.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +95 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +155 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +229 -16
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +455 -43
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +8 -2
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +788 -71
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.d.ts +2 -0
- package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.js +6 -1
- package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +2 -2
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +50 -0
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +43 -4
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/profiler.d.ts +12 -0
- package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
- package/out/zero-cache/src/types/profiler.js +46 -1
- package/out/zero-cache/src/types/profiler.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts +1 -15
- package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
- package/out/zero-cache/src/types/row-key.js +6 -8
- package/out/zero-cache/src/types/row-key.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts +49 -7
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +190 -58
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +15 -0
- package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
- package/out/zero-cache/src/types/subscription.js +123 -31
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +18 -9
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/types/ws.d.ts.map +1 -1
- package/out/zero-cache/src/types/ws.js +1 -16
- package/out/zero-cache/src/types/ws.js.map +1 -1
- package/out/zero-cache/src/workers/connect-params.d.ts +1 -0
- package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connect-params.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +2 -1
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +9 -1
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +24 -7
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +55 -4
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.js +4 -1
- package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +20 -0
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +77 -13
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
- package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.js +3 -1
- package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +6 -0
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js +2 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +23 -13
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +94 -26
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/crud-impl.d.ts.map +1 -1
- package/out/zero-client/src/client/crud-impl.js +1 -1
- package/out/zero-client/src/client/crud-impl.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts +5 -4
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.js +3 -3
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +1 -1
- package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
- package/out/zero-client/src/client/ivm-branch.js +20 -3
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/keys.d.ts.map +1 -1
- package/out/zero-client/src/client/keys.js +19 -1
- package/out/zero-client/src/client/keys.js.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts +1 -1
- package/out/zero-client/src/client/make-mutate-property.d.ts.map +1 -1
- package/out/zero-client/src/client/make-mutate-property.js.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.d.ts.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts +2 -2
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.js +3 -7
- package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js +9 -4
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +33 -0
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts +9 -0
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.js +47 -14
- package/out/zero-client/src/client/query-manager.js.map +1 -1
- package/out/zero-client/src/client/reload-error-handler.js +2 -2
- package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
- package/out/zero-client/src/client/storage-version.d.ts +23 -0
- package/out/zero-client/src/client/storage-version.d.ts.map +1 -0
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts +1 -0
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +8 -6
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +18 -3
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +86 -48
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +2 -1
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-client/src/mod.js +1 -0
- package/out/zero-client/src/types/query-result.d.ts +2 -0
- package/out/zero-client/src/types/query-result.d.ts.map +1 -1
- package/out/zero-events/src/status.d.ts +64 -0
- package/out/zero-events/src/status.d.ts.map +1 -1
- package/out/zero-protocol/src/analyze-query-result.d.ts +12 -12
- package/out/zero-protocol/src/analyze-query-result.d.ts.map +1 -1
- package/out/zero-protocol/src/analyze-query-result.js +3 -3
- package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
- package/out/zero-protocol/src/ast.d.ts +24 -0
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +39 -16
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +36 -36
- package/out/zero-protocol/src/inspect-down.d.ts +31 -31
- package/out/zero-protocol/src/inspect-up.d.ts +158 -61
- package/out/zero-protocol/src/inspect-up.d.ts.map +1 -1
- package/out/zero-protocol/src/inspect-up.js +12 -6
- package/out/zero-protocol/src/inspect-up.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +4 -1
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/queries-patch.js +2 -2
- package/out/zero-protocol/src/queries-patch.js.map +1 -1
- package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
- package/out/zero-protocol/src/query-hash.js +2 -5
- package/out/zero-protocol/src/query-hash.js.map +1 -1
- package/out/zero-protocol/src/up.d.ts +766 -256
- package/out/zero-protocol/src/up.d.ts.map +1 -1
- package/out/zero-protocol/src/up.js +25 -3
- package/out/zero-protocol/src/up.js.map +1 -1
- package/out/zero-react/src/use-query.d.ts +5 -4
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +75 -8
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-react/src/zero.js +1 -0
- package/out/zero-server/src/adapters/drizzle.d.ts +16 -4
- package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
- package/out/zero-server/src/adapters/drizzle.js +19 -11
- package/out/zero-server/src/adapters/drizzle.js.map +1 -1
- package/out/zero-server/src/adapters/kysely.d.ts +6 -3
- package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
- package/out/zero-server/src/adapters/kysely.js +16 -6
- package/out/zero-server/src/adapters/kysely.js.map +1 -1
- package/out/zero-server/src/adapters/pg.d.ts +7 -2
- package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
- package/out/zero-server/src/adapters/pg.js +34 -10
- package/out/zero-server/src/adapters/pg.js.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.d.ts +4 -2
- package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.js +15 -5
- package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
- package/out/zero-server/src/adapters/prisma.d.ts +17 -5
- package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
- package/out/zero-server/src/adapters/prisma.js +20 -6
- package/out/zero-server/src/adapters/prisma.js.map +1 -1
- package/out/zero-server/src/closable-db-transaction.d.ts +16 -0
- package/out/zero-server/src/closable-db-transaction.d.ts.map +1 -0
- package/out/zero-server/src/closable-db-transaction.js +31 -0
- package/out/zero-server/src/closable-db-transaction.js.map +1 -0
- package/out/zero-server/src/custom.d.ts +10 -4
- package/out/zero-server/src/custom.d.ts.map +1 -1
- package/out/zero-server/src/custom.js +15 -6
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/logging.d.ts +2 -2
- package/out/zero-server/src/logging.d.ts.map +1 -1
- package/out/zero-server/src/logging.js +2 -2
- package/out/zero-server/src/logging.js.map +1 -1
- package/out/zero-server/src/mod.d.ts +2 -1
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.d.ts +2 -2
- package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.js +2 -2
- package/out/zero-server/src/pg-query-executor.js.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +25 -4
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js +103 -52
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/push-processor.d.ts +8 -2
- package/out/zero-server/src/push-processor.d.ts.map +1 -1
- package/out/zero-server/src/push-processor.js +12 -4
- package/out/zero-server/src/push-processor.js.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +1 -1
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-server/src/schema.d.ts +2 -2
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +3 -2
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-server/src/transaction-options.d.ts +24 -0
- package/out/zero-server/src/transaction-options.d.ts.map +1 -0
- package/out/zero-server/src/transaction-options.js +11 -0
- package/out/zero-server/src/transaction-options.js.map +1 -0
- package/out/zero-server/src/zql-database.d.ts +21 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js +61 -24
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +17 -0
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +39 -1
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-query.js +1 -2
- package/out/zero-solid/src/use-query.js.map +1 -1
- package/out/zero-solid/src/zero.js +1 -0
- package/out/zql/src/builder/builder.d.ts +25 -0
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +69 -19
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +43 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +1 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.js +161 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -0
- package/out/zql/src/builder/debug-delegate.d.ts +6 -1
- package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
- package/out/zql/src/builder/debug-delegate.js +14 -2
- package/out/zql/src/builder/debug-delegate.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts +29 -0
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +74 -16
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/cap.d.ts +2 -1
- package/out/zql/src/ivm/cap.d.ts.map +1 -1
- package/out/zql/src/ivm/cap.js +14 -4
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +8 -3
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.d.ts.map +1 -1
- package/out/zql/src/ivm/deferred-input.js +3 -2
- package/out/zql/src/ivm/deferred-input.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +3 -1
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +4 -1
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +6 -2
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +13 -5
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +5 -2
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js +4 -0
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +8 -6
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +19 -8
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +5 -2
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +10 -4
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts +9 -4
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +97 -46
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join-index-tap.d.ts +33 -0
- package/out/zql/src/ivm/join-index-tap.d.ts.map +1 -0
- package/out/zql/src/ivm/join-index-tap.js +70 -0
- package/out/zql/src/ivm/join-index-tap.js.map +1 -0
- package/out/zql/src/ivm/join-index.d.ts +35 -0
- package/out/zql/src/ivm/join-index.d.ts.map +1 -0
- package/out/zql/src/ivm/join-index.js +141 -0
- package/out/zql/src/ivm/join-index.js.map +1 -0
- package/out/zql/src/ivm/join-utils.d.ts +6 -0
- package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
- package/out/zql/src/ivm/join-utils.js +22 -1
- package/out/zql/src/ivm/join-utils.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts +19 -1
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +107 -15
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +29 -4
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +70 -34
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/memory-storage.d.ts +1 -0
- package/out/zql/src/ivm/memory-storage.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-storage.js +1 -0
- package/out/zql/src/ivm/memory-storage.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +45 -10
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js +9 -4
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/push-accumulated.d.ts +6 -1
- package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
- package/out/zql/src/ivm/push-accumulated.js +47 -2
- package/out/zql/src/ivm/push-accumulated.js.map +1 -1
- package/out/zql/src/ivm/skip.d.ts +2 -1
- package/out/zql/src/ivm/skip.d.ts.map +1 -1
- package/out/zql/src/ivm/skip.js +3 -0
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/take-gate.d.ts +57 -0
- package/out/zql/src/ivm/take-gate.d.ts.map +1 -0
- package/out/zql/src/ivm/take-gate.js +106 -0
- package/out/zql/src/ivm/take-gate.js.map +1 -0
- package/out/zql/src/ivm/take.d.ts +8 -2
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +139 -103
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +3 -0
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +63 -10
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts +2 -1
- package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js +5 -0
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +9 -4
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/ivm/view.d.ts +15 -0
- package/out/zql/src/ivm/view.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.d.ts +53 -1
- package/out/zql/src/mutate/custom.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +3 -3
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +2 -2
- package/out/zql/src/mutate/mutator.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator.js.map +1 -1
- package/out/zql/src/planner/planner-builder.d.ts +23 -3
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
- package/out/zql/src/planner/planner-builder.js +34 -17
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-connection.d.ts +58 -2
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
- package/out/zql/src/planner/planner-connection.js +103 -11
- package/out/zql/src/planner/planner-connection.js.map +1 -1
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js +3 -8
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-graph.d.ts +10 -0
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
- package/out/zql/src/planner/planner-graph.js +14 -0
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zql/src/planner/planner-source.d.ts +2 -2
- package/out/zql/src/planner/planner-source.d.ts.map +1 -1
- package/out/zql/src/planner/planner-source.js +2 -2
- package/out/zql/src/planner/planner-source.js.map +1 -1
- package/out/zql/src/planner/planner-warnings.d.ts +83 -0
- package/out/zql/src/planner/planner-warnings.d.ts.map +1 -0
- package/out/zql/src/planner/planner-warnings.js +78 -0
- package/out/zql/src/planner/planner-warnings.js.map +1 -0
- package/out/zql/src/query/expression.d.ts +2 -2
- package/out/zql/src/query/expression.d.ts.map +1 -1
- package/out/zql/src/query/expression.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.d.ts +9 -2
- package/out/zql/src/query/measure-push-operator.d.ts.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +52 -5
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +4 -2
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +66 -33
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +33 -6
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +1 -0
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +6 -23
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-registry.js +1 -1
- package/out/zql/src/query/query-transitions.d.ts.map +1 -1
- package/out/zql/src/query/query-transitions.js +2 -5
- package/out/zql/src/query/query-transitions.js.map +1 -1
- package/out/zql/src/query/query.d.ts +26 -10
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js +2 -10
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/typed-view.d.ts +1 -1
- package/out/zql/src/query/typed-view.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.js +9 -1
- package/out/zqlite/src/database-storage.js.map +1 -1
- package/out/zqlite/src/db.d.ts +17 -1
- package/out/zqlite/src/db.d.ts.map +1 -1
- package/out/zqlite/src/db.js +73 -30
- package/out/zqlite/src/db.js.map +1 -1
- package/out/zqlite/src/index-usage.d.ts +19 -0
- package/out/zqlite/src/index-usage.d.ts.map +1 -0
- package/out/zqlite/src/index-usage.js +49 -0
- package/out/zqlite/src/index-usage.js.map +1 -0
- package/out/zqlite/src/pending-delta.d.ts +110 -0
- package/out/zqlite/src/pending-delta.d.ts.map +1 -0
- package/out/zqlite/src/pending-delta.js +278 -0
- package/out/zqlite/src/pending-delta.js.map +1 -0
- package/out/zqlite/src/query-builder.d.ts +17 -1
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +111 -20
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-delegate.js +10 -7
- package/out/zqlite/src/query-delegate.js.map +1 -1
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts +3 -1
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +1 -1
- package/out/zqlite/src/resolve-scalar-subqueries.js +1 -0
- package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +53 -1
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +5 -31
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/sqlite-stat4-sample.d.ts +37 -0
- package/out/zqlite/src/sqlite-stat4-sample.d.ts.map +1 -0
- package/out/zqlite/src/sqlite-stat4-sample.js +61 -0
- package/out/zqlite/src/sqlite-stat4-sample.js.map +1 -0
- package/out/zqlite/src/table-source.d.ts +87 -2
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +276 -42
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +5 -6
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +0 -25
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +0 -1
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js +0 -83
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +0 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts +0 -29
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +0 -154
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +0 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { assert, unreachable } from "../../../../shared/src/asserts.js";
|
|
2
2
|
import { deepEqual } from "../../../../shared/src/json.js";
|
|
3
|
+
import { getOrInsertComputed } from "../../../../shared/src/map.js";
|
|
3
4
|
import { must } from "../../../../shared/src/must.js";
|
|
5
|
+
import { assignProperty } from "../../../../shared/src/objects.js";
|
|
4
6
|
import { skipYields } from "../../../../zql/src/ivm/skip-yields.js";
|
|
5
7
|
import { throwOutput } from "../../../../zql/src/ivm/operator.js";
|
|
6
8
|
import { MeasurePushOperator } from "../../../../zql/src/query/measure-push-operator.js";
|
|
@@ -14,13 +16,20 @@ import { resolveSimpleScalarSubqueries } from "../../../../zqlite/src/resolve-sc
|
|
|
14
16
|
import { randInt } from "../../../../shared/src/rand.js";
|
|
15
17
|
import { createSQLiteCostModel } from "../../../../zqlite/src/sqlite-cost-model.js";
|
|
16
18
|
import { reloadPermissionsIfChanged } from "../../auth/load-permissions.js";
|
|
19
|
+
import { LogThrottle } from "../../observability/log-throttle.js";
|
|
17
20
|
import { getOrCreateCounter, getOrCreateLatencyHistogram } from "../../observability/metrics.js";
|
|
18
21
|
import "../../types/row-key.js";
|
|
19
22
|
import { getSubscriptionState } from "../replicator/schema/replication-state.js";
|
|
20
23
|
import { checkClientSchema } from "./client-schema.js";
|
|
24
|
+
import { planWarningMessage } from "./plan-warnings.js";
|
|
25
|
+
import { PushCutoff } from "./push-cutoff.js";
|
|
26
|
+
import { PushCostEstimator, ReadCostEstimator, shouldRebuildInsteadOfReading, shouldStartOnRebuild } from "./push-cost.js";
|
|
27
|
+
import { queryShape } from "./query-shape.js";
|
|
21
28
|
import { rowIDSignatureUnit } from "./row-set-signature.js";
|
|
22
29
|
import { ResetPipelinesSignal } from "./snapshotter.js";
|
|
23
30
|
//#region ../zero-cache/src/services/view-syncer/pipeline-driver.ts
|
|
31
|
+
/** The most queries a log of an advancement timeout lists. */
|
|
32
|
+
var ADVANCE_TIMEOUT_LOG_MAX_QUERIES = 3;
|
|
24
33
|
/**
|
|
25
34
|
* No matter how fast hydration is, advancement is given at least this long to
|
|
26
35
|
* complete before doing a pipeline reset.
|
|
@@ -33,6 +42,8 @@ var MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS = 5;
|
|
|
33
42
|
var MIN_PROJECTED_ADVANCEMENT_CHANGES = 16;
|
|
34
43
|
var PROJECTED_ADVANCEMENT_RESET_MULTIPLIER = 1.5;
|
|
35
44
|
var LATE_ADVANCEMENT_FINISH_PROGRESS = .8;
|
|
45
|
+
var planWarningLogThrottle = new LogThrottle({ windowMs: 60 * 6e4 });
|
|
46
|
+
var slowAdvanceLogThrottle = new LogThrottle({ windowMs: 5 * 6e4 });
|
|
36
47
|
function randomID() {
|
|
37
48
|
return randInt(1, Number.MAX_SAFE_INTEGER).toString(36);
|
|
38
49
|
}
|
|
@@ -46,9 +57,11 @@ function advancementResetTimeLimitMs(totalHydrationTimeMs) {
|
|
|
46
57
|
function minProjectedAdvancementSampleChanges(numChanges) {
|
|
47
58
|
return Math.max(MIN_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES, Math.min(MAX_PROJECTED_ADVANCEMENT_SAMPLE_CHANGES, Math.ceil(numChanges * PROJECTED_ADVANCEMENT_SAMPLE_FRACTION)));
|
|
48
59
|
}
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
|
|
60
|
+
function canProjectAdvancement(elapsedMs, projectedTotalTimeMs, processedChanges, numChanges) {
|
|
61
|
+
return projectedTotalTimeMs !== void 0 && numChanges >= MIN_PROJECTED_ADVANCEMENT_CHANGES && processedChanges >= minProjectedAdvancementSampleChanges(numChanges) && elapsedMs >= MIN_PROJECTED_ADVANCEMENT_SAMPLE_MS;
|
|
62
|
+
}
|
|
63
|
+
function shouldResetProjectedAdvancement(elapsedMs, projectedTotalTimeMs, totalHydrationTimeMs) {
|
|
64
|
+
return projectedTotalTimeMs - elapsedMs > advancementResetTimeLimitMs(totalHydrationTimeMs) * PROJECTED_ADVANCEMENT_RESET_MULTIPLIER;
|
|
52
65
|
}
|
|
53
66
|
function shouldFinishLateAdvancement(processedChanges, numChanges) {
|
|
54
67
|
return numChanges > 0 && processedChanges / numChanges >= LATE_ADVANCEMENT_FINISH_PROGRESS;
|
|
@@ -56,6 +69,14 @@ function shouldFinishLateAdvancement(processedChanges, numChanges) {
|
|
|
56
69
|
function shouldResetSlowCurrentChange(currentChangeElapsedMs, totalHydrationTimeMs) {
|
|
57
70
|
return currentChangeElapsedMs > MIN_ADVANCEMENT_TIME_LIMIT_MS && currentChangeElapsedMs > advancementResetTimeLimitMs(totalHydrationTimeMs);
|
|
58
71
|
}
|
|
72
|
+
function formatAdvancementBreakdown(advanceContext, elapsed) {
|
|
73
|
+
const { diff, pushTimeMs, stage, currentChangeStartMs, currentTable } = advanceContext;
|
|
74
|
+
const totalPushMs = pushTimeMs + (stage === "push" && currentChangeStartMs !== void 0 ? Math.max(0, elapsed - currentChangeStartMs) : 0);
|
|
75
|
+
const stats = diff.stats;
|
|
76
|
+
const diffTimeMs = stats?.totalDiffMs ?? 0;
|
|
77
|
+
const clMs = stats ? ` [changelog: ${stats.changeLogReadMs.toFixed(1)}ms, parse: ${stats.parseMs.toFixed(1)}ms, rows: ${stats.rowReadMs.toFixed(1)}ms]` : "";
|
|
78
|
+
return `stage: ${stage}, diff: ${diffTimeMs.toFixed(1)}ms${clMs}, push: ${totalPushMs.toFixed(1)}ms` + (currentTable ? `, table: ${currentTable}` : "");
|
|
79
|
+
}
|
|
59
80
|
/**
|
|
60
81
|
* Manages the state of IVM pipelines for a given ViewSyncer (i.e. client group).
|
|
61
82
|
*/
|
|
@@ -67,39 +88,83 @@ var PipelineDriver = class {
|
|
|
67
88
|
* query, maintained as RowChanges are yielded from {@link addQuery} and
|
|
68
89
|
* {@link advance}. ADDs / REMOVEs XOR the row's unit in (XOR is
|
|
69
90
|
* self-inverse, so one op serves both directions); EDITs are no-ops.
|
|
70
|
-
* Hydration
|
|
71
|
-
*
|
|
91
|
+
* Hydration starts the query's entry at `0n` (the empty row set), so every
|
|
92
|
+
* hydrated query has one, even if it has no rows. A hydration that does not
|
|
93
|
+
* finish removes it.
|
|
72
94
|
*/
|
|
73
95
|
#rowSetSignatures = /* @__PURE__ */ new Map();
|
|
96
|
+
/**
|
|
97
|
+
* IDs of the queries whose {@link #rowSetSignatures} entry changed since the
|
|
98
|
+
* last {@link clearChangedRowSetSignatures}, so that the CVR flush only has
|
|
99
|
+
* to look at those instead of every query.
|
|
100
|
+
*/
|
|
101
|
+
#changedRowSetSignatures = /* @__PURE__ */ new Set();
|
|
74
102
|
#lc;
|
|
75
103
|
#snapshotter;
|
|
76
104
|
#storage;
|
|
77
105
|
#shardID;
|
|
78
106
|
#logConfig;
|
|
79
107
|
#config;
|
|
108
|
+
#deferredWrites;
|
|
80
109
|
#tableSpecs = /* @__PURE__ */ new Map();
|
|
81
110
|
#allTableNames = /* @__PURE__ */ new Set();
|
|
82
111
|
#costModels;
|
|
112
|
+
#planWarningThresholds;
|
|
83
113
|
#yieldThresholdMs;
|
|
84
114
|
#streamer = null;
|
|
115
|
+
/** The row changes of the push in progress, until #push yields them. */
|
|
116
|
+
#pushedRowChanges = null;
|
|
85
117
|
#hydrateContext = null;
|
|
86
118
|
#advanceContext = null;
|
|
119
|
+
/**
|
|
120
|
+
* Whether a {@link CostBasedAdvance} has been set up and has not
|
|
121
|
+
* completed. It may already have removed pipelines, but the sources only
|
|
122
|
+
* move to the new snapshot when the iteration over its changes completes,
|
|
123
|
+
* so nothing can be hydrated until then. If the iteration is given up on
|
|
124
|
+
* or throws, they never do, and nothing can be hydrated until the
|
|
125
|
+
* pipelines are {@link reset()}.
|
|
126
|
+
*/
|
|
127
|
+
#costBasedAdvanceIncomplete = false;
|
|
128
|
+
/**
|
|
129
|
+
* The queries abandoned by a {@link CostBasedAdvance} that have not been
|
|
130
|
+
* added again since.
|
|
131
|
+
*/
|
|
132
|
+
#abandoned = /* @__PURE__ */ new Map();
|
|
133
|
+
#pushCosts = new PushCostEstimator();
|
|
134
|
+
#readCosts = new ReadCostEstimator();
|
|
87
135
|
#replicaVersion = null;
|
|
88
136
|
#primaryKeys = null;
|
|
89
137
|
#permissions = null;
|
|
90
138
|
#advanceTime = getOrCreateLatencyHistogram("sync", "ivm.advance-time", "Time to advance all queries for a given client group in response to a single change.");
|
|
91
139
|
#conflictRowsDeleted = getOrCreateCounter("sync", "ivm.conflict-rows-deleted", "Number of rows deleted because they conflicted with added row");
|
|
140
|
+
#deferredWritesFallbacks = getOrCreateCounter("sync", "ivm.deferred-writes-fallbacks", "Number of advancements written through to the replica snapshot because their changes did not fit in the deferred IVM writes budget, from the start or partway (because of the bytes held, a change that needed more rows than were left, or more rows held than reserved)");
|
|
92
141
|
#inspectorDelegate;
|
|
93
|
-
|
|
142
|
+
#queryStats;
|
|
143
|
+
/**
|
|
144
|
+
* Passes the pipelines' metrics on to the inspector, and accounts the time
|
|
145
|
+
* spent pushing to each query to the advancement in progress.
|
|
146
|
+
*/
|
|
147
|
+
#metricsDelegate = { addMetric: (metric, value, ...args) => {
|
|
148
|
+
this.#inspectorDelegate.addMetric(metric, value, ...args);
|
|
149
|
+
if (metric === "query-update-server") this.#recordAdvancePush(args[0], value);
|
|
150
|
+
} };
|
|
151
|
+
constructor(lc, logConfig, snapshotter, shardID, storage, clientGroupID, inspectorDelegate, yieldThresholdMs, enablePlanner, config, deferredWrites, queryStats) {
|
|
94
152
|
this.#lc = lc.withContext("clientGroupID", clientGroupID);
|
|
95
153
|
this.#snapshotter = snapshotter;
|
|
96
154
|
this.#storage = storage;
|
|
97
155
|
this.#shardID = shardID;
|
|
98
156
|
this.#logConfig = logConfig;
|
|
99
157
|
this.#config = config;
|
|
158
|
+
this.#deferredWrites = deferredWrites;
|
|
100
159
|
this.#inspectorDelegate = inspectorDelegate;
|
|
101
160
|
this.#costModels = enablePlanner ? /* @__PURE__ */ new WeakMap() : void 0;
|
|
161
|
+
const planWarningThresholds = {
|
|
162
|
+
rows: logConfig.planWarningRowThreshold,
|
|
163
|
+
cost: logConfig.planWarningCostThreshold
|
|
164
|
+
};
|
|
165
|
+
this.#planWarningThresholds = planWarningThresholds.rows > 0 || planWarningThresholds.cost > 0 ? planWarningThresholds : void 0;
|
|
102
166
|
this.#yieldThresholdMs = yieldThresholdMs;
|
|
167
|
+
this.#queryStats = queryStats;
|
|
103
168
|
}
|
|
104
169
|
/**
|
|
105
170
|
* Initializes the PipelineDriver to the current head of the database.
|
|
@@ -128,9 +193,12 @@ var PipelineDriver = class {
|
|
|
128
193
|
this.#pipelines.delete(queryID);
|
|
129
194
|
this.#destroyPipeline(queryID, pipeline, "reset");
|
|
130
195
|
}
|
|
196
|
+
this.#abandoned.clear();
|
|
197
|
+
this.#costBasedAdvanceIncomplete = false;
|
|
131
198
|
this.#tables.clear();
|
|
132
199
|
this.#allTableNames.clear();
|
|
133
200
|
this.#rowSetSignatures.clear();
|
|
201
|
+
this.#changedRowSetSignatures.clear();
|
|
134
202
|
this.#initAndResetCommon(clientSchema);
|
|
135
203
|
}
|
|
136
204
|
#initAndResetCommon(clientSchema) {
|
|
@@ -140,11 +208,9 @@ var PipelineDriver = class {
|
|
|
140
208
|
checkClientSchema(this.#shardID, clientSchema, this.#tableSpecs, fullTables);
|
|
141
209
|
this.#allTableNames.clear();
|
|
142
210
|
for (const table of fullTables.keys()) this.#allTableNames.add(table);
|
|
143
|
-
const primaryKeys = this.#primaryKeys ??
|
|
211
|
+
const primaryKeys = buildRowKeys(clientSchema, this.#tableSpecs, this.#primaryKeys ?? void 0);
|
|
144
212
|
this.#primaryKeys = primaryKeys;
|
|
145
|
-
primaryKeys
|
|
146
|
-
for (const [table, spec] of this.#tableSpecs.entries()) primaryKeys.set(table, spec.tableSpec.primaryKey);
|
|
147
|
-
buildPrimaryKeys(clientSchema, primaryKeys);
|
|
213
|
+
this.#streamer ??= new Streamer(primaryKeys, this.#tableSpecs);
|
|
148
214
|
const { replicaVersion } = getSubscriptionState(db);
|
|
149
215
|
this.#replicaVersion = replicaVersion;
|
|
150
216
|
}
|
|
@@ -173,10 +239,28 @@ var PipelineDriver = class {
|
|
|
173
239
|
}
|
|
174
240
|
return this.#permissions;
|
|
175
241
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
242
|
+
/**
|
|
243
|
+
* Advances the snapshot to the head of the database without diffing the
|
|
244
|
+
* change log, in preparation for hydrating queries at head.
|
|
245
|
+
*
|
|
246
|
+
* Throws a {@link ResetPipelinesSignal} if the change log records a
|
|
247
|
+
* schema change since the previous snapshot. The table specs (and any
|
|
248
|
+
* TableSources built from them) were computed at or before that snapshot
|
|
249
|
+
* and are stale with respect to the new head, so the caller must
|
|
250
|
+
* {@link reset()} before hydrating. ({@link advance()} detects this when
|
|
251
|
+
* the diff encounters the RESET op; this path skips the diff and so must
|
|
252
|
+
* check explicitly.)
|
|
253
|
+
*
|
|
254
|
+
* @param releasePreviousSnapshot Whether to release the snapshot that the
|
|
255
|
+
* driver was at, which is otherwise left open until the next
|
|
256
|
+
* advance (see `Snapshotter.releasePrevious()`).
|
|
257
|
+
*/
|
|
258
|
+
advanceWithoutDiff(releasePreviousSnapshot = false) {
|
|
259
|
+
const { prev, curr } = this.#snapshotter.advanceWithoutDiff();
|
|
260
|
+
if (curr.schemaChangedSince(prev.version)) throw new ResetPipelinesSignal(`schema changed between ${prev.version} and ${curr.version}`, "schema-change");
|
|
261
|
+
for (const table of this.#tables.values()) table.setDB(curr.db.db);
|
|
262
|
+
if (releasePreviousSnapshot) this.#snapshotter.releasePrevious();
|
|
263
|
+
return curr.version;
|
|
180
264
|
}
|
|
181
265
|
#ensureCostModelExistsIfEnabled(db) {
|
|
182
266
|
let existing = this.#costModels?.get(db);
|
|
@@ -196,7 +280,9 @@ var PipelineDriver = class {
|
|
|
196
280
|
this.#pipelines.delete(queryID);
|
|
197
281
|
this.#destroyPipeline(queryID, pipeline, "destroy");
|
|
198
282
|
}
|
|
283
|
+
this.#tables.clear();
|
|
199
284
|
this.#rowSetSignatures.clear();
|
|
285
|
+
this.#changedRowSetSignatures.clear();
|
|
200
286
|
this.#storage.destroy();
|
|
201
287
|
this.#snapshotter.destroy();
|
|
202
288
|
}
|
|
@@ -204,20 +290,91 @@ var PipelineDriver = class {
|
|
|
204
290
|
queries() {
|
|
205
291
|
return this.#pipelines;
|
|
206
292
|
}
|
|
293
|
+
/**
|
|
294
|
+
* The queries whose pipelines a {@link CostBasedAdvance} removed and that
|
|
295
|
+
* have not been hydrated again since, by query ID. They are not in
|
|
296
|
+
* {@link queries()}. A query whose hydration is started but does not
|
|
297
|
+
* finish is still one of them.
|
|
298
|
+
*/
|
|
299
|
+
abandonedQueries() {
|
|
300
|
+
return this.#abandoned;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Stats from the hydration of the pipeline for `queryID`, or `undefined` if
|
|
304
|
+
* the query has no pipeline.
|
|
305
|
+
*/
|
|
306
|
+
hydrationStats(queryID) {
|
|
307
|
+
const pipeline = this.#pipelines.get(queryID);
|
|
308
|
+
return pipeline ? {
|
|
309
|
+
rowCount: pipeline.hydrationRowCount,
|
|
310
|
+
rowsRead: pipeline.hydrationRowsRead,
|
|
311
|
+
planWarnings: pipeline.planWarnings,
|
|
312
|
+
shape: pipeline.shape
|
|
313
|
+
} : void 0;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Logs what the planner warned about the plan it chose for `query`, at
|
|
317
|
+
* most once per query shape per {@link PLAN_WARNING_LOG_WINDOW_MS}.
|
|
318
|
+
*/
|
|
319
|
+
#logPlanWarnings(shape, { queryHash, transformationHash, queryName }, warnings) {
|
|
320
|
+
if (!this.#lc.warn) return;
|
|
321
|
+
const suppressed = planWarningLogThrottle.admit(`${queryName ?? ""}:${shape.hash}`);
|
|
322
|
+
if (suppressed === void 0) return;
|
|
323
|
+
const messages = warnings.map(planWarningMessage);
|
|
324
|
+
this.#lc.warn(`Query plan warning${queryName === void 0 ? "" : ` for ${queryName}`}: ` + messages.join(" "), {
|
|
325
|
+
zeroEvent: "query-plan-warning",
|
|
326
|
+
queryHash,
|
|
327
|
+
transformationHash,
|
|
328
|
+
...queryName !== void 0 && { queryName },
|
|
329
|
+
queryShape: shape.hash,
|
|
330
|
+
warnings,
|
|
331
|
+
...suppressed > 0 && { suppressedSinceLastLog: suppressed },
|
|
332
|
+
zql: shape.zql
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
#totalRowsRead() {
|
|
336
|
+
let total = 0;
|
|
337
|
+
for (const table of this.#tables.values()) total += table.rowsRead;
|
|
338
|
+
return total;
|
|
339
|
+
}
|
|
207
340
|
totalHydrationTimeMs() {
|
|
208
341
|
let total = 0;
|
|
209
342
|
for (const pipeline of this.#pipelines.values()) total += pipeline.hydrationTimeMs;
|
|
210
343
|
return total;
|
|
211
344
|
}
|
|
212
|
-
|
|
345
|
+
/**
|
|
346
|
+
* The rows the sources hold in memory for the advancement in progress.
|
|
347
|
+
* The advancement's reservation from the {@link DeferredWritesBudget}
|
|
348
|
+
* bounds this.
|
|
349
|
+
*/
|
|
350
|
+
get pendingRows() {
|
|
351
|
+
let total = 0;
|
|
352
|
+
for (const source of this.#tables.values()) total += source.pendingRows;
|
|
353
|
+
return total;
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* The estimated bytes of {@link pendingRows}, which are added to the
|
|
357
|
+
* {@link DeferredWritesBudget}'s held bytes as the advancement goes.
|
|
358
|
+
*/
|
|
359
|
+
get pendingBytes() {
|
|
360
|
+
let total = 0;
|
|
361
|
+
for (const source of this.#tables.values()) total += source.pendingBytes;
|
|
362
|
+
return total;
|
|
363
|
+
}
|
|
364
|
+
#logQueryPipelineLifecycle({ zeroEvent, pipelineRunID, queryHash, transformationHash, queryName, hydrationReason, stopReason, hydrationTimeMs, hydrationRowCount, hydrationRowsRead, pipelineLifetimeMs, abandonReason, estimatedPushMs, pushTimeMs, pushedChanges, level = "info" }) {
|
|
213
365
|
let lc = this.#lc.withContext("zeroEvent", zeroEvent).withContext("pipelineRunID", pipelineRunID).withContext("queryHash", queryHash).withContext("transformationHash", transformationHash);
|
|
214
366
|
if (queryName !== void 0) lc = lc.withContext("queryName", queryName);
|
|
215
367
|
if (hydrationReason !== void 0) lc = lc.withContext("hydrationReason", hydrationReason);
|
|
216
368
|
if (stopReason !== void 0) lc = lc.withContext("stopReason", stopReason);
|
|
217
369
|
if (hydrationTimeMs !== void 0) lc = lc.withContext("hydrationTimeMs", hydrationTimeMs);
|
|
218
370
|
if (hydrationRowCount !== void 0) lc = lc.withContext("hydrationRowCount", hydrationRowCount);
|
|
371
|
+
if (hydrationRowsRead !== void 0) lc = lc.withContext("hydrationRowsRead", hydrationRowsRead);
|
|
219
372
|
if (pipelineLifetimeMs !== void 0) lc = lc.withContext("pipelineLifetimeMs", pipelineLifetimeMs);
|
|
220
|
-
lc.
|
|
373
|
+
if (abandonReason !== void 0) lc = lc.withContext("abandonReason", abandonReason);
|
|
374
|
+
if (estimatedPushMs !== void 0) lc = lc.withContext("estimatedPushMs", estimatedPushMs);
|
|
375
|
+
if (pushTimeMs !== void 0) lc = lc.withContext("pushTimeMs", pushTimeMs);
|
|
376
|
+
if (pushedChanges !== void 0) lc = lc.withContext("pushedChanges", pushedChanges);
|
|
377
|
+
lc[level]?.("query pipeline lifecycle");
|
|
221
378
|
}
|
|
222
379
|
/**
|
|
223
380
|
* A `{scalar: true}` that cannot be honored degrades silently to a plain
|
|
@@ -232,35 +389,39 @@ var PipelineDriver = class {
|
|
|
232
389
|
this.#lc.warn?.(`Ignoring {scalar: true} on the "${table}" subquery of query ${queryID}: it does not constrain every column of any unique key ${keys.length > 0 ? `[${keys}]` : "(none on this table)"} to a literal with "=", so it is not provably limited to one row. The gate runs as a plain EXISTS.`);
|
|
233
390
|
}
|
|
234
391
|
}
|
|
235
|
-
#
|
|
236
|
-
|
|
392
|
+
#disableCorrelatedPredicatePushdown() {
|
|
393
|
+
return this.#config?.enableCorrelatedPredicatePushdown === false;
|
|
394
|
+
}
|
|
395
|
+
#resolveScalarSubqueries(ast, tables) {
|
|
237
396
|
const companionInputs = [];
|
|
238
397
|
const executor = (subqueryAST, childField) => {
|
|
239
398
|
const input = buildPipeline(subqueryAST, {
|
|
240
|
-
|
|
399
|
+
enableNotExists: true,
|
|
400
|
+
disableCorrelatedPredicatePushdown: this.#disableCorrelatedPredicatePushdown(),
|
|
401
|
+
getSource: (name) => {
|
|
402
|
+
tables.add(name);
|
|
403
|
+
return this.#getSource(name);
|
|
404
|
+
},
|
|
241
405
|
createStorage: () => this.#createStorage(),
|
|
242
406
|
decorateSourceInput: (input) => input,
|
|
243
407
|
decorateInput: (input) => input,
|
|
244
408
|
addEdge() {},
|
|
245
409
|
decorateFilterInput: (input) => input
|
|
246
410
|
}, "scalar-subquery");
|
|
247
|
-
let node;
|
|
248
|
-
for (const n of skipYields(input.fetch({}))) node ??= n;
|
|
249
|
-
if (!node) {
|
|
250
|
-
companionInputs.push(input);
|
|
251
|
-
return;
|
|
252
|
-
}
|
|
253
|
-
companionRows.push({
|
|
254
|
-
table: subqueryAST.table,
|
|
255
|
-
row: node.row
|
|
256
|
-
});
|
|
257
411
|
companionInputs.push(input);
|
|
258
|
-
return
|
|
412
|
+
return fetchScalarValue(input, childField);
|
|
259
413
|
};
|
|
260
|
-
|
|
414
|
+
let resolved;
|
|
415
|
+
let companions;
|
|
416
|
+
let ignoredScalarHints;
|
|
417
|
+
try {
|
|
418
|
+
({ast: resolved, companions, ignoredScalarHints} = resolveSimpleScalarSubqueries(ast, this.#tableSpecs, executor));
|
|
419
|
+
} catch (e) {
|
|
420
|
+
for (const input of companionInputs) input.destroy();
|
|
421
|
+
throw e;
|
|
422
|
+
}
|
|
261
423
|
return {
|
|
262
424
|
ast: resolved,
|
|
263
|
-
companionRows,
|
|
264
425
|
companions,
|
|
265
426
|
companionInputs,
|
|
266
427
|
ignoredScalarHints
|
|
@@ -288,57 +449,74 @@ var PipelineDriver = class {
|
|
|
288
449
|
assert(this.initialized(), "Pipeline driver must be initialized before adding queries");
|
|
289
450
|
this.removeQuery(queryID, "replace-query");
|
|
290
451
|
const pipelineRunID = randomID();
|
|
452
|
+
const shape = queryShape(query);
|
|
453
|
+
const level = this.#abandoned.has(queryID) ? "debug" : "info";
|
|
291
454
|
this.#logQueryPipelineLifecycle({
|
|
292
455
|
zeroEvent: "query-pipeline-hydrate-start",
|
|
293
456
|
pipelineRunID,
|
|
294
457
|
queryHash: queryID,
|
|
295
458
|
transformationHash,
|
|
296
459
|
queryName,
|
|
297
|
-
hydrationReason
|
|
460
|
+
hydrationReason,
|
|
461
|
+
level
|
|
298
462
|
});
|
|
299
|
-
const debugDelegate = runtimeDebugFlags.trackRowsVended ? new Debug() : void 0;
|
|
463
|
+
const debugDelegate = runtimeDebugFlags.trackRowsVended ? new Debug(true) : void 0;
|
|
300
464
|
const costModel = this.#ensureCostModelExistsIfEnabled(this.#snapshotter.current().db.db);
|
|
301
465
|
assert(this.#advanceContext === null, "Cannot hydrate while advance is in progress");
|
|
466
|
+
assert(!this.#costBasedAdvanceIncomplete, "Cannot hydrate before the advance has completed");
|
|
302
467
|
this.#hydrateContext = { timer };
|
|
468
|
+
const rowsReadAtStart = this.#totalRowsRead();
|
|
303
469
|
let hydrationFinished = false;
|
|
304
470
|
let hydrationFailed = false;
|
|
305
471
|
let hydrationRowCount = 0;
|
|
472
|
+
let planWarnings = [];
|
|
473
|
+
const planWarningThresholds = this.#planWarningThresholds;
|
|
474
|
+
let builtInputs = [];
|
|
475
|
+
const tables = /* @__PURE__ */ new Set();
|
|
306
476
|
try {
|
|
307
|
-
|
|
477
|
+
this.#rowSetSignatures.set(queryID, 0n);
|
|
478
|
+
this.#changedRowSetSignatures.add(queryID);
|
|
479
|
+
const { ast: resolvedQuery, companions: companionMeta, companionInputs, ignoredScalarHints } = this.#resolveScalarSubqueries(query, tables);
|
|
480
|
+
builtInputs = [...companionInputs];
|
|
308
481
|
this.#warnIgnoredScalarHints(queryID, ignoredScalarHints);
|
|
309
482
|
const input = buildPipeline(resolvedQuery, {
|
|
310
483
|
debug: debugDelegate,
|
|
311
484
|
enableNotExists: true,
|
|
312
|
-
|
|
485
|
+
disableCorrelatedPredicatePushdown: this.#disableCorrelatedPredicatePushdown(),
|
|
486
|
+
enablePlannerAwarePushdown: this.#config?.enablePlannerAwarePushdown !== false,
|
|
487
|
+
getSource: (name) => {
|
|
488
|
+
tables.add(name);
|
|
489
|
+
return this.#getSource(name);
|
|
490
|
+
},
|
|
313
491
|
createStorage: () => this.#createStorage(),
|
|
314
|
-
decorateSourceInput: (input, _queryID) => new MeasurePushOperator(new QueryFailureLoggingOperator(this.#lc, input, queryID, transformationHash, queryName), queryID, this.#
|
|
492
|
+
decorateSourceInput: (input, _queryID) => new MeasurePushOperator(new QueryFailureLoggingOperator(this.#lc, input, queryID, transformationHash, queryName), queryID, this.#metricsDelegate, "query-update-server"),
|
|
315
493
|
decorateInput: (input) => input,
|
|
316
494
|
addEdge() {},
|
|
317
|
-
decorateFilterInput: (input) => input
|
|
495
|
+
decorateFilterInput: (input) => input,
|
|
496
|
+
planWarnings: planWarningThresholds && {
|
|
497
|
+
thresholds: planWarningThresholds,
|
|
498
|
+
report: (warnings) => {
|
|
499
|
+
planWarnings = warnings;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
318
502
|
}, queryID, costModel);
|
|
503
|
+
builtInputs.push(input);
|
|
504
|
+
if (planWarnings.length > 0) this.#logPlanWarnings(shape, {
|
|
505
|
+
queryHash: queryID,
|
|
506
|
+
transformationHash,
|
|
507
|
+
queryName
|
|
508
|
+
}, planWarnings);
|
|
319
509
|
const schema = input.getSchema();
|
|
320
|
-
input.setOutput({ push: (change) =>
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
streamer.
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
if (change !== "yield") hydrationRowCount++;
|
|
328
|
-
yield change;
|
|
329
|
-
}
|
|
330
|
-
for (const { table, row } of companionRows) {
|
|
331
|
-
const primaryKey = mustGetPrimaryKey(this.#primaryKeys, table);
|
|
332
|
-
hydrationRowCount++;
|
|
333
|
-
yield {
|
|
334
|
-
type: 0,
|
|
335
|
-
queryID,
|
|
336
|
-
table,
|
|
337
|
-
rowKey: getRowKey(primaryKey, row),
|
|
338
|
-
row
|
|
339
|
-
};
|
|
510
|
+
input.setOutput({ push: (change) => this.#streamPushed(queryID, schema, change) });
|
|
511
|
+
for (let i = -1; i < companionInputs.length; i++) {
|
|
512
|
+
const pipeline = i < 0 ? input : companionInputs[i];
|
|
513
|
+
for (const change of must(this.#streamer).streamNodes(queryID, i < 0 ? schema : companionStreamSchema(pipeline, companionMeta[i]), 0, pipeline.fetch({}))) {
|
|
514
|
+
if (change !== "yield") hydrationRowCount++;
|
|
515
|
+
yield change;
|
|
516
|
+
}
|
|
340
517
|
}
|
|
341
518
|
const hydrationTimeMs = timer.totalElapsed();
|
|
519
|
+
const hydrationRowsRead = this.#totalRowsRead() - rowsReadAtStart;
|
|
342
520
|
if (runtimeDebugFlags.trackRowCountsVended) {
|
|
343
521
|
if (hydrationTimeMs > this.#logConfig.slowHydrateThreshold) {
|
|
344
522
|
let totalRowsConsidered = 0;
|
|
@@ -356,7 +534,7 @@ var PipelineDriver = class {
|
|
|
356
534
|
for (let i = 0; i < companionMeta.length; i++) {
|
|
357
535
|
const meta = companionMeta[i];
|
|
358
536
|
const companionInput = companionInputs[i];
|
|
359
|
-
const companionSchema = companionInput
|
|
537
|
+
const companionSchema = companionStreamSchema(companionInput, meta);
|
|
360
538
|
const { childField, resolvedValue } = meta;
|
|
361
539
|
companionInput.setOutput({ push: (change) => {
|
|
362
540
|
let newValue;
|
|
@@ -368,13 +546,10 @@ var PipelineDriver = class {
|
|
|
368
546
|
case 1:
|
|
369
547
|
newValue = void 0;
|
|
370
548
|
break;
|
|
371
|
-
case 3: return
|
|
549
|
+
case 3: return this.#streamPushed(queryID, companionSchema, change);
|
|
372
550
|
}
|
|
373
551
|
if (!scalarValuesEqual(newValue, resolvedValue)) throw new ResetPipelinesSignal(`Scalar subquery value changed for ${meta.ast.table}: ${String(resolvedValue)} -> ${String(newValue)}`, "scalar-subquery");
|
|
374
|
-
|
|
375
|
-
assert(streamer, "must #startAccumulating() before pushing changes");
|
|
376
|
-
streamer.accumulate(queryID, companionSchema, [change]);
|
|
377
|
-
return [];
|
|
552
|
+
return this.#streamPushed(queryID, companionSchema, change);
|
|
378
553
|
} });
|
|
379
554
|
liveCompanions.push({
|
|
380
555
|
input: companionInput,
|
|
@@ -387,15 +562,31 @@ var PipelineDriver = class {
|
|
|
387
562
|
input,
|
|
388
563
|
hydrationTimeMs,
|
|
389
564
|
hydrationRowCount,
|
|
565
|
+
hydrationRowsRead,
|
|
566
|
+
planWarnings,
|
|
390
567
|
hydrationReason,
|
|
391
568
|
pipelineRunID,
|
|
392
569
|
pipelineReadyAtMs,
|
|
393
570
|
transformedAst: resolvedQuery,
|
|
571
|
+
originalAst: query,
|
|
572
|
+
shape,
|
|
394
573
|
transformationHash,
|
|
395
574
|
...queryName !== void 0 && { queryName },
|
|
396
|
-
companions: liveCompanions
|
|
575
|
+
companions: liveCompanions,
|
|
576
|
+
tables
|
|
397
577
|
});
|
|
578
|
+
this.#abandoned.delete(queryID);
|
|
398
579
|
hydrationFinished = true;
|
|
580
|
+
this.#queryStats?.recordHydration({
|
|
581
|
+
queryName,
|
|
582
|
+
shape
|
|
583
|
+
}, {
|
|
584
|
+
outcome: "finished",
|
|
585
|
+
timeMs: hydrationTimeMs,
|
|
586
|
+
rowCount: hydrationRowCount,
|
|
587
|
+
rowsRead: hydrationRowsRead,
|
|
588
|
+
planWarnings
|
|
589
|
+
});
|
|
399
590
|
this.#logQueryPipelineLifecycle({
|
|
400
591
|
zeroEvent: "query-pipeline-hydrate-finish",
|
|
401
592
|
pipelineRunID,
|
|
@@ -404,10 +595,19 @@ var PipelineDriver = class {
|
|
|
404
595
|
queryName,
|
|
405
596
|
hydrationReason,
|
|
406
597
|
hydrationTimeMs,
|
|
407
|
-
hydrationRowCount
|
|
598
|
+
hydrationRowCount,
|
|
599
|
+
hydrationRowsRead,
|
|
600
|
+
level
|
|
408
601
|
});
|
|
409
602
|
} catch (e) {
|
|
410
603
|
hydrationFailed = true;
|
|
604
|
+
this.#queryStats?.recordHydration({
|
|
605
|
+
queryName,
|
|
606
|
+
shape
|
|
607
|
+
}, {
|
|
608
|
+
outcome: "failed",
|
|
609
|
+
timeMs: timer.totalElapsed()
|
|
610
|
+
});
|
|
411
611
|
this.#logQueryPipelineLifecycle({
|
|
412
612
|
zeroEvent: "query-pipeline-hydrate-failed",
|
|
413
613
|
pipelineRunID,
|
|
@@ -425,16 +625,30 @@ var PipelineDriver = class {
|
|
|
425
625
|
}, "query hydration failed", e);
|
|
426
626
|
throw e;
|
|
427
627
|
} finally {
|
|
428
|
-
if (!hydrationFinished && !hydrationFailed)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
628
|
+
if (!hydrationFinished && !hydrationFailed) {
|
|
629
|
+
this.#queryStats?.recordHydration({
|
|
630
|
+
queryName,
|
|
631
|
+
shape
|
|
632
|
+
}, {
|
|
633
|
+
outcome: "aborted",
|
|
634
|
+
timeMs: timer.totalElapsed()
|
|
635
|
+
});
|
|
636
|
+
this.#logQueryPipelineLifecycle({
|
|
637
|
+
zeroEvent: "query-pipeline-hydrate-aborted",
|
|
638
|
+
pipelineRunID,
|
|
639
|
+
queryHash: queryID,
|
|
640
|
+
transformationHash,
|
|
641
|
+
queryName,
|
|
642
|
+
hydrationReason,
|
|
643
|
+
hydrationTimeMs: timer.totalElapsed(),
|
|
644
|
+
hydrationRowCount
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
if (!hydrationFinished) {
|
|
648
|
+
for (const input of builtInputs) input.destroy();
|
|
649
|
+
this.#rowSetSignatures.delete(queryID);
|
|
650
|
+
this.#changedRowSetSignatures.delete(queryID);
|
|
651
|
+
}
|
|
438
652
|
this.#hydrateContext = null;
|
|
439
653
|
}
|
|
440
654
|
}
|
|
@@ -443,14 +657,24 @@ var PipelineDriver = class {
|
|
|
443
657
|
* was not added.
|
|
444
658
|
*/
|
|
445
659
|
removeQuery(queryID, stopReason = "remove-query") {
|
|
660
|
+
this.#removeQuery(queryID, stopReason);
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* @param abandoned If an advancement is abandoning the query's pipeline,
|
|
664
|
+
* the record of that, which is logged.
|
|
665
|
+
*/
|
|
666
|
+
#removeQuery(queryID, stopReason, abandoned) {
|
|
446
667
|
const pipeline = this.#pipelines.get(queryID);
|
|
447
668
|
if (pipeline) {
|
|
448
669
|
this.#pipelines.delete(queryID);
|
|
449
|
-
this.#destroyPipeline(queryID, pipeline, stopReason);
|
|
670
|
+
this.#destroyPipeline(queryID, pipeline, stopReason, abandoned);
|
|
450
671
|
}
|
|
451
672
|
this.#rowSetSignatures.delete(queryID);
|
|
673
|
+
this.#changedRowSetSignatures.delete(queryID);
|
|
674
|
+
if (stopReason !== "replace-query") this.#abandoned.delete(queryID);
|
|
675
|
+
if (stopReason === "remove-query") this.#pushCosts.forget(queryID);
|
|
452
676
|
}
|
|
453
|
-
#destroyPipeline(queryID, pipeline, stopReason) {
|
|
677
|
+
#destroyPipeline(queryID, pipeline, stopReason, abandoned) {
|
|
454
678
|
this.#logQueryPipelineLifecycle({
|
|
455
679
|
zeroEvent: "query-pipeline-stop",
|
|
456
680
|
pipelineRunID: pipeline.pipelineRunID,
|
|
@@ -461,7 +685,14 @@ var PipelineDriver = class {
|
|
|
461
685
|
stopReason,
|
|
462
686
|
hydrationTimeMs: pipeline.hydrationTimeMs,
|
|
463
687
|
hydrationRowCount: pipeline.hydrationRowCount,
|
|
464
|
-
pipelineLifetimeMs: Date.now() - pipeline.pipelineReadyAtMs
|
|
688
|
+
pipelineLifetimeMs: Date.now() - pipeline.pipelineReadyAtMs,
|
|
689
|
+
...abandoned && {
|
|
690
|
+
abandonReason: abandoned.reason,
|
|
691
|
+
estimatedPushMs: abandoned.estimatedPushMs,
|
|
692
|
+
pushTimeMs: abandoned.pushTimeMs,
|
|
693
|
+
pushedChanges: abandoned.changes,
|
|
694
|
+
level: "debug"
|
|
695
|
+
}
|
|
465
696
|
});
|
|
466
697
|
pipeline.input.destroy();
|
|
467
698
|
for (const companion of pipeline.companions) companion.input.destroy();
|
|
@@ -475,6 +706,20 @@ var PipelineDriver = class {
|
|
|
475
706
|
return this.#rowSetSignatures.get(queryID);
|
|
476
707
|
}
|
|
477
708
|
/**
|
|
709
|
+
* IDs of the queries whose {@link rowSetSignature} changed (by an ADD or
|
|
710
|
+
* REMOVE from {@link addQuery} or {@link advance}) since the last call to
|
|
711
|
+
* {@link clearChangedRowSetSignatures}.
|
|
712
|
+
*/
|
|
713
|
+
changedRowSetSignatures() {
|
|
714
|
+
return this.#changedRowSetSignatures;
|
|
715
|
+
}
|
|
716
|
+
/**
|
|
717
|
+
* Called once the {@link changedRowSetSignatures} have been persisted.
|
|
718
|
+
*/
|
|
719
|
+
clearChangedRowSetSignatures() {
|
|
720
|
+
this.#changedRowSetSignatures.clear();
|
|
721
|
+
}
|
|
722
|
+
/**
|
|
478
723
|
* Wraps an iterable of RowChanges, XORing each row's unit hash into the
|
|
479
724
|
* query's signature (ADDs and REMOVEs share the same op; EDITs are no-ops).
|
|
480
725
|
* Used to intercept the yield streams from {@link addQuery} and
|
|
@@ -490,6 +735,7 @@ var PipelineDriver = class {
|
|
|
490
735
|
rowKey: change.rowKey
|
|
491
736
|
});
|
|
492
737
|
this.#rowSetSignatures.set(change.queryID, cur ^ unit);
|
|
738
|
+
this.#changedRowSetSignatures.add(change.queryID);
|
|
493
739
|
}
|
|
494
740
|
yield change;
|
|
495
741
|
}
|
|
@@ -510,44 +756,212 @@ var PipelineDriver = class {
|
|
|
510
756
|
* measure the progress of the advancement and abort with a
|
|
511
757
|
* {@link ResetPipelinesSignal} if it is estimated to take longer
|
|
512
758
|
* than a hydration.
|
|
759
|
+
* @param costBased If given, the advancement is bounded query by query
|
|
760
|
+
* instead (see {@link CostBasedAdvance}).
|
|
513
761
|
* @return The resulting row changes for all added queries. Note that the
|
|
514
762
|
* `changes` must be iterated over in their entirety in order to
|
|
515
763
|
* advance the database snapshot.
|
|
764
|
+
* @throws A {@link ResetPipelinesSignal} if `costBased` is given and the
|
|
765
|
+
* changes include a schema change, a truncation or a change of
|
|
766
|
+
* the permissions. It is thrown before any change is pushed or
|
|
767
|
+
* any pipeline is removed, as the caller resets the pipelines
|
|
768
|
+
* either way. Without `costBased`, it is iterating over the
|
|
769
|
+
* `changes` that throws it, on getting to that change.
|
|
516
770
|
*/
|
|
517
|
-
advance(timer) {
|
|
771
|
+
advance(timer, costBased) {
|
|
518
772
|
assert(this.initialized(), "Pipeline driver must be initialized before advancing");
|
|
519
|
-
|
|
773
|
+
let diff;
|
|
774
|
+
let context;
|
|
775
|
+
if (costBased === void 0) diff = this.#snapshotter.advance(this.#tableSpecs, this.#allTableNames, this.#tables, "divergent");
|
|
776
|
+
else {
|
|
777
|
+
const { prev, curr } = this.#snapshotter.advanceWithoutDiff();
|
|
778
|
+
const counts = curr.countChangesSince(prev.version);
|
|
779
|
+
const reset = this.#snapshotter.pendingReset(this.#tableSpecs, counts);
|
|
780
|
+
if (reset) throw reset;
|
|
781
|
+
context = this.#startCostBasedAdvance(costBased, curr.version > prev.version, counts);
|
|
782
|
+
diff = this.#snapshotter.diff(this.#tableSpecs, this.#allTableNames, this.#tables, "divergent", counts, context.abandoned.length > 0 ? this.#tablesRead() : void 0);
|
|
783
|
+
this.#costBasedAdvanceIncomplete = true;
|
|
784
|
+
}
|
|
520
785
|
const { prev, curr, changes } = diff;
|
|
521
786
|
this.#lc.debug?.(`advance ${prev.version} => ${curr.version}: ${changes} changes`);
|
|
787
|
+
const progress = { changesProcessed: 0 };
|
|
522
788
|
return {
|
|
523
789
|
version: curr.version,
|
|
524
790
|
numChanges: changes,
|
|
525
|
-
changes: this.#trackRowSetSignatures(this.#advance(diff, timer, changes))
|
|
791
|
+
changes: this.#trackRowSetSignatures(this.#advance(diff, timer, changes, progress, context)),
|
|
792
|
+
abandoned: () => context?.abandoned ?? [],
|
|
793
|
+
estimates: () => context?.estimates ?? [],
|
|
794
|
+
progress: () => ({
|
|
795
|
+
changesScanned: diff.changesScanned,
|
|
796
|
+
changesProcessed: progress.changesProcessed,
|
|
797
|
+
changesSkipped: diff.changesSkipped
|
|
798
|
+
})
|
|
526
799
|
};
|
|
527
800
|
}
|
|
528
|
-
|
|
801
|
+
/** The tables that the pipelines read. */
|
|
802
|
+
#tablesRead() {
|
|
803
|
+
const tables = /* @__PURE__ */ new Set();
|
|
804
|
+
for (const pipeline of this.#pipelines.values()) for (const table of pipeline.tables) tables.add(table);
|
|
805
|
+
return tables;
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Removes the pipelines of the queries that are estimated to be cheaper to
|
|
809
|
+
* hydrate again than to push the advancement's changes to: first each
|
|
810
|
+
* query for what pushing costs it, and then the ones that are left for
|
|
811
|
+
* what reading the changes costs them together.
|
|
812
|
+
*
|
|
813
|
+
* @param canAbandon Whether pipelines can be removed, by this or by the
|
|
814
|
+
* cutoff.
|
|
815
|
+
* @param counts The rows that changed since the previous snapshot.
|
|
816
|
+
*/
|
|
817
|
+
#startCostBasedAdvance({ shouldCutOff, rebuildMargin }, canAbandon, counts) {
|
|
818
|
+
const changes = counts.byTable;
|
|
819
|
+
const estimatedPushMs = /* @__PURE__ */ new Map();
|
|
820
|
+
const abandoned = [];
|
|
821
|
+
if (canAbandon) {
|
|
822
|
+
for (const [queryID, pipeline] of this.#pipelines) {
|
|
823
|
+
const estimate = this.#pushCosts.estimate(queryID, pipeline.tables, changes);
|
|
824
|
+
if (estimate === void 0) continue;
|
|
825
|
+
if (shouldStartOnRebuild(estimate, pipeline.hydrationTimeMs, rebuildMargin)) this.#abandon(abandoned, "estimate", pipeline, {
|
|
826
|
+
queryID,
|
|
827
|
+
pushTimeMs: 0,
|
|
828
|
+
changes: 0,
|
|
829
|
+
hydrationTimeMs: pipeline.hydrationTimeMs,
|
|
830
|
+
estimatedPushMs: estimate
|
|
831
|
+
});
|
|
832
|
+
else estimatedPushMs.set(queryID, estimate);
|
|
833
|
+
}
|
|
834
|
+
this.#abandonInsteadOfReading(counts, rebuildMargin, estimatedPushMs, abandoned);
|
|
835
|
+
}
|
|
836
|
+
return {
|
|
837
|
+
cutoff: new PushCutoff(canAbandon ? shouldCutOff : () => false),
|
|
838
|
+
entries: counts.total,
|
|
839
|
+
estimatedPushMs,
|
|
840
|
+
abandoned,
|
|
841
|
+
estimates: []
|
|
842
|
+
};
|
|
843
|
+
}
|
|
844
|
+
/**
|
|
845
|
+
* Removes the pipelines that are left, if reading the advancement's
|
|
846
|
+
* changes and pushing them to those is estimated to cost more than
|
|
847
|
+
* hydrating them again. The changes are then not read at all.
|
|
848
|
+
*/
|
|
849
|
+
#abandonInsteadOfReading(counts, rebuildMargin, estimatedPushMs, abandoned) {
|
|
850
|
+
if (this.#pipelines.size === 0) return;
|
|
851
|
+
let entriesOfTablesRead = 0;
|
|
852
|
+
for (const table of this.#tablesRead()) entriesOfTablesRead += counts.byTable.get(table) ?? 0;
|
|
853
|
+
const queries = Array.from(this.#pipelines, ([queryID, pipeline]) => ({
|
|
854
|
+
queryID,
|
|
855
|
+
pipeline,
|
|
856
|
+
estimatedPushMs: estimatedPushMs.get(queryID),
|
|
857
|
+
hydrationTimeMs: pipeline.hydrationTimeMs
|
|
858
|
+
}));
|
|
859
|
+
const estimatedReadMs = this.#readCosts.estimate({
|
|
860
|
+
walk: counts.total,
|
|
861
|
+
parse: abandoned.length > 0 ? entriesOfTablesRead : counts.total,
|
|
862
|
+
lookup: entriesOfTablesRead
|
|
863
|
+
});
|
|
864
|
+
if (!shouldRebuildInsteadOfReading(estimatedReadMs, queries, rebuildMargin)) return;
|
|
865
|
+
let pushMs = 0;
|
|
866
|
+
let hydrationMs = 0;
|
|
867
|
+
for (const query of queries) {
|
|
868
|
+
pushMs += query.estimatedPushMs ?? 0;
|
|
869
|
+
hydrationMs += query.hydrationTimeMs;
|
|
870
|
+
}
|
|
871
|
+
this.#lc.debug?.("Not reading a batch of changes: hydrating its queries again is estimated to cost less", {
|
|
872
|
+
entries: counts.total,
|
|
873
|
+
entriesOfTablesRead,
|
|
874
|
+
estimatedReadMs,
|
|
875
|
+
estimatedPushMs: pushMs,
|
|
876
|
+
hydrationTimeMs: hydrationMs,
|
|
877
|
+
rebuildMargin,
|
|
878
|
+
queries: queries.length
|
|
879
|
+
});
|
|
880
|
+
for (const { queryID, pipeline, ...estimate } of queries) this.#abandon(abandoned, "read", pipeline, {
|
|
881
|
+
queryID,
|
|
882
|
+
pushTimeMs: 0,
|
|
883
|
+
changes: 0,
|
|
884
|
+
...estimate
|
|
885
|
+
});
|
|
886
|
+
estimatedPushMs.clear();
|
|
887
|
+
}
|
|
888
|
+
#abandon(abandoned, reason, pipeline, progress) {
|
|
889
|
+
const { transformationHash, transformedAst, originalAst, queryName } = pipeline;
|
|
890
|
+
const query = {
|
|
891
|
+
...progress,
|
|
892
|
+
reason,
|
|
893
|
+
transformationHash,
|
|
894
|
+
transformedAst,
|
|
895
|
+
originalAst,
|
|
896
|
+
...queryName !== void 0 && { queryName }
|
|
897
|
+
};
|
|
898
|
+
this.#removeQuery(progress.queryID, "abandon-advance", query);
|
|
899
|
+
this.#abandoned.set(progress.queryID, query);
|
|
900
|
+
abandoned.push(query);
|
|
901
|
+
this.#queryStats?.recordAbandoned(pipeline, reason);
|
|
902
|
+
}
|
|
903
|
+
*#advance(diff, timer, numChanges, progress, costBased) {
|
|
529
904
|
assert(this.#hydrateContext === null, "Cannot advance while hydration is in progress");
|
|
530
905
|
const totalHydrationTimeMs = this.totalHydrationTimeMs();
|
|
531
|
-
|
|
906
|
+
const advanceContext = {
|
|
532
907
|
timer,
|
|
908
|
+
progress,
|
|
909
|
+
diff,
|
|
910
|
+
completedChanges: 0,
|
|
533
911
|
totalHydrationTimeMs,
|
|
534
912
|
numChanges,
|
|
913
|
+
reservedRows: void 0,
|
|
914
|
+
heldBytes: 0,
|
|
535
915
|
currentChangeStartMs: void 0,
|
|
536
|
-
pos: 0
|
|
916
|
+
pos: 0,
|
|
917
|
+
currentTable: void 0,
|
|
918
|
+
queryStats: /* @__PURE__ */ new Map(),
|
|
919
|
+
costBased,
|
|
920
|
+
pushTimeMs: 0,
|
|
921
|
+
stage: "diff"
|
|
537
922
|
};
|
|
538
|
-
this.#
|
|
923
|
+
this.#advanceContext = advanceContext;
|
|
924
|
+
let timedOut = false;
|
|
925
|
+
let readToEnd = true;
|
|
539
926
|
try {
|
|
540
|
-
|
|
541
|
-
|
|
927
|
+
advanceContext.reservedRows = this.#reserveDeferredWrites(numChanges);
|
|
928
|
+
const deferWrites = advanceContext.reservedRows !== void 0;
|
|
929
|
+
if (deferWrites) diff.setPrevWrites("none");
|
|
930
|
+
for (const table of this.#tables.values()) table.setDeferWrites(deferWrites);
|
|
931
|
+
this.#lc.debug?.(`starting pipeline advancement of ${numChanges} changes with an advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms (${deferWrites ? "deferred" : "write-through"}).`);
|
|
932
|
+
for (const { table, prevValues: probedPrevValues, nextValue, rowKey } of diff) {
|
|
933
|
+
advanceContext.stage = "between";
|
|
934
|
+
advanceContext.completedChanges = diff.changesScanned - 1;
|
|
935
|
+
if (this.#checkAdvance(advanceContext)) yield "yield";
|
|
936
|
+
if (costBased) {
|
|
937
|
+
this.#cutOffQueries(advanceContext, costBased, diff, table);
|
|
938
|
+
if (this.#pipelines.size === 0) {
|
|
939
|
+
readToEnd = false;
|
|
940
|
+
break;
|
|
941
|
+
}
|
|
942
|
+
}
|
|
542
943
|
const start = timer.totalElapsed();
|
|
543
|
-
const advanceContext = must(this.#advanceContext);
|
|
544
944
|
advanceContext.currentChangeStartMs = start;
|
|
545
|
-
|
|
945
|
+
advanceContext.currentTable = table;
|
|
946
|
+
advanceContext.stage = "push";
|
|
947
|
+
let holds = "fits";
|
|
948
|
+
let pushCompleted = false;
|
|
546
949
|
try {
|
|
547
950
|
try {
|
|
548
951
|
const tableSource = this.#tables.get(table);
|
|
549
|
-
if (!tableSource)
|
|
952
|
+
if (!tableSource) {
|
|
953
|
+
pushCompleted = true;
|
|
954
|
+
continue;
|
|
955
|
+
}
|
|
550
956
|
const primaryKey = mustGetPrimaryKey(this.#primaryKeys, table);
|
|
957
|
+
const isUnobservableAdd = probedPrevValues.length === 0 && nextValue !== null && !tableSource.mayAcceptRow(nextValue);
|
|
958
|
+
const isUnobservableEdit = probedPrevValues.length === 1 && nextValue !== null && !tableSource.mayAcceptRow(nextValue) && !tableSource.mayAcceptRow(probedPrevValues[0]) && deepEqual(getRowKey(primaryKey, probedPrevValues[0]), rowKey);
|
|
959
|
+
if (isUnobservableAdd || isUnobservableEdit) {
|
|
960
|
+
pushCompleted = true;
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
if (nextValue !== null && !this.#reserveSecondRow(advanceContext, rowKey, primaryKey)) holds = "rows";
|
|
964
|
+
const prevValues = tableSource.reconcilePendingConflicts(probedPrevValues, nextValue, rowKey, this.#tableSpecs.get(table)?.tableSpec.uniqueKeys ?? []);
|
|
551
965
|
let editOldRow = void 0;
|
|
552
966
|
for (const prevValue of prevValues) if (nextValue && deepEqual(getRowKey(primaryKey, prevValue), getRowKey(primaryKey, nextValue))) editOldRow = prevValue;
|
|
553
967
|
else {
|
|
@@ -556,42 +970,318 @@ var PipelineDriver = class {
|
|
|
556
970
|
}
|
|
557
971
|
if (nextValue) if (editOldRow) yield* this.#push(tableSource, makeSourceChangeEdit(nextValue, editOldRow));
|
|
558
972
|
else yield* this.#push(tableSource, makeSourceChangeAdd(nextValue));
|
|
973
|
+
pushCompleted = true;
|
|
559
974
|
} finally {
|
|
560
975
|
advanceContext.pos++;
|
|
976
|
+
if (pushCompleted) {
|
|
977
|
+
progress.changesProcessed++;
|
|
978
|
+
advanceContext.completedChanges = diff.changesScanned;
|
|
979
|
+
}
|
|
561
980
|
}
|
|
562
|
-
this.#
|
|
981
|
+
this.#checkAdvance(advanceContext, false);
|
|
982
|
+
if (holds === "fits") holds = this.#holdPendingRows(advanceContext);
|
|
563
983
|
} finally {
|
|
984
|
+
advanceContext.pushTimeMs += timer.totalElapsed() - start;
|
|
985
|
+
advanceContext.stage = "diff";
|
|
564
986
|
advanceContext.currentChangeStartMs = void 0;
|
|
565
987
|
}
|
|
566
988
|
const elapsed = timer.totalElapsed() - start;
|
|
567
|
-
this.#advanceTime.recordMs(elapsed, {
|
|
568
|
-
|
|
569
|
-
type
|
|
570
|
-
});
|
|
989
|
+
this.#advanceTime.recordMs(elapsed, { table });
|
|
990
|
+
if (holds !== "fits") yield* this.#writeThrough(advanceContext, diff, holds);
|
|
571
991
|
}
|
|
992
|
+
advanceContext.completedChanges = diff.changesScanned;
|
|
572
993
|
const { curr } = diff;
|
|
573
994
|
for (const table of this.#tables.values()) table.setDB(curr.db.db);
|
|
995
|
+
this.#costBasedAdvanceIncomplete = false;
|
|
574
996
|
this.#ensureCostModelExistsIfEnabled(curr.db.db);
|
|
575
997
|
this.#lc.debug?.(`Advanced to ${curr.version}`);
|
|
998
|
+
this.#logSlowAdvances(advanceContext);
|
|
999
|
+
if (costBased) {
|
|
1000
|
+
this.#recordPushCosts(advanceContext, costBased, diff.changesScannedByTable);
|
|
1001
|
+
if (readToEnd && diff.changes > 0 && diff.stats) {
|
|
1002
|
+
const { changeLogReadMs, parseMs, rowReadMs } = diff.stats;
|
|
1003
|
+
this.#readCosts.record({
|
|
1004
|
+
walk: changeLogReadMs,
|
|
1005
|
+
parse: parseMs,
|
|
1006
|
+
lookup: rowReadMs
|
|
1007
|
+
}, {
|
|
1008
|
+
walk: costBased.entries,
|
|
1009
|
+
parse: diff.changesScanned,
|
|
1010
|
+
lookup: diff.changesLookedUp
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
this.#snapshotter.releasePrevious();
|
|
1014
|
+
}
|
|
1015
|
+
} catch (e) {
|
|
1016
|
+
if (e instanceof ResetPipelinesSignal && e.reason === "advancement-timeout") {
|
|
1017
|
+
timedOut = true;
|
|
1018
|
+
this.#logAdvanceTimeout(advanceContext, e);
|
|
1019
|
+
}
|
|
1020
|
+
throw e;
|
|
576
1021
|
} finally {
|
|
1022
|
+
if (advanceContext.reservedRows !== void 0) for (const table of this.#tables.values()) table.discardPendingChanges();
|
|
1023
|
+
this.#releaseDeferredWrites(advanceContext);
|
|
577
1024
|
this.#advanceContext = null;
|
|
1025
|
+
this.#recordAdvanceStats(advanceContext, timedOut);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Checks the progress of the advancement. Returns whether it should yield.
|
|
1030
|
+
*
|
|
1031
|
+
* An advancement is bounded in one of two ways, never both. A
|
|
1032
|
+
* {@link CostBasedAdvance} cuts queries off one by one between changes
|
|
1033
|
+
* (see {@link #cutOffQueries}) and always runs to completion.
|
|
1034
|
+
* Without one, {@link #shouldAdvanceYieldMaybeAbortAdvance} aborts the
|
|
1035
|
+
* advancement with a {@link ResetPipelinesSignal} if it takes too long.
|
|
1036
|
+
*/
|
|
1037
|
+
#checkAdvance(advanceContext, checkYield = true) {
|
|
1038
|
+
if (advanceContext.costBased === void 0) return this.#shouldAdvanceYieldMaybeAbortAdvance(checkYield);
|
|
1039
|
+
return checkYield && advanceContext.timer.elapsedLap() > this.#yieldThresholdMs();
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Removes the pipelines of the queries that the cutoff says to.
|
|
1043
|
+
*
|
|
1044
|
+
* @param nextTable The table of the change that `diff` has just yielded,
|
|
1045
|
+
* which has not been pushed yet.
|
|
1046
|
+
*/
|
|
1047
|
+
#cutOffQueries({ queryStats }, costBased, diff, nextTable) {
|
|
1048
|
+
const cutOff = costBased.cutoff.takeCutOff((queryID) => {
|
|
1049
|
+
const pipeline = this.#pipelines.get(queryID);
|
|
1050
|
+
const stats = queryStats.get(queryID);
|
|
1051
|
+
return pipeline === void 0 || stats === void 0 ? void 0 : {
|
|
1052
|
+
queryID,
|
|
1053
|
+
pushTimeMs: stats.timeMs,
|
|
1054
|
+
changes: stats.changes,
|
|
1055
|
+
hydrationTimeMs: pipeline.hydrationTimeMs
|
|
1056
|
+
};
|
|
1057
|
+
});
|
|
1058
|
+
if (cutOff.length === 0) return;
|
|
1059
|
+
const entriesByTable = new Map(diff.changesScannedByTable);
|
|
1060
|
+
entriesByTable.set(nextTable, (entriesByTable.get(nextTable) ?? 1) - 1);
|
|
1061
|
+
for (const progress of cutOff) {
|
|
1062
|
+
const { queryID } = progress;
|
|
1063
|
+
const pipeline = must(this.#pipelines.get(queryID));
|
|
1064
|
+
this.#pushCosts.record(queryID, pipeline.tables, queryStats.get(queryID)?.timeMsByTable, entriesByTable);
|
|
1065
|
+
this.#queryStats?.recordAdvance(pipeline, {
|
|
1066
|
+
timeMs: progress.pushTimeMs,
|
|
1067
|
+
changes: progress.changes,
|
|
1068
|
+
timedOut: false
|
|
1069
|
+
});
|
|
1070
|
+
this.#abandon(costBased.abandoned, "cutoff", pipeline, {
|
|
1071
|
+
...progress,
|
|
1072
|
+
estimatedPushMs: costBased.estimatedPushMs.get(queryID)
|
|
1073
|
+
});
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Learns from a completed advancement what its changes cost the queries
|
|
1078
|
+
* that were pushed all of them.
|
|
1079
|
+
*/
|
|
1080
|
+
#recordPushCosts({ queryStats }, { estimatedPushMs, estimates }, entriesByTable) {
|
|
1081
|
+
for (const [queryID, pipeline] of this.#pipelines) {
|
|
1082
|
+
const stats = queryStats.get(queryID);
|
|
1083
|
+
this.#pushCosts.record(queryID, pipeline.tables, stats?.timeMsByTable, entriesByTable);
|
|
1084
|
+
const estimate = estimatedPushMs.get(queryID);
|
|
1085
|
+
if (estimate !== void 0) estimates.push({
|
|
1086
|
+
queryID,
|
|
1087
|
+
estimatedPushMs: estimate,
|
|
1088
|
+
pushTimeMs: stats?.timeMs ?? 0
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
/** Accounts the time each query took in an advancement to its shape. */
|
|
1093
|
+
#recordAdvanceStats({ queryStats }, timedOut) {
|
|
1094
|
+
if (this.#queryStats === void 0) return;
|
|
1095
|
+
for (const [queryID, { timeMs, changes }] of queryStats) {
|
|
1096
|
+
const pipeline = this.#pipelines.get(queryID);
|
|
1097
|
+
if (pipeline !== void 0) this.#queryStats.recordAdvance(pipeline, {
|
|
1098
|
+
timeMs,
|
|
1099
|
+
changes,
|
|
1100
|
+
timedOut
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Decides how the sources apply an advancement's changes: in memory if
|
|
1106
|
+
* they fit in the worker's {@link DeferredWritesBudget}, and otherwise
|
|
1107
|
+
* written through to the `prev` snapshot. Returns the number of rows
|
|
1108
|
+
* reserved if they are held in memory.
|
|
1109
|
+
*/
|
|
1110
|
+
#reserveDeferredWrites(numChanges) {
|
|
1111
|
+
const budget = this.#deferredWrites;
|
|
1112
|
+
if (!budget) return;
|
|
1113
|
+
if (budget.tryReserve(numChanges)) return numChanges;
|
|
1114
|
+
this.#deferredWritesFallbacks.add(1, { stage: "start" });
|
|
1115
|
+
this.#lc.debug?.(`writing through ${numChanges} changes: ${budget.reservedRows} rows of the deferred writes budget are reserved`);
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* If the change log identifies the rows of a table by a key other than its
|
|
1119
|
+
* primary key here, an entry that sets a row can change its primary key,
|
|
1120
|
+
* which is two rows to a source: the old and the new. (An entry that removes
|
|
1121
|
+
* a row removes the one row its key identifies.) Reserves the second row for
|
|
1122
|
+
* such an entry, if the advancement holds its changes in memory, and
|
|
1123
|
+
* returns whether it fit.
|
|
1124
|
+
*/
|
|
1125
|
+
#reserveSecondRow(advanceContext, rowKey, primaryKey) {
|
|
1126
|
+
if (advanceContext.reservedRows === void 0 || isKeyedBy(rowKey, primaryKey)) return true;
|
|
1127
|
+
if (!must(this.#deferredWrites).tryReserveMore(1)) return false;
|
|
1128
|
+
advanceContext.reservedRows++;
|
|
1129
|
+
return true;
|
|
1130
|
+
}
|
|
1131
|
+
/**
|
|
1132
|
+
* Writes the changes that an advancement holds in memory through to the
|
|
1133
|
+
* `prev` snapshot, and the rest of its changes after them, when they no
|
|
1134
|
+
* longer fit (see {@link HeldRows}). The advancement then continues as if
|
|
1135
|
+
* it had written through from the start.
|
|
1136
|
+
*/
|
|
1137
|
+
*#writeThrough(advanceContext, diff, reason) {
|
|
1138
|
+
const budget = must(this.#deferredWrites);
|
|
1139
|
+
this.#deferredWritesFallbacks.add(1, {
|
|
1140
|
+
stage: "partway",
|
|
1141
|
+
reason
|
|
1142
|
+
});
|
|
1143
|
+
this.#lc.debug?.(`writing through (${reason}) at ${advanceContext.pos} of ${advanceContext.numChanges} changes, holding ${advanceContext.heldBytes} of the ${budget.heldBytes} estimated bytes held on this worker (budget: ${budget.maxBytes})`);
|
|
1144
|
+
diff.setPrevWrites("divergent");
|
|
1145
|
+
for (const source of this.#tables.values()) yield* source.writePendingChanges();
|
|
1146
|
+
this.#releaseDeferredWrites(advanceContext);
|
|
1147
|
+
}
|
|
1148
|
+
#releaseDeferredWrites(advanceContext) {
|
|
1149
|
+
const { reservedRows, heldBytes } = advanceContext;
|
|
1150
|
+
if (reservedRows !== void 0) {
|
|
1151
|
+
must(this.#deferredWrites).release(reservedRows, heldBytes);
|
|
1152
|
+
advanceContext.reservedRows = void 0;
|
|
1153
|
+
advanceContext.heldBytes = 0;
|
|
1154
|
+
}
|
|
1155
|
+
}
|
|
1156
|
+
#recordAdvancePush(queryID, timeMs) {
|
|
1157
|
+
const advance = this.#advanceContext;
|
|
1158
|
+
if (advance === null) return;
|
|
1159
|
+
const stats = getOrInsertComputed(advance.queryStats, queryID, () => ({
|
|
1160
|
+
timeMs: 0,
|
|
1161
|
+
changes: 0,
|
|
1162
|
+
lastPos: -1,
|
|
1163
|
+
timeMsByTable: /* @__PURE__ */ new Map()
|
|
1164
|
+
}));
|
|
1165
|
+
stats.timeMs += timeMs;
|
|
1166
|
+
advance.costBased?.cutoff.recordPush(queryID);
|
|
1167
|
+
if (stats.lastPos !== advance.pos) {
|
|
1168
|
+
stats.lastPos = advance.pos;
|
|
1169
|
+
stats.changes++;
|
|
1170
|
+
}
|
|
1171
|
+
const table = advance.currentTable;
|
|
1172
|
+
if (table !== void 0) stats.timeMsByTable.set(table, (stats.timeMsByTable.get(table) ?? 0) + timeMs);
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* The identity of the query of the pipeline for `queryID` and its
|
|
1176
|
+
* {@link queryShape}, for logging.
|
|
1177
|
+
*/
|
|
1178
|
+
#queryForLog(queryID) {
|
|
1179
|
+
const pipeline = this.#pipelines.get(queryID);
|
|
1180
|
+
if (pipeline === void 0) return;
|
|
1181
|
+
const { transformationHash, queryName, shape } = pipeline;
|
|
1182
|
+
return {
|
|
1183
|
+
queryName,
|
|
1184
|
+
shape,
|
|
1185
|
+
fields: {
|
|
1186
|
+
queryHash: queryID,
|
|
1187
|
+
transformationHash,
|
|
1188
|
+
...queryName !== void 0 && { queryName },
|
|
1189
|
+
queryShape: shape.hash
|
|
1190
|
+
}
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
/** Compute once for an admitted log, without clocks or allocations per change. */
|
|
1194
|
+
#advancementLogFields({ timer, diff, progress, completedChanges, queryStats, totalHydrationTimeMs }) {
|
|
1195
|
+
const advancementTimeMs = timer.totalElapsed();
|
|
1196
|
+
let queryPushTimeMs = 0;
|
|
1197
|
+
for (const stats of queryStats.values()) queryPushTimeMs += stats.timeMs;
|
|
1198
|
+
return {
|
|
1199
|
+
advancementTimeMs,
|
|
1200
|
+
queryPushTimeMs,
|
|
1201
|
+
outsideQueryPushTimeMs: Math.max(0, advancementTimeMs - queryPushTimeMs),
|
|
1202
|
+
totalHydrationTimeMs,
|
|
1203
|
+
changesScanned: diff.changesScanned,
|
|
1204
|
+
changesCompleted: completedChanges,
|
|
1205
|
+
changesProcessed: progress.changesProcessed,
|
|
1206
|
+
changesSkipped: diff.changesSkipped
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Logs each query whose pushes took longer than the slow advance
|
|
1211
|
+
* threshold, at most once per query shape per
|
|
1212
|
+
* {@link SLOW_ADVANCE_LOG_WINDOW_MS}.
|
|
1213
|
+
*/
|
|
1214
|
+
#logSlowAdvances(context) {
|
|
1215
|
+
if (!this.#lc.warn) return;
|
|
1216
|
+
const { queryStats, numChanges } = context;
|
|
1217
|
+
let advancementFields;
|
|
1218
|
+
for (const [queryID, stats] of queryStats) {
|
|
1219
|
+
if (stats.timeMs <= this.#logConfig.slowAdvanceThreshold) continue;
|
|
1220
|
+
const query = this.#queryForLog(queryID);
|
|
1221
|
+
if (query === void 0) continue;
|
|
1222
|
+
const suppressed = slowAdvanceLogThrottle.admit(`${query.queryName ?? ""}:${query.shape.hash}`);
|
|
1223
|
+
if (suppressed === void 0) continue;
|
|
1224
|
+
this.#lc.warn(`Slow query advancement${query.queryName === void 0 ? "" : ` for ${query.queryName}`}: ${Math.round(stats.timeMs)} ms for ${stats.changes} of ${numChanges} changes`, {
|
|
1225
|
+
zeroEvent: "query-slow-advance",
|
|
1226
|
+
...query.fields,
|
|
1227
|
+
advanceTimeMs: stats.timeMs,
|
|
1228
|
+
changes: stats.changes,
|
|
1229
|
+
advancementChanges: numChanges,
|
|
1230
|
+
...advancementFields ??= this.#advancementLogFields(context),
|
|
1231
|
+
timeMsByTable: Object.fromEntries(stats.timeMsByTable),
|
|
1232
|
+
...suppressed > 0 && { suppressedSinceLastLog: suppressed },
|
|
1233
|
+
zql: query.shape.zql
|
|
1234
|
+
});
|
|
578
1235
|
}
|
|
579
1236
|
}
|
|
1237
|
+
/**
|
|
1238
|
+
* Logs the queries that took the most time in an advancement that timed
|
|
1239
|
+
* out, since the reset that follows would otherwise not say what was slow.
|
|
1240
|
+
* Throttled per query shape of the slowest query, with a shared fallback
|
|
1241
|
+
* when the timeout happens before any query push timings are recorded.
|
|
1242
|
+
*/
|
|
1243
|
+
#logAdvanceTimeout(context, reset) {
|
|
1244
|
+
if (!this.#lc.warn) return;
|
|
1245
|
+
const { queryStats, numChanges } = context;
|
|
1246
|
+
const slowest = [...queryStats].toSorted(([, a], [, b]) => b.timeMs - a.timeMs).slice(0, ADVANCE_TIMEOUT_LOG_MAX_QUERIES).flatMap(([queryID, stats]) => {
|
|
1247
|
+
const query = this.#queryForLog(queryID);
|
|
1248
|
+
return query ? [{
|
|
1249
|
+
query,
|
|
1250
|
+
stats
|
|
1251
|
+
}] : [];
|
|
1252
|
+
});
|
|
1253
|
+
const leadingQuery = slowest[0]?.query;
|
|
1254
|
+
const suppressed = slowAdvanceLogThrottle.admit(leadingQuery ? `timeout:${leadingQuery.queryName ?? ""}:${leadingQuery.shape.hash}` : "timeout:outside-query-push");
|
|
1255
|
+
if (suppressed === void 0) return;
|
|
1256
|
+
const summary = slowest.map(({ query, stats }) => `${query.queryName ?? query.fields.queryHash} (${Math.round(stats.timeMs)} ms)`).join(", ");
|
|
1257
|
+
this.#lc.warn(`Advancement of ${numChanges} changes timed out. ` + (summary ? `The queries that took the most time: ${summary}` : "No query push timings were recorded."), {
|
|
1258
|
+
zeroEvent: "query-advance-timeout",
|
|
1259
|
+
reason: reset.message,
|
|
1260
|
+
advancementChanges: numChanges,
|
|
1261
|
+
...this.#advancementLogFields(context),
|
|
1262
|
+
queries: slowest.map(({ query, stats }) => ({
|
|
1263
|
+
...query.fields,
|
|
1264
|
+
advanceTimeMs: stats.timeMs,
|
|
1265
|
+
changes: stats.changes,
|
|
1266
|
+
zql: query.shape.zql
|
|
1267
|
+
})),
|
|
1268
|
+
...suppressed > 0 && { suppressedSinceLastLog: suppressed }
|
|
1269
|
+
});
|
|
1270
|
+
}
|
|
580
1271
|
/** Implements `BuilderDelegate.getSource()` */
|
|
581
1272
|
#getSource(tableName) {
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
return source;
|
|
1273
|
+
return getOrInsertComputed(this.#tables, tableName, (tableName) => {
|
|
1274
|
+
const tableSpec = mustGetTableSpec(this.#tableSpecs, tableName);
|
|
1275
|
+
const primaryKey = mustGetPrimaryKey(this.#primaryKeys, tableName);
|
|
1276
|
+
const { db } = this.#snapshotter.current();
|
|
1277
|
+
const source = new TableSource(this.#lc, this.#logConfig, db.db, tableName, tableSpec.zqlSpec, primaryKey, () => this.#shouldYield(), { skipUnobservableChanges: true });
|
|
1278
|
+
this.#lc.debug?.(`created TableSource for ${tableName}`);
|
|
1279
|
+
return source;
|
|
1280
|
+
});
|
|
591
1281
|
}
|
|
592
1282
|
#shouldYield() {
|
|
593
1283
|
if (this.#hydrateContext) return this.#hydrateContext.timer.elapsedLap() > this.#yieldThresholdMs();
|
|
594
|
-
if (this.#advanceContext) return this.#
|
|
1284
|
+
if (this.#advanceContext) return this.#checkAdvance(this.#advanceContext);
|
|
595
1285
|
throw new Error("shouldYield called outside of hydration or advancement");
|
|
596
1286
|
}
|
|
597
1287
|
/**
|
|
@@ -601,120 +1291,132 @@ var PipelineDriver = class {
|
|
|
601
1291
|
* checks; a single pathological push always resets.
|
|
602
1292
|
*/
|
|
603
1293
|
#shouldAdvanceYieldMaybeAbortAdvance(checkYield = true) {
|
|
604
|
-
const { currentChangeStartMs,
|
|
1294
|
+
const { currentChangeStartMs, completedChanges, numChanges, timer: advanceTimer, totalHydrationTimeMs } = must(this.#advanceContext);
|
|
605
1295
|
const elapsed = advanceTimer.totalElapsed();
|
|
606
1296
|
const currentChangeElapsedMs = currentChangeStartMs === void 0 ? void 0 : elapsed - currentChangeStartMs;
|
|
607
|
-
if (currentChangeElapsedMs !== void 0 && shouldResetSlowCurrentChange(currentChangeElapsedMs, totalHydrationTimeMs)) this.#throwSlowCurrentChangeReset(
|
|
608
|
-
const projectedTotalTimeMs = projectedAdvancementTimeMs(elapsed,
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
1297
|
+
if (currentChangeElapsedMs !== void 0 && shouldResetSlowCurrentChange(currentChangeElapsedMs, totalHydrationTimeMs)) this.#throwSlowCurrentChangeReset(completedChanges, numChanges, elapsed, currentChangeElapsedMs, totalHydrationTimeMs);
|
|
1298
|
+
const projectedTotalTimeMs = projectedAdvancementTimeMs(elapsed, completedChanges, numChanges);
|
|
1299
|
+
if (!shouldFinishLateAdvancement(completedChanges, numChanges)) {
|
|
1300
|
+
if (canProjectAdvancement(elapsed, projectedTotalTimeMs, completedChanges, numChanges)) {
|
|
1301
|
+
const projectedTotal = must(projectedTotalTimeMs);
|
|
1302
|
+
if (shouldResetProjectedAdvancement(elapsed, projectedTotal, totalHydrationTimeMs)) this.#throwProjectedAdvancementReset(completedChanges, numChanges, elapsed, projectedTotal, totalHydrationTimeMs);
|
|
1303
|
+
} else if (elapsed > MIN_ADVANCEMENT_TIME_LIMIT_MS && elapsed > totalHydrationTimeMs) {
|
|
1304
|
+
const breakdown = formatAdvancementBreakdown(must(this.#advanceContext), elapsed);
|
|
1305
|
+
this.#lc.warn?.(`Advancement exceeded timeout at ${completedChanges} of ${numChanges} changes after ${elapsed.toFixed(1)} ms (${breakdown}). Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`);
|
|
1306
|
+
throw new ResetPipelinesSignal(`Advancement exceeded timeout at ${completedChanges} of ${numChanges} changes after ${elapsed} ms. Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout", breakdown);
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
612
1309
|
return checkYield && advanceTimer.elapsedLap() > this.#yieldThresholdMs();
|
|
613
1310
|
}
|
|
1311
|
+
/**
|
|
1312
|
+
* The rows an advancement holds in memory are bounded by its reservation,
|
|
1313
|
+
* but their width is not known in advance. So the bytes they are estimated
|
|
1314
|
+
* to hold are added to those held by the other advancements on this worker.
|
|
1315
|
+
* Says whether that takes them past the budget, or if the rows are not
|
|
1316
|
+
* bounded by the reservation after all.
|
|
1317
|
+
*/
|
|
1318
|
+
#holdPendingRows(advanceContext) {
|
|
1319
|
+
const { reservedRows, heldBytes, pos, numChanges } = advanceContext;
|
|
1320
|
+
if (reservedRows === void 0) return "fits";
|
|
1321
|
+
const budget = must(this.#deferredWrites);
|
|
1322
|
+
const rows = this.pendingRows;
|
|
1323
|
+
const bytes = this.pendingBytes;
|
|
1324
|
+
advanceContext.heldBytes = bytes;
|
|
1325
|
+
const bytesFit = budget.holdBytes(bytes - heldBytes);
|
|
1326
|
+
if (rows > reservedRows) {
|
|
1327
|
+
budget.recordRowOverrun();
|
|
1328
|
+
this.#lc.error?.(`Advancement holds ${rows} rows at ${pos} of ${numChanges} changes, more than the ${reservedRows} it reserved. Writing through the rest.`);
|
|
1329
|
+
return "row-overrun";
|
|
1330
|
+
}
|
|
1331
|
+
return bytesFit ? "fits" : "bytes";
|
|
1332
|
+
}
|
|
614
1333
|
#throwSlowCurrentChangeReset(pos, numChanges, elapsed, currentChangeElapsedMs, totalHydrationTimeMs) {
|
|
615
|
-
|
|
1334
|
+
const breakdown = this.#advanceContext ? formatAdvancementBreakdown(this.#advanceContext, elapsed) : void 0;
|
|
1335
|
+
this.#lc.warn?.(`Advancement slow current change at ${pos} of ${numChanges} changes after ${currentChangeElapsedMs.toFixed(1)} ms (${elapsed.toFixed(1)} ms total)` + (breakdown ? ` (${breakdown})` : "") + `. Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`);
|
|
1336
|
+
throw new ResetPipelinesSignal(`Advancement exceeded timeout processing current change at ${pos} of ${numChanges} changes after ${currentChangeElapsedMs} ms (${elapsed} ms total). Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout", breakdown);
|
|
616
1337
|
}
|
|
617
1338
|
#throwProjectedAdvancementReset(pos, numChanges, elapsed, projectedTotalTimeMs, totalHydrationTimeMs) {
|
|
1339
|
+
const breakdown = this.#advanceContext ? formatAdvancementBreakdown(this.#advanceContext, elapsed) : void 0;
|
|
618
1340
|
const projection = projectedTotalTimeMs === void 0 ? "" : ` Projected total advancement time is ${projectedTotalTimeMs} ms.`;
|
|
619
|
-
|
|
1341
|
+
this.#lc.warn?.(`Advancement projected timeout at ${pos} of ${numChanges} changes after ${elapsed.toFixed(1)} ms` + projection + (breakdown ? ` (${breakdown})` : "") + `. Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`);
|
|
1342
|
+
throw new ResetPipelinesSignal(`Advancement projected to exceed hydration time at ${pos} of ${numChanges} changes after ${elapsed} ms.` + projection + ` Advancement time limited based on total hydration time of ${totalHydrationTimeMs} ms.`, "advancement-timeout", breakdown);
|
|
620
1343
|
}
|
|
621
1344
|
/** Implements `BuilderDelegate.createStorage()` */
|
|
622
1345
|
#createStorage() {
|
|
623
1346
|
return this.#storage.createStorage();
|
|
624
1347
|
}
|
|
625
1348
|
*#push(source, change) {
|
|
626
|
-
this.#
|
|
1349
|
+
assert(this.#pushedRowChanges === null, "push already in progress");
|
|
627
1350
|
try {
|
|
1351
|
+
this.#pushedRowChanges = [];
|
|
628
1352
|
for (const val of source.genPush(change)) {
|
|
629
1353
|
if (val === "yield") yield "yield";
|
|
630
|
-
|
|
631
|
-
this.#
|
|
1354
|
+
const rowChanges = this.#pushedRowChanges;
|
|
1355
|
+
this.#pushedRowChanges = [];
|
|
1356
|
+
yield* rowChanges;
|
|
632
1357
|
}
|
|
633
1358
|
} finally {
|
|
634
|
-
|
|
1359
|
+
this.#pushedRowChanges = null;
|
|
635
1360
|
}
|
|
636
1361
|
}
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
const
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
1362
|
+
/**
|
|
1363
|
+
* Converts a change pushed out of a query pipeline into row changes during
|
|
1364
|
+
* the push. The relationships of a pushed node are lazy, and operators such
|
|
1365
|
+
* as Join compute them from the state of the push in progress: while a child
|
|
1366
|
+
* change is pushed to each matching parent in turn, parents not yet pushed
|
|
1367
|
+
* must not see it. Read after the push has moved on to the next parent, or
|
|
1368
|
+
* after it has finished, a node's relationships show the later state, and
|
|
1369
|
+
* rows that are also pushed separately are counted twice.
|
|
1370
|
+
*/
|
|
1371
|
+
*#streamPushed(queryID, schema, change) {
|
|
1372
|
+
assert(this.#pushedRowChanges, "changes are only pushed by #push");
|
|
1373
|
+
for (const rowChange of must(this.#streamer).streamChange(queryID, schema, change)) {
|
|
1374
|
+
if (rowChange === "yield") {
|
|
1375
|
+
yield rowChange;
|
|
1376
|
+
continue;
|
|
1377
|
+
}
|
|
1378
|
+
must(this.#pushedRowChanges).push(rowChange);
|
|
1379
|
+
}
|
|
655
1380
|
}
|
|
656
1381
|
};
|
|
1382
|
+
/** Turns the output of query pipelines into the row changes sent to clients. */
|
|
657
1383
|
var Streamer = class {
|
|
658
1384
|
#primaryKeys;
|
|
659
1385
|
#tableSpecs;
|
|
660
|
-
|
|
661
|
-
constructor(primaryKeys, tableSpecs, logQueryFailure) {
|
|
1386
|
+
constructor(primaryKeys, tableSpecs) {
|
|
662
1387
|
this.#primaryKeys = primaryKeys;
|
|
663
1388
|
this.#tableSpecs = tableSpecs;
|
|
664
|
-
this.#logQueryFailure = logQueryFailure;
|
|
665
1389
|
}
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
this.#changes.push([
|
|
669
|
-
queryID,
|
|
670
|
-
schema,
|
|
671
|
-
changes
|
|
672
|
-
]);
|
|
673
|
-
return this;
|
|
674
|
-
}
|
|
675
|
-
*stream() {
|
|
676
|
-
for (const [queryID, schema, changes] of this.#changes) try {
|
|
677
|
-
yield* this.#streamChanges(queryID, schema, changes);
|
|
678
|
-
} catch (e) {
|
|
679
|
-
this.#logQueryFailure?.(queryID, e);
|
|
680
|
-
throw e;
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
*#streamChanges(queryID, schema, changes) {
|
|
1390
|
+
/** The row changes for a change pushed out of the pipeline of `queryID`. */
|
|
1391
|
+
*streamChange(queryID, schema, change) {
|
|
684
1392
|
if (schema.system === "permissions") return;
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
break;
|
|
696
|
-
case 3: {
|
|
697
|
-
const child = change[2];
|
|
698
|
-
const childSchema = must(schema.relationships[child.relationshipName]);
|
|
699
|
-
yield* this.#streamChanges(queryID, childSchema, [child.change]);
|
|
700
|
-
break;
|
|
701
|
-
}
|
|
702
|
-
case 2:
|
|
703
|
-
yield* this.#streamNodes(queryID, schema, type, () => [{
|
|
704
|
-
row: change[1].row,
|
|
705
|
-
relationships: {}
|
|
706
|
-
}]);
|
|
707
|
-
break;
|
|
708
|
-
default: unreachable(change[0]);
|
|
1393
|
+
const type = change[0];
|
|
1394
|
+
switch (type) {
|
|
1395
|
+
case 1:
|
|
1396
|
+
case 0:
|
|
1397
|
+
yield* this.streamNodes(queryID, schema, type, [change[1]]);
|
|
1398
|
+
break;
|
|
1399
|
+
case 3: {
|
|
1400
|
+
const child = change[2];
|
|
1401
|
+
yield* this.streamChange(queryID, must(schema.relationships[child.relationshipName]), child.change);
|
|
1402
|
+
break;
|
|
709
1403
|
}
|
|
1404
|
+
case 2:
|
|
1405
|
+
yield* this.streamNodes(queryID, schema, type, [{
|
|
1406
|
+
row: change[1].row,
|
|
1407
|
+
relationships: {}
|
|
1408
|
+
}]);
|
|
1409
|
+
break;
|
|
1410
|
+
default: unreachable(change[0]);
|
|
710
1411
|
}
|
|
711
1412
|
}
|
|
712
|
-
|
|
1413
|
+
/** A row change of type `op` for each of `nodes` and their descendants. */
|
|
1414
|
+
*streamNodes(queryID, schema, op, nodes) {
|
|
713
1415
|
const { tableName: table, system } = schema;
|
|
1416
|
+
if (system === "permissions") return;
|
|
714
1417
|
const primaryKey = must(this.#primaryKeys.get(table));
|
|
715
1418
|
const spec = must(this.#tableSpecs.get(table)).tableSpec;
|
|
716
|
-
|
|
717
|
-
for (const node of nodes()) {
|
|
1419
|
+
for (const node of nodes) {
|
|
718
1420
|
if (node === "yield") {
|
|
719
1421
|
yield node;
|
|
720
1422
|
continue;
|
|
@@ -736,9 +1438,9 @@ var Streamer = class {
|
|
|
736
1438
|
rowKey,
|
|
737
1439
|
row: op === 1 ? void 0 : row
|
|
738
1440
|
};
|
|
739
|
-
for (const
|
|
1441
|
+
for (const relationship of Object.keys(relationships)) {
|
|
740
1442
|
const childSchema = must(schema.relationships[relationship]);
|
|
741
|
-
yield* this
|
|
1443
|
+
if (childSchema.system !== "permissions") yield* this.streamNodes(queryID, childSchema, op, relationships[relationship]());
|
|
742
1444
|
}
|
|
743
1445
|
}
|
|
744
1446
|
}
|
|
@@ -782,6 +1484,18 @@ var QueryFailureLoggingOperator = class {
|
|
|
782
1484
|
throw e;
|
|
783
1485
|
}
|
|
784
1486
|
}
|
|
1487
|
+
*reconcile(_pusher) {
|
|
1488
|
+
if (this.#output.reconcile) try {
|
|
1489
|
+
yield* this.#output.reconcile(this);
|
|
1490
|
+
} catch (e) {
|
|
1491
|
+
logQueryFailure(this.#lc, {
|
|
1492
|
+
queryHash: this.#queryHash,
|
|
1493
|
+
transformationHash: this.#transformationHash,
|
|
1494
|
+
queryName: this.#queryName
|
|
1495
|
+
}, "query pipeline failed during reconcile", e);
|
|
1496
|
+
throw e;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
785
1499
|
};
|
|
786
1500
|
function logQueryFailure(lc, queryInfo, message, error) {
|
|
787
1501
|
if (error instanceof ResetPipelinesSignal) return;
|
|
@@ -792,43 +1506,73 @@ function logQueryFailure(lc, queryInfo, message, error) {
|
|
|
792
1506
|
}
|
|
793
1507
|
queryLC.error?.(message, error);
|
|
794
1508
|
}
|
|
795
|
-
function* toAdds(nodes) {
|
|
796
|
-
for (const node of nodes) {
|
|
797
|
-
if (node === "yield") {
|
|
798
|
-
yield node;
|
|
799
|
-
continue;
|
|
800
|
-
}
|
|
801
|
-
yield [
|
|
802
|
-
0,
|
|
803
|
-
node,
|
|
804
|
-
null
|
|
805
|
-
];
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
1509
|
function getRowKey(cols, row) {
|
|
809
|
-
|
|
1510
|
+
const rowKey = {};
|
|
1511
|
+
for (const col of cols) assignProperty(rowKey, col, must(row[col]));
|
|
1512
|
+
return rowKey;
|
|
1513
|
+
}
|
|
1514
|
+
/** Whether `rowKey` has exactly the columns of `primaryKey`. */
|
|
1515
|
+
function isKeyedBy(rowKey, primaryKey) {
|
|
1516
|
+
let cols = 0;
|
|
1517
|
+
for (const col in rowKey) {
|
|
1518
|
+
if (!primaryKey.includes(col)) return false;
|
|
1519
|
+
cols++;
|
|
1520
|
+
}
|
|
1521
|
+
return cols === primaryKey.length;
|
|
810
1522
|
}
|
|
811
1523
|
/**
|
|
812
1524
|
* Core hydration logic used by {@link PipelineDriver#addQuery}, extracted to a
|
|
813
1525
|
* function for reuse by the analyze-query RPC path so that analysis hydrates
|
|
814
|
-
* queries the same way the view-syncer does in production.
|
|
1526
|
+
* queries the same way the view-syncer does in production. As there, the rows
|
|
1527
|
+
* of a table outside `clientSchema` are keyed by its key in the replica.
|
|
1528
|
+
*/
|
|
1529
|
+
function hydrate(input, hash, clientSchema, tableSpecs) {
|
|
1530
|
+
return new Streamer(buildRowKeys(clientSchema, tableSpecs), tableSpecs).streamNodes(hash, input.getSchema(), 0, input.fetch({}));
|
|
1531
|
+
}
|
|
1532
|
+
/**
|
|
1533
|
+
* Returns the value of `childField` in the row of `input`, the pipeline of a
|
|
1534
|
+
* scalar subquery: `null` if the field is `NULL`, or `undefined` if there is
|
|
1535
|
+
* no row. Used by {@link PipelineDriver#addQuery} and the analyze-query RPC
|
|
1536
|
+
* path to resolve scalar subqueries the same way.
|
|
815
1537
|
*/
|
|
816
|
-
function
|
|
817
|
-
|
|
818
|
-
|
|
1538
|
+
function fetchScalarValue(input, childField) {
|
|
1539
|
+
let node;
|
|
1540
|
+
for (const n of skipYields(input.fetch({}))) node ??= n;
|
|
1541
|
+
if (!node) return;
|
|
1542
|
+
return node.row[childField] ?? null;
|
|
819
1543
|
}
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
1544
|
+
/**
|
|
1545
|
+
* The schema the rows of a companion pipeline are streamed with. A companion is
|
|
1546
|
+
* built from the bare subquery, so its schema says `'client'` even when its
|
|
1547
|
+
* gate came from a permission rule. Rows read for a rule are never synced, so
|
|
1548
|
+
* such a companion takes the gate's system and the Streamer skips it, the rows
|
|
1549
|
+
* behind any EXISTS nested in it included.
|
|
1550
|
+
*/
|
|
1551
|
+
function companionStreamSchema(input, { system }) {
|
|
1552
|
+
const schema = input.getSchema();
|
|
1553
|
+
return system === "permissions" ? {
|
|
1554
|
+
...schema,
|
|
1555
|
+
system
|
|
1556
|
+
} : schema;
|
|
823
1557
|
}
|
|
824
1558
|
function buildPrimaryKeys(clientSchema, primaryKeys = /* @__PURE__ */ new Map()) {
|
|
825
1559
|
for (const [tableName, { primaryKey }] of Object.entries(clientSchema.tables)) primaryKeys.set(tableName, primaryKey);
|
|
826
1560
|
return primaryKeys;
|
|
827
1561
|
}
|
|
1562
|
+
/**
|
|
1563
|
+
* Sets `primaryKeys` to the columns that key the synced rows of each table:
|
|
1564
|
+
* the table's primary key in `clientSchema`, or, for a table outside it, its
|
|
1565
|
+
* key in the replica.
|
|
1566
|
+
*/
|
|
1567
|
+
function buildRowKeys(clientSchema, tableSpecs, primaryKeys = /* @__PURE__ */ new Map()) {
|
|
1568
|
+
primaryKeys.clear();
|
|
1569
|
+
for (const [table, spec] of tableSpecs.entries()) primaryKeys.set(table, spec.tableSpec.primaryKey);
|
|
1570
|
+
return buildPrimaryKeys(clientSchema, primaryKeys);
|
|
1571
|
+
}
|
|
828
1572
|
function mustGetPrimaryKey(primaryKeys, table) {
|
|
829
1573
|
const pKeys = must(primaryKeys, "primaryKey map must be non-null");
|
|
830
1574
|
const rv = pKeys.get(table);
|
|
831
|
-
assert(rv, () => `table '${table}' is not one of: ${[...pKeys.keys()].sort()}. Check the spelling and ensure that the table has a primary key.`);
|
|
1575
|
+
assert(rv, () => `table '${table}' is not one of: ${JSON.stringify([...pKeys.keys()].sort())}. Check the spelling and ensure that the table has a primary key.`);
|
|
832
1576
|
return rv;
|
|
833
1577
|
}
|
|
834
1578
|
/**
|
|
@@ -841,6 +1585,6 @@ function scalarValuesEqual(a, b) {
|
|
|
841
1585
|
return a === b;
|
|
842
1586
|
}
|
|
843
1587
|
//#endregion
|
|
844
|
-
export { PipelineDriver, hydrate };
|
|
1588
|
+
export { PipelineDriver, fetchScalarValue, hydrate };
|
|
845
1589
|
|
|
846
1590
|
//# sourceMappingURL=pipeline-driver.js.map
|