@rocicorp/zero 1.12.0-canary.1 → 1.12.0-canary.11
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/_virtual/{_@oxc-project_runtime@0.130.0/helpers → _@oxc-project_runtime@0.154.0/helpers/esm}/usingCtx.js +2 -2
- package/out/analyze-query/src/analyze-cli.d.ts.map +1 -1
- package/out/analyze-query/src/analyze-cli.js +6 -4
- package/out/analyze-query/src/analyze-cli.js.map +1 -1
- package/out/analyze-query/src/bin-transform.js +4 -3
- package/out/analyze-query/src/bin-transform.js.map +1 -1
- package/out/analyze-query/src/zql-chain.d.ts +23 -0
- package/out/analyze-query/src/zql-chain.d.ts.map +1 -0
- package/out/analyze-query/src/zql-chain.js +170 -0
- package/out/analyze-query/src/zql-chain.js.map +1 -0
- package/out/ast-to-zql/src/ast-to-zql.d.ts.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.js +61 -20
- package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
- package/out/ast-to-zql/src/bin.js +4 -3
- package/out/ast-to-zql/src/bin.js.map +1 -1
- package/out/ast-to-zql/src/format.js.map +1 -1
- package/out/datadog/src/datadog-log-sink.js +5 -4
- package/out/datadog/src/datadog-log-sink.js.map +1 -1
- package/out/otel/src/log-options.js.map +1 -1
- package/out/replicache/src/btree/node.d.ts +0 -2
- package/out/replicache/src/btree/node.d.ts.map +1 -1
- package/out/replicache/src/btree/node.js +14 -12
- package/out/replicache/src/btree/node.js.map +1 -1
- package/out/replicache/src/btree/read.js +4 -2
- package/out/replicache/src/btree/read.js.map +1 -1
- package/out/replicache/src/btree/splice.js.map +1 -1
- package/out/replicache/src/btree/write.js +9 -5
- package/out/replicache/src/btree/write.js.map +1 -1
- package/out/replicache/src/config.js +1 -2
- package/out/replicache/src/connection-loop.d.ts.map +1 -1
- package/out/replicache/src/connection-loop.js +1 -1
- package/out/replicache/src/connection-loop.js.map +1 -1
- package/out/replicache/src/dag/chunk.js +1 -1
- package/out/replicache/src/dag/gc.js.map +1 -1
- package/out/replicache/src/dag/lazy-store.js +8 -7
- package/out/replicache/src/dag/lazy-store.js.map +1 -1
- package/out/replicache/src/dag/store-impl.js +1 -1
- package/out/replicache/src/dag/store-impl.js.map +1 -1
- package/out/replicache/src/dag/visitor.js.map +1 -1
- package/out/replicache/src/db/commit.d.ts +0 -1
- package/out/replicache/src/db/commit.d.ts.map +1 -1
- package/out/replicache/src/db/commit.js +5 -3
- package/out/replicache/src/db/commit.js.map +1 -1
- package/out/replicache/src/db/read.js +1 -1
- package/out/replicache/src/db/read.js.map +1 -1
- package/out/replicache/src/db/rebase.js.map +1 -1
- package/out/replicache/src/db/write.d.ts +0 -2
- package/out/replicache/src/db/write.d.ts.map +1 -1
- package/out/replicache/src/db/write.js +5 -2
- package/out/replicache/src/db/write.js.map +1 -1
- package/out/replicache/src/deleted-clients.d.ts +0 -2
- package/out/replicache/src/deleted-clients.d.ts.map +1 -1
- package/out/replicache/src/deleted-clients.js +5 -3
- package/out/replicache/src/deleted-clients.js.map +1 -1
- package/out/replicache/src/expo-sqlite.js +1 -2
- package/out/replicache/src/frozen-json.d.ts +0 -1
- package/out/replicache/src/frozen-json.d.ts.map +1 -1
- package/out/replicache/src/frozen-json.js +1 -1
- package/out/replicache/src/frozen-json.js.map +1 -1
- package/out/replicache/src/get-default-puller.js +1 -1
- package/out/replicache/src/hash.js +1 -1
- package/out/replicache/src/hash.js.map +1 -1
- package/out/replicache/src/impl.js +1 -2
- package/out/replicache/src/index-defs.d.ts +0 -2
- package/out/replicache/src/index-defs.d.ts.map +1 -1
- package/out/replicache/src/index-defs.js +5 -3
- package/out/replicache/src/index-defs.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts +0 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/idb-store.js +2 -2
- package/out/replicache/src/kv/idb-store.js.map +1 -1
- package/out/replicache/src/kv/mem-fallback-store.js +1 -1
- package/out/replicache/src/kv/mem-fallback-store.js.map +1 -1
- package/out/replicache/src/kv/mem-store.js.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/op-sqlite/types.js.map +1 -1
- package/out/replicache/src/kv/read-impl.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +8 -4
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/kv/throw-if-closed.d.ts +0 -3
- package/out/replicache/src/kv/throw-if-closed.d.ts.map +1 -1
- package/out/replicache/src/kv/throw-if-closed.js.map +1 -1
- package/out/replicache/src/kv/write-impl-base.js +4 -1
- package/out/replicache/src/kv/write-impl-base.js.map +1 -1
- package/out/replicache/src/kv/write-impl.js.map +1 -1
- package/out/replicache/src/log-options.js +2 -1
- package/out/replicache/src/log-options.js.map +1 -1
- package/out/replicache/src/make-idb-name.js +1 -1
- package/out/replicache/src/new-client-channel.js +9 -7
- package/out/replicache/src/new-client-channel.js.map +1 -1
- package/out/replicache/src/on-persist-channel.js +1 -1
- package/out/replicache/src/on-persist-channel.js.map +1 -1
- package/out/replicache/src/op-sqlite.js +1 -2
- package/out/replicache/src/pending-mutations.js +2 -1
- package/out/replicache/src/pending-mutations.js.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 +0 -7
- package/out/replicache/src/persist/client-group-gc.d.ts.map +1 -1
- package/out/replicache/src/persist/client-group-gc.js +1 -1
- package/out/replicache/src/persist/client-group-gc.js.map +1 -1
- package/out/replicache/src/persist/client-groups.js +1 -1
- package/out/replicache/src/persist/client-groups.js.map +1 -1
- package/out/replicache/src/persist/clients.js +1 -1
- package/out/replicache/src/persist/clients.js.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.js +5 -4
- package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
- package/out/replicache/src/persist/gather-mem-only-visitor.js.map +1 -1
- package/out/replicache/src/persist/gather-not-cached-visitor.js.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.js +1 -1
- package/out/replicache/src/persist/idb-databases-store.js.map +1 -1
- package/out/replicache/src/persist/make-client-id.js +1 -1
- package/out/replicache/src/persist/make-client-id.js.map +1 -1
- package/out/replicache/src/persist/persist.js +3 -2
- package/out/replicache/src/persist/persist.js.map +1 -1
- package/out/replicache/src/persist/refresh.js +8 -5
- package/out/replicache/src/persist/refresh.js.map +1 -1
- package/out/replicache/src/process-scheduler.js +1 -1
- package/out/replicache/src/process-scheduler.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +2 -7
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +21 -18
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/scan-iterator.js.map +1 -1
- package/out/replicache/src/scan-options.js +7 -6
- package/out/replicache/src/scan-options.js.map +1 -1
- package/out/replicache/src/sqlite.js +1 -2
- package/out/replicache/src/subscriptions.js +1 -1
- package/out/replicache/src/subscriptions.js.map +1 -1
- package/out/replicache/src/sync/diff.js +3 -1
- package/out/replicache/src/sync/diff.js.map +1 -1
- package/out/replicache/src/sync/ids.js.map +1 -1
- package/out/replicache/src/sync/patch.d.ts +0 -5
- package/out/replicache/src/sync/patch.d.ts.map +1 -1
- package/out/replicache/src/sync/patch.js +2 -4
- package/out/replicache/src/sync/patch.js.map +1 -1
- package/out/replicache/src/sync/pull.d.ts +0 -1
- package/out/replicache/src/sync/pull.d.ts.map +1 -1
- package/out/replicache/src/sync/pull.js +3 -1
- package/out/replicache/src/sync/pull.js.map +1 -1
- package/out/replicache/src/sync/push.d.ts +2 -1
- package/out/replicache/src/sync/push.d.ts.map +1 -1
- package/out/replicache/src/sync/push.js.map +1 -1
- package/out/replicache/src/sync/request-id.js +1 -1
- package/out/replicache/src/sync/request-id.js.map +1 -1
- package/out/replicache/src/transactions.js +1 -1
- package/out/replicache/src/transactions.js.map +1 -1
- package/out/replicache/src/types.d.ts +2 -1
- package/out/replicache/src/types.d.ts.map +1 -1
- package/out/shared/src/arrays.js +4 -1
- package/out/shared/src/arrays.js.map +1 -1
- package/out/shared/src/asserts.d.ts +0 -5
- package/out/shared/src/asserts.d.ts.map +1 -1
- package/out/shared/src/asserts.js.map +1 -1
- package/out/shared/src/bigint-json.d.ts +9 -0
- package/out/shared/src/bigint-json.d.ts.map +1 -1
- package/out/shared/src/bigint-json.js +27 -2
- package/out/shared/src/bigint-json.js.map +1 -1
- package/out/shared/src/broadcast-channel.js +1 -1
- package/out/shared/src/browser-env.d.ts +0 -17
- package/out/shared/src/browser-env.d.ts.map +1 -1
- package/out/shared/src/browser-env.js.map +1 -1
- package/out/shared/src/btree-set.js +11 -8
- package/out/shared/src/btree-set.js.map +1 -1
- package/out/shared/src/cache.js.map +1 -1
- package/out/shared/src/config.js +1 -1
- package/out/shared/src/custom-key-map.js.map +1 -1
- package/out/shared/src/custom-key-set.js.map +1 -1
- package/out/shared/src/deep-clone.d.ts +0 -1
- package/out/shared/src/deep-clone.d.ts.map +1 -1
- package/out/shared/src/deep-clone.js.map +1 -1
- package/out/shared/src/document-visible.js +1 -1
- package/out/shared/src/document-visible.js.map +1 -1
- package/out/shared/src/dotenv.js.map +1 -1
- package/out/shared/src/error.js +1 -1
- package/out/shared/src/error.js.map +1 -1
- package/out/shared/src/expand.d.ts +0 -3
- package/out/shared/src/expand.d.ts.map +1 -1
- package/out/shared/src/hash.js +2 -2
- package/out/shared/src/hash.js.map +1 -1
- package/out/shared/src/immutable.d.ts +1 -1
- package/out/shared/src/immutable.d.ts.map +1 -1
- package/out/shared/src/iterables.d.ts +0 -1
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/json-schema.js.map +1 -1
- package/out/shared/src/json.js.map +1 -1
- package/out/shared/src/logging-test-utils.js.map +1 -1
- package/out/shared/src/logging.js +1 -1
- package/out/shared/src/logging.js.map +1 -1
- package/out/shared/src/navigator.js +1 -1
- package/out/shared/src/options-types.d.ts +1 -1
- package/out/shared/src/options-types.d.ts.map +1 -1
- package/out/shared/src/options.d.ts +2 -3
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +8 -11
- package/out/shared/src/options.js.map +1 -1
- package/out/shared/src/promise-race.js +1 -1
- package/out/shared/src/promise-race.js.map +1 -1
- package/out/shared/src/queue.js +1 -1
- package/out/shared/src/queue.js.map +1 -1
- package/out/shared/src/record-proxy.js.map +1 -1
- package/out/shared/src/resolved-promises.d.ts +0 -4
- package/out/shared/src/resolved-promises.d.ts.map +1 -1
- package/out/shared/src/resolved-promises.js +0 -1
- package/out/shared/src/resolved-promises.js.map +1 -1
- package/out/shared/src/resolver.d.ts +9 -0
- package/out/shared/src/resolver.d.ts.map +1 -0
- package/out/shared/src/resolver.js +6 -0
- package/out/shared/src/resolver.js.map +1 -0
- package/out/shared/src/ring-buffer.js.map +1 -1
- package/out/shared/src/size-of-value.js +7 -10
- package/out/shared/src/size-of-value.js.map +1 -1
- package/out/shared/src/sleep.js +1 -1
- package/out/shared/src/sleep.js.map +1 -1
- package/out/shared/src/sorted-entries.js.map +1 -1
- package/out/shared/src/tdigest-schema.js.map +1 -1
- package/out/shared/src/tdigest.d.ts +0 -1
- package/out/shared/src/tdigest.d.ts.map +1 -1
- package/out/shared/src/tdigest.js.map +1 -1
- package/out/shared/src/valita.js +1 -1
- package/out/shared/src/valita.js.map +1 -1
- package/out/z2s/src/compiler.d.ts +1 -1
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +344 -9
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/z2s/src/sql.d.ts +9 -5
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +58 -11
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +210 -189
- package/out/zero/package.js.map +1 -1
- package/out/zero/src/adapters/drizzle.js +1 -2
- package/out/zero/src/adapters/kysely.js +1 -2
- package/out/zero/src/adapters/pg.js +1 -2
- package/out/zero/src/adapters/postgresjs.js +1 -2
- package/out/zero/src/adapters/prisma.js +1 -2
- package/out/zero/src/analyze.js +1 -2
- package/out/zero/src/bindings.js +4 -4
- package/out/zero/src/change-protocol/v0.js +1 -2
- package/out/zero/src/expo-sqlite.js +1 -2
- package/out/zero/src/op-sqlite.js +1 -2
- package/out/zero/src/react-native.js.map +1 -1
- package/out/zero/src/sqlite.js +1 -2
- package/out/zero/src/zero-cache-dev.js +11 -10
- package/out/zero/src/zero-cache-dev.js.map +1 -1
- package/out/zero/src/zero-out.js +2 -1
- package/out/zero/src/zero-out.js.map +1 -1
- package/out/zero-cache/src/auth/auth.js +1 -1
- package/out/zero-cache/src/auth/auth.js.map +1 -1
- package/out/zero-cache/src/auth/jwt.js +4 -1
- package/out/zero-cache/src/auth/jwt.js.map +1 -1
- package/out/zero-cache/src/auth/load-permissions.js +1 -1
- package/out/zero-cache/src/auth/load-permissions.js.map +1 -1
- package/out/zero-cache/src/auth/read-authorizer.js +3 -2
- package/out/zero-cache/src/auth/read-authorizer.js.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +16 -20
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/network.js +1 -1
- package/out/zero-cache/src/config/network.js.map +1 -1
- package/out/zero-cache/src/config/server-context.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +23 -11
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +51 -4
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.js +1 -1
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
- package/out/zero-cache/src/db/create.js +1 -1
- package/out/zero-cache/src/db/create.js.map +1 -1
- package/out/zero-cache/src/db/index-predicate.js.map +1 -1
- package/out/zero-cache/src/db/lite-tables.d.ts +2 -2
- package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/db/migration-lite.js +1 -1
- package/out/zero-cache/src/db/migration-lite.js.map +1 -1
- package/out/zero-cache/src/db/migration.js +5 -3
- package/out/zero-cache/src/db/migration.js.map +1 -1
- package/out/zero-cache/src/db/pg-copy-binary.js +4 -3
- package/out/zero-cache/src/db/pg-copy-binary.js.map +1 -1
- package/out/zero-cache/src/db/pg-copy.js +0 -1
- package/out/zero-cache/src/db/pg-copy.js.map +1 -1
- package/out/zero-cache/src/db/pg-to-lite.js +1 -1
- package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
- package/out/zero-cache/src/db/pg-type-parser.js.map +1 -1
- package/out/zero-cache/src/db/run-transaction.js.map +1 -1
- package/out/zero-cache/src/db/specs.d.ts +3 -4
- package/out/zero-cache/src/db/specs.d.ts.map +1 -1
- package/out/zero-cache/src/db/specs.js +1 -1
- package/out/zero-cache/src/db/specs.js.map +1 -1
- package/out/zero-cache/src/db/sqlite-corruption.js.map +1 -1
- package/out/zero-cache/src/db/statements.d.ts.map +1 -1
- package/out/zero-cache/src/db/statements.js +9 -2
- package/out/zero-cache/src/db/statements.js.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.js +6 -4
- package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
- package/out/zero-cache/src/db/warmup.js.map +1 -1
- package/out/zero-cache/src/observability/events.js +1 -1
- package/out/zero-cache/src/observability/events.js.map +1 -1
- package/out/zero-cache/src/observability/log-throttle.js.map +1 -1
- package/out/zero-cache/src/observability/metrics.js.map +1 -1
- package/out/zero-cache/src/scripts/deploy-permissions.js +5 -3
- package/out/zero-cache/src/scripts/deploy-permissions.js.map +1 -1
- package/out/zero-cache/src/scripts/permissions.js.map +1 -1
- package/out/zero-cache/src/server/anonymous-otel-start.js +2 -1
- package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +35 -11
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/logging.js +1 -1
- package/out/zero-cache/src/server/logging.js.map +1 -1
- package/out/zero-cache/src/server/main.js +2 -2
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
- package/out/zero-cache/src/server/otel-start.js.map +1 -1
- package/out/zero-cache/src/server/reaper.js +2 -2
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/replicator.js +1 -1
- 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 -8
- package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
- package/out/zero-cache/src/server/runner/runtime.js +2 -1
- package/out/zero-cache/src/server/runner/runtime.js.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts +9 -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 +29 -2
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/shadow-syncer.js +1 -1
- package/out/zero-cache/src/server/shadow-syncer.js.map +1 -1
- package/out/zero-cache/src/server/slot-keeper.js.map +1 -1
- package/out/zero-cache/src/server/syncer-assigner.js.map +1 -1
- package/out/zero-cache/src/server/syncer.js +10 -5
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/worker-urls.js.map +1 -1
- package/out/zero-cache/src/services/analyze.js +2 -2
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +3 -3
- 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.js +1 -1
- 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.js.map +1 -1
- 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.js +4 -4
- 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.js +3 -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-metadata.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +3 -3
- 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.js +52 -27
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +70 -15
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/decommission.js +2 -1
- package/out/zero-cache/src/services/change-source/pg/decommission.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/fork-request.js +54 -0
- package/out/zero-cache/src/services/change-source/pg/fork-request.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +9 -7
- 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/binary-reader.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +4 -3
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/lsn.d.ts +0 -2
- package/out/zero-cache/src/services/change-source/pg/lsn.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/lsn.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +2 -2
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-health.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +9 -3
- 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/ddl.d.ts +0 -12
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +5 -3
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts +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 +13 -12
- 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.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.js +2 -2
- package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +9 -6
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts +0 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/validation.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js +1 -1
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/control.js.map +1 -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 +1 -0
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts +3 -0
- package/out/zero-cache/src/services/change-source/protocol/current/status.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/status.js +2 -1
- package/out/zero-cache/src/services/change-source/protocol/current/status.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/upstream.d.ts +1 -0
- 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.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current.js +1 -1
- package/out/zero-cache/src/services/change-source/protocol/mod.js +1 -2
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backfill-state.js +1 -1
- package/out/zero-cache/src/services/change-streamer/backfill-state.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.js +6 -6
- 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.js +56 -21
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +2 -2
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js +2 -3
- 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.js +3 -3
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +4 -2
- 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.js +49 -30
- 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.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js +1 -1
- package/out/zero-cache/src/services/change-streamer/drain-tracker.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +11 -10
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js +81 -12
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js +4 -4
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/replica-poller.js +2 -2
- package/out/zero-cache/src/services/change-streamer/replica-poller.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/restore-admission.js +12 -1
- package/out/zero-cache/src/services/change-streamer/restore-admission.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/init.js +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/server-start-metrics.js +42 -0
- package/out/zero-cache/src/services/change-streamer/server-start-metrics.js.map +1 -0
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js +1 -2
- package/out/zero-cache/src/services/change-streamer/snapshot-message.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js +2 -2
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js +2 -2
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js +4 -6
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +3 -5
- 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.js +4 -4
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +8 -7
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js +0 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
- package/out/zero-cache/src/services/heapz.js +2 -1
- package/out/zero-cache/src/services/heapz.js.map +1 -1
- package/out/zero-cache/src/services/http-service.d.ts +8 -2
- package/out/zero-cache/src/services/http-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/http-service.js +19 -5
- package/out/zero-cache/src/services/http-service.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts +19 -0
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +55 -3
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/limiter/sliding-window-limiter.js +4 -2
- package/out/zero-cache/src/services/limiter/sliding-window-limiter.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +4 -4
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +2 -2
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.js.map +1 -1
- package/out/zero-cache/src/services/litestream/metrics.js.map +1 -1
- package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +3 -4
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +61 -17
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/plannerz.d.ts +4 -12
- package/out/zero-cache/src/services/plannerz.d.ts.map +1 -1
- package/out/zero-cache/src/services/plannerz.js +6 -7
- package/out/zero-cache/src/services/plannerz.js.map +1 -1
- package/out/zero-cache/src/services/profz.js +5 -3
- package/out/zero-cache/src/services/profz.js.map +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-db.js +4 -3
- package/out/zero-cache/src/services/replicator/change-log-db.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/drain-handler.js +1 -1
- package/out/zero-cache/src/services/replicator/drain-handler.js.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js +4 -4
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/notifier.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.js +4 -3
- package/out/zero-cache/src/services/replicator/replication-status.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replicator.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js +2 -2
- package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/report-schema.d.ts +2 -11
- package/out/zero-cache/src/services/replicator/reporter/report-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/report-schema.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/backfilling.js +2 -2
- package/out/zero-cache/src/services/replicator/schema/backfilling.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/change-log.d.ts +19 -17
- package/out/zero-cache/src/services/replicator/schema/change-log.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/change-log.js +31 -15
- package/out/zero-cache/src/services/replicator/schema/change-log.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts +0 -7
- package/out/zero-cache/src/services/replicator/schema/column-metadata.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/column-metadata.js +1 -1
- package/out/zero-cache/src/services/replicator/schema/column-metadata.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/replication-state.js +10 -7
- package/out/zero-cache/src/services/replicator/schema/replication-state.js.map +1 -1
- package/out/zero-cache/src/services/replicator/schema/table-metadata.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js +2 -2
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +3 -3
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +1 -1
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/runner.js.map +1 -1
- package/out/zero-cache/src/services/running-state.js +1 -1
- package/out/zero-cache/src/services/running-state.js.map +1 -1
- package/out/zero-cache/src/services/shadow-sync/shadow-sync-service.js.map +1 -1
- package/out/zero-cache/src/services/statz.js +4 -3
- package/out/zero-cache/src/services/statz.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +2 -2
- package/out/zero-cache/src/services/view-syncer/active-users-gauge.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/batch-pacer.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +71 -24
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-schema.js +46 -6
- package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-purger.js +2 -2
- package/out/zero-cache/src/services/view-syncer/cvr-purger.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +12 -7
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +12 -4
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js +1 -1
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +2 -2
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +2 -2
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +6 -4
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +112 -21
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/plan-warnings.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/push-cost.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/push-cutoff.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.js +2 -2
- package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-shape.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-stats.js +1 -1
- package/out/zero-cache/src/services/view-syncer/query-stats.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js +2 -2
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +2 -16
- 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.js +7 -1
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +13 -9
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/ttl-clock.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +52 -28
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/error-with-level.js.map +1 -1
- package/out/zero-cache/src/types/lexi-version.js.map +1 -1
- package/out/zero-cache/src/types/lite.d.ts +0 -1
- package/out/zero-cache/src/types/lite.d.ts.map +1 -1
- package/out/zero-cache/src/types/lite.js +1 -1
- package/out/zero-cache/src/types/lite.js.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.js +1 -1
- package/out/zero-cache/src/types/pg-data-type.js.map +1 -1
- package/out/zero-cache/src/types/pg-types.d.ts +0 -40
- package/out/zero-cache/src/types/pg-types.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg-types.js.map +1 -1
- package/out/zero-cache/src/types/pg.js +6 -4
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/poke-chunk.d.ts +0 -1
- package/out/zero-cache/src/types/poke-chunk.d.ts.map +1 -1
- package/out/zero-cache/src/types/poke-chunk.js +1 -1
- package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
- package/out/zero-cache/src/types/processes.js +5 -5
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/profiler.js +1 -1
- package/out/zero-cache/src/types/profiler.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts +0 -5
- package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
- package/out/zero-cache/src/types/row-key.js +8 -1
- package/out/zero-cache/src/types/row-key.js.map +1 -1
- package/out/zero-cache/src/types/sql.js.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +11 -10
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/strings.js.map +1 -1
- package/out/zero-cache/src/types/subscription.js +1 -1
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/types/timeout.js +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +4 -7
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +16 -2
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/types/ws.d.ts +2 -1
- package/out/zero-cache/src/types/ws.d.ts.map +1 -1
- package/out/zero-cache/src/types/ws.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +1 -2
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +10 -8
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/mutator.js +1 -1
- package/out/zero-cache/src/workers/mutator.js.map +1 -1
- package/out/zero-cache/src/workers/rehome.d.ts +15 -0
- package/out/zero-cache/src/workers/rehome.d.ts.map +1 -0
- package/out/zero-cache/src/workers/rehome.js +36 -0
- package/out/zero-cache/src/workers/rehome.js.map +1 -0
- package/out/zero-cache/src/workers/replicator.js +5 -4
- package/out/zero-cache/src/workers/replicator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +9 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +32 -7
- 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 +2 -2
- package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
- package/out/zero-client/src/client/bindings.d.ts +1 -1
- package/out/zero-client/src/client/bindings.d.ts.map +1 -1
- package/out/zero-client/src/client/bindings.js +11 -11
- package/out/zero-client/src/client/connection-manager.js +1 -1
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection.js +1 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +7 -1
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +7 -0
- 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 +172 -3
- package/out/zero-client/src/client/crud-impl.js.map +1 -1
- package/out/zero-client/src/client/crud.d.ts +2 -8
- package/out/zero-client/src/client/crud.d.ts.map +1 -1
- package/out/zero-client/src/client/crud.js.map +1 -1
- package/out/zero-client/src/client/custom.d.ts +0 -2
- package/out/zero-client/src/client/custom.d.ts.map +1 -1
- package/out/zero-client/src/client/custom.js +42 -3
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/delete-clients-manager.js.map +1 -1
- package/out/zero-client/src/client/enable-analytics.d.ts +0 -1
- package/out/zero-client/src/client/enable-analytics.d.ts.map +1 -1
- package/out/zero-client/src/client/enable-analytics.js +1 -0
- package/out/zero-client/src/client/enable-analytics.js.map +1 -1
- package/out/zero-client/src/client/error.d.ts +4 -5
- package/out/zero-client/src/client/error.d.ts.map +1 -1
- package/out/zero-client/src/client/error.js.map +1 -1
- package/out/zero-client/src/client/inspector/client-group.js.map +1 -1
- package/out/zero-client/src/client/inspector/client.js.map +1 -1
- package/out/zero-client/src/client/inspector/html-dialog-prompt.js +1 -1
- package/out/zero-client/src/client/inspector/html-dialog-prompt.js.map +1 -1
- package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
- package/out/zero-client/src/client/inspector/query.js.map +1 -1
- package/out/zero-client/src/client/ivm-branch.d.ts +62 -2
- package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
- package/out/zero-client/src/client/ivm-branch.js +153 -34
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/keys.d.ts +33 -1
- package/out/zero-client/src/client/keys.d.ts.map +1 -1
- package/out/zero-client/src/client/keys.js +49 -7
- package/out/zero-client/src/client/keys.js.map +1 -1
- package/out/zero-client/src/client/log-options.js.map +1 -1
- package/out/zero-client/src/client/make-replicache-mutators.js +5 -3
- package/out/zero-client/src/client/make-replicache-mutators.js.map +1 -1
- package/out/zero-client/src/client/metrics.js +3 -5
- package/out/zero-client/src/client/metrics.js.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.js +1 -1
- package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +0 -4
- 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.js +2 -2
- package/out/zero-client/src/client/query-manager.js.map +1 -1
- package/out/zero-client/src/client/reload-error-handler.js +4 -3
- package/out/zero-client/src/client/reload-error-handler.js.map +1 -1
- package/out/zero-client/src/client/replicache-types.d.ts +3 -2
- package/out/zero-client/src/client/replicache-types.d.ts.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-poke-handler.d.ts +1 -2
- package/out/zero-client/src/client/zero-poke-handler.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-poke-handler.js +30 -2
- package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +2 -15
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +1 -5
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +21 -13
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.d.ts +3 -3
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-client/src/mod.js +23 -23
- package/out/zero-client/src/types/client-state.d.ts +0 -6
- package/out/zero-client/src/types/client-state.d.ts.map +1 -1
- package/out/zero-client/src/util/nanoid.js.map +1 -1
- package/out/zero-permissions/src/permissions.d.ts +1 -12
- package/out/zero-permissions/src/permissions.d.ts.map +1 -1
- package/out/zero-permissions/src/permissions.js +3 -3
- package/out/zero-permissions/src/permissions.js.map +1 -1
- package/out/zero-pg/src/mod.js +9 -9
- package/out/zero-protocol/src/aggregate-table.d.ts +15 -0
- package/out/zero-protocol/src/aggregate-table.d.ts.map +1 -0
- package/out/zero-protocol/src/aggregate-table.js +5 -0
- package/out/zero-protocol/src/aggregate-table.js.map +1 -0
- package/out/zero-protocol/src/analyze-query-result.js +1 -1
- package/out/zero-protocol/src/analyze-query-result.js.map +1 -1
- package/out/zero-protocol/src/application-error.js.map +1 -1
- package/out/zero-protocol/src/ast.d.ts +140 -8
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +264 -28
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/change-desired-queries.d.ts +0 -20
- package/out/zero-protocol/src/change-desired-queries.d.ts.map +1 -1
- package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
- package/out/zero-protocol/src/client-schema.d.ts +2 -5
- package/out/zero-protocol/src/client-schema.d.ts.map +1 -1
- package/out/zero-protocol/src/client-schema.js.map +1 -1
- package/out/zero-protocol/src/close-connection.d.ts +0 -8
- package/out/zero-protocol/src/close-connection.d.ts.map +1 -1
- package/out/zero-protocol/src/close-connection.js.map +1 -1
- package/out/zero-protocol/src/connect.d.ts +0 -12
- package/out/zero-protocol/src/connect.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.js.map +1 -1
- package/out/zero-protocol/src/custom-queries.d.ts +3 -17
- package/out/zero-protocol/src/custom-queries.d.ts.map +1 -1
- package/out/zero-protocol/src/custom-queries.js.map +1 -1
- package/out/zero-protocol/src/data.d.ts +0 -1
- package/out/zero-protocol/src/data.d.ts.map +1 -1
- package/out/zero-protocol/src/data.js +3 -1
- package/out/zero-protocol/src/data.js.map +1 -1
- package/out/zero-protocol/src/delete-clients.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +27 -27
- package/out/zero-protocol/src/down.js.map +1 -1
- package/out/zero-protocol/src/error.js.map +1 -1
- package/out/zero-protocol/src/inspect-down.d.ts +1 -3
- package/out/zero-protocol/src/inspect-down.d.ts.map +1 -1
- package/out/zero-protocol/src/inspect-down.js.map +1 -1
- package/out/zero-protocol/src/inspect-up.d.ts +0 -28
- package/out/zero-protocol/src/inspect-up.d.ts.map +1 -1
- package/out/zero-protocol/src/inspect-up.js.map +1 -1
- package/out/zero-protocol/src/mutate-server.d.ts +0 -21
- package/out/zero-protocol/src/mutate-server.d.ts.map +1 -1
- package/out/zero-protocol/src/mutate-server.js.map +1 -1
- package/out/zero-protocol/src/mutation-id.js.map +1 -1
- package/out/zero-protocol/src/mutation-type-enum.d.ts +0 -1
- package/out/zero-protocol/src/mutation-type-enum.d.ts.map +1 -1
- package/out/zero-protocol/src/mutation-type-enum.js.map +1 -1
- package/out/zero-protocol/src/mutation.d.ts +2 -4
- package/out/zero-protocol/src/mutation.d.ts.map +1 -1
- package/out/zero-protocol/src/mutation.js.map +1 -1
- package/out/zero-protocol/src/mutations-patch.d.ts +0 -33
- package/out/zero-protocol/src/mutations-patch.d.ts.map +1 -1
- package/out/zero-protocol/src/mutations-patch.js.map +1 -1
- package/out/zero-protocol/src/ping.d.ts +0 -2
- package/out/zero-protocol/src/ping.d.ts.map +1 -1
- package/out/zero-protocol/src/ping.js.map +1 -1
- package/out/zero-protocol/src/poke.d.ts +3 -2
- package/out/zero-protocol/src/poke.d.ts.map +1 -1
- package/out/zero-protocol/src/poke.js +1 -1
- package/out/zero-protocol/src/poke.js.map +1 -1
- package/out/zero-protocol/src/pong.d.ts +0 -2
- package/out/zero-protocol/src/pong.d.ts.map +1 -1
- package/out/zero-protocol/src/pong.js.map +1 -1
- package/out/zero-protocol/src/primary-key.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js +1 -0
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/pull.d.ts +2 -7
- package/out/zero-protocol/src/pull.d.ts.map +1 -1
- package/out/zero-protocol/src/pull.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +1 -3
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero-protocol/src/queries-patch.d.ts +0 -16
- package/out/zero-protocol/src/queries-patch.d.ts.map +1 -1
- package/out/zero-protocol/src/queries-patch.js +1 -1
- package/out/zero-protocol/src/queries-patch.js.map +1 -1
- package/out/zero-protocol/src/query-hash-visitor.d.ts.map +1 -1
- package/out/zero-protocol/src/query-hash-visitor.js +38 -0
- package/out/zero-protocol/src/query-hash-visitor.js.map +1 -1
- package/out/zero-protocol/src/query-hash.js +2 -2
- package/out/zero-protocol/src/query-server.d.ts +2 -41
- package/out/zero-protocol/src/query-server.d.ts.map +1 -1
- package/out/zero-protocol/src/query-server.js.map +1 -1
- package/out/zero-protocol/src/row-patch.js.map +1 -1
- package/out/zero-protocol/src/up.d.ts +60 -60
- package/out/zero-protocol/src/up.js +1 -1
- package/out/zero-protocol/src/up.js.map +1 -1
- package/out/zero-protocol/src/update-auth.js.map +1 -1
- package/out/zero-protocol/src/version.d.ts +0 -1
- package/out/zero-protocol/src/version.d.ts.map +1 -1
- package/out/zero-protocol/src/version.js.map +1 -1
- package/out/zero-react/src/bindings.js +11 -11
- package/out/zero-react/src/mod.js +5 -5
- package/out/zero-react/src/use-query.d.ts +3 -1
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +6 -4
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-react/src/zero-provider.d.ts +1 -1
- package/out/zero-react/src/zero-provider.d.ts.map +1 -1
- package/out/zero-react/src/zero-provider.js +2 -1
- package/out/zero-react/src/zero-provider.js.map +1 -1
- package/out/zero-react/src/zero.js +23 -23
- package/out/zero-schema/src/builder/relationship-builder.d.ts +0 -2
- package/out/zero-schema/src/builder/relationship-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/relationship-builder.js.map +1 -1
- package/out/zero-schema/src/builder/schema-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/schema-builder.js +5 -2
- package/out/zero-schema/src/builder/schema-builder.js.map +1 -1
- package/out/zero-schema/src/builder/table-builder.d.ts +1 -1
- package/out/zero-schema/src/builder/table-builder.d.ts.map +1 -1
- package/out/zero-schema/src/builder/table-builder.js +1 -1
- package/out/zero-schema/src/builder/table-builder.js.map +1 -1
- package/out/zero-schema/src/compiled-permissions.js.map +1 -1
- package/out/zero-schema/src/name-mapper.d.ts.map +1 -1
- package/out/zero-schema/src/name-mapper.js +14 -9
- package/out/zero-schema/src/name-mapper.js.map +1 -1
- package/out/zero-schema/src/schema-config.d.ts +0 -1
- package/out/zero-schema/src/schema-config.d.ts.map +1 -1
- package/out/zero-schema/src/schema-config.js +1 -1
- package/out/zero-schema/src/schema-config.js.map +1 -1
- package/out/zero-schema/src/table-schema.d.ts +3 -11
- package/out/zero-schema/src/table-schema.d.ts.map +1 -1
- package/out/zero-server/src/adapters/drizzle.js.map +1 -1
- package/out/zero-server/src/adapters/kysely.js.map +1 -1
- package/out/zero-server/src/adapters/pg.js.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
- package/out/zero-server/src/adapters/prisma.js.map +1 -1
- package/out/zero-server/src/closable-db-transaction.js.map +1 -1
- package/out/zero-server/src/custom.js +2 -2
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/mod.js +8 -8
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/push-processor.js.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts +2 -4
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +2 -1
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +20 -9
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/bindings.js +11 -11
- package/out/zero-solid/src/mod.js +5 -5
- package/out/zero-solid/src/solid-view.d.ts +0 -2
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +4 -4
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-connection-state.js +2 -1
- package/out/zero-solid/src/use-connection-state.js.map +1 -1
- package/out/zero-solid/src/use-query.js.map +1 -1
- package/out/zero-solid/src/use-zero-online.js +2 -1
- package/out/zero-solid/src/use-zero-online.js.map +1 -1
- package/out/zero-solid/src/use-zero.js +3 -2
- package/out/zero-solid/src/use-zero.js.map +1 -1
- package/out/zero-solid/src/zero.js +23 -23
- package/out/zero-types/src/format.d.ts +13 -0
- package/out/zero-types/src/format.d.ts.map +1 -1
- package/out/zero-types/src/format.js.map +1 -1
- package/out/zero-types/src/name-mapper.d.ts +16 -1
- package/out/zero-types/src/name-mapper.d.ts.map +1 -1
- package/out/zero-types/src/name-mapper.js +12 -0
- package/out/zero-types/src/name-mapper.js.map +1 -1
- package/out/zero-types/src/schema-value.d.ts +5 -2
- package/out/zero-types/src/schema-value.d.ts.map +1 -1
- package/out/zero-types/src/schema-value.js +15 -0
- package/out/zero-types/src/schema-value.js.map +1 -0
- package/out/zero-types/src/schema.d.ts +1 -1
- package/out/zero-types/src/schema.d.ts.map +1 -1
- package/out/zero-types/src/server-schema.d.ts +18 -0
- package/out/zero-types/src/server-schema.d.ts.map +1 -1
- package/out/zql/src/builder/builder.d.ts +124 -9
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +295 -23
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -1
- package/out/zql/src/builder/debug-delegate.js.map +1 -1
- package/out/zql/src/builder/filter.d.ts +1 -2
- package/out/zql/src/builder/filter.d.ts.map +1 -1
- package/out/zql/src/builder/filter.js +41 -3
- package/out/zql/src/builder/filter.js.map +1 -1
- package/out/zql/src/builder/like.js +0 -1
- package/out/zql/src/builder/like.js.map +1 -1
- package/out/zql/src/error.d.ts +0 -5
- package/out/zql/src/error.d.ts.map +1 -1
- package/out/zql/src/error.js.map +1 -1
- package/out/zql/src/ivm/aggregate.d.ts +188 -0
- package/out/zql/src/ivm/aggregate.d.ts.map +1 -0
- package/out/zql/src/ivm/aggregate.js +470 -0
- package/out/zql/src/ivm/aggregate.js.map +1 -0
- package/out/zql/src/ivm/array-view.d.ts +1 -1
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +3 -3
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/cap.d.ts +1 -1
- package/out/zql/src/ivm/cap.d.ts.map +1 -1
- package/out/zql/src/ivm/cap.js +14 -6
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/constraint.d.ts +0 -7
- package/out/zql/src/ivm/constraint.d.ts.map +1 -1
- package/out/zql/src/ivm/constraint.js +3 -2
- package/out/zql/src/ivm/constraint.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts +15 -2
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +15 -1
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.js +1 -1
- package/out/zql/src/ivm/deferred-input.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +32 -22
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.js +1 -1
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +5 -0
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +1 -1
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter-push.js.map +1 -1
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +4 -5
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/group-by.d.ts +98 -0
- package/out/zql/src/ivm/group-by.d.ts.map +1 -0
- package/out/zql/src/ivm/group-by.js +384 -0
- package/out/zql/src/ivm/group-by.js.map +1 -0
- package/out/zql/src/ivm/join-index-tap.js.map +1 -1
- package/out/zql/src/ivm/join-index.d.ts.map +1 -1
- package/out/zql/src/ivm/join-index.js +2 -1
- package/out/zql/src/ivm/join-index.js.map +1 -1
- package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
- package/out/zql/src/ivm/join-utils.js +13 -14
- package/out/zql/src/ivm/join-utils.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +7 -4
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/lift-field.d.ts +54 -0
- package/out/zql/src/ivm/lift-field.d.ts.map +1 -0
- package/out/zql/src/ivm/lift-field.js +168 -0
- package/out/zql/src/ivm/lift-field.js.map +1 -0
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +3 -2
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +36 -27
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/memory-storage.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +6 -0
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js +2 -2
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/push-accumulated.js +1 -2
- package/out/zql/src/ivm/push-accumulated.js.map +1 -1
- package/out/zql/src/ivm/schema.d.ts +1 -0
- package/out/zql/src/ivm/schema.d.ts.map +1 -1
- package/out/zql/src/ivm/skip-yields.js.map +1 -1
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/source.d.ts +21 -0
- package/out/zql/src/ivm/source.d.ts.map +1 -1
- package/out/zql/src/ivm/source.js.map +1 -1
- package/out/zql/src/ivm/stream.d.ts +0 -1
- package/out/zql/src/ivm/stream.d.ts.map +1 -1
- package/out/zql/src/ivm/stream.js.map +1 -1
- package/out/zql/src/ivm/take-gate.js.map +1 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +8 -9
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +0 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +1 -1
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts +8 -33
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +23 -3
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/mutate/crud.d.ts +1 -3
- package/out/zql/src/mutate/crud.d.ts.map +1 -1
- package/out/zql/src/mutate/crud.js +2 -1
- package/out/zql/src/mutate/crud.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/mutate/mutator.d.ts +1 -1
- 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.js +1 -1
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-connection.js.map +1 -1
- package/out/zql/src/planner/planner-debug.d.ts +11 -10
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js +4 -0
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-fan-in.js.map +1 -1
- package/out/zql/src/planner/planner-fan-out.js.map +1 -1
- package/out/zql/src/planner/planner-filter.js.map +1 -1
- package/out/zql/src/planner/planner-graph.js +1 -5
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zql/src/planner/planner-join.js +1 -1
- package/out/zql/src/planner/planner-join.js.map +1 -1
- package/out/zql/src/planner/planner-node.d.ts +0 -1
- package/out/zql/src/planner/planner-node.d.ts.map +1 -1
- package/out/zql/src/planner/planner-node.js.map +1 -1
- package/out/zql/src/planner/planner-source.js.map +1 -1
- package/out/zql/src/planner/planner-terminus.js.map +1 -1
- package/out/zql/src/planner/planner-warnings.d.ts +3 -3
- package/out/zql/src/planner/planner-warnings.d.ts.map +1 -1
- package/out/zql/src/planner/planner-warnings.js.map +1 -1
- package/out/zql/src/query/create-builder.js +2 -1
- package/out/zql/src/query/create-builder.js.map +1 -1
- package/out/zql/src/query/expression.d.ts +49 -24
- package/out/zql/src/query/expression.d.ts.map +1 -1
- package/out/zql/src/query/expression.js +62 -6
- package/out/zql/src/query/expression.js.map +1 -1
- package/out/zql/src/query/measure-push-operator.js +1 -1
- package/out/zql/src/query/measure-push-operator.js.map +1 -1
- package/out/zql/src/query/named.js +2 -1
- package/out/zql/src/query/named.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +8 -7
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +14 -6
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +1 -4
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +17 -3
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +242 -9
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-internals.d.ts +0 -3
- package/out/zql/src/query/query-internals.d.ts.map +1 -1
- package/out/zql/src/query/query-internals.js.map +1 -1
- package/out/zql/src/query/query-registry.d.ts +5 -5
- package/out/zql/src/query/query-registry.d.ts.map +1 -1
- package/out/zql/src/query/query-registry.js +1 -1
- package/out/zql/src/query/query-registry.js.map +1 -1
- package/out/zql/src/query/query-transitions.js +1 -1
- package/out/zql/src/query/query-transitions.js.map +1 -1
- package/out/zql/src/query/query.d.ts +321 -20
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +1 -19
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js +2 -1
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/static-query.js.map +1 -1
- package/out/zql/src/query/ttl.d.ts +2 -3
- package/out/zql/src/query/ttl.d.ts.map +1 -1
- package/out/zql/src/query/ttl.js +8 -8
- package/out/zql/src/query/ttl.js.map +1 -1
- package/out/zql/src/query/validate-input.js.map +1 -1
- package/out/zqlite/src/database-storage.js +195 -26
- package/out/zqlite/src/database-storage.js.map +1 -1
- package/out/zqlite/src/db.d.ts +47 -1
- package/out/zqlite/src/db.d.ts.map +1 -1
- package/out/zqlite/src/db.js +121 -21
- package/out/zqlite/src/db.js.map +1 -1
- package/out/zqlite/src/explain-queries.js.map +1 -1
- package/out/zqlite/src/fetch-sql.d.ts +27 -0
- package/out/zqlite/src/fetch-sql.d.ts.map +1 -0
- package/out/zqlite/src/fetch-sql.js +112 -0
- package/out/zqlite/src/fetch-sql.js.map +1 -0
- package/out/zqlite/src/index-usage.js.map +1 -1
- package/out/zqlite/src/internal/sql-inline.js.map +1 -1
- package/out/zqlite/src/internal/sql.js.map +1 -1
- package/out/zqlite/src/internal/statement-cache.d.ts +7 -0
- package/out/zqlite/src/internal/statement-cache.d.ts.map +1 -1
- package/out/zqlite/src/internal/statement-cache.js +11 -4
- package/out/zqlite/src/internal/statement-cache.js.map +1 -1
- package/out/zqlite/src/mod.js +5 -5
- package/out/zqlite/src/pending-delta.d.ts.map +1 -1
- package/out/zqlite/src/pending-delta.js +4 -3
- package/out/zqlite/src/pending-delta.js.map +1 -1
- package/out/zqlite/src/query-builder.d.ts +23 -4
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +135 -19
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/query-delegate.js.map +1 -1
- package/out/zqlite/src/resolve-scalar-subqueries.js +2 -5
- package/out/zqlite/src/resolve-scalar-subqueries.js.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +3 -2
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +20 -3
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +110 -42
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +39 -39
- package/out/analyze-query/src/bin-analyze.d.ts +0 -2
- package/out/analyze-query/src/bin-analyze.d.ts.map +0 -1
- package/out/analyze-query/src/bin-analyze.js +0 -283
- package/out/analyze-query/src/bin-analyze.js.map +0 -1
- package/out/otel/src/maybe-time.d.ts +0 -3
- package/out/otel/src/maybe-time.d.ts.map +0 -1
- package/out/otel/src/maybe-time.js +0 -15
- package/out/otel/src/maybe-time.js.map +0 -1
- package/out/shared/src/cache.d.ts +0 -22
- package/out/shared/src/cache.d.ts.map +0 -1
- package/out/shared/src/custom-key-map.d.ts +0 -26
- package/out/shared/src/custom-key-map.d.ts.map +0 -1
- package/out/shared/src/custom-key-set.d.ts +0 -25
- package/out/shared/src/custom-key-set.d.ts.map +0 -1
- package/out/shared/src/logging-test-utils.d.ts +0 -12
- package/out/shared/src/logging-test-utils.d.ts.map +0 -1
- package/out/shared/src/sorted-entries.d.ts +0 -2
- package/out/shared/src/sorted-entries.d.ts.map +0 -1
- package/out/zero/src/analyze-query.d.ts +0 -3
- package/out/zero/src/analyze-query.d.ts.map +0 -1
- package/out/zero/src/analyze-query.js +0 -3
- package/out/zero/src/server/change-streamer.d.ts +0 -2
- package/out/zero/src/server/change-streamer.d.ts.map +0 -1
- package/out/zero/src/server/main.d.ts +0 -2
- package/out/zero/src/server/main.d.ts.map +0 -1
- package/out/zero/src/server/reaper.d.ts +0 -2
- package/out/zero/src/server/reaper.d.ts.map +0 -1
- package/out/zero/src/server/replicator.d.ts +0 -2
- package/out/zero/src/server/replicator.d.ts.map +0 -1
- package/out/zero/src/server/syncer.d.ts +0 -2
- package/out/zero/src/server/syncer.d.ts.map +0 -1
- package/out/zero-cache/src/auth/jwt.d.ts +0 -12
- package/out/zero-cache/src/auth/jwt.d.ts.map +0 -1
- package/out/zero-cache/src/auth/load-permissions.d.ts +0 -17
- package/out/zero-cache/src/auth/load-permissions.d.ts.map +0 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts +0 -28
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +0 -1
- package/out/zero-cache/src/config/server-context.d.ts +0 -16
- package/out/zero-cache/src/config/server-context.d.ts.map +0 -1
- package/out/zero-cache/src/custom/fetch.d.ts +0 -38
- package/out/zero-cache/src/custom/fetch.d.ts.map +0 -1
- package/out/zero-cache/src/custom/metrics.d.ts +0 -31
- package/out/zero-cache/src/custom/metrics.d.ts.map +0 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts +0 -68
- package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +0 -1
- package/out/zero-cache/src/db/create.d.ts +0 -12
- package/out/zero-cache/src/db/create.d.ts.map +0 -1
- package/out/zero-cache/src/db/delete-lite-db.d.ts +0 -2
- package/out/zero-cache/src/db/delete-lite-db.d.ts.map +0 -1
- package/out/zero-cache/src/db/index-predicate.d.ts +0 -4
- package/out/zero-cache/src/db/index-predicate.d.ts.map +0 -1
- package/out/zero-cache/src/db/migration-lite.d.ts +0 -78
- package/out/zero-cache/src/db/migration-lite.d.ts.map +0 -1
- package/out/zero-cache/src/db/migration.d.ts +0 -80
- package/out/zero-cache/src/db/migration.d.ts.map +0 -1
- package/out/zero-cache/src/db/pg-copy-binary.d.ts +0 -101
- package/out/zero-cache/src/db/pg-copy-binary.d.ts.map +0 -1
- package/out/zero-cache/src/db/pg-copy.d.ts +0 -30
- package/out/zero-cache/src/db/pg-copy.d.ts.map +0 -1
- package/out/zero-cache/src/db/pg-type-parser.d.ts +0 -15
- package/out/zero-cache/src/db/pg-type-parser.d.ts.map +0 -1
- package/out/zero-cache/src/db/transaction-pool.d.ts +0 -205
- package/out/zero-cache/src/db/transaction-pool.d.ts.map +0 -1
- package/out/zero-cache/src/db/warmup.d.ts +0 -4
- package/out/zero-cache/src/db/warmup.d.ts.map +0 -1
- package/out/zero-cache/src/observability/events.d.ts +0 -15
- package/out/zero-cache/src/observability/events.d.ts.map +0 -1
- package/out/zero-cache/src/observability/log-throttle.d.ts +0 -44
- package/out/zero-cache/src/observability/log-throttle.d.ts.map +0 -1
- package/out/zero-cache/src/server/anonymous-otel-start.d.ts +0 -21
- package/out/zero-cache/src/server/anonymous-otel-start.d.ts.map +0 -1
- package/out/zero-cache/src/server/change-streamer.d.ts +0 -3
- package/out/zero-cache/src/server/change-streamer.d.ts.map +0 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +0 -71
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +0 -1
- package/out/zero-cache/src/server/main.d.ts +0 -3
- package/out/zero-cache/src/server/main.d.ts.map +0 -1
- package/out/zero-cache/src/server/otel-diag-logger.d.ts +0 -16
- package/out/zero-cache/src/server/otel-diag-logger.d.ts.map +0 -1
- package/out/zero-cache/src/server/otel-start.d.ts +0 -3
- package/out/zero-cache/src/server/otel-start.d.ts.map +0 -1
- package/out/zero-cache/src/server/priority-op.d.ts +0 -8
- package/out/zero-cache/src/server/priority-op.d.ts.map +0 -1
- package/out/zero-cache/src/server/reaper.d.ts +0 -3
- package/out/zero-cache/src/server/reaper.d.ts.map +0 -1
- package/out/zero-cache/src/server/replicator.d.ts +0 -10
- package/out/zero-cache/src/server/replicator.d.ts.map +0 -1
- package/out/zero-cache/src/server/slot-keeper.d.ts +0 -26
- package/out/zero-cache/src/server/slot-keeper.d.ts.map +0 -1
- package/out/zero-cache/src/server/syncer.d.ts +0 -3
- package/out/zero-cache/src/server/syncer.d.ts.map +0 -1
- package/out/zero-cache/src/services/analyze.d.ts +0 -9
- package/out/zero-cache/src/services/analyze.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/change-source.d.ts +0 -32
- package/out/zero-cache/src/services/change-source/change-source.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts +0 -57
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts +0 -55
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts +0 -24
- package/out/zero-cache/src/services/change-source/common/init-cleanup.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts +0 -115
- package/out/zero-cache/src/services/change-source/common/replica-restore.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts +0 -14
- package/out/zero-cache/src/services/change-source/common/replica-schema.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts +0 -25
- package/out/zero-cache/src/services/change-source/custom/change-source.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-metadata.d.ts +0 -14
- package/out/zero-cache/src/services/change-source/pg/backfill-metadata.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts +0 -36
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +0 -65
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +0 -115
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +0 -155
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.d.ts +0 -17
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.d.ts +0 -28
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput-parser.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.d.ts +0 -76
- package/out/zero-cache/src/services/change-source/pg/logical-replication/pgoutput.types.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts +0 -169
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +0 -16
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-health.d.ts +0 -15
- package/out/zero-cache/src/services/change-source/pg/replication-slot-health.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +0 -127
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts +0 -9
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts +0 -68
- package/out/zero-cache/src/services/change-source/protocol/backfill-progress.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts +0 -72
- package/out/zero-cache/src/services/change-streamer/backfill-state-tracker.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts +0 -50
- package/out/zero-cache/src/services/change-streamer/backfill-state.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts +0 -14
- package/out/zero-cache/src/services/change-streamer/backup-cleanup-monitor-factory.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts +0 -18
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +0 -98
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +0 -34
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts +0 -34
- package/out/zero-cache/src/services/change-streamer/change-log-compare-digest.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts +0 -158
- package/out/zero-cache/src/services/change-streamer/change-log-initializer.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.d.ts +0 -19
- package/out/zero-cache/src/services/change-streamer/change-log-transaction-hash.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +0 -78
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +0 -143
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +0 -586
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts +0 -24
- package/out/zero-cache/src/services/change-streamer/drain-tracker.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/error-type-enum.d.ts +0 -15
- package/out/zero-cache/src/services/change-streamer/error-type-enum.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +0 -49
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts +0 -53
- package/out/zero-cache/src/services/change-streamer/litestream-sync-requester.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts +0 -88
- package/out/zero-cache/src/services/change-streamer/litestream3-prometheus-poller.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts +0 -15
- package/out/zero-cache/src/services/change-streamer/replica-poller.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts +0 -243
- package/out/zero-cache/src/services/change-streamer/restore-admission.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/schema/init.d.ts +0 -6
- package/out/zero-cache/src/services/change-streamer/schema/init.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +0 -152
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts +0 -11
- package/out/zero-cache/src/services/change-streamer/shard-sampling.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts +0 -92
- package/out/zero-cache/src/services/change-streamer/snapshot-message.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts +0 -36
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +0 -22
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts +0 -99
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-catchup.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts +0 -83
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-comparator.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.d.ts +0 -121
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-purge-scheduler.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts +0 -73
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-read-router.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts +0 -62
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-reader.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +0 -114
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +0 -276
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts +0 -485
- package/out/zero-cache/src/services/change-streamer/subscribe.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +0 -194
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +0 -52
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +0 -1
- package/out/zero-cache/src/services/limiter/sliding-window-limiter.d.ts +0 -57
- package/out/zero-cache/src/services/limiter/sliding-window-limiter.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +0 -77
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +0 -78
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/metrics.d.ts +0 -31
- package/out/zero-cache/src/services/litestream/metrics.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts +0 -24
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +0 -1
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +0 -40
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +0 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +0 -63
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts +0 -368
- package/out/zero-cache/src/services/replicator/change-log-db.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts +0 -56
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/change-processor.d.ts +0 -37
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/drain-handler.d.ts +0 -82
- package/out/zero-cache/src/services/replicator/drain-handler.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +0 -25
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/notifier.d.ts +0 -9
- package/out/zero-cache/src/services/replicator/notifier.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts +0 -71
- package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/replicator.d.ts +0 -86
- package/out/zero-cache/src/services/replicator/replicator.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts +0 -55
- package/out/zero-cache/src/services/replicator/reporter/recorder.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts +0 -132
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.d.ts +0 -120
- package/out/zero-cache/src/services/replicator/sqlite-change-log-purger.d.ts.map +0 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +0 -111
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +0 -1
- package/out/zero-cache/src/services/run-ast.d.ts +0 -39
- package/out/zero-cache/src/services/run-ast.d.ts.map +0 -1
- package/out/zero-cache/src/services/runner.d.ts +0 -19
- package/out/zero-cache/src/services/runner.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/active-users-gauge.d.ts +0 -17
- package/out/zero-cache/src/services/view-syncer/active-users-gauge.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts +0 -26
- package/out/zero-cache/src/services/view-syncer/advancement-metrics.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts +0 -79
- package/out/zero-cache/src/services/view-syncer/batch-pacer.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +0 -79
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/client-schema.d.ts +0 -5
- package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts +0 -184
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/cvr-purger.d.ts +0 -22
- package/out/zero-cache/src/services/view-syncer/cvr-purger.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +0 -128
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +0 -294
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts +0 -81
- package/out/zero-cache/src/services/view-syncer/deferred-writes-budget.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +0 -45
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.d.ts +0 -53
- package/out/zero-cache/src/services/view-syncer/e2e-serving-lag.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +0 -33
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +0 -51
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +0 -34
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +0 -296
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts +0 -7
- package/out/zero-cache/src/services/view-syncer/plan-warnings.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/push-cost.d.ts +0 -132
- package/out/zero-cache/src/services/view-syncer/push-cost.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts +0 -55
- package/out/zero-cache/src/services/view-syncer/push-cutoff.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts +0 -28
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts +0 -25
- package/out/zero-cache/src/services/view-syncer/query-shape.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts +0 -89
- package/out/zero-cache/src/services/view-syncer/query-stats.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts +0 -90
- package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/row-set-signature.d.ts +0 -17
- package/out/zero-cache/src/services/view-syncer/row-set-signature.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts +0 -86
- package/out/zero-cache/src/services/view-syncer/schema/cvr.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/schema/init.d.ts +0 -5
- package/out/zero-cache/src/services/view-syncer/schema/init.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts +0 -563
- package/out/zero-cache/src/services/view-syncer/schema/types.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +0 -95
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +0 -412
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/tracer.d.ts +0 -2
- package/out/zero-cache/src/services/view-syncer/tracer.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/ttl-clock.d.ts +0 -10
- package/out/zero-cache/src/services/view-syncer/ttl-clock.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +0 -133
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +0 -1
- package/out/zero-cache/src/types/pg-patch.d.ts +0 -21
- package/out/zero-cache/src/types/pg-patch.d.ts.map +0 -1
- package/out/zero-cache/src/types/pg-versions.d.ts +0 -3
- package/out/zero-cache/src/types/pg-versions.d.ts.map +0 -1
- package/out/zero-cache/src/workers/replicator.d.ts +0 -57
- package/out/zero-cache/src/workers/replicator.d.ts.map +0 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts +0 -14
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +0 -1
- package/out/zero-cache/src/workers/syncer.d.ts +0 -67
- package/out/zero-cache/src/workers/syncer.d.ts.map +0 -1
- package/out/zero-events/src/index.d.ts +0 -27
- package/out/zero-events/src/index.d.ts.map +0 -1
- package/out/zero-events/src/json.d.ts +0 -20
- package/out/zero-events/src/json.d.ts.map +0 -1
- package/out/zero-events/src/status.d.ts +0 -144
- package/out/zero-events/src/status.d.ts.map +0 -1
- package/out/zqlite/src/database-storage.d.ts +0 -24
- package/out/zqlite/src/database-storage.d.ts.map +0 -1
- package/out/zqlite/src/explain-queries.d.ts +0 -4
- package/out/zqlite/src/explain-queries.d.ts.map +0 -1
- package/out/zqlite/src/internal/sql-inline.d.ts +0 -13
- package/out/zqlite/src/internal/sql-inline.d.ts.map +0 -1
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts +0 -72
- package/out/zqlite/src/resolve-scalar-subqueries.d.ts.map +0 -1
- package/out/zqlite/src/sqlite-cost-model.d.ts +0 -17
- package/out/zqlite/src/sqlite-cost-model.d.ts.map +0 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts +0 -121
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","names":[],"sources":["../../../../../zql/src/builder/builder.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {JSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport type {\n AST,\n ColumnReference,\n CompoundKey,\n Condition,\n Conjunction,\n CorrelatedSubquery,\n CorrelatedSubqueryCondition,\n Disjunction,\n LiteralValue,\n Ordering,\n Parameter,\n SimpleCondition,\n ValuePosition,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../../zero-protocol/src/primary-key.ts';\nimport {Cap} from '../ivm/cap.ts';\nimport {Exists} from '../ivm/exists.ts';\nimport {FanIn} from '../ivm/fan-in.ts';\nimport {FanOut} from '../ivm/fan-out.ts';\nimport {\n buildFilterPipeline,\n type FilterInput,\n} from '../ivm/filter-operators.ts';\nimport {Filter} from '../ivm/filter.ts';\nimport {FlippedJoin} from '../ivm/flipped-join.ts';\nimport {JoinIndexTap} from '../ivm/join-index-tap.ts';\nimport {JoinIndex} from '../ivm/join-index.ts';\nimport {Join, type ExistsJoin} from '../ivm/join.ts';\nimport type {Input, InputBase, Storage} from '../ivm/operator.ts';\nimport {Skip} from '../ivm/skip.ts';\nimport type {Source, SourceInput} from '../ivm/source.ts';\nimport {TakeGate, type TakeBoundProvider} from '../ivm/take-gate.ts';\nimport {Take} from '../ivm/take.ts';\nimport {UnionFanIn} from '../ivm/union-fan-in.ts';\nimport {UnionFanOut} from '../ivm/union-fan-out.ts';\nimport {planQuery, type PlanWarningSink} from '../planner/planner-builder.ts';\nimport type {ConnectionCostModel} from '../planner/planner-connection.ts';\nimport type {PlanDebugger} from '../planner/planner-debug.ts';\nimport {completeOrdering} from '../query/complete-ordering.ts';\nimport {pushDownCorrelatedPredicates} from './correlated-predicate-pushdown.ts';\nimport type {DebugDelegate} from './debug-delegate.ts';\nimport {\n createPredicate,\n transformFilters,\n type NoSubqueryCondition,\n} from './filter.ts';\n\nexport type StaticQueryParameters = {\n authData: Record<string, JSONValue>;\n preMutationRow?: Row | undefined;\n};\n\n/**\n * Interface required of caller to buildPipeline. Connects to constructed\n * pipeline to delegate environment to provide sources and storage.\n */\nexport interface BuilderDelegate {\n readonly applyFiltersAnyway?: boolean | undefined;\n debug?: DebugDelegate | undefined;\n\n /**\n * When true, allows NOT EXISTS conditions in queries.\n * Defaults to false.\n *\n * We only set this to true on the server.\n * The client-side query engine cannot support NOT EXISTS because:\n * 1. Zero only syncs a subset of data to the client\n * 2. On the client, we can't distinguish between a row not existing vs.\n * a row not being synced to the client\n * 3. NOT EXISTS requires complete knowledge of what doesn't exist\n */\n readonly enableNotExists?: boolean | undefined;\n\n /**\n * When true, does not copy a parent's conditions on correlation columns\n * into its subqueries (see {@link pushDownCorrelatedPredicates}).\n * Defaults to false.\n *\n * Only zero-cache sets this, as a kill switch.\n */\n readonly disableCorrelatedPredicatePushdown?: boolean | undefined;\n\n /**\n * When true, copies a parent's conditions into its subqueries before\n * planning instead of after, and tells the planner which conditions it\n * copied. The planner then sees when a copied condition makes a flipped\n * join cheap. Has no effect when `disableCorrelatedPredicatePushdown` is\n * true. Defaults to false.\n *\n * Only zero-cache sets this. This changes plans, and the pushdown alone\n * does not.\n */\n readonly enablePlannerAwarePushdown?: boolean | undefined;\n\n /**\n * Called once for each source needed by the AST.\n * Might be called multiple times with same tableName. It is OK to return\n * same storage instance in that case.\n */\n getSource(tableName: string): Source | undefined;\n\n /**\n * Called once for each operator that requires storage. Should return a new\n * unique storage object for each call.\n */\n createStorage(name: string): Storage;\n\n decorateInput(input: Input, name: string): Input;\n\n addEdge(source: InputBase, dest: InputBase): void;\n\n decorateFilterInput(input: FilterInput, name: string): FilterInput;\n\n decorateSourceInput(input: SourceInput, queryID: string): Input;\n\n /**\n * Receives warnings about the plan the planner chose for the query, when\n * there is a cost model to plan with. Only zero-cache sets this.\n */\n readonly planWarnings?: PlanWarningSink | undefined;\n\n /**\n * The AST is mapped on-the-wire between client and server names.\n *\n * There is no \"wire\" for zqlite tests so this function is provided\n * to allow tests to remap the AST.\n */\n mapAst?: ((ast: AST) => AST) | undefined;\n}\n\n/**\n * Builds a pipeline from an AST. Caller must provide a delegate to create source\n * and storage interfaces as necessary.\n *\n * Usage:\n *\n * ```ts\n * class MySink implements Output {\n * readonly #input: Input;\n *\n * constructor(input: Input) {\n * this.#input = input;\n * input.setOutput(this);\n * }\n *\n * push(change: Change, _: Operator) {\n * console.log(change);\n * }\n * }\n *\n * const input = buildPipeline(ast, myDelegate, hash(ast));\n * const sink = new MySink(input);\n * ```\n */\nexport function buildPipeline(\n ast: AST,\n delegate: BuilderDelegate,\n queryID: string,\n costModel?: ConnectionCostModel,\n lc?: LogContext,\n planDebugger?: PlanDebugger,\n): Input {\n ast = delegate.mapAst ? delegate.mapAst(ast) : ast;\n ast = completeOrdering(\n ast,\n tableName => must(delegate.getSource(tableName)).tableSchema.primaryKey,\n );\n\n const columnsOf = (tableName: string) =>\n must(delegate.getSource(tableName)).tableSchema.columns;\n const {planWarnings} = delegate;\n if (delegate.disableCorrelatedPredicatePushdown) {\n if (costModel) {\n ast = planQuery(\n ast,\n costModel,\n planDebugger,\n lc,\n undefined,\n planWarnings,\n );\n }\n } else if (delegate.enablePlannerAwarePushdown) {\n const pushed = new Set<SimpleCondition>();\n ast = pushDownCorrelatedPredicates(ast, columnsOf, pushed);\n if (costModel) {\n ast = planQuery(ast, costModel, planDebugger, lc, pushed, planWarnings);\n }\n } else {\n if (costModel) {\n ast = planQuery(\n ast,\n costModel,\n planDebugger,\n lc,\n undefined,\n planWarnings,\n );\n }\n // After planning, so that the planner does not read the pushed conditions\n // as selective filters.\n ast = pushDownCorrelatedPredicates(ast, columnsOf);\n }\n return buildPipelineInternal(ast, delegate, queryID, '');\n}\n\nexport function bindStaticParameters(\n ast: AST,\n staticQueryParameters: StaticQueryParameters | undefined,\n) {\n const visit = (node: AST): AST => ({\n ...node,\n where: node.where ? bindCondition(node.where) : undefined,\n related: node.related?.map(sq => ({\n ...sq,\n subquery: visit(sq.subquery),\n })),\n });\n\n function bindCondition(condition: Condition): Condition {\n if (condition.type === 'simple') {\n return {\n ...condition,\n left: bindValue(condition.left),\n right: bindValue(condition.right) as Exclude<\n ValuePosition,\n ColumnReference\n >,\n };\n }\n if (condition.type === 'correlatedSubquery') {\n return {\n ...condition,\n related: {\n ...condition.related,\n subquery: visit(condition.related.subquery),\n },\n };\n }\n\n return {\n ...condition,\n conditions: condition.conditions.map(bindCondition),\n };\n }\n\n const bindValue = (value: ValuePosition): ValuePosition => {\n if (isParameter(value)) {\n const anchor = must(\n staticQueryParameters,\n 'Static query params do not exist',\n )[value.anchor];\n const resolvedValue = resolveField(anchor, value.field);\n return {\n type: 'literal',\n value: resolvedValue as LiteralValue,\n };\n }\n return value;\n };\n\n return visit(ast);\n}\n\nfunction resolveField(\n anchor: Record<string, JSONValue> | Row | undefined,\n field: string | string[],\n): unknown {\n if (anchor === undefined) {\n return null;\n }\n\n if (Array.isArray(field)) {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n return field.reduce((acc, f) => (acc as any)?.[f], anchor) ?? null;\n }\n\n return anchor[field] ?? null;\n}\n\nfunction isParameter(value: ValuePosition): value is Parameter {\n return value.type === 'static';\n}\n\nconst EXISTS_LIMIT = 3;\nconst PERMISSIONS_EXISTS_LIMIT = 1;\n\n/**\n * Checks if a condition tree contains any NOT EXISTS operations.\n * Recursively checks AND/OR branches but does not recurse into nested subqueries\n * (those are checked when buildPipelineInternal processes them).\n */\nexport function assertNoNotExists(condition: Condition): void {\n switch (condition.type) {\n case 'simple':\n return;\n\n case 'correlatedSubquery':\n if (condition.op === 'NOT EXISTS') {\n throw new Error(\n 'not(exists()) is not supported on the client - see https://bugs.rocicorp.dev/issue/3438',\n );\n }\n return;\n\n case 'and':\n case 'or':\n for (const c of condition.conditions) {\n assertNoNotExists(c);\n }\n return;\n default:\n unreachable(condition);\n }\n}\n\nfunction buildPipelineInternal(\n ast: AST,\n delegate: BuilderDelegate,\n queryID: string,\n name: string,\n partitionKey?: CompoundKey,\n isNonFlippedExistsChild?: boolean,\n): Input {\n const source = delegate.getSource(ast.table);\n if (!source) {\n throw new Error(`Source not found: ${ast.table}`);\n }\n\n ast = uniquifyCorrelatedSubqueryConditionAliases(ast);\n\n if (!delegate.enableNotExists && ast.where) {\n assertNoNotExists(ast.where);\n }\n\n const csqConditions = gatherCorrelatedSubqueryQueryConditions(ast.where);\n const splitEditKeys: Set<string> = partitionKey\n ? new Set(partitionKey)\n : new Set();\n const aliases = new Set<string>();\n for (const csq of csqConditions) {\n aliases.add(csq.related.subquery.alias || '');\n for (const key of csq.related.correlation.parentField) {\n splitEditKeys.add(key);\n }\n }\n if (ast.related) {\n for (const csq of ast.related) {\n for (const key of csq.correlation.parentField) {\n splitEditKeys.add(key);\n }\n }\n }\n if (isNonFlippedExistsChild) {\n assert(ast.start === undefined, 'EXISTS subqueries must not have start');\n assert(\n ast.related === undefined,\n 'EXISTS subqueries must not have related',\n );\n }\n\n // The Cap optimization needs the source connect to be unordered, but\n // applyFilterWithFlips builds a UnionFanIn over the source whenever\n // ast.where contains a flipped subquery, and UnionFanIn requires a\n // sort on its inputs. In that case, fall back to the ordered + Take\n // path for this EXISTS child.\n const useCap =\n isNonFlippedExistsChild &&\n !(ast.where && conditionIncludesFlippedSubqueryAtAnyLevel(ast.where));\n\n const conn = source.connect(\n // exists pipelines are unordered — orderBy is ignored here.\n // Non-exists pipelines always have orderBy completed with PKs.\n useCap ? undefined : must(ast.orderBy),\n ast.where,\n splitEditKeys,\n delegate.debug,\n );\n\n let end: Input = delegate.decorateSourceInput(conn, queryID);\n end = delegate.decorateInput(end, `${name}:source(${ast.table})`);\n const {fullyAppliedFilters} = conn;\n\n if (ast.start) {\n const skip = new Skip(end, ast.start);\n delegate.addEdge(end, skip);\n end = delegate.decorateInput(skip, `${name}:skip)`);\n }\n\n let takeGate: TakeGate | undefined;\n if (ast.limit !== undefined && !useCap) {\n const takeGateName = `${name}:take-gate`;\n takeGate = new TakeGate(end);\n delegate.addEdge(end, takeGate);\n end = delegate.decorateInput(takeGate, takeGateName);\n }\n\n // The parent indexes of the EXISTS joins below. They hold the rows this\n // pipeline emits, which the JoinIndexTap after the limit maintains.\n const existsParentIndexes: JoinIndex[] = [];\n for (const csqCondition of csqConditions) {\n // flipped EXISTS are handled in applyWhere\n if (!csqCondition.flip) {\n const parentIndex = new JoinIndex(\n csqCondition.related.correlation.parentField,\n end.getSchema().primaryKey,\n );\n existsParentIndexes.push(parentIndex);\n end = applyCorrelatedSubQuery(\n {\n ...csqCondition.related,\n subquery: {\n ...csqCondition.related.subquery,\n limit:\n csqCondition.related.system === 'permissions'\n ? PERMISSIONS_EXISTS_LIMIT\n : EXISTS_LIMIT,\n },\n },\n delegate,\n queryID,\n end,\n name,\n true,\n undefined,\n takeGate,\n {op: csqCondition.op, parentIndex},\n );\n }\n }\n\n if (ast.where && (!fullyAppliedFilters || delegate.applyFiltersAnyway)) {\n end = applyWhere(\n end,\n ast.where,\n delegate,\n name,\n partitionKey,\n takeGate,\n existsParentIndexes,\n );\n }\n\n if (ast.limit !== undefined) {\n // We end `exists` pipelines with `cap`\n // The reason is that `cap` does not care about the order of the pipeline.\n // This allows SQLite to chose the order and never end up creating temp b-trees.\n // The problem with SQLite creating a temp b-tree is it will incur a scan of the entire\n // result set where exists only needs the first row.\n if (useCap) {\n const capName = `${name}:cap`;\n const cap = new Cap(\n end,\n delegate.createStorage(capName),\n ast.limit,\n partitionKey,\n );\n delegate.addEdge(end, cap);\n end = delegate.decorateInput(cap, capName);\n } else {\n const takeName = `${name}:take`;\n const take = new Take(\n end,\n delegate.createStorage(takeName),\n ast.limit,\n partitionKey,\n );\n delegate.addEdge(end, take);\n end = delegate.decorateInput(take, takeName);\n takeGate?.setBoundProvider(take);\n if (takeGate) {\n take.setTakeGate(takeGate);\n }\n }\n }\n\n if (existsParentIndexes.length > 0) {\n const tapName = `${name}:join-index`;\n const tap = new JoinIndexTap(end, existsParentIndexes);\n delegate.addEdge(end, tap);\n end = delegate.decorateInput(tap, tapName);\n }\n\n if (ast.related) {\n // Dedupe by alias - last one wins (LWW), like limit(5).limit(10)\n const byAlias = new Map<string, CorrelatedSubquery>();\n for (const csq of ast.related) {\n byAlias.set(csq.subquery.alias ?? '', csq);\n }\n for (const csq of byAlias.values()) {\n end = applyCorrelatedSubQuery(\n csq,\n delegate,\n queryID,\n end,\n name,\n false,\n partitionKey,\n );\n }\n }\n\n return end;\n}\n\nfunction applyWhere(\n input: Input,\n condition: Condition,\n delegate: BuilderDelegate,\n name: string,\n parentPartitionKey?: CompoundKey,\n boundProvider?: TakeBoundProvider,\n existsParentIndexes?: JoinIndex[],\n): Input {\n if (!conditionIncludesFlippedSubqueryAtAnyLevel(condition)) {\n return buildFilterPipeline(\n input,\n delegate,\n filterInput => applyFilter(filterInput, condition, delegate, name),\n transformFilters(condition).filters,\n );\n }\n\n return applyFilterWithFlips(\n input,\n condition,\n delegate,\n name,\n parentPartitionKey,\n boundProvider,\n existsParentIndexes,\n );\n}\n\nfunction applyFilterWithFlips(\n input: Input,\n condition: Condition,\n delegate: BuilderDelegate,\n name: string,\n parentPartitionKey?: CompoundKey,\n boundProvider?: TakeBoundProvider,\n existsParentIndexes?: JoinIndex[],\n): Input {\n let end = input;\n assert(condition.type !== 'simple', 'Simple conditions cannot have flips');\n\n switch (condition.type) {\n case 'and': {\n const [withFlipped, withoutFlipped] = partitionBranches(\n condition.conditions,\n conditionIncludesFlippedSubqueryAtAnyLevel,\n );\n if (withoutFlipped.length > 0) {\n const andCondition: Conjunction = {\n type: 'and',\n conditions: withoutFlipped,\n };\n end = buildFilterPipeline(\n input,\n delegate,\n filterInput => applyAnd(filterInput, andCondition, delegate, name),\n transformFilters(andCondition).filters,\n );\n }\n assert(withFlipped.length > 0, 'Impossible to have no flips here');\n for (const cond of withFlipped) {\n end = applyFilterWithFlips(\n end,\n cond,\n delegate,\n name,\n parentPartitionKey,\n boundProvider,\n existsParentIndexes,\n );\n }\n break;\n }\n case 'or': {\n const [withFlipped, withoutFlipped] = partitionBranches(\n condition.conditions,\n conditionIncludesFlippedSubqueryAtAnyLevel,\n );\n assert(withFlipped.length > 0, 'Impossible to have no flips here');\n\n const ufo = new UnionFanOut(end);\n delegate.addEdge(end, ufo);\n end = delegate.decorateInput(ufo, `${name}:ufo`);\n\n const branches: Input[] = [];\n if (withoutFlipped.length > 0) {\n const orCondition: Disjunction = {\n type: 'or',\n conditions: withoutFlipped,\n };\n branches.push(\n buildFilterPipeline(\n end,\n delegate,\n filterInput => applyOr(filterInput, orCondition, delegate, name),\n transformFilters(orCondition).filters,\n ),\n );\n }\n\n for (const cond of withFlipped) {\n branches.push(\n applyFilterWithFlips(\n end,\n cond,\n delegate,\n name,\n parentPartitionKey,\n boundProvider,\n existsParentIndexes,\n ),\n );\n }\n\n const ufi = new UnionFanIn(ufo, branches);\n for (const branch of branches) {\n delegate.addEdge(branch, ufi);\n }\n end = delegate.decorateInput(ufi, `${name}:ufi`);\n\n break;\n }\n case 'correlatedSubquery': {\n const sq = condition.related;\n const child = buildPipelineInternal(\n sq.subquery,\n delegate,\n '',\n `${name}.${sq.subquery.alias}`,\n sq.correlation.childField,\n false,\n );\n let parentIndex: JoinIndex | undefined;\n if (existsParentIndexes) {\n parentIndex = new JoinIndex(\n sq.correlation.parentField,\n end.getSchema().primaryKey,\n parentPartitionKey,\n );\n existsParentIndexes.push(parentIndex);\n }\n const flippedJoinName = `${name}:flipped-join(${sq.subquery.alias})`;\n const flippedJoin = new FlippedJoin({\n parent: end,\n child,\n parentKey: sq.correlation.parentField,\n childKey: sq.correlation.childField,\n relationshipName: must(\n sq.subquery.alias,\n 'Subquery must have an alias',\n ),\n hidden: sq.hidden ?? false,\n system: sq.system ?? 'client',\n parentPartitionKey,\n boundProvider,\n parentIndex,\n });\n delegate.addEdge(end, flippedJoin);\n delegate.addEdge(child, flippedJoin);\n end = delegate.decorateInput(flippedJoin, flippedJoinName);\n break;\n }\n }\n\n return end;\n}\n\nfunction applyFilter(\n input: FilterInput,\n condition: Condition,\n delegate: BuilderDelegate,\n name: string,\n): FilterInput {\n switch (condition.type) {\n case 'and':\n return applyAnd(input, condition, delegate, name);\n case 'or':\n return applyOr(input, condition, delegate, name);\n case 'correlatedSubquery':\n return applyCorrelatedSubqueryCondition(input, condition, delegate, name);\n case 'simple':\n return applySimpleCondition(input, delegate, condition);\n }\n}\n\nfunction applyAnd(\n input: FilterInput,\n condition: Conjunction,\n delegate: BuilderDelegate,\n name: string,\n): FilterInput {\n for (const subCondition of condition.conditions) {\n input = applyFilter(input, subCondition, delegate, name);\n }\n return input;\n}\n\nexport function applyOr(\n input: FilterInput,\n condition: Disjunction,\n delegate: BuilderDelegate,\n name: string,\n): FilterInput {\n const [subqueryConditions, otherConditions] =\n groupSubqueryConditions(condition);\n // if there are no subquery conditions, no fan-in / fan-out is needed\n if (subqueryConditions.length === 0) {\n const filter = new Filter(\n input,\n createPredicate({\n type: 'or',\n conditions: otherConditions,\n }),\n );\n delegate.addEdge(input, filter);\n return filter;\n }\n\n const fanOut = new FanOut(input);\n delegate.addEdge(input, fanOut);\n const branches = subqueryConditions.map(subCondition =>\n applyFilter(fanOut, subCondition, delegate, name),\n );\n if (otherConditions.length > 0) {\n const filter = new Filter(\n fanOut,\n createPredicate({\n type: 'or',\n conditions: otherConditions,\n }),\n );\n delegate.addEdge(fanOut, filter);\n branches.push(filter);\n }\n const ret = new FanIn(fanOut, branches);\n for (const branch of branches) {\n delegate.addEdge(branch, ret);\n }\n fanOut.setFanIn(ret);\n return ret;\n}\n\nexport function groupSubqueryConditions(condition: Disjunction) {\n const partitioned: [\n subqueryConditions: Condition[],\n otherConditions: NoSubqueryCondition[],\n ] = [[], []];\n for (const subCondition of condition.conditions) {\n if (isNotAndDoesNotContainSubquery(subCondition)) {\n partitioned[1].push(subCondition);\n } else {\n partitioned[0].push(subCondition);\n }\n }\n return partitioned;\n}\n\nexport function isNotAndDoesNotContainSubquery(\n condition: Condition,\n): condition is NoSubqueryCondition {\n if (condition.type === 'correlatedSubquery') {\n return false;\n }\n if (condition.type === 'simple') {\n return true;\n }\n return condition.conditions.every(isNotAndDoesNotContainSubquery);\n}\n\nfunction applySimpleCondition(\n input: FilterInput,\n delegate: BuilderDelegate,\n condition: SimpleCondition,\n): FilterInput {\n const filter = new Filter(input, createPredicate(condition));\n delegate.decorateFilterInput(\n filter,\n `${valuePosName(condition.left)}:${condition.op}:${valuePosName(condition.right)}`,\n );\n delegate.addEdge(input, filter);\n return filter;\n}\n\nfunction valuePosName(left: ValuePosition) {\n switch (left.type) {\n case 'static':\n return left.field;\n case 'literal':\n return left.value;\n case 'column':\n return left.name;\n }\n}\n\nfunction applyCorrelatedSubQuery(\n sq: CorrelatedSubquery,\n delegate: BuilderDelegate,\n queryID: string,\n end: Input,\n name: string,\n fromCondition: boolean,\n parentPartitionKey?: CompoundKey,\n boundProvider?: TakeBoundProvider,\n exists?: ExistsJoin,\n) {\n // TODO: we only omit the join if the CSQ if from a condition since\n // we want to create an empty array for `related` fields that are `limit(0)`\n if (sq.subquery.limit === 0 && fromCondition) {\n return end;\n }\n\n assert(sq.subquery.alias, 'Subquery must have an alias');\n const child = buildPipelineInternal(\n sq.subquery,\n delegate,\n queryID,\n `${name}.${sq.subquery.alias}`,\n sq.correlation.childField,\n fromCondition,\n );\n\n const joinName = `${name}:join(${sq.subquery.alias})`;\n const join = new Join({\n parent: end,\n child,\n parentKey: sq.correlation.parentField,\n childKey: sq.correlation.childField,\n relationshipName: sq.subquery.alias,\n hidden: sq.hidden ?? false,\n system: sq.system ?? 'client',\n parentPartitionKey: fromCondition ? undefined : parentPartitionKey,\n boundProvider,\n exists,\n });\n delegate.addEdge(end, join);\n delegate.addEdge(child, join);\n return delegate.decorateInput(join, joinName);\n}\n\nfunction applyCorrelatedSubqueryCondition(\n input: FilterInput,\n condition: CorrelatedSubqueryCondition,\n delegate: BuilderDelegate,\n name: string,\n): FilterInput {\n assert(\n condition.op === 'EXISTS' || condition.op === 'NOT EXISTS',\n 'Expected EXISTS or NOT EXISTS operator',\n );\n if (condition.related.subquery.limit === 0) {\n if (condition.op === 'EXISTS') {\n const filter = new Filter(input, () => false);\n delegate.addEdge(input, filter);\n return filter;\n }\n const filter = new Filter(input, () => true);\n delegate.addEdge(input, filter);\n return filter;\n }\n const existsName = `${name}:exists(${condition.related.subquery.alias})`;\n const exists = new Exists(\n input,\n must(condition.related.subquery.alias),\n condition.related.correlation.parentField,\n condition.op,\n );\n delegate.addEdge(input, exists);\n return delegate.decorateFilterInput(exists, existsName);\n}\n\nfunction gatherCorrelatedSubqueryQueryConditions(\n condition: Condition | undefined,\n) {\n const csqs: CorrelatedSubqueryCondition[] = [];\n const gather = (condition: Condition) => {\n if (condition.type === 'correlatedSubquery') {\n csqs.push(condition);\n return;\n }\n if (condition.type === 'and' || condition.type === 'or') {\n for (const c of condition.conditions) {\n gather(c);\n }\n return;\n }\n };\n if (condition) {\n gather(condition);\n }\n return csqs;\n}\n\nexport function assertOrderingIncludesPK(\n ordering: Ordering,\n pk: PrimaryKey,\n): void {\n // oxlint-disable-next-line unicorn/prefer-set-has -- Array is more appropriate here for small collections\n const orderingFields = ordering.map(([field]) => field);\n const missingFields = pk.filter(pkField => !orderingFields.includes(pkField));\n\n if (missingFields.length > 0) {\n throw new Error(\n `Ordering must include all primary key fields. Missing: ${missingFields.join(\n ', ',\n )}. ZQL automatically appends primary key fields to the ordering if they are missing \n so a common cause of this error is a casing mismatch between Postgres and ZQL.\n E.g., \"userid\" vs \"userID\".\n You may want to add double-quotes around your Postgres column names to prevent Postgres from lower-casing them:\n https://www.postgresql.org/docs/current/sql-syntax-lexical.htm`,\n );\n }\n}\n\nfunction uniquifyCorrelatedSubqueryConditionAliases(ast: AST): AST {\n if (!ast.where) {\n return ast;\n }\n const {where} = ast;\n if (where.type !== 'and' && where.type !== 'or') {\n return ast;\n }\n\n let count = 0;\n const uniquifyCorrelatedSubquery = (csqc: CorrelatedSubqueryCondition) => ({\n ...csqc,\n related: {\n ...csqc.related,\n subquery: {\n ...csqc.related.subquery,\n alias: (csqc.related.subquery.alias ?? '') + '_' + count++,\n },\n },\n });\n\n const uniquify = (cond: Condition): Condition => {\n if (cond.type === 'simple') {\n return cond;\n } else if (cond.type === 'correlatedSubquery') {\n return uniquifyCorrelatedSubquery(cond);\n }\n const conditions = [];\n for (const c of cond.conditions) {\n conditions.push(uniquify(c));\n }\n return {\n type: cond.type,\n conditions,\n };\n };\n\n const result = {\n ...ast,\n where: uniquify(where),\n };\n return result;\n}\n\nexport function conditionIncludesFlippedSubqueryAtAnyLevel(\n cond: Condition,\n): boolean {\n if (cond.type === 'correlatedSubquery') {\n return !!cond.flip;\n }\n if (cond.type === 'and' || cond.type === 'or') {\n return cond.conditions.some(c =>\n conditionIncludesFlippedSubqueryAtAnyLevel(c),\n );\n }\n // simple conditions don't have flips\n return false;\n}\n\nexport function partitionBranches(\n conditions: readonly Condition[],\n predicate: (c: Condition) => boolean,\n) {\n const matched: Condition[] = [];\n const notMatched: Condition[] = [];\n for (const c of conditions) {\n if (predicate(c)) {\n matched.push(c);\n } else {\n notMatched.push(c);\n }\n }\n return [matched, notMatched] as const;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"builder.js","names":[],"sources":["../../../../../zql/src/builder/builder.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\nimport {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {JSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport {assignProperty} from '../../../shared/src/objects.ts';\nimport * as v from '../../../shared/src/valita.ts';\nimport {\n AGGREGATE_TABLE_PREFIX,\n AGGREGATE_TABLE_SEPARATOR,\n} from '../../../zero-protocol/src/aggregate-table.ts';\nimport {\n formatJsonPathReference,\n simpleConditionSchema,\n type AggregateFunction,\n type AST,\n type CompoundKey,\n type Condition,\n type Conjunction,\n type CorrelatedSubquery,\n type CorrelatedSubqueryCondition,\n type Disjunction,\n type LiteralValue,\n type Parameter,\n type SimpleCondition,\n type ValuePosition,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../../zero-protocol/src/primary-key.ts';\nimport type {SchemaValue} from '../../../zero-types/src/schema-value.ts';\nimport {\n AGGREGATE_KEY_COLUMN,\n Aggregate,\n aggregateSourceSchema,\n assertNotSyntheticColumn,\n isInvertible,\n Reducer,\n} from '../ivm/aggregate.ts';\nimport {Cap} from '../ivm/cap.ts';\nimport {Exists} from '../ivm/exists.ts';\nimport {FanIn} from '../ivm/fan-in.ts';\nimport {FanOut} from '../ivm/fan-out.ts';\nimport {\n buildFilterPipeline,\n type FilterInput,\n} from '../ivm/filter-operators.ts';\nimport {Filter} from '../ivm/filter.ts';\nimport {FlippedJoin} from '../ivm/flipped-join.ts';\nimport {\n GroupBy,\n groupOrdering,\n GroupProjection,\n groupSourceSchema,\n} from '../ivm/group-by.ts';\nimport {JoinIndexTap} from '../ivm/join-index-tap.ts';\nimport {JoinIndex} from '../ivm/join-index.ts';\nimport {Join, type ExistsJoin} from '../ivm/join.ts';\nimport {LiftField, LIFTED_FIELD_COLUMN} from '../ivm/lift-field.ts';\nimport type {Input, InputBase, Storage} from '../ivm/operator.ts';\nimport {Skip} from '../ivm/skip.ts';\nimport type {Source, SourceInput} from '../ivm/source.ts';\nimport {TakeGate, type TakeBoundProvider} from '../ivm/take-gate.ts';\nimport {Take} from '../ivm/take.ts';\nimport {UnionFanIn} from '../ivm/union-fan-in.ts';\nimport {UnionFanOut} from '../ivm/union-fan-out.ts';\nimport {planQuery, type PlanWarningSink} from '../planner/planner-builder.ts';\nimport type {ConnectionCostModel} from '../planner/planner-connection.ts';\nimport type {PlanDebugger} from '../planner/planner-debug.ts';\nimport {completeOrdering} from '../query/complete-ordering.ts';\nimport {pushDownCorrelatedPredicates} from './correlated-predicate-pushdown.ts';\nimport type {DebugDelegate} from './debug-delegate.ts';\nimport {\n createPredicate,\n transformFilters,\n type NoSubqueryCondition,\n} from './filter.ts';\n\nexport type StaticQueryParameters = {\n authData: Record<string, JSONValue>;\n preMutationRow?: Row | undefined;\n};\n\n/**\n * Interface required of caller to buildPipeline. Connects to constructed\n * pipeline to delegate environment to provide sources and storage.\n */\nexport interface BuilderDelegate {\n readonly applyFiltersAnyway?: boolean | undefined;\n debug?: DebugDelegate | undefined;\n\n /**\n * When true, allows NOT EXISTS conditions in queries.\n * Defaults to false.\n *\n * We only set this to true on the server.\n * The client-side query engine cannot support NOT EXISTS because:\n * 1. Zero only syncs a subset of data to the client\n * 2. On the client, we can't distinguish between a row not existing vs.\n * a row not being synced to the client\n * 3. NOT EXISTS requires complete knowledge of what doesn't exist\n */\n readonly enableNotExists?: boolean | undefined;\n\n /**\n * When true, does not copy a parent's conditions on correlation columns\n * into its subqueries (see {@link pushDownCorrelatedPredicates}).\n * Defaults to false.\n *\n * Only zero-cache sets this, as a kill switch.\n */\n readonly disableCorrelatedPredicatePushdown?: boolean | undefined;\n\n /**\n * When true, copies a parent's conditions into its subqueries before\n * planning instead of after, and tells the planner which conditions it\n * copied. The planner then sees when a copied condition makes a flipped\n * join cheap. Has no effect when `disableCorrelatedPredicatePushdown` is\n * true. Defaults to false.\n *\n * Only zero-cache sets this. This changes plans, and the pushdown alone\n * does not.\n */\n readonly enablePlannerAwarePushdown?: boolean | undefined;\n\n /**\n * When true, an `aggregate` relationship is read from a synthetic,\n * pre-computed aggregate source (see {@link aggregateTableName}) via a\n * plain Join, instead of being computed by an {@link Aggregate} operator\n * over the child rows.\n *\n * This is the *synced client* mode: the server computes the aggregate (the\n * Aggregate operator consumes the child rows so they never sync) and streams\n * only the per-parent result rows; the client reads them and never holds the\n * children. Defaults to false (compute locally), which is correct for the\n * server and for single-process client materialization.\n */\n readonly aggregatesFromSource?: boolean | undefined;\n\n /**\n * Called once for each source needed by the AST.\n * Might be called multiple times with same tableName. It is OK to return\n * same storage instance in that case.\n */\n getSource(tableName: string): Source | undefined;\n\n /**\n * Get-or-create the synthetic source for a *relationship* aggregate read in\n * `aggregatesFromSource` mode. Unlike a top-level aggregate (whose shape is\n * derivable from the table name), a relationship aggregate's source needs the\n * correlation-key columns + types, which only the builder knows here — so it\n * passes them in. Optional: only the synced client implements it; the server\n * (compute mode) never takes the `aggregatesFromSource` path, and tests may\n * instead provide the source directly via {@link getSource}.\n */\n getAggregateSource?(\n name: string,\n columns: Record<string, SchemaValue>,\n primaryKey: PrimaryKey,\n /**\n * When present, the client may optimistically update this aggregate when a\n * child row in `table` is locally mutated (only supplied for the invertible\n * cases with a per-row-evaluable `where` — see the call site). Omitted ⇒\n * server-authoritative only.\n */\n optimisticDelta?: AggregateOptimisticDelta,\n ): Source;\n\n /**\n * The names under which a synced aggregate row carries the key `columns` of\n * `table`, in the same order. The server computes aggregates over the AST it\n * was sent, which the client maps to server names, so the rows it streams\n * key by server column names; the synthetic source has to match them. Only\n * the synced client implements it; absent, the names are used unchanged.\n */\n aggregateKeyColumns?(table: string, columns: CompoundKey): CompoundKey;\n\n /**\n * Called once for each operator that requires storage. Should return a new\n * unique storage object for each call.\n */\n createStorage(name: string): Storage;\n\n decorateInput(input: Input, name: string): Input;\n\n addEdge(source: InputBase, dest: InputBase): void;\n\n decorateFilterInput(input: FilterInput, name: string): FilterInput;\n\n decorateSourceInput(input: SourceInput, queryID: string): Input;\n\n /**\n * Receives warnings about the plan the planner chose for the query, when\n * there is a cost model to plan with. Only zero-cache sets this.\n */\n readonly planWarnings?: PlanWarningSink | undefined;\n\n /**\n * The AST is mapped on-the-wire between client and server names.\n *\n * There is no \"wire\" for zqlite tests so this function is provided\n * to allow tests to remap the AST.\n */\n mapAst?: ((ast: AST) => AST) | undefined;\n}\n\n/**\n * Builds a pipeline from an AST. Caller must provide a delegate to create source\n * and storage interfaces as necessary.\n *\n * Usage:\n *\n * ```ts\n * class MySink implements Output {\n * readonly #input: Input;\n *\n * constructor(input: Input) {\n * this.#input = input;\n * input.setOutput(this);\n * }\n *\n * push(change: Change, _: Operator) {\n * console.log(change);\n * }\n * }\n *\n * const input = buildPipeline(ast, myDelegate, hash(ast));\n * const sink = new MySink(input);\n * ```\n */\nexport function buildPipeline(\n ast: AST,\n delegate: BuilderDelegate,\n queryID: string,\n costModel?: ConnectionCostModel,\n lc?: LogContext,\n planDebugger?: PlanDebugger,\n): Input {\n ast = delegate.mapAst ? delegate.mapAst(ast) : ast;\n\n assert(\n ast.groupBy === undefined || ast.aggregate?.distinct === undefined,\n 'a count of distinct values per group is not supported yet',\n );\n\n // Synced client reading a top-level (ungrouped) aggregate: the underlying\n // table is not synced and has no source here, and ordering/planning don't\n // apply to a scalar result. Read the precomputed row directly from the\n // synthetic source (see buildPipelineInternal's short-circuit).\n if ((ast.aggregate || ast.groupBy) && delegate.aggregatesFromSource) {\n return buildPipelineInternal(ast, delegate, queryID, '');\n }\n\n if (ast.groupBy || ast.aggregate?.distinct) {\n // The input of a grouping is sorted by its columns first, so the rows of\n // each group are adjacent (see GroupBy).\n ast = {...ast, orderBy: groupOrdering(ast)};\n }\n\n ast = completeOrdering(\n ast,\n tableName => must(delegate.getSource(tableName)).tableSchema.primaryKey,\n );\n\n const columnsOf = (tableName: string) =>\n must(delegate.getSource(tableName)).tableSchema.columns;\n const {planWarnings} = delegate;\n if (delegate.disableCorrelatedPredicatePushdown) {\n if (costModel) {\n ast = planQuery(\n ast,\n costModel,\n planDebugger,\n lc,\n undefined,\n planWarnings,\n );\n }\n } else if (delegate.enablePlannerAwarePushdown) {\n const pushed = new Set<SimpleCondition>();\n ast = pushDownCorrelatedPredicates(ast, columnsOf, pushed);\n if (costModel) {\n ast = planQuery(ast, costModel, planDebugger, lc, pushed, planWarnings);\n }\n } else {\n if (costModel) {\n ast = planQuery(\n ast,\n costModel,\n planDebugger,\n lc,\n undefined,\n planWarnings,\n );\n }\n // After planning, so that the planner does not read the pushed conditions\n // as selective filters.\n ast = pushDownCorrelatedPredicates(ast, columnsOf);\n }\n return buildPipelineInternal(ast, delegate, queryID, '');\n}\n\nexport function bindStaticParameters(\n ast: AST,\n staticQueryParameters: StaticQueryParameters | undefined,\n) {\n const visit = (node: AST): AST => ({\n ...node,\n where: node.where ? bindCondition(node.where) : undefined,\n related: node.related?.map(sq => ({\n ...sq,\n subquery: visit(sq.subquery),\n })),\n });\n\n function bindCondition(condition: Condition): Condition {\n if (condition.type === 'simple') {\n const bound: SimpleCondition = {\n ...condition,\n left: bindValue(condition.left),\n right: bindValue(condition.right) as SimpleCondition['right'],\n };\n if (bound.left.type === 'json' && condition.right.type === 'static') {\n // The wire schema requires the literal compared against a JSON path\n // leaf to be a primitive or a homogeneous primitive list (the engines\n // gate and cast on the type of the first element). A parameter is\n // bound after that validation ran, so re-apply it to the bound value:\n // a mixed list from authData then fails here, loudly, instead of as a\n // Postgres cast error or silently dropped elements on the other\n // engines.\n v.parse(bound, simpleConditionSchema);\n }\n return bound;\n }\n if (condition.type === 'correlatedSubquery') {\n return {\n ...condition,\n related: {\n ...condition.related,\n subquery: visit(condition.related.subquery),\n },\n };\n }\n\n return {\n ...condition,\n conditions: condition.conditions.map(bindCondition),\n };\n }\n\n const bindValue = (value: ValuePosition): ValuePosition => {\n if (isParameter(value)) {\n const anchor = must(\n staticQueryParameters,\n 'Static query params do not exist',\n )[value.anchor];\n const resolvedValue = resolveField(anchor, value.field);\n return {\n type: 'literal',\n value: resolvedValue as LiteralValue,\n };\n }\n return value;\n };\n\n return visit(ast);\n}\n\nfunction resolveField(\n anchor: Record<string, JSONValue> | Row | undefined,\n field: string | string[],\n): unknown {\n if (anchor === undefined) {\n return null;\n }\n\n if (Array.isArray(field)) {\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n return field.reduce((acc, f) => (acc as any)?.[f], anchor) ?? null;\n }\n\n return anchor[field] ?? null;\n}\n\nfunction isParameter(value: ValuePosition): value is Parameter {\n return value.type === 'static';\n}\n\nconst EXISTS_LIMIT = 3;\nconst PERMISSIONS_EXISTS_LIMIT = 1;\n\n/**\n * Checks if a condition tree contains any NOT EXISTS operations.\n * Recursively checks AND/OR branches but does not recurse into nested subqueries\n * (those are checked when buildPipelineInternal processes them).\n */\nfunction assertNoNotExists(condition: Condition): void {\n switch (condition.type) {\n case 'simple':\n return;\n\n case 'correlatedSubquery':\n if (condition.op === 'NOT EXISTS') {\n throw new Error(\n 'not(exists()) is not supported on the client - see https://bugs.rocicorp.dev/issue/3438',\n );\n }\n return;\n\n case 'and':\n case 'or':\n for (const c of condition.conditions) {\n assertNoNotExists(c);\n }\n return;\n default:\n unreachable(condition);\n }\n}\n\nfunction buildPipelineInternal(\n ast: AST,\n delegate: BuilderDelegate,\n queryID: string,\n name: string,\n partitionKey?: CompoundKey,\n isNonFlippedExistsChild?: boolean,\n): Input {\n assert(\n ast.groupBy === undefined || name === '',\n 'groupBy is only supported at the top level',\n );\n // Synced client reading a top-level (ungrouped) aggregate: the precomputed\n // single row is read from the synthetic source `aggregate:<queryID>`; the\n // underlying table is never synced, so its pipeline is not built at all.\n if (ast.aggregate && !ast.groupBy && delegate.aggregatesFromSource) {\n const aggTable = topLevelAggregateTableName(queryID);\n const aggSource = delegate.getSource(aggTable);\n if (!aggSource) {\n throw new Error(`Aggregate source not found: ${aggTable}`);\n }\n const conn = aggSource.connect([[AGGREGATE_KEY_COLUMN, 'asc']]);\n return delegate.decorateInput(\n delegate.decorateSourceInput(conn, queryID),\n `${name}:aggregateSource`,\n );\n }\n\n if (ast.groupBy && delegate.aggregatesFromSource) {\n return groupFromSource(ast, delegate, queryID, name);\n }\n\n const source = delegate.getSource(ast.table);\n if (!source) {\n throw new Error(`Source not found: ${ast.table}`);\n }\n\n ast = uniquifyCorrelatedSubqueryConditionAliases(ast);\n\n if (!delegate.enableNotExists && ast.where) {\n assertNoNotExists(ast.where);\n }\n\n const csqConditions = gatherCorrelatedSubqueryQueryConditions(ast.where);\n const splitEditKeys: Set<string> = partitionKey\n ? new Set(partitionKey)\n : new Set();\n const aliases = new Set<string>();\n for (const csq of csqConditions) {\n aliases.add(csq.related.subquery.alias || '');\n for (const key of csq.related.correlation.parentField) {\n splitEditKeys.add(key);\n }\n }\n if (ast.related) {\n for (const csq of ast.related) {\n for (const key of csq.correlation.parentField) {\n splitEditKeys.add(key);\n }\n }\n }\n if (isNonFlippedExistsChild) {\n assert(ast.start === undefined, 'EXISTS subqueries must not have start');\n assert(\n ast.related === undefined,\n 'EXISTS subqueries must not have related',\n );\n }\n\n // The Cap optimization needs the source connect to be unordered, but\n // applyFilterWithFlips builds a UnionFanIn over the source whenever\n // ast.where contains a flipped subquery, and UnionFanIn requires a\n // sort on its inputs. In that case, fall back to the ordered + Take\n // path for this EXISTS child.\n const useCap =\n isNonFlippedExistsChild &&\n !(ast.where && conditionIncludesFlippedSubqueryAtAnyLevel(ast.where));\n\n const conn = source.connect(\n // exists pipelines are unordered — orderBy is ignored here.\n // Non-exists pipelines always have orderBy completed with PKs.\n useCap ? undefined : must(ast.orderBy),\n ast.where,\n splitEditKeys,\n delegate.debug,\n );\n\n let end: Input = delegate.decorateSourceInput(conn, queryID);\n end = delegate.decorateInput(end, `${name}:source(${ast.table})`);\n const {fullyAppliedFilters} = conn;\n\n if (ast.start) {\n const skip = new Skip(end, ast.start);\n delegate.addEdge(end, skip);\n end = delegate.decorateInput(skip, `${name}:skip)`);\n }\n\n let takeGate: TakeGate | undefined;\n if (ast.limit !== undefined && !useCap) {\n const takeGateName = `${name}:take-gate`;\n takeGate = new TakeGate(end);\n delegate.addEdge(end, takeGate);\n end = delegate.decorateInput(takeGate, takeGateName);\n }\n\n // The parent indexes of the EXISTS joins below. They hold the rows this\n // pipeline emits, which the JoinIndexTap after the limit maintains.\n const existsParentIndexes: JoinIndex[] = [];\n for (const csqCondition of csqConditions) {\n // flipped EXISTS are handled in applyWhere\n if (!csqCondition.flip) {\n const parentIndex = new JoinIndex(\n csqCondition.related.correlation.parentField,\n end.getSchema().primaryKey,\n );\n existsParentIndexes.push(parentIndex);\n end = applyCorrelatedSubQuery(\n {\n ...csqCondition.related,\n subquery: {\n ...csqCondition.related.subquery,\n limit:\n csqCondition.related.system === 'permissions'\n ? PERMISSIONS_EXISTS_LIMIT\n : EXISTS_LIMIT,\n },\n },\n delegate,\n queryID,\n end,\n name,\n true,\n undefined,\n takeGate,\n {op: csqCondition.op, parentIndex},\n );\n }\n }\n\n if (ast.where && (!fullyAppliedFilters || delegate.applyFiltersAnyway)) {\n end = applyWhere(\n end,\n ast.where,\n delegate,\n name,\n partitionKey,\n takeGate,\n existsParentIndexes,\n );\n }\n\n if (ast.limit !== undefined) {\n // We end `exists` pipelines with `cap`\n // The reason is that `cap` does not care about the order of the pipeline.\n // This allows SQLite to chose the order and never end up creating temp b-trees.\n // The problem with SQLite creating a temp b-tree is it will incur a scan of the entire\n // result set where exists only needs the first row.\n if (useCap) {\n const capName = `${name}:cap`;\n const cap = new Cap(\n end,\n delegate.createStorage(capName),\n ast.limit,\n partitionKey,\n );\n delegate.addEdge(end, cap);\n end = delegate.decorateInput(cap, capName);\n } else {\n const takeName = `${name}:take`;\n const take = new Take(\n end,\n delegate.createStorage(takeName),\n ast.limit,\n partitionKey,\n );\n delegate.addEdge(end, take);\n end = delegate.decorateInput(take, takeName);\n takeGate?.setBoundProvider(take);\n if (takeGate) {\n take.setTakeGate(takeGate);\n }\n }\n }\n\n if (existsParentIndexes.length > 0) {\n const tapName = `${name}:join-index`;\n const tap = new JoinIndexTap(end, existsParentIndexes);\n delegate.addEdge(end, tap);\n end = delegate.decorateInput(tap, tapName);\n }\n\n if (ast.groupBy) {\n // A grouping, compute mode (server / local): a distinct is a GroupBy with\n // a count, which a view doesn't show. The synced client reads the rows\n // from the synthetic source instead (see groupFromSource). As for a count\n // below, a source that applies every filter can count the groups without\n // the rows being read.\n assert(\n ast.start === undefined &&\n ast.limit === undefined &&\n ast.related === undefined,\n 'groupBy does not support start, limit or related',\n );\n const sourceAppliesAll =\n csqConditions.length === 0 &&\n (!ast.where || (fullyAppliedFilters && !delegate.applyFiltersAnyway));\n const groupName = `${name}:groupBy`;\n const groupBy = new GroupBy(\n end,\n delegate.createStorage(groupName),\n groupOrdering(ast),\n groupTableName(queryID),\n reducerOf(ast),\n sourceAppliesAll ? conn : undefined,\n );\n delegate.addEdge(end, groupBy);\n return delegate.decorateInput(groupBy, groupName);\n }\n\n if (ast.aggregate) {\n // Top-level (ungrouped) aggregate, compute mode (server / local): the\n // Aggregate operator reduces the rows that survive `where`, `start` and\n // `limit` to one synthetic row emitted to `aggregate:<queryID>`, so\n // `limit(10).count()` counts at most 10 rows, as in SQL. `related` does not\n // apply to a scalar result. (The synced client takes the\n // aggregatesFromSource short-circuit at the top of this function instead.)\n //\n // When the source applies every filter and nothing else sits between it\n // and the Aggregate (no `start`, `limit` or EXISTS join), the source's\n // rows are exactly the rows to reduce, so a `count` can ask it for the\n // number rather than reading them all.\n const sourceAppliesAll =\n ast.start === undefined &&\n ast.limit === undefined &&\n csqConditions.length === 0 &&\n (!ast.where || (fullyAppliedFilters && !delegate.applyFiltersAnyway));\n let countSource: SourceInput | undefined = conn;\n if (ast.aggregate.distinct) {\n // A count of the distinct combinations counts the groups of a GroupBy,\n // which gets the source's groups instead (see GroupBy). Its input is\n // in the group's order, not the one a bound would be taken in.\n assert(\n ast.start === undefined && ast.limit === undefined,\n 'a count of distinct values does not support start or limit',\n );\n const groupName = `${name}:groupBy`;\n const groupBy = new GroupBy(\n end,\n delegate.createStorage(groupName),\n groupOrdering(ast),\n groupTableName(queryID),\n new Reducer('count', undefined, undefined),\n sourceAppliesAll ? conn : undefined,\n );\n delegate.addEdge(end, groupBy);\n end = delegate.decorateInput(groupBy, groupName);\n countSource = undefined;\n }\n const aggName = `${name}:aggregate`;\n const aggregate = new Aggregate(\n end,\n delegate.createStorage(aggName),\n [], // ungrouped — one global group\n ast.aggregate.fn,\n ast.aggregate.field,\n topLevelAggregateTableName(queryID),\n sourceAppliesAll ? countSource : undefined,\n ast.aggregate.path,\n );\n delegate.addEdge(end, aggregate);\n return delegate.decorateInput(aggregate, aggName);\n }\n\n if (ast.related) {\n // Dedupe by alias - last one wins (LWW), like limit(5).limit(10)\n const byAlias = new Map<string, CorrelatedSubquery>();\n for (const csq of ast.related) {\n byAlias.set(csq.subquery.alias ?? '', csq);\n }\n for (const csq of byAlias.values()) {\n end = applyCorrelatedSubQuery(\n csq,\n delegate,\n queryID,\n end,\n name,\n false,\n partitionKey,\n );\n }\n }\n\n return end;\n}\n\nfunction applyWhere(\n input: Input,\n condition: Condition,\n delegate: BuilderDelegate,\n name: string,\n parentPartitionKey?: CompoundKey,\n boundProvider?: TakeBoundProvider,\n existsParentIndexes?: JoinIndex[],\n): Input {\n if (!conditionIncludesFlippedSubqueryAtAnyLevel(condition)) {\n return buildFilterPipeline(\n input,\n delegate,\n filterInput => applyFilter(filterInput, condition, delegate, name),\n transformFilters(condition).filters,\n );\n }\n\n return applyFilterWithFlips(\n input,\n condition,\n delegate,\n name,\n parentPartitionKey,\n boundProvider,\n existsParentIndexes,\n );\n}\n\nfunction applyFilterWithFlips(\n input: Input,\n condition: Condition,\n delegate: BuilderDelegate,\n name: string,\n parentPartitionKey?: CompoundKey,\n boundProvider?: TakeBoundProvider,\n existsParentIndexes?: JoinIndex[],\n): Input {\n let end = input;\n assert(condition.type !== 'simple', 'Simple conditions cannot have flips');\n\n switch (condition.type) {\n case 'and': {\n const [withFlipped, withoutFlipped] = partitionBranches(\n condition.conditions,\n conditionIncludesFlippedSubqueryAtAnyLevel,\n );\n if (withoutFlipped.length > 0) {\n const andCondition: Conjunction = {\n type: 'and',\n conditions: withoutFlipped,\n };\n end = buildFilterPipeline(\n input,\n delegate,\n filterInput => applyAnd(filterInput, andCondition, delegate, name),\n transformFilters(andCondition).filters,\n );\n }\n assert(withFlipped.length > 0, 'Impossible to have no flips here');\n for (const cond of withFlipped) {\n end = applyFilterWithFlips(\n end,\n cond,\n delegate,\n name,\n parentPartitionKey,\n boundProvider,\n existsParentIndexes,\n );\n }\n break;\n }\n case 'or': {\n const [withFlipped, withoutFlipped] = partitionBranches(\n condition.conditions,\n conditionIncludesFlippedSubqueryAtAnyLevel,\n );\n assert(withFlipped.length > 0, 'Impossible to have no flips here');\n\n const ufo = new UnionFanOut(end);\n delegate.addEdge(end, ufo);\n end = delegate.decorateInput(ufo, `${name}:ufo`);\n\n const branches: Input[] = [];\n if (withoutFlipped.length > 0) {\n const orCondition: Disjunction = {\n type: 'or',\n conditions: withoutFlipped,\n };\n branches.push(\n buildFilterPipeline(\n end,\n delegate,\n filterInput => applyOr(filterInput, orCondition, delegate, name),\n transformFilters(orCondition).filters,\n ),\n );\n }\n\n for (const cond of withFlipped) {\n branches.push(\n applyFilterWithFlips(\n end,\n cond,\n delegate,\n name,\n parentPartitionKey,\n boundProvider,\n existsParentIndexes,\n ),\n );\n }\n\n const ufi = new UnionFanIn(ufo, branches);\n for (const branch of branches) {\n delegate.addEdge(branch, ufi);\n }\n end = delegate.decorateInput(ufi, `${name}:ufi`);\n\n break;\n }\n case 'correlatedSubquery': {\n const sq = condition.related;\n const child = buildPipelineInternal(\n sq.subquery,\n delegate,\n '',\n childPipelineName(name, sq),\n sq.correlation.childField,\n false,\n );\n let parentIndex: JoinIndex | undefined;\n if (existsParentIndexes) {\n parentIndex = new JoinIndex(\n sq.correlation.parentField,\n end.getSchema().primaryKey,\n parentPartitionKey,\n );\n existsParentIndexes.push(parentIndex);\n }\n const flippedJoinName = `${name}:flipped-join(${sq.subquery.alias})`;\n const flippedJoin = new FlippedJoin({\n parent: end,\n child,\n parentKey: sq.correlation.parentField,\n childKey: sq.correlation.childField,\n relationshipName: must(\n sq.subquery.alias,\n 'Subquery must have an alias',\n ),\n hidden: sq.hidden ?? false,\n system: sq.system ?? 'client',\n parentPartitionKey,\n boundProvider,\n parentIndex,\n });\n delegate.addEdge(end, flippedJoin);\n delegate.addEdge(child, flippedJoin);\n end = delegate.decorateInput(flippedJoin, flippedJoinName);\n break;\n }\n }\n\n return end;\n}\n\nfunction applyFilter(\n input: FilterInput,\n condition: Condition,\n delegate: BuilderDelegate,\n name: string,\n): FilterInput {\n switch (condition.type) {\n case 'and':\n return applyAnd(input, condition, delegate, name);\n case 'or':\n return applyOr(input, condition, delegate, name);\n case 'correlatedSubquery':\n return applyCorrelatedSubqueryCondition(input, condition, delegate, name);\n case 'simple':\n return applySimpleCondition(input, delegate, condition);\n }\n}\n\nfunction applyAnd(\n input: FilterInput,\n condition: Conjunction,\n delegate: BuilderDelegate,\n name: string,\n): FilterInput {\n for (const subCondition of condition.conditions) {\n input = applyFilter(input, subCondition, delegate, name);\n }\n return input;\n}\n\nfunction applyOr(\n input: FilterInput,\n condition: Disjunction,\n delegate: BuilderDelegate,\n name: string,\n): FilterInput {\n const [subqueryConditions, otherConditions] =\n groupSubqueryConditions(condition);\n // if there are no subquery conditions, no fan-in / fan-out is needed\n if (subqueryConditions.length === 0) {\n const filter = new Filter(\n input,\n createPredicate({\n type: 'or',\n conditions: otherConditions,\n }),\n );\n delegate.addEdge(input, filter);\n return filter;\n }\n\n const fanOut = new FanOut(input);\n delegate.addEdge(input, fanOut);\n const branches = subqueryConditions.map(subCondition =>\n applyFilter(fanOut, subCondition, delegate, name),\n );\n if (otherConditions.length > 0) {\n const filter = new Filter(\n fanOut,\n createPredicate({\n type: 'or',\n conditions: otherConditions,\n }),\n );\n delegate.addEdge(fanOut, filter);\n branches.push(filter);\n }\n const ret = new FanIn(fanOut, branches);\n for (const branch of branches) {\n delegate.addEdge(branch, ret);\n }\n fanOut.setFanIn(ret);\n return ret;\n}\n\nexport function groupSubqueryConditions(condition: Disjunction) {\n const partitioned: [\n subqueryConditions: Condition[],\n otherConditions: NoSubqueryCondition[],\n ] = [[], []];\n for (const subCondition of condition.conditions) {\n if (isNotAndDoesNotContainSubquery(subCondition)) {\n partitioned[1].push(subCondition);\n } else {\n partitioned[0].push(subCondition);\n }\n }\n return partitioned;\n}\n\nfunction isNotAndDoesNotContainSubquery(\n condition: Condition,\n): condition is NoSubqueryCondition {\n if (condition.type === 'correlatedSubquery') {\n return false;\n }\n if (condition.type === 'simple') {\n return true;\n }\n return condition.conditions.every(isNotAndDoesNotContainSubquery);\n}\n\nfunction applySimpleCondition(\n input: FilterInput,\n delegate: BuilderDelegate,\n condition: SimpleCondition,\n): FilterInput {\n const filter = new Filter(input, createPredicate(condition));\n delegate.decorateFilterInput(\n filter,\n `${valuePosName(condition.left)}:${condition.op}:${valuePosName(condition.right)}`,\n );\n delegate.addEdge(input, filter);\n return filter;\n}\n\nfunction valuePosName(left: ValuePosition) {\n switch (left.type) {\n case 'static':\n return left.field;\n case 'literal':\n return left.value;\n case 'column':\n return left.name;\n case 'json':\n return formatJsonPathReference(left);\n default:\n unreachable(left);\n }\n}\n\nfunction applyCorrelatedSubQuery(\n sq: CorrelatedSubquery,\n delegate: BuilderDelegate,\n queryID: string,\n end: Input,\n name: string,\n fromCondition: boolean,\n parentPartitionKey?: CompoundKey,\n boundProvider?: TakeBoundProvider,\n exists?: ExistsJoin,\n) {\n // TODO: we only omit the join if the CSQ if from a condition since\n // we want to create an empty array for `related` fields that are `limit(0)`\n if (sq.subquery.limit === 0 && fromCondition) {\n return end;\n }\n\n assert(sq.subquery.alias, 'Subquery must have an alias');\n\n // An `aggregate` relationship (count/sum/avg/min/max).\n //\n // The Join below is unchanged regardless of mode: the aggregate \"child\" emits\n // a single synthetic row per parent carrying the correlation key, so Join\n // routes by childField as usual.\n //\n // Two modes (see BuilderDelegate.aggregatesFromSource):\n // - compute (server / single-process client): an Aggregate operator reduces\n // the child rows. It consumes them, so the children never flow downstream\n // (i.e. never sync). Its output rows are routed to a synthetic table.\n // - source (synced client): the children are not present at all; read the\n // pre-computed results from the synthetic aggregate source.\n let childInput: Input;\n // The columns the child input is keyed by for the join. For a synced\n // aggregate these are the names the server streams the rows with.\n let childKey = sq.correlation.childField;\n if (sq.aggregate) {\n assert(\n sq.aggregate.distinct === undefined,\n 'a count of distinct values is not supported in a relationship yet',\n );\n const aggTable = aggregateTableName(queryID, sq, name);\n if (delegate.aggregatesFromSource) {\n childKey =\n delegate.aggregateKeyColumns?.(\n sq.subquery.table,\n sq.correlation.childField,\n ) ?? sq.correlation.childField;\n // The server builds its operator with these names and rejects a\n // collision there; check here too so the client fails the same way.\n for (const col of childKey) {\n assertNotSyntheticColumn(col);\n }\n // Always go through getAggregateSource when the delegate has one, even\n // if the source already exists: on reload it is provisioned from the\n // persisted rows before the query materializes (see IVMSourceBranch\n // applyDiffs), and this call is what registers the optimistic-delta\n // metadata. The delegate hands back the existing source in that case.\n let source: Source | undefined;\n if (delegate.getAggregateSource) {\n // The synthetic source isn't a schema table; provision it from the\n // child's column types + the aggregate fn/field so the synced rows have\n // a correctly-shaped place to land (key = correlation child field).\n const childSource = delegate.getSource(sq.subquery.table);\n if (!childSource) {\n throw new Error(`Source not found: ${sq.subquery.table}`);\n }\n // For a junction (many-to-many) aggregate the key lives on the junction\n // table but the aggregated field lives on the destination one hop past\n // it — so merge the destination's columns in for the value-type lookup.\n let inputColumns = childSource.tableSchema.columns;\n const isJunction = !!(\n sq.subquery.related && sq.subquery.related.length\n );\n if (isJunction) {\n const destTable = must(sq.subquery.related)[0].subquery.table;\n const destSource = delegate.getSource(destTable);\n if (!destSource) {\n throw new Error(`Source not found: ${destTable}`);\n }\n inputColumns = {\n ...childSource.tableSchema.columns,\n ...destSource.tableSchema.columns,\n };\n }\n const {columns: clientColumns} = aggregateSourceSchema(\n inputColumns,\n sq.correlation.childField,\n sq.aggregate.fn,\n sq.aggregate.field,\n sq.aggregate.path,\n );\n const columns = renameColumns(\n clientColumns,\n sq.correlation.childField,\n childKey,\n );\n const {fn} = sq.aggregate;\n const invertible = isInvertible(fn);\n // A `where` is honored optimistically by compiling it to a per-row\n // predicate, but only when fully per-row evaluable. A correlated\n // subquery in the `where` can't be judged from a single child row, so\n // `transformFilters` flags it (`conditionsRemoved`) and the aggregate\n // stays server-authoritative rather than risk over-counting.\n let whereEvaluable = true;\n let wherePredicate: ((row: Row) => boolean) | undefined;\n if (!isJunction && invertible && sq.subquery.where !== undefined) {\n const {filters, conditionsRemoved} = transformFilters(\n sq.subquery.where,\n );\n if (conditionsRemoved || filters === undefined) {\n whereEvaluable = false;\n } else {\n wherePredicate = createPredicate(filters);\n }\n }\n source = delegate.getAggregateSource(\n aggTable,\n columns,\n childKey,\n // Optimistic deltas are only safe for invertible, direct\n // (non-junction) aggregates: `count` (±1), `sum`/`avg` (±field) per\n // child add/remove. `min`/`max` aren't invertible, and a junction's\n // field lives past the junction (an edge mutation doesn't carry it) —\n // both fall back to the server-authoritative value, as does a `where`\n // that isn't per-row evaluable (see above) and a bounded subquery\n // (`limit`/`start`), where whether a child counts depends on its\n // siblings.\n !isJunction &&\n invertible &&\n whereEvaluable &&\n sq.subquery.limit === undefined &&\n sq.subquery.start === undefined\n ? {\n table: sq.subquery.table,\n childField: sq.correlation.childField,\n keyField: childKey,\n fn,\n field: sq.aggregate.field,\n path: sq.aggregate.path,\n predicate: wherePredicate,\n }\n : undefined,\n );\n } else {\n source = delegate.getSource(aggTable);\n }\n if (!source) {\n throw new Error(`Aggregate source not found: ${aggTable}`);\n }\n const conn = source.connect(childKey.map(f => [f, 'asc'] as const));\n childInput = delegate.decorateSourceInput(conn, queryID);\n childInput = delegate.decorateInput(\n childInput,\n `${name}:aggregateSource(${sq.subquery.alias})`,\n );\n } else {\n const child = buildPipelineInternal(\n sq.subquery,\n delegate,\n queryID,\n childPipelineName(name, sq),\n sq.correlation.childField,\n fromCondition,\n );\n const aggName = `${name}:aggregate(${sq.subquery.alias})`;\n\n // Junction (many-to-many) aggregate: the subquery is the junction table\n // with a related() to the destination, and the aggregated field lives on\n // that destination. Lift the field onto the junction row so the Aggregate\n // (which reads a flat field) collapses it as a single hop. `count` never\n // takes this path — it's collapsed to a plain count over the junction.\n let aggInput = child;\n let aggField = sq.aggregate.field;\n // A JSON path is read by the Aggregate itself, or, for a junction, by the\n // LiftField, which then lifts just the leaf.\n let aggPath = sq.aggregate.path;\n if (sq.subquery.related && sq.subquery.related.length > 0) {\n const destAlias = must(sq.subquery.related[0].subquery.alias);\n const lift = new LiftField(\n child,\n destAlias,\n must(sq.aggregate.field),\n aggPath === undefined ? undefined : sq.aggregate,\n );\n delegate.addEdge(child, lift);\n aggInput = lift;\n aggField = LIFTED_FIELD_COLUMN;\n aggPath = undefined;\n }\n\n const aggregate = new Aggregate(\n aggInput,\n delegate.createStorage(aggName),\n sq.correlation.childField,\n sq.aggregate.fn,\n aggField,\n aggTable,\n undefined,\n aggPath,\n );\n delegate.addEdge(aggInput, aggregate);\n childInput = delegate.decorateInput(aggregate, aggName);\n }\n } else {\n childInput = buildPipelineInternal(\n sq.subquery,\n delegate,\n queryID,\n childPipelineName(name, sq),\n sq.correlation.childField,\n fromCondition,\n );\n }\n\n const joinName = `${name}:join(${sq.subquery.alias})`;\n const join = new Join({\n parent: end,\n child: childInput,\n parentKey: sq.correlation.parentField,\n childKey,\n relationshipName: sq.subquery.alias,\n hidden: sq.hidden ?? false,\n system: sq.system ?? 'client',\n parentPartitionKey: fromCondition ? undefined : parentPartitionKey,\n boundProvider,\n exists,\n });\n delegate.addEdge(end, join);\n delegate.addEdge(childInput, join);\n return delegate.decorateInput(join, joinName);\n}\n\nfunction applyCorrelatedSubqueryCondition(\n input: FilterInput,\n condition: CorrelatedSubqueryCondition,\n delegate: BuilderDelegate,\n name: string,\n): FilterInput {\n assert(\n condition.op === 'EXISTS' || condition.op === 'NOT EXISTS',\n 'Expected EXISTS or NOT EXISTS operator',\n );\n if (condition.related.subquery.limit === 0) {\n if (condition.op === 'EXISTS') {\n const filter = new Filter(input, () => false);\n delegate.addEdge(input, filter);\n return filter;\n }\n const filter = new Filter(input, () => true);\n delegate.addEdge(input, filter);\n return filter;\n }\n const existsName = `${name}:exists(${condition.related.subquery.alias})`;\n const exists = new Exists(\n input,\n must(condition.related.subquery.alias),\n condition.related.correlation.parentField,\n condition.op,\n );\n delegate.addEdge(input, exists);\n return delegate.decorateFilterInput(exists, existsName);\n}\n\nfunction gatherCorrelatedSubqueryQueryConditions(\n condition: Condition | undefined,\n) {\n const csqs: CorrelatedSubqueryCondition[] = [];\n const gather = (condition: Condition) => {\n if (condition.type === 'correlatedSubquery') {\n csqs.push(condition);\n return;\n }\n if (condition.type === 'and' || condition.type === 'or') {\n for (const c of condition.conditions) {\n gather(c);\n }\n return;\n }\n };\n if (condition) {\n gather(condition);\n }\n return csqs;\n}\n\n/** `columns` with each of `from` renamed to the name at its index in `to`. */\nfunction renameColumns(\n columns: Record<string, SchemaValue>,\n from: CompoundKey,\n to: CompoundKey,\n): Record<string, SchemaValue> {\n const renamed: Record<string, SchemaValue> = {};\n for (const [name, schema] of Object.entries(columns)) {\n const i = from.indexOf(name);\n assignProperty(renamed, i === -1 ? name : to[i], schema);\n }\n return renamed;\n}\n\n/**\n * What the synced client needs to optimistically update a relationship\n * aggregate when one of its child rows is mutated locally.\n */\nexport type AggregateOptimisticDelta = {\n /** The child table whose mutations move the aggregate. */\n readonly table: string;\n /** The correlation columns of a child row, as the client names them. */\n readonly childField: CompoundKey;\n /**\n * The same columns as the aggregate rows name them (see\n * {@link BuilderDelegate.aggregateKeyColumns}), in the same order.\n */\n readonly keyField: CompoundKey;\n readonly fn: AggregateFunction;\n readonly field: string | undefined;\n /** A JSON path into `field` (see `Aggregate.path`). */\n readonly path?: readonly (string | number)[] | undefined;\n /**\n * The child `where` compiled to a per-row predicate, or `undefined` when the\n * aggregate has no `where` (every child contributes).\n */\n readonly predicate: ((row: Row) => boolean) | undefined;\n /**\n * The aggregate rows are the groups of a grouped query (a `distinct()` or a\n * `groupBy()`) rather than one per parent: keyed by `_0_key`, which a row's\n * values of `childField` give, `null` included. A group is added with its\n * first row and removed with its last (a sum/avg row carries its row count\n * for that).\n */\n readonly grouped?: boolean | undefined;\n};\n\n/**\n * Deterministic synthetic table name for an `aggregate` relationship. Must\n * agree between the server (which produces the rows) and the synced client\n * (which reads them). It folds in the `queryID` — the client query hash, which\n * both sides share and which already distinguishes differently-filtered queries\n * — and the relationship's alias path from the root, so two aggregates never\n * collide, even ones with the same alias at different depths.\n *\n * @param parentName The pipeline name of the parent, which the builder forms\n * from the aliases of the relationships leading to it (`''` at the\n * root, `'.comments'` one level down). It is the same on both sides.\n */\nexport function aggregateTableName(\n queryID: string,\n sq: CorrelatedSubquery,\n parentName = '',\n): string {\n const path = childPipelineName(parentName, sq).slice(1);\n return `${AGGREGATE_TABLE_PREFIX}${queryID}${AGGREGATE_TABLE_SEPARATOR}${path}`;\n}\n\n/**\n * The pipeline name of the child `sq` under the pipeline `name`: the parent's\n * name, a `.`, and the escaped alias. A relationship name can be any string, so\n * the alias is escaped to keep the `.`-joined path unambiguous and free of the\n * `/` and `:` that {@link aggregateTableName} must not contain.\n */\nfunction childPipelineName(name: string, sq: CorrelatedSubquery): string {\n const alias = encodeURIComponent(sq.subquery.alias ?? '').replaceAll(\n '.',\n '%2E',\n );\n return `${name}.${alias}`;\n}\n\n/**\n * Deterministic synthetic table name for a *top-level* (ungrouped) aggregate\n * query (e.g. `z.query.issue.count()`). There is no relationship alias, so the\n * name is just the prefix + `queryID` (`aggregate:<queryID>`). Distinct from\n * relationship-aggregate names (`aggregate:<queryID>:<alias>`), which always\n * carry an alias segment — which is how the client tells the two apart by name.\n */\nexport function topLevelAggregateTableName(queryID: string): string {\n return `${AGGREGATE_TABLE_PREFIX}${queryID}`;\n}\n\n/**\n * The synthetic table of a grouped query's rows (a `distinct()` or a\n * `groupBy()`): `aggregate:<queryID>:` and a `#`, which an escaped\n * relationship alias never contains, so it can't be a relationship\n * aggregate's, and isn't a top-level aggregate's either, whose shape the\n * client derives from the name.\n */\nexport function groupTableName(queryID: string): string {\n return `${AGGREGATE_TABLE_PREFIX}${queryID}${GROUP_TABLE_SUFFIX}`;\n}\n\nconst GROUP_TABLE_SUFFIX = `${AGGREGATE_TABLE_SEPARATOR}#group`;\n\n/** What a grouped query reduces each group to: its aggregate, or a count. */\nfunction reducerOf(ast: AST): Reducer {\n const {aggregate} = ast;\n return aggregate\n ? new Reducer(aggregate.fn, aggregate.field, aggregate.path)\n : new Reducer('count', undefined, undefined);\n}\n\n/**\n * The names a grouped query's input rows have `columns` under: the query's\n * own, or, for a synced client reading them from the synthetic source, the\n * server's.\n */\nfunction inputNames(\n ast: AST,\n delegate: BuilderDelegate,\n columns: readonly string[],\n): readonly string[] {\n return delegate.aggregatesFromSource && delegate.aggregateKeyColumns\n ? delegate.aggregateKeyColumns(ast.table, columns as unknown as CompoundKey)\n : columns;\n}\n\n/**\n * A synced client reads a grouped query's rows from the synthetic source the\n * server streams them to; the table's rows are not synced for it.\n */\nfunction groupFromSource(\n ast: AST,\n delegate: BuilderDelegate,\n queryID: string,\n name: string,\n): Input {\n const tableSource = must(\n delegate.getSource(ast.table),\n `Source not found: ${ast.table}`,\n );\n const reducer = reducerOf(ast);\n // The group columns and the aggregated field, under the server's names.\n const columns = [...must(ast.groupBy)];\n if (reducer.field !== undefined && !columns.includes(reducer.field)) {\n columns.push(reducer.field);\n }\n const names = inputNames(ast, delegate, columns);\n const inputName = (col: string) => names[columns.indexOf(col)];\n const inputColumns: Record<string, SchemaValue> = {};\n for (const col of columns) {\n assignProperty(\n inputColumns,\n inputName(col),\n tableSource.tableSchema.columns[col],\n );\n }\n const {\n columns: sourceColumns,\n primaryKey,\n sort,\n } = groupSourceSchema(\n inputColumns,\n groupOrdering(ast).map(([col, dir]) => [inputName(col), dir] as const),\n {\n fn: reducer.fn,\n field: reducer.field === undefined ? undefined : inputName(reducer.field),\n path: reducer.path,\n },\n );\n const table = groupTableName(queryID);\n const source = delegate.getAggregateSource\n ? delegate.getAggregateSource(\n table,\n sourceColumns,\n primaryKey,\n groupOptimisticDelta(ast, reducer, inputName),\n )\n : delegate.getSource(table);\n if (!source) {\n throw new Error(`Group source not found: ${table}`);\n }\n return delegate.decorateInput(\n delegate.decorateSourceInput(source.connect(sort), queryID),\n `${name}:groupSource`,\n );\n}\n\n/**\n * What the synced client needs to move a grouped query's rows when it mutates\n * a row of its table, so that a mutator reads its own writes and a view shows\n * them before the server answers. As for a relationship aggregate, only for\n * the invertible functions, and only when the `where` can be judged from the\n * row alone: otherwise the rows are server-authoritative.\n */\nfunction groupOptimisticDelta(\n ast: AST,\n reducer: Reducer,\n inputName: (col: string) => string,\n): AggregateOptimisticDelta | undefined {\n if (!isInvertible(reducer.fn)) {\n return undefined;\n }\n let predicate: ((row: Row) => boolean) | undefined;\n if (ast.where !== undefined) {\n const {filters, conditionsRemoved} = transformFilters(ast.where);\n if (conditionsRemoved || filters === undefined) {\n return undefined;\n }\n predicate = createPredicate(filters);\n }\n // In the order of the group, which the server's GroupBy keys a row by.\n const columns = groupOrdering(ast).map(\n ([col]) => col,\n ) as unknown as CompoundKey;\n return {\n table: ast.table,\n childField: columns,\n keyField: columns.map(inputName) as unknown as CompoundKey,\n fn: reducer.fn,\n field: reducer.field,\n path: ast.aggregate?.path,\n predicate,\n grouped: true,\n };\n}\n\n/**\n * The input of a view of a grouped query: its rows reduced to the group\n * columns, and for a `groupBy()` its value under the aggregate function's\n * name, under the names the view shows a row's columns by, those of the\n * pipeline's AST (see {@link GroupProjection}).\n */\nexport function groupViewInput(\n input: Input,\n ast: AST,\n delegate: BuilderDelegate,\n): Input {\n const viewNames = must(\n (delegate.mapAst ? delegate.mapAst(ast) : ast).groupBy,\n );\n const names = delegate.aggregatesFromSource\n ? inputNames(ast, delegate, must(ast.groupBy))\n : viewNames;\n return new GroupProjection(\n input,\n viewNames.map((col, i) => [col, names[i]] as const),\n ast.aggregate?.fn,\n );\n}\n\n/** True if `name` is a synthetic aggregate table (any kind). */\nexport function isAggregateTableName(name: string): boolean {\n return name.startsWith(AGGREGATE_TABLE_PREFIX);\n}\n\n/**\n * True if `name` is a *top-level* aggregate table (`aggregate:<queryID>`), as\n * opposed to a relationship one (`aggregate:<queryID>:<alias>`). Top-level names\n * have no further separator after the prefix. The client uses this to recognize\n * a synthetic source it can provision from the name alone (fixed key + value\n * shape), which relationship aggregates — needing the correlation key — cannot.\n */\nexport function isTopLevelAggregateTableName(name: string): boolean {\n return (\n name.startsWith(AGGREGATE_TABLE_PREFIX) &&\n !name\n .slice(AGGREGATE_TABLE_PREFIX.length)\n .includes(AGGREGATE_TABLE_SEPARATOR)\n );\n}\n\n/**\n * True if the rows of the synthetic table `name` are keyed by `_0_key`\n * alone: a top-level aggregate's ({@link topLevelAggregateTableName}) or a\n * grouped query's ({@link groupTableName}). A relationship aggregate's rows\n * are keyed by their correlation columns, whatever they are named.\n */\nexport function isKeyedAggregateTableName(name: string): boolean {\n return (\n isTopLevelAggregateTableName(name) ||\n (name.startsWith(AGGREGATE_TABLE_PREFIX) &&\n name.endsWith(GROUP_TABLE_SUFFIX))\n );\n}\n\nfunction uniquifyCorrelatedSubqueryConditionAliases(ast: AST): AST {\n if (!ast.where) {\n return ast;\n }\n const {where} = ast;\n if (where.type !== 'and' && where.type !== 'or') {\n return ast;\n }\n\n let count = 0;\n const uniquifyCorrelatedSubquery = (csqc: CorrelatedSubqueryCondition) => ({\n ...csqc,\n related: {\n ...csqc.related,\n subquery: {\n ...csqc.related.subquery,\n alias: (csqc.related.subquery.alias ?? '') + '_' + count++,\n },\n },\n });\n\n const uniquify = (cond: Condition): Condition => {\n if (cond.type === 'simple') {\n return cond;\n } else if (cond.type === 'correlatedSubquery') {\n return uniquifyCorrelatedSubquery(cond);\n }\n const conditions = [];\n for (const c of cond.conditions) {\n conditions.push(uniquify(c));\n }\n return {\n type: cond.type,\n conditions,\n };\n };\n\n const result = {\n ...ast,\n where: uniquify(where),\n };\n return result;\n}\n\nexport function conditionIncludesFlippedSubqueryAtAnyLevel(\n cond: Condition,\n): boolean {\n if (cond.type === 'correlatedSubquery') {\n return !!cond.flip;\n }\n if (cond.type === 'and' || cond.type === 'or') {\n return cond.conditions.some(c =>\n conditionIncludesFlippedSubqueryAtAnyLevel(c),\n );\n }\n // simple conditions don't have flips\n return false;\n}\n\nexport function partitionBranches(\n conditions: readonly Condition[],\n predicate: (c: Condition) => boolean,\n) {\n const matched: Condition[] = [];\n const notMatched: Condition[] = [];\n for (const c of conditions) {\n if (predicate(c)) {\n matched.push(c);\n } else {\n notMatched.push(c);\n }\n }\n return [matched, notMatched] as const;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"correlated-predicate-pushdown.js","names":[],"sources":["../../../../../zql/src/builder/correlated-predicate-pushdown.ts"],"sourcesContent":["import {deepEqual} from '../../../shared/src/json.ts';\nimport type {\n AST,\n Condition,\n Conjunction,\n CorrelatedSubquery,\n SimpleCondition,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {SchemaValue} from '../../../zero-types/src/schema-value.ts';\nimport {simplifyCondition} from '../query/expression.ts';\n\n/**\n * The longest `IN` list that is copied into a child. `IN` compiles to\n * `IN (SELECT value FROM json_each(?))`, and every per-parent fetch of the\n * child carries the whole list.\n */\nexport const MAX_PUSHED_IN_VALUES = 32;\n\ntype ColumnCondition = SimpleCondition & {\n readonly left: {readonly type: 'column'; readonly name: string};\n};\n\n/**\n * Copies a parent's condition on a correlation column into the child\n * subquery, renamed to the matching child column. For example,\n * `user.where('user_id', X).related('reading')` becomes\n * `user.where('user_id', X).related('reading', r => r.where('user_id', X))`.\n *\n * The result is the same. Only child rows that cannot join to a parent that\n * matters are removed. But a push that climbs the tree then fetches parents\n * with SQL that includes the ancestor's condition, and a change to a child row\n * that cannot match stops at the child's source.\n *\n * Conditions are copied only when they are true for every parent row where\n * the edge can affect the result:\n * - for `related`, the top-level AND conjuncts of the parent's `where`;\n * - for EXISTS and NOT EXISTS, the conjuncts of every AND on the path from\n * the root of `where` to the subquery condition. An OR adds no facts.\n *\n * A condition is copied when it is `column = literal`, `column IS literal`, or\n * `column IN literal-list` (at most {@link MAX_PUSHED_IN_VALUES} values), the\n * column is a `parentField` of the correlation, and the parent and child\n * columns have the same Zero type, which is not `json`.\n *\n * A condition is not copied when the child already has the same condition as\n * a conjunct. So the pass does not change an AST that it already pushed.\n *\n * Does not change its input. Returns the same object for every part of the\n * AST that it does not change.\n *\n * @param pushed When given, receives each child conjunct that is a copy of a\n * parent condition: the copies that the pass adds, and the child's own\n * conjuncts that equal a copy. The parent's condition implies each of them\n * wherever the join binds its column, so the planner ignores them there.\n */\nexport function pushDownCorrelatedPredicates(\n ast: AST,\n columnsOf: (table: string) => Record<string, SchemaValue>,\n pushed?: Set<SimpleCondition> | undefined,\n): AST {\n function visit(ast: AST): AST {\n const where = ast.where && visitCondition(ast.where, ast.table, []);\n const facts = where ? simpleConjuncts(where) : [];\n const related =\n ast.related &&\n mapShared(ast.related, csq => {\n const subquery = visit(pushInto(csq, facts, ast.table));\n return subquery === csq.subquery ? csq : {...csq, subquery};\n });\n if (where === ast.where && related === ast.related) {\n return ast;\n }\n return {...ast, where, related};\n }\n\n function visitCondition(\n c: Condition,\n table: string,\n facts: readonly SimpleCondition[],\n ): Condition {\n switch (c.type) {\n case 'simple':\n return c;\n case 'and':\n return visitConjunction(c, table, [...facts, ...simpleConjuncts(c)]);\n case 'or': {\n const conditions = mapShared(c.conditions, x =>\n visitCondition(x, table, facts),\n );\n return conditions === c.conditions ? c : {...c, conditions};\n }\n case 'correlatedSubquery': {\n const subquery = visit(pushInto(c.related, facts, table));\n return subquery === c.related.subquery\n ? c\n : {...c, related: {...c.related, subquery}};\n }\n }\n }\n\n // `facts` already holds the simple conjuncts of `c` and of the ANDs nested\n // directly in it, so nested ANDs must not add them again.\n function visitConjunction(\n c: Conjunction,\n table: string,\n facts: readonly SimpleCondition[],\n ): Conjunction {\n const conditions = mapShared(c.conditions, x =>\n x.type === 'and'\n ? visitConjunction(x, table, facts)\n : visitCondition(x, table, facts),\n );\n return conditions === c.conditions ? c : {...c, conditions};\n }\n\n function pushInto(\n csq: CorrelatedSubquery,\n facts: readonly SimpleCondition[],\n parentTable: string,\n ): AST {\n const {parentField, childField} = csq.correlation;\n const {subquery} = csq;\n const conjuncts = subquery.where ? simpleConjuncts(subquery.where) : [];\n const added: SimpleCondition[] = [];\n for (const fact of facts) {\n if (!isPushable(fact)) {\n continue;\n }\n for (let i = 0; i < parentField.length; i++) {\n if (\n parentField[i] === fact.left.name &&\n haveSameScalarType(\n columnsOf(parentTable)[parentField[i]],\n columnsOf(subquery.table)[childField[i]],\n )\n ) {\n const copy: SimpleCondition = {\n ...fact,\n left: {type: 'column', name: childField[i]},\n };\n const same = conjuncts.find(c => isSameCondition(c, copy));\n if (same) {\n pushed?.add(same);\n } else {\n conjuncts.push(copy);\n added.push(copy);\n pushed?.add(copy);\n }\n }\n }\n }\n if (added.length === 0) {\n return subquery;\n }\n return {\n ...subquery,\n where: simplifyCondition({\n type: 'and',\n conditions: subquery.where ? [subquery.where, ...added] : added,\n }),\n };\n }\n\n return visit(ast);\n}\n\n/**\n * The simple conditions that are conjuncts of `c`, including those of ANDs\n * nested in ANDs.\n */\nfunction simpleConjuncts(c: Condition): SimpleCondition[] {\n switch (c.type) {\n case 'simple':\n return [c];\n case 'and':\n return c.conditions.flatMap(simpleConjuncts);\n default:\n return [];\n }\n}\n\nfunction isPushable(c: SimpleCondition): c is ColumnCondition {\n if (c.left.type !== 'column' || c.right.type !== 'literal') {\n return false;\n }\n switch (c.op) {\n case '=':\n case 'IS':\n return true;\n case 'IN':\n return (\n Array.isArray(c.right.value) &&\n c.right.value.length <= MAX_PUSHED_IN_VALUES\n );\n default:\n return false;\n }\n}\n\nfunction isSameCondition(a: SimpleCondition, b: SimpleCondition): boolean {\n return (\n a.op === b.op &&\n a.left.type === 'column' &&\n b.left.type === 'column' &&\n a.left.name === b.left.name &&\n a.right.type === 'literal' &&\n b.right.type === 'literal' &&\n deepEqual(a.right.value, b.right.value)\n );\n}\n\nfunction haveSameScalarType(\n parent: SchemaValue | undefined,\n child: SchemaValue | undefined,\n): boolean {\n return (\n parent !== undefined &&\n child !== undefined &&\n parent.type === child.type &&\n parent.type !== 'json'\n );\n}\n\n/**\n * Like `Array.prototype.map`, but returns `arr` itself when `f` returns every\n * element unchanged.\n */\nfunction mapShared<T>(arr: readonly T[], f: (x: T) => T): readonly T[] {\n let result: T[] | undefined;\n for (let i = 0; i < arr.length; i++) {\n const x = f(arr[i]);\n if (result === undefined && x !== arr[i]) {\n result = arr.slice(0, i);\n }\n result?.push(x);\n }\n return result ?? arr;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"correlated-predicate-pushdown.js","names":[],"sources":["../../../../../zql/src/builder/correlated-predicate-pushdown.ts"],"sourcesContent":["import {deepEqual} from '../../../shared/src/json.ts';\nimport type {\n AST,\n Condition,\n Conjunction,\n CorrelatedSubquery,\n SimpleCondition,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {SchemaValue} from '../../../zero-types/src/schema-value.ts';\nimport {simplifyCondition} from '../query/expression.ts';\n\n/**\n * The longest `IN` list that is copied into a child. `IN` compiles to\n * `IN (SELECT value FROM json_each(?))`, and every per-parent fetch of the\n * child carries the whole list.\n */\nexport const MAX_PUSHED_IN_VALUES = 32;\n\ntype ColumnCondition = SimpleCondition & {\n readonly left: {readonly type: 'column'; readonly name: string};\n};\n\n/**\n * Copies a parent's condition on a correlation column into the child\n * subquery, renamed to the matching child column. For example,\n * `user.where('user_id', X).related('reading')` becomes\n * `user.where('user_id', X).related('reading', r => r.where('user_id', X))`.\n *\n * The result is the same. Only child rows that cannot join to a parent that\n * matters are removed. But a push that climbs the tree then fetches parents\n * with SQL that includes the ancestor's condition, and a change to a child row\n * that cannot match stops at the child's source.\n *\n * Conditions are copied only when they are true for every parent row where\n * the edge can affect the result:\n * - for `related`, the top-level AND conjuncts of the parent's `where`;\n * - for EXISTS and NOT EXISTS, the conjuncts of every AND on the path from\n * the root of `where` to the subquery condition. An OR adds no facts.\n *\n * A condition is copied when it is `column = literal`, `column IS literal`, or\n * `column IN literal-list` (at most {@link MAX_PUSHED_IN_VALUES} values), the\n * column is a `parentField` of the correlation, and the parent and child\n * columns have the same Zero type, which is not `json`.\n *\n * A condition is not copied when the child already has the same condition as\n * a conjunct. So the pass does not change an AST that it already pushed.\n *\n * Does not change its input. Returns the same object for every part of the\n * AST that it does not change.\n *\n * @param pushed When given, receives each child conjunct that is a copy of a\n * parent condition: the copies that the pass adds, and the child's own\n * conjuncts that equal a copy. The parent's condition implies each of them\n * wherever the join binds its column, so the planner ignores them there.\n */\nexport function pushDownCorrelatedPredicates(\n ast: AST,\n columnsOf: (table: string) => Record<string, SchemaValue>,\n pushed?: Set<SimpleCondition> | undefined,\n): AST {\n function visit(ast: AST): AST {\n const where = ast.where && visitCondition(ast.where, ast.table, []);\n const facts = where ? simpleConjuncts(where) : [];\n const related =\n ast.related &&\n mapShared(ast.related, csq => {\n const subquery = visit(pushInto(csq, facts, ast.table));\n return subquery === csq.subquery ? csq : {...csq, subquery};\n });\n if (where === ast.where && related === ast.related) {\n return ast;\n }\n return {...ast, where, related};\n }\n\n function visitCondition(\n c: Condition,\n table: string,\n facts: readonly SimpleCondition[],\n ): Condition {\n switch (c.type) {\n case 'simple':\n return c;\n case 'and':\n return visitConjunction(c, table, [...facts, ...simpleConjuncts(c)]);\n case 'or': {\n const conditions = mapShared(c.conditions, x =>\n visitCondition(x, table, facts),\n );\n return conditions === c.conditions ? c : {...c, conditions};\n }\n case 'correlatedSubquery': {\n const subquery = visit(pushInto(c.related, facts, table));\n return subquery === c.related.subquery\n ? c\n : {...c, related: {...c.related, subquery}};\n }\n }\n }\n\n // `facts` already holds the simple conjuncts of `c` and of the ANDs nested\n // directly in it, so nested ANDs must not add them again.\n function visitConjunction(\n c: Conjunction,\n table: string,\n facts: readonly SimpleCondition[],\n ): Conjunction {\n const conditions = mapShared(c.conditions, x =>\n x.type === 'and'\n ? visitConjunction(x, table, facts)\n : visitCondition(x, table, facts),\n );\n return conditions === c.conditions ? c : {...c, conditions};\n }\n\n function pushInto(\n csq: CorrelatedSubquery,\n facts: readonly SimpleCondition[],\n parentTable: string,\n ): AST {\n const {parentField, childField} = csq.correlation;\n const {subquery} = csq;\n const conjuncts = subquery.where ? simpleConjuncts(subquery.where) : [];\n const added: SimpleCondition[] = [];\n for (const fact of facts) {\n if (!isPushable(fact)) {\n continue;\n }\n for (let i = 0; i < parentField.length; i++) {\n if (\n parentField[i] === fact.left.name &&\n haveSameScalarType(\n columnsOf(parentTable)[parentField[i]],\n columnsOf(subquery.table)[childField[i]],\n )\n ) {\n const copy: SimpleCondition = {\n ...fact,\n left: {type: 'column', name: childField[i]},\n };\n const same = conjuncts.find(c => isSameCondition(c, copy));\n if (same) {\n pushed?.add(same);\n } else {\n conjuncts.push(copy);\n added.push(copy);\n pushed?.add(copy);\n }\n }\n }\n }\n if (added.length === 0) {\n return subquery;\n }\n return {\n ...subquery,\n where: simplifyCondition({\n type: 'and',\n conditions: subquery.where ? [subquery.where, ...added] : added,\n }),\n };\n }\n\n return visit(ast);\n}\n\n/**\n * The simple conditions that are conjuncts of `c`, including those of ANDs\n * nested in ANDs.\n */\nfunction simpleConjuncts(c: Condition): SimpleCondition[] {\n switch (c.type) {\n case 'simple':\n return [c];\n case 'and':\n return c.conditions.flatMap(simpleConjuncts);\n default:\n return [];\n }\n}\n\nfunction isPushable(c: SimpleCondition): c is ColumnCondition {\n if (c.left.type !== 'column' || c.right.type !== 'literal') {\n return false;\n }\n switch (c.op) {\n case '=':\n case 'IS':\n return true;\n case 'IN':\n return (\n Array.isArray(c.right.value) &&\n c.right.value.length <= MAX_PUSHED_IN_VALUES\n );\n default:\n return false;\n }\n}\n\nfunction isSameCondition(a: SimpleCondition, b: SimpleCondition): boolean {\n return (\n a.op === b.op &&\n a.left.type === 'column' &&\n b.left.type === 'column' &&\n a.left.name === b.left.name &&\n a.right.type === 'literal' &&\n b.right.type === 'literal' &&\n deepEqual(a.right.value, b.right.value)\n );\n}\n\nfunction haveSameScalarType(\n parent: SchemaValue | undefined,\n child: SchemaValue | undefined,\n): boolean {\n return (\n parent !== undefined &&\n child !== undefined &&\n parent.type === child.type &&\n parent.type !== 'json'\n );\n}\n\n/**\n * Like `Array.prototype.map`, but returns `arr` itself when `f` returns every\n * element unchanged.\n */\nfunction mapShared<T>(arr: readonly T[], f: (x: T) => T): readonly T[] {\n let result: T[] | undefined;\n for (let i = 0; i < arr.length; i++) {\n const x = f(arr[i]);\n if (result === undefined && x !== arr[i]) {\n result = arr.slice(0, i);\n }\n result?.push(x);\n }\n return result ?? arr;\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"debug-delegate.js","names":[
|
|
1
|
+
{"version":3,"file":"debug-delegate.js","names":[],"sources":["../../../../../zql/src/builder/debug-delegate.ts"],"sourcesContent":["import type {\n RowCountsByQuery,\n RowCountsBySource,\n RowsByQuery,\n RowsBySource,\n} from '../../../zero-protocol/src/analyze-query-result.ts';\nimport {type Row} from '../../../zero-protocol/src/data.ts';\n\nexport const runtimeDebugFlags = {\n trackRowCountsVended: false,\n trackRowsVended: false,\n};\n\ntype SourceName = string;\ntype SQL = string;\n\nexport type SQLitePlans = Record<SQL, string[]>;\n\nexport interface DebugDelegate {\n initQuery(table: SourceName, query: SQL): void;\n rowVended(table: SourceName, query: SQL, row: Row): void;\n getVendedRowCounts(): RowCountsBySource;\n getVendedRows(): RowsBySource;\n recordNVisit(table: SourceName, query: SQL, nvisit: number): void;\n getNVisitCounts(): RowCountsBySource;\n recordExplain(table: SourceName, query: SQL, plan: string[]): void;\n getSQLitePlans(): SQLitePlans;\n // clears all internal state\n reset(): void;\n}\n\nexport class Debug implements DebugDelegate {\n #rowCountsBySource: RowCountsBySource;\n #rowsBySource: RowsBySource;\n #nvisitBySource: RowCountsBySource;\n #plans: SQLitePlans;\n readonly #collectRows: boolean;\n readonly #maxRowsPerQuery: number;\n\n /**\n * @param collectRows Whether to keep the vended rows.\n * @param maxRowsPerQuery Maximum number of rows kept per table/query. Rows\n * past this are still counted but not kept.\n */\n constructor(collectRows: boolean, maxRowsPerQuery = Infinity) {\n this.#collectRows = collectRows;\n this.#maxRowsPerQuery = maxRowsPerQuery;\n this.#rowCountsBySource = {};\n this.#rowsBySource = {};\n this.#nvisitBySource = {};\n this.#plans = {};\n }\n\n getVendedRowCounts(): RowCountsBySource {\n return this.#rowCountsBySource;\n }\n\n getVendedRows(): RowsBySource {\n return this.#rowsBySource;\n }\n\n getNVisitCounts(): RowCountsBySource {\n return this.#nvisitBySource;\n }\n\n getSQLitePlans(): SQLitePlans {\n return this.#plans;\n }\n\n initQuery(table: SourceName, query: SQL): void {\n const {counts} = this.#getRowStats(table);\n if (counts) {\n if (!counts[query]) {\n counts[query] = 0;\n }\n }\n }\n\n reset(): void {\n this.#rowCountsBySource = {};\n this.#rowsBySource = {};\n this.#nvisitBySource = {};\n this.#plans = {};\n }\n\n rowVended(table: SourceName, query: SQL, row: Row): void {\n const {counts, rows} = this.#getRowStats(table);\n if (counts) {\n counts[query] = (counts[query] ?? 0) + 1;\n }\n if (this.#collectRows) {\n const queryRows = (rows[query] ??= []);\n if (queryRows.length < this.#maxRowsPerQuery) {\n queryRows.push(row);\n }\n }\n }\n\n recordNVisit(table: SourceName, query: SQL, nvisit: number): void {\n let nvisitCounts = this.#nvisitBySource[table];\n if (!nvisitCounts) {\n nvisitCounts = {};\n this.#nvisitBySource[table] = nvisitCounts;\n }\n if (!nvisitCounts[query]) {\n nvisitCounts[query] = 0;\n }\n nvisitCounts[query] += nvisit;\n }\n\n recordExplain(_table: SourceName, query: SQL, plan: string[]): void {\n this.#plans[query] = plan;\n }\n\n #getRowStats(source: SourceName) {\n let counts: RowCountsByQuery | undefined;\n let rows: RowsByQuery | undefined;\n counts = this.#rowCountsBySource[source];\n if (!counts) {\n counts = {};\n this.#rowCountsBySource[source] = counts;\n }\n rows = this.#rowsBySource[source];\n if (!rows) {\n rows = {};\n this.#rowsBySource[source] = rows;\n }\n return {counts, rows};\n }\n}\n"],"mappings":";;AAQA,IAAa,oBAAoB;CAC/B,sBAAsB;CACtB,iBAAiB;AACnB;AAoBA,IAAa,QAAb,MAA4C;CAC1C;CACA;CACA;CACA;CACA;CACA;;;;;;CAOA,YAAY,aAAsB,kBAAkB,UAAU;EAC5D,KAAK,eAAe;EACpB,KAAK,mBAAmB;EACxB,KAAK,qBAAqB,CAAC;EAC3B,KAAK,gBAAgB,CAAC;EACtB,KAAK,kBAAkB,CAAC;EACxB,KAAK,SAAS,CAAC;CACjB;CAEA,qBAAwC;EACtC,OAAO,KAAK;CACd;CAEA,gBAA8B;EAC5B,OAAO,KAAK;CACd;CAEA,kBAAqC;EACnC,OAAO,KAAK;CACd;CAEA,iBAA8B;EAC5B,OAAO,KAAK;CACd;CAEA,UAAU,OAAmB,OAAkB;EAC7C,MAAM,EAAC,WAAU,KAAK,aAAa,KAAK;EACxC,IAAI,QACE;OAAA,CAAC,OAAO,QACV,OAAO,SAAS;EAAA;CAGtB;CAEA,QAAc;EACZ,KAAK,qBAAqB,CAAC;EAC3B,KAAK,gBAAgB,CAAC;EACtB,KAAK,kBAAkB,CAAC;EACxB,KAAK,SAAS,CAAC;CACjB;CAEA,UAAU,OAAmB,OAAY,KAAgB;EACvD,MAAM,EAAC,QAAQ,SAAQ,KAAK,aAAa,KAAK;EAC9C,IAAI,QACF,OAAO,UAAU,OAAO,UAAU,KAAK;EAEzC,IAAI,KAAK,cAAc;GACrB,MAAM,YAAa,KAAK,WAAW,CAAC;GACpC,IAAI,UAAU,SAAS,KAAK,kBAC1B,UAAU,KAAK,GAAG;EAEtB;CACF;CAEA,aAAa,OAAmB,OAAY,QAAsB;EAChE,IAAI,eAAe,KAAK,gBAAgB;EACxC,IAAI,CAAC,cAAc;GACjB,eAAe,CAAC;GAChB,KAAK,gBAAgB,SAAS;EAChC;EACA,IAAI,CAAC,aAAa,QAChB,aAAa,SAAS;EAExB,aAAa,UAAU;CACzB;CAEA,cAAc,QAAoB,OAAY,MAAsB;EAClE,KAAK,OAAO,SAAS;CACvB;CAEA,aAAa,QAAoB;EAC/B,IAAI;EACJ,IAAI;EACJ,SAAS,KAAK,mBAAmB;EACjC,IAAI,CAAC,QAAQ;GACX,SAAS,CAAC;GACV,KAAK,mBAAmB,UAAU;EACpC;EACA,OAAO,KAAK,cAAc;EAC1B,IAAI,CAAC,MAAM;GACT,OAAO,CAAC;GACR,KAAK,cAAc,UAAU;EAC/B;EACA,OAAO;GAAC;GAAQ;EAAI;CACtB;AACF"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Condition, type SimpleCondition } from '../../../zero-protocol/src/ast.ts';
|
|
2
2
|
import type { Row, Value } from '../../../zero-protocol/src/data.ts';
|
|
3
3
|
export type NonNullValue = Exclude<Value, null | undefined>;
|
|
4
|
-
export type SimplePredicate = (rhs: Value) => boolean;
|
|
5
4
|
export type SimplePredicateNoNull = (rhs: NonNullValue) => boolean;
|
|
6
5
|
export type NoSubqueryCondition = SimpleCondition | {
|
|
7
6
|
type: 'and';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../../../zql/src/builder/filter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../../../zql/src/builder/filter.ts"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,SAAS,EACd,KAAK,eAAe,EAErB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAC,GAAG,EAAE,KAAK,EAAC,MAAM,oCAAoC,CAAC;AAKnE,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,EAAE,IAAI,GAAG,SAAS,CAAC,CAAC;AAE5D,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC;AAqBnE,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,UAAU,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC5C,GACD;IACE,IAAI,EAAE,IAAI,CAAC;IACX,UAAU,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC5C,CAAC;AAEN,wBAAgB,eAAe,CAC7B,SAAS,EAAE,mBAAmB,GAC7B,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAqGvB;AAmED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG;IAChE,OAAO,EAAE,mBAAmB,GAAG,SAAS,CAAC;IACzC,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAoCA"}
|
|
@@ -1,8 +1,27 @@
|
|
|
1
1
|
import { assert, unreachable } from "../../../shared/src/asserts.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isLikeOperator, isNegatedOperator, jsonLiteralType, jsonValueAtPath } from "../../../zero-protocol/src/ast.js";
|
|
3
3
|
import { compareValues } from "../ivm/data.js";
|
|
4
|
+
import { simplifyCondition } from "../query/expression.js";
|
|
4
5
|
import { getLikePredicate } from "./like.js";
|
|
5
6
|
//#region ../zql/src/builder/filter.ts
|
|
7
|
+
/**
|
|
8
|
+
* Navigates into a JSON column value following `path`, strictly: a `number`
|
|
9
|
+
* segment indexes an array and a `string` segment reads an own property of a
|
|
10
|
+
* plain object, never a string's characters, an array's `length`, or an
|
|
11
|
+
* inherited member such as `constructor`. Any other step (a null/undefined or
|
|
12
|
+
* scalar intermediate, a segment of the wrong kind, a missing key) yields
|
|
13
|
+
* `null`.
|
|
14
|
+
*
|
|
15
|
+
* This is the rule SQLite `json_extract` applies (`$[i]` is array-only and
|
|
16
|
+
* `$."k"` is object-only, anything else is NULL), so the client and the replica
|
|
17
|
+
* it syncs from agree. JSON has no `undefined`, so absence collapses to `null`,
|
|
18
|
+
* matching SQLite `json_extract` (which returns SQL NULL for both a missing
|
|
19
|
+
* path and a JSON null), so `IS NULL` behaves identically on the client and
|
|
20
|
+
* against the replica.
|
|
21
|
+
*/
|
|
22
|
+
function valueAtPath(value, path) {
|
|
23
|
+
return jsonValueAtPath(value, path);
|
|
24
|
+
}
|
|
6
25
|
function createPredicate(condition) {
|
|
7
26
|
if (condition.type !== "simple") {
|
|
8
27
|
const predicates = condition.conditions.map((c) => createPredicate(c));
|
|
@@ -26,7 +45,13 @@ function createPredicate(condition) {
|
|
|
26
45
|
const result = impl(left.value);
|
|
27
46
|
return () => result;
|
|
28
47
|
}
|
|
29
|
-
|
|
48
|
+
if (left.type === "json") {
|
|
49
|
+
const { name } = left.value;
|
|
50
|
+
const { path } = left;
|
|
51
|
+
return (row) => impl(valueAtPath(row[name], path));
|
|
52
|
+
}
|
|
53
|
+
const { name } = left;
|
|
54
|
+
return (row) => impl(row[name]);
|
|
30
55
|
}
|
|
31
56
|
}
|
|
32
57
|
if (right.value === null || right.value === void 0) return (_row) => false;
|
|
@@ -36,8 +61,21 @@ function createPredicate(condition) {
|
|
|
36
61
|
const result = impl(left.value);
|
|
37
62
|
return () => result;
|
|
38
63
|
}
|
|
64
|
+
if (left.type === "json") {
|
|
65
|
+
const requiredType = isLikeOperator(condition.op) ? "string" : jsonLiteralType(right.value);
|
|
66
|
+
const negated = isNegatedOperator(condition.op);
|
|
67
|
+
const { name } = left.value;
|
|
68
|
+
const { path } = left;
|
|
69
|
+
return (row) => {
|
|
70
|
+
const lhs = valueAtPath(row[name], path);
|
|
71
|
+
if (lhs === null || lhs === void 0) return false;
|
|
72
|
+
if (requiredType === void 0 || typeof lhs !== requiredType) return negated;
|
|
73
|
+
return impl(lhs);
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const { name } = left;
|
|
39
77
|
return (row) => {
|
|
40
|
-
const lhs = row[
|
|
78
|
+
const lhs = row[name];
|
|
41
79
|
if (lhs === null || lhs === void 0) return false;
|
|
42
80
|
return impl(lhs);
|
|
43
81
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","names":[],"sources":["../../../../../zql/src/builder/filter.ts"],"sourcesContent":["import {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {\n Condition,\n SimpleCondition,\n SimpleOperator,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport {compareValues} from '../ivm/data.ts';\nimport {simplifyCondition} from '../query/expression.ts';\nimport {getLikePredicate} from './like.ts';\n\nexport type NonNullValue = Exclude<Value, null | undefined>;\nexport type SimplePredicate = (rhs: Value) => boolean;\nexport type SimplePredicateNoNull = (rhs: NonNullValue) => boolean;\n\nexport type NoSubqueryCondition =\n | SimpleCondition\n | {\n type: 'and';\n conditions: readonly NoSubqueryCondition[];\n }\n | {\n type: 'or';\n conditions: readonly NoSubqueryCondition[];\n };\n\nexport function createPredicate(\n condition: NoSubqueryCondition,\n): (row: Row) => boolean {\n if (condition.type !== 'simple') {\n const predicates = condition.conditions.map(c => createPredicate(c));\n return condition.type === 'and'\n ? (row: Row) => {\n // and\n for (const predicate of predicates) {\n if (!predicate(row)) {\n return false;\n }\n }\n return true;\n }\n : (row: Row) => {\n // or\n for (const predicate of predicates) {\n if (predicate(row)) {\n return true;\n }\n }\n return false;\n };\n }\n const {left} = condition;\n const {right} = condition;\n assert(\n right.type !== 'static',\n 'static values should be resolved before creating predicates',\n );\n assert(\n left.type !== 'static',\n 'static values should be resolved before creating predicates',\n );\n\n switch (condition.op) {\n case 'IS':\n case 'IS NOT': {\n const impl = createIsPredicate(right.value, condition.op);\n if (left.type === 'literal') {\n const result = impl(left.value);\n return () => result;\n }\n return (row: Row) => impl(row[left.name]);\n }\n }\n\n if (right.value === null || right.value === undefined) {\n return (_row: Row) => false;\n }\n\n const impl = createPredicateImpl(right.value, condition.op);\n if (left.type === 'literal') {\n if (left.value === null || left.value === undefined) {\n return (_row: Row) => false;\n }\n const result = impl(left.value);\n return () => result;\n }\n\n return (row: Row) => {\n const lhs = row[left.name];\n if (lhs === null || lhs === undefined) {\n return false;\n }\n return impl(lhs);\n };\n}\n\nfunction createIsPredicate(\n rhs: Value | readonly Value[],\n operator: 'IS' | 'IS NOT',\n): SimplePredicate {\n switch (operator) {\n case 'IS':\n return lhs => lhs === rhs;\n case 'IS NOT':\n return lhs => lhs !== rhs;\n }\n}\n\nfunction createPredicateImpl(\n rhs: NonNullValue | readonly NonNullValue[],\n operator: Exclude<SimpleOperator, 'IS' | 'IS NOT'>,\n): SimplePredicateNoNull {\n switch (operator) {\n case '=':\n return lhs => lhs === rhs;\n case '!=':\n return lhs => lhs !== rhs;\n // Use compareValues (UTF-8 / code-point order for strings) so range\n // comparisons match ORDER BY and SQLite. Raw JS `<`/`>` compare strings by\n // UTF-16 code unit, which disagrees for non-BMP characters (e.g. emoji),\n // wrongly including/excluding rows relative to the sort order. Mixed-type\n // comparisons are unsupported (compareValues throws), matching SQLite.\n case '<':\n return lhs => compareValues(lhs, rhs) < 0;\n case '<=':\n return lhs => compareValues(lhs, rhs) <= 0;\n case '>':\n return lhs => compareValues(lhs, rhs) > 0;\n case '>=':\n return lhs => compareValues(lhs, rhs) >= 0;\n case 'LIKE':\n return getLikePredicate(rhs, '');\n case 'NOT LIKE':\n return not(getLikePredicate(rhs, ''));\n case 'ILIKE':\n return getLikePredicate(rhs, 'i');\n case 'NOT ILIKE':\n return not(getLikePredicate(rhs, 'i'));\n case 'IN': {\n assert(Array.isArray(rhs), 'Expected rhs to be an array for IN operator');\n const set = new Set(rhs);\n return lhs => set.has(lhs);\n }\n case 'NOT IN': {\n assert(\n Array.isArray(rhs),\n 'Expected rhs to be an array for NOT IN operator',\n );\n const set = new Set(rhs);\n return lhs => !set.has(lhs);\n }\n default:\n operator satisfies never;\n throw new Error(`Unexpected operator: ${operator}`);\n }\n}\n\nfunction not<T>(f: (lhs: T) => boolean) {\n return (lhs: T) => !f(lhs);\n}\n\n/**\n * If the condition contains any CorrelatedSubqueryConditions, returns a\n * transformed condition which contains no CorrelatedSubqueryCondition(s) but\n * which will filter a subset of the rows that would be filtered by the original\n * condition, or undefined if no such transformation exists.\n *\n * If the condition does not contain any CorrelatedSubqueryConditions\n * returns the condition unmodified and `conditionsRemoved: false`.\n */\nexport function transformFilters(filters: Condition | undefined): {\n filters: NoSubqueryCondition | undefined;\n conditionsRemoved: boolean;\n} {\n if (!filters) {\n return {filters: undefined, conditionsRemoved: false};\n }\n switch (filters.type) {\n case 'simple':\n return {filters, conditionsRemoved: false};\n case 'correlatedSubquery':\n return {filters: undefined, conditionsRemoved: true};\n case 'and':\n case 'or': {\n const transformedConditions: NoSubqueryCondition[] = [];\n let conditionsRemoved = false;\n for (const cond of filters.conditions) {\n const transformed = transformFilters(cond);\n // If any branch of the OR ends up empty, the entire OR needs\n // to be removed.\n if (transformed.filters === undefined && filters.type === 'or') {\n return {filters: undefined, conditionsRemoved: true};\n }\n conditionsRemoved = conditionsRemoved || transformed.conditionsRemoved;\n if (transformed.filters) {\n transformedConditions.push(transformed.filters);\n }\n }\n return {\n filters: simplifyCondition({\n type: filters.type,\n conditions: transformedConditions,\n }) as NoSubqueryCondition,\n conditionsRemoved,\n };\n }\n default:\n unreachable(filters);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filter.js","names":[],"sources":["../../../../../zql/src/builder/filter.ts"],"sourcesContent":["import {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport {\n isLikeOperator,\n isNegatedOperator,\n jsonLiteralType,\n jsonValueAtPath,\n type Condition,\n type SimpleCondition,\n type SimpleOperator,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../../zero-protocol/src/data.ts';\nimport {compareValues} from '../ivm/data.ts';\nimport {simplifyCondition} from '../query/expression.ts';\nimport {getLikePredicate} from './like.ts';\n\nexport type NonNullValue = Exclude<Value, null | undefined>;\ntype SimplePredicate = (rhs: Value) => boolean;\nexport type SimplePredicateNoNull = (rhs: NonNullValue) => boolean;\n\n/**\n * Navigates into a JSON column value following `path`, strictly: a `number`\n * segment indexes an array and a `string` segment reads an own property of a\n * plain object, never a string's characters, an array's `length`, or an\n * inherited member such as `constructor`. Any other step (a null/undefined or\n * scalar intermediate, a segment of the wrong kind, a missing key) yields\n * `null`.\n *\n * This is the rule SQLite `json_extract` applies (`$[i]` is array-only and\n * `$.\"k\"` is object-only, anything else is NULL), so the client and the replica\n * it syncs from agree. JSON has no `undefined`, so absence collapses to `null`,\n * matching SQLite `json_extract` (which returns SQL NULL for both a missing\n * path and a JSON null), so `IS NULL` behaves identically on the client and\n * against the replica.\n */\nfunction valueAtPath(value: Value, path: readonly (string | number)[]): Value {\n return jsonValueAtPath(value, path) as Value;\n}\n\nexport type NoSubqueryCondition =\n | SimpleCondition\n | {\n type: 'and';\n conditions: readonly NoSubqueryCondition[];\n }\n | {\n type: 'or';\n conditions: readonly NoSubqueryCondition[];\n };\n\nexport function createPredicate(\n condition: NoSubqueryCondition,\n): (row: Row) => boolean {\n if (condition.type !== 'simple') {\n const predicates = condition.conditions.map(c => createPredicate(c));\n return condition.type === 'and'\n ? (row: Row) => {\n // and\n for (const predicate of predicates) {\n if (!predicate(row)) {\n return false;\n }\n }\n return true;\n }\n : (row: Row) => {\n // or\n for (const predicate of predicates) {\n if (predicate(row)) {\n return true;\n }\n }\n return false;\n };\n }\n const {left} = condition;\n const {right} = condition;\n assert(\n right.type !== 'static',\n 'static values should be resolved before creating predicates',\n );\n assert(\n left.type !== 'static',\n 'static values should be resolved before creating predicates',\n );\n\n switch (condition.op) {\n case 'IS':\n case 'IS NOT': {\n const impl = createIsPredicate(right.value, condition.op);\n if (left.type === 'literal') {\n const result = impl(left.value);\n return () => result;\n }\n if (left.type === 'json') {\n const {name} = left.value;\n const {path} = left;\n return (row: Row) => impl(valueAtPath(row[name], path));\n }\n const {name} = left;\n return (row: Row) => impl(row[name]);\n }\n }\n\n if (right.value === null || right.value === undefined) {\n return (_row: Row) => false;\n }\n\n const impl = createPredicateImpl(right.value, condition.op);\n if (left.type === 'literal') {\n if (left.value === null || left.value === undefined) {\n return (_row: Row) => false;\n }\n const result = impl(left.value);\n return () => result;\n }\n\n if (left.type === 'json') {\n // A JSON leaf is dynamically typed, unlike a schema-typed column, so the\n // comparison is type-strict (see JsonPathReference): a leaf whose JSON\n // type differs from the literal's is never equal (a non-match for a\n // positive operator and a match for a negated one) and never an error.\n // This keeps `compareValues` and the LIKE matcher (which assume operands\n // of one type) from throwing on user data. The LIKE family compares text,\n // so it requires a string leaf whatever the literal's type.\n const requiredType = isLikeOperator(condition.op)\n ? 'string'\n : jsonLiteralType(right.value);\n const negated = isNegatedOperator(condition.op);\n const {name} = left.value;\n const {path} = left;\n return (row: Row) => {\n const lhs = valueAtPath(row[name], path);\n if (lhs === null || lhs === undefined) {\n return false;\n }\n // An empty IN/NOT IN list has no type to be strict about: `IN ()` never\n // matches and `NOT IN ()` always does (for a non-null leaf).\n if (requiredType === undefined || typeof lhs !== requiredType) {\n return negated;\n }\n return impl(lhs);\n };\n }\n\n const {name} = left;\n return (row: Row) => {\n const lhs = row[name];\n if (lhs === null || lhs === undefined) {\n return false;\n }\n return impl(lhs);\n };\n}\n\nfunction createIsPredicate(\n rhs: Value | readonly Value[],\n operator: 'IS' | 'IS NOT',\n): SimplePredicate {\n switch (operator) {\n case 'IS':\n return lhs => lhs === rhs;\n case 'IS NOT':\n return lhs => lhs !== rhs;\n }\n}\n\nfunction createPredicateImpl(\n rhs: NonNullValue | readonly NonNullValue[],\n operator: Exclude<SimpleOperator, 'IS' | 'IS NOT'>,\n): SimplePredicateNoNull {\n switch (operator) {\n case '=':\n return lhs => lhs === rhs;\n case '!=':\n return lhs => lhs !== rhs;\n // Use compareValues (UTF-8 / code-point order for strings) so range\n // comparisons match ORDER BY and SQLite. Raw JS `<`/`>` compare strings by\n // UTF-16 code unit, which disagrees for non-BMP characters (e.g. emoji),\n // wrongly including/excluding rows relative to the sort order. Mixed-type\n // comparisons are unsupported (compareValues throws), matching SQLite.\n case '<':\n return lhs => compareValues(lhs, rhs) < 0;\n case '<=':\n return lhs => compareValues(lhs, rhs) <= 0;\n case '>':\n return lhs => compareValues(lhs, rhs) > 0;\n case '>=':\n return lhs => compareValues(lhs, rhs) >= 0;\n case 'LIKE':\n return getLikePredicate(rhs, '');\n case 'NOT LIKE':\n return not(getLikePredicate(rhs, ''));\n case 'ILIKE':\n return getLikePredicate(rhs, 'i');\n case 'NOT ILIKE':\n return not(getLikePredicate(rhs, 'i'));\n case 'IN': {\n assert(Array.isArray(rhs), 'Expected rhs to be an array for IN operator');\n const set = new Set(rhs);\n return lhs => set.has(lhs);\n }\n case 'NOT IN': {\n assert(\n Array.isArray(rhs),\n 'Expected rhs to be an array for NOT IN operator',\n );\n const set = new Set(rhs);\n return lhs => !set.has(lhs);\n }\n default:\n operator satisfies never;\n throw new Error(`Unexpected operator: ${operator}`);\n }\n}\n\nfunction not<T>(f: (lhs: T) => boolean) {\n return (lhs: T) => !f(lhs);\n}\n\n/**\n * If the condition contains any CorrelatedSubqueryConditions, returns a\n * transformed condition which contains no CorrelatedSubqueryCondition(s) but\n * which will filter a subset of the rows that would be filtered by the original\n * condition, or undefined if no such transformation exists.\n *\n * If the condition does not contain any CorrelatedSubqueryConditions\n * returns the condition unmodified and `conditionsRemoved: false`.\n */\nexport function transformFilters(filters: Condition | undefined): {\n filters: NoSubqueryCondition | undefined;\n conditionsRemoved: boolean;\n} {\n if (!filters) {\n return {filters: undefined, conditionsRemoved: false};\n }\n switch (filters.type) {\n case 'simple':\n return {filters, conditionsRemoved: false};\n case 'correlatedSubquery':\n return {filters: undefined, conditionsRemoved: true};\n case 'and':\n case 'or': {\n const transformedConditions: NoSubqueryCondition[] = [];\n let conditionsRemoved = false;\n for (const cond of filters.conditions) {\n const transformed = transformFilters(cond);\n // If any branch of the OR ends up empty, the entire OR needs\n // to be removed.\n if (transformed.filters === undefined && filters.type === 'or') {\n return {filters: undefined, conditionsRemoved: true};\n }\n conditionsRemoved = conditionsRemoved || transformed.conditionsRemoved;\n if (transformed.filters) {\n transformedConditions.push(transformed.filters);\n }\n }\n return {\n filters: simplifyCondition({\n type: filters.type,\n conditions: transformedConditions,\n }) as NoSubqueryCondition,\n conditionsRemoved,\n };\n }\n default:\n unreachable(filters);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"like.js","names":[],"sources":["../../../../../zql/src/builder/like.ts"],"sourcesContent":["import {assertString} from '../../../shared/src/asserts.ts';\nimport type {NonNullValue, SimplePredicateNoNull} from './filter.ts';\n\nexport function getLikePredicate(\n pattern: NonNullValue,\n flags: 'i' | '',\n): SimplePredicateNoNull {\n const op = getLikeOp(String(pattern), flags);\n return (lhs: NonNullValue) => {\n assertString(lhs);\n return op(String(lhs));\n };\n}\n\nconst likePatternRe = /_|%|\\\\/;\n\nfunction getLikeOp(pattern: string, flags: 'i' | ''): (lhs: string) => boolean {\n // if lhs does not contain '%' or '_' then it is a simple string comparison.\n // if it does contain '%' or '_' then it is a regex comparison.\n // '%' is a wildcard for any number of characters\n // '_' is a wildcard for a single character\n // Postgres SQL allows escaping using `\\`.\n\n if (!likePatternRe.test(pattern)) {\n if (flags === 'i') {\n const rhsLower = pattern.toLowerCase();\n return (lhs: string) => lhs.toLowerCase() === rhsLower;\n }\n return (lhs: string) => lhs === pattern;\n }\n const re = patternToRegExp(pattern, flags);\n return (lhs: string) => re.test(lhs);\n}\n\nconst specialCharsRe = /[$()*+.?[\\]\\\\^{|}]/;\n\nfunction patternToRegExp(source: string, flags: '' | 'i' = ''): RegExp {\n // There are a few cases:\n // % => .*\n // _ => .\n // \\x => \\x for any x except special regexp chars\n // special regexp chars => \\special regexp chars\n let pattern = '^';\n for (let i = 0; i < source.length; i++) {\n let c = source[i];\n switch (c) {\n case '%':\n pattern += '.*';\n break;\n case '_':\n pattern += '.';\n break;\n\n // @ts-expect-error fallthrough\n case '\\\\':\n if (i === source.length - 1) {\n throw new Error('LIKE pattern must not end with escape character');\n }\n i++;\n c = source[i];\n\n // fall through\n default:\n if (specialCharsRe.test(c)) {\n pattern += '\\\\';\n }\n pattern += c;\n\n break;\n }\n }\n // Use the `s` (dotall) flag so `.` (from `_`) and `.*` (from `%`) match\n // newlines, and keep `^`/`$` anchored to the whole string. The `m` (multiline)\n // flag was wrong on both counts: it let `^`/`$` match interior line boundaries\n // (false positives, e.g. 'fooa\\nbar' LIKE 'foo_') while the wildcards still\n // skipped newlines (false negatives, e.g. 'a\\nb' NOT LIKE 'a%b').\n return new RegExp(pattern + '$', flags + 's');\n}\n"],"mappings":";;AAGA,SAAgB,iBACd,SACA,OACuB;CACvB,MAAM,KAAK,UAAU,OAAO,OAAO,GAAG,KAAK;CAC3C,QAAQ,QAAsB;EAC5B,aAAa,GAAG;EAChB,OAAO,GAAG,OAAO,GAAG,CAAC;CACvB;AACF;AAEA,IAAM,gBAAgB;AAEtB,SAAS,UAAU,SAAiB,OAA2C;CAO7E,IAAI,CAAC,cAAc,KAAK,OAAO,GAAG;EAChC,IAAI,UAAU,KAAK;GACjB,MAAM,WAAW,QAAQ,YAAY;GACrC,QAAQ,QAAgB,IAAI,YAAY,MAAM;EAChD;EACA,QAAQ,QAAgB,QAAQ;CAClC;CACA,MAAM,KAAK,gBAAgB,SAAS,KAAK;CACzC,QAAQ,QAAgB,GAAG,KAAK,GAAG;AACrC;AAEA,IAAM,iBAAiB;AAEvB,SAAS,gBAAgB,QAAgB,QAAkB,IAAY;CAMrE,IAAI,UAAU;CACd,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,IAAI,IAAI,OAAO;EACf,QAAQ,GAAR;GACE,KAAK;IACH,WAAW;IACX;GACF,KAAK;IACH,WAAW;IACX;GAGF,KAAK;IACH,IAAI,MAAM,OAAO,SAAS,GACxB,MAAM,IAAI,MAAM,iDAAiD;IAEnE;IACA,IAAI,OAAO;GAGb;IACE,IAAI,eAAe,KAAK,CAAC,GACvB,WAAW;IAEb,WAAW;
|
|
1
|
+
{"version":3,"file":"like.js","names":[],"sources":["../../../../../zql/src/builder/like.ts"],"sourcesContent":["import {assertString} from '../../../shared/src/asserts.ts';\nimport type {NonNullValue, SimplePredicateNoNull} from './filter.ts';\n\nexport function getLikePredicate(\n pattern: NonNullValue,\n flags: 'i' | '',\n): SimplePredicateNoNull {\n const op = getLikeOp(String(pattern), flags);\n return (lhs: NonNullValue) => {\n assertString(lhs);\n return op(String(lhs));\n };\n}\n\nconst likePatternRe = /_|%|\\\\/;\n\nfunction getLikeOp(pattern: string, flags: 'i' | ''): (lhs: string) => boolean {\n // if lhs does not contain '%' or '_' then it is a simple string comparison.\n // if it does contain '%' or '_' then it is a regex comparison.\n // '%' is a wildcard for any number of characters\n // '_' is a wildcard for a single character\n // Postgres SQL allows escaping using `\\`.\n\n if (!likePatternRe.test(pattern)) {\n if (flags === 'i') {\n const rhsLower = pattern.toLowerCase();\n return (lhs: string) => lhs.toLowerCase() === rhsLower;\n }\n return (lhs: string) => lhs === pattern;\n }\n const re = patternToRegExp(pattern, flags);\n return (lhs: string) => re.test(lhs);\n}\n\nconst specialCharsRe = /[$()*+.?[\\]\\\\^{|}]/;\n\nfunction patternToRegExp(source: string, flags: '' | 'i' = ''): RegExp {\n // There are a few cases:\n // % => .*\n // _ => .\n // \\x => \\x for any x except special regexp chars\n // special regexp chars => \\special regexp chars\n let pattern = '^';\n for (let i = 0; i < source.length; i++) {\n let c = source[i];\n switch (c) {\n case '%':\n pattern += '.*';\n break;\n case '_':\n pattern += '.';\n break;\n\n // @ts-expect-error fallthrough\n case '\\\\':\n if (i === source.length - 1) {\n throw new Error('LIKE pattern must not end with escape character');\n }\n i++;\n c = source[i];\n\n // fall through\n default:\n if (specialCharsRe.test(c)) {\n pattern += '\\\\';\n }\n pattern += c;\n\n break;\n }\n }\n // Use the `s` (dotall) flag so `.` (from `_`) and `.*` (from `%`) match\n // newlines, and keep `^`/`$` anchored to the whole string. The `m` (multiline)\n // flag was wrong on both counts: it let `^`/`$` match interior line boundaries\n // (false positives, e.g. 'fooa\\nbar' LIKE 'foo_') while the wildcards still\n // skipped newlines (false negatives, e.g. 'a\\nb' NOT LIKE 'a%b').\n return new RegExp(pattern + '$', flags + 's');\n}\n"],"mappings":";;AAGA,SAAgB,iBACd,SACA,OACuB;CACvB,MAAM,KAAK,UAAU,OAAO,OAAO,GAAG,KAAK;CAC3C,QAAQ,QAAsB;EAC5B,aAAa,GAAG;EAChB,OAAO,GAAG,OAAO,GAAG,CAAC;CACvB;AACF;AAEA,IAAM,gBAAgB;AAEtB,SAAS,UAAU,SAAiB,OAA2C;CAO7E,IAAI,CAAC,cAAc,KAAK,OAAO,GAAG;EAChC,IAAI,UAAU,KAAK;GACjB,MAAM,WAAW,QAAQ,YAAY;GACrC,QAAQ,QAAgB,IAAI,YAAY,MAAM;EAChD;EACA,QAAQ,QAAgB,QAAQ;CAClC;CACA,MAAM,KAAK,gBAAgB,SAAS,KAAK;CACzC,QAAQ,QAAgB,GAAG,KAAK,GAAG;AACrC;AAEA,IAAM,iBAAiB;AAEvB,SAAS,gBAAgB,QAAgB,QAAkB,IAAY;CAMrE,IAAI,UAAU;CACd,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EACtC,IAAI,IAAI,OAAO;EACf,QAAQ,GAAR;GACE,KAAK;IACH,WAAW;IACX;GACF,KAAK;IACH,WAAW;IACX;GAGF,KAAK;IACH,IAAI,MAAM,OAAO,SAAS,GACxB,MAAM,IAAI,MAAM,iDAAiD;IAEnE;IACA,IAAI,OAAO;GAGb;IACE,IAAI,eAAe,KAAK,CAAC,GACvB,WAAW;IAEb,WAAW;EAGf;CACF;CAMA,OAAO,IAAI,OAAO,UAAU,KAAK,QAAQ,GAAG;AAC9C"}
|
package/out/zql/src/error.d.ts
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
1
|
export declare class NotImplementedError extends Error {
|
|
2
2
|
constructor(message: string);
|
|
3
3
|
}
|
|
4
|
-
export type PlannerExceptionKind = 'max_flippable_joins';
|
|
5
|
-
export declare class PlannerException extends Error {
|
|
6
|
-
readonly kind: PlannerExceptionKind;
|
|
7
|
-
constructor(kind: PlannerExceptionKind, message: string);
|
|
8
|
-
}
|
|
9
4
|
//# sourceMappingURL=error.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../zql/src/error.ts"],"names":[],"mappings":"AAAA,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../../zql/src/error.ts"],"names":[],"mappings":"AAAA,qBAAa,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,OAAO,EAAE,MAAM,EAG1B;CACF"}
|
package/out/zql/src/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","names":[],"sources":["../../../../zql/src/error.ts"],"sourcesContent":["export class NotImplementedError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NotImplementedError';\n }\n}\n
|
|
1
|
+
{"version":3,"file":"error.js","names":[],"sources":["../../../../zql/src/error.ts"],"sourcesContent":["export class NotImplementedError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'NotImplementedError';\n }\n}\n"],"mappings":";AAAA,IAAa,sBAAb,cAAyC,MAAM;CAC7C,YAAY,SAAiB;EAC3B,MAAM,OAAO;EACb,KAAK,OAAO;CACd;AACF"}
|