@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
package/out/zqlite/src/mod.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "../../zero-types/src/format.js";
|
|
2
|
-
import "../../zql/src/query/query-impl.js";
|
|
3
|
-
import "./db.js";
|
|
4
|
-
import "./query-delegate.js";
|
|
5
|
-
export {};
|
|
1
|
+
import { defaultFormat } from "../../zero-types/src/format.js";
|
|
2
|
+
import { QueryImpl } from "../../zql/src/query/query-impl.js";
|
|
3
|
+
import { Database } from "./db.js";
|
|
4
|
+
import { QueryDelegateImpl } from "./query-delegate.js";
|
|
5
|
+
export { Database, QueryDelegateImpl as QueryDelegate, QueryImpl, defaultFormat };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pending-delta.d.ts","sourceRoot":"","sources":["../../../../zqlite/src/pending-delta.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pending-delta.d.ts","sourceRoot":"","sources":["../../../../zqlite/src/pending-delta.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,QAAQ,EAAY,MAAM,gCAAgC,CAAC;AACxE,OAAO,KAAK,EAAC,GAAG,EAAQ,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,wCAAwC,CAAC;AACvE,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,2BAA2B,CAAC;AAQ1D,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAEnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,YAAY;;IA0BvB,YAAY,UAAU,EAAE,UAAU,EAGjC;IAED;;;OAGG;IACH,IAAI,OAAO,IAAI,OAAO,CAErB;IAED,qEAAqE;IACrE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;OAGG;IACH,IAAI,cAAc,IAAI,MAAM,CAO3B;IAqBD,yDAAyD;IACzD,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAgBlB;IAED,wCAAwC;IACxC,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAUrB;IAED;;;;OAIG;IACH,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAQ3B;IAED;;;;OAIG;IACH,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,GAAG,OAAO,cAAc,CAMrD;IAED;;;;OAIG;IACH,YAAY,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,SAAS,CAOrE;IA8BD;;;;;;;;;OASG;IACF,OAAO,CACN,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,eAAe,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,GAAG,SAAS,CAAC,GAAG,SAAS,EAChE,gBAAgB,EAAE,SAAS,eAAe,EAAE,GAAG,SAAS,EACxD,KAAK,CAAC,EAAE,GAAG,GAAG,SAAS,GACtB,QAAQ,CAAC,GAAG,CAAC,CAiEf;IAED;;;OAGG;IACF,WAAW,IAAI,QAAQ,CAAC,GAAG,CAAC,CAc5B;IAED,qEAAqE;IACpE,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAC,CAMzB;IAED,+EAA+E;IAC/E,KAAK,IAAI,IAAI,CAOZ;CACF;AAwBD,eAAO,MAAM,cAAc,eAA2B,CAAC;AAwBvD;;;;;;;;GAQG;AACH,wBAAiB,wBAAwB,CACvC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EACvB,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,EACxB,KAAK,EAAE,YAAY,EACnB,OAAO,EAAE,UAAU,GAClB,gBAAgB,CAAC,GAAG,CAAC,CAwBvB;AAED;;;GAGG;AACH,wBAAiB,iCAAiC,CAChD,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EACvB,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,EACxB,KAAK,EAAE,YAAY,GAClB,gBAAgB,CAAC,GAAG,CAAC,CAOvB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { hasOwn } from "../../shared/src/has-own.js";
|
|
2
|
+
import { assignProperty } from "../../shared/src/objects.js";
|
|
2
3
|
import { constraintMatchesPrimaryKey, constraintMatchesRow } from "../../zql/src/ivm/constraint.js";
|
|
3
4
|
import { BTreeSet } from "../../shared/src/btree-set.js";
|
|
4
5
|
import { generateRows, makeBoundComparator, maxValue, minValue } from "../../zql/src/ivm/memory-source.js";
|
|
@@ -177,9 +178,9 @@ var PendingDelta = class {
|
|
|
177
178
|
if (start !== void 0 && sorted && (!constraint || constraintMatchesRow(constraint, start))) scanStart = start;
|
|
178
179
|
else if (constraint) {
|
|
179
180
|
scanStart = {};
|
|
180
|
-
for (const [key, dir] of indexSort) if (hasOwn(constraint, key)) scanStart
|
|
181
|
-
else if (reverse) scanStart
|
|
182
|
-
else scanStart
|
|
181
|
+
for (const [key, dir] of indexSort) if (hasOwn(constraint, key)) assignProperty(scanStart, key, constraint[key]);
|
|
182
|
+
else if (reverse) assignProperty(scanStart, key, dir === "asc" ? maxValue : minValue);
|
|
183
|
+
else assignProperty(scanStart, key, dir === "asc" ? minValue : maxValue);
|
|
183
184
|
}
|
|
184
185
|
for (const row of generateRows(data, scanStart, reverse)) {
|
|
185
186
|
if (constraint && !constraintMatchesRow(constraint, row)) break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pending-delta.js","names":["#primaryKey","#singleColumnKey","#firstKeyValues","#byKey","#indexes","#rowBytes","#indexBytes","#liveCount","#key","#track","#removeFromIndexes","#addToIndexes","#getOrCreateIndex"],"sources":["../../../../zqlite/src/pending-delta.ts"],"sourcesContent":["import {BTreeSet} from '../../shared/src/btree-set.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport type {Ordering, OrderPart} from '../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../zero-protocol/src/primary-key.ts';\nimport {\n constraintMatchesPrimaryKey,\n constraintMatchesRow,\n type Constraint,\n} from '../../zql/src/ivm/constraint.ts';\nimport type {Comparator} from '../../zql/src/ivm/data.ts';\nimport {\n generateRows,\n makeBoundComparator,\n maxValue,\n minValue,\n type RowBound,\n} from '../../zql/src/ivm/memory-source.ts';\nimport type {MultiConstraint} from '../../zql/src/ivm/operator.ts';\n\n/**\n * The batch overlay that lets a `TableSource` derive a transaction without\n * writing to the database it is reading from.\n *\n * A `TableSource` normally makes each change durable in its backing SQLite\n * connection as soon as it has been vended to every output, because change\n * *k+1* has to read a base that already includes changes *1..k* -- IVM's\n * joins fetch from the source mid-push. On the server that backing connection\n * is a `BEGIN CONCURRENT` snapshot that is never committed and always rolled\n * back, so those writes exist only to serve reads for the rest of the pass.\n *\n * A `PendingDelta` holds them in memory instead. The base stays pinned at the\n * state it had when the pass began and this object supplies *1..k*, merged\n * into every leaf scan. The durable copy comes from the replicator's own\n * commit, which the source picks up when it leapfrogs to the next snapshot.\n *\n * State is coalesced by primary key: whatever the batch did to a row, all that\n * matters downstream is the row's final value, or that it is gone. A key that\n * appears here overrides the base unconditionally -- an added row has no base\n * to override, an edited row's base copy is suppressed in favor of the new\n * value, and a removed row's base copy is suppressed with nothing to put in\n * its place.\n *\n * Live rows are additionally kept in lazily built sorted indexes, one per\n * `[...constraintKeys, ...sort]` shape a fetch has asked for, so that merging\n * the delta into a constrained scan costs `O(log D + matches)` rather than a\n * walk of the whole delta. This mirrors `MemorySource`'s index handling; see\n * its `#fetch` for the bound construction the scans here reproduce.\n */\nexport class PendingDelta {\n readonly #primaryKey: PrimaryKey;\n readonly #singleColumnKey: string | undefined;\n\n /**\n * For a composite primary key, the first key column's value of every key in\n * `#byKey`. {@link overrides} runs for every base row of a merged fetch, and\n * building a composite key allocates, so this rules most rows out first.\n */\n readonly #firstKeyValues = new Set<Value>();\n\n /**\n * The coalesced net state, keyed by primary key. A `undefined` value is a\n * tombstone: the batch removed the row, so the base copy is suppressed and\n * nothing replaces it. Membership alone is what suppresses a base row, so\n * this map is also the \"is this key overridden\" test.\n */\n readonly #byKey = new Map<unknown, Row | undefined>();\n\n /** Sorted views over the live (non-tombstone) rows, keyed by `JSON(sort)`. */\n readonly #indexes = new Map<string, BTreeSet<Row>>();\n\n #liveCount = 0;\n #rowBytes = 0;\n #indexBytes = 0;\n\n constructor(primaryKey: PrimaryKey) {\n this.#primaryKey = primaryKey;\n this.#singleColumnKey = primaryKey.length === 1 ? primaryKey[0] : undefined;\n }\n\n /**\n * True when the source can take its untouched fast path: no suppression\n * test per base row, no merge, no index maintenance.\n */\n get isEmpty(): boolean {\n return this.#byKey.size === 0;\n }\n\n /** The number of rows the batch has touched, tombstones included. */\n get size(): number {\n return this.#byKey.size;\n }\n\n /**\n * Estimated retained bytes, including keys, tombstones, and sorted indexes.\n * This is a budgeting heuristic, not a measurement of the JavaScript heap.\n */\n get estimatedBytes(): number {\n // Budget 32 bytes per live row per index for references and B-tree nodes.\n return (\n this.#rowBytes +\n this.#indexBytes +\n this.#liveCount * this.#indexes.size * 32\n );\n }\n\n #key(row: Row): unknown {\n const single = this.#singleColumnKey;\n if (single !== undefined) {\n return row[single];\n }\n const key = this.#primaryKey.map(k => row[k]);\n return JSON.stringify(key);\n }\n\n #track(row: Row, key: unknown): void {\n if (this.#byKey.has(key)) {\n return;\n }\n this.#rowBytes += 64 + estimateBytes(key as Value);\n if (this.#singleColumnKey === undefined) {\n this.#firstKeyValues.add(row[this.#primaryKey[0]]);\n }\n }\n\n /** Records that `row` is now present with this value. */\n set(row: Row): void {\n const key = this.#key(row);\n const existing = this.#byKey.get(key);\n this.#track(row, key);\n this.#rowBytes +=\n estimateBytes(row) -\n (existing === undefined ? 0 : estimateBytes(existing));\n if (existing !== undefined) {\n // A live row for this key is already indexed under its old value, which\n // may sort differently. Retract it before inserting the new one.\n this.#removeFromIndexes(existing);\n this.#liveCount--;\n }\n this.#byKey.set(key, row);\n this.#addToIndexes(row);\n this.#liveCount++;\n }\n\n /** Records that `row` is now absent. */\n delete(row: Row): void {\n const key = this.#key(row);\n const existing = this.#byKey.get(key);\n this.#track(row, key);\n if (existing !== undefined) {\n this.#rowBytes -= estimateBytes(existing);\n this.#removeFromIndexes(existing);\n this.#liveCount--;\n }\n this.#byKey.set(key, undefined);\n }\n\n /**\n * Whether the batch overrides this base row. Callers use it to suppress base\n * rows during a merge, so it must be answered by primary key -- the value\n * carried by the base row is exactly what the delta is replacing.\n */\n overrides(row: Row): boolean {\n if (\n this.#singleColumnKey === undefined &&\n !this.#firstKeyValues.has(row[this.#primaryKey[0]])\n ) {\n return false;\n }\n return this.#byKey.has(this.#key(row));\n }\n\n /**\n * The batch's value for a row, by primary key. Returns `NOT_OVERRIDDEN` when\n * the batch has not touched the key at all (so the caller should consult the\n * base) and `undefined` when the batch removed it.\n */\n get(row: Row): Row | undefined | typeof NOT_OVERRIDDEN {\n const key = this.#key(row);\n if (!this.#byKey.has(key)) {\n return NOT_OVERRIDDEN;\n }\n return this.#byKey.get(key);\n }\n\n /**\n * Looks a row up by an arbitrary (not necessarily primary) unique key. Only\n * reachable when the delta is non-empty, which is never the case for the one\n * caller that uses a non-primary key, so a walk is fine here.\n */\n getByColumns(keyCols: readonly string[], keyRow: Row): Row | undefined {\n for (const row of this.#byKey.values()) {\n if (row !== undefined && keyCols.every(c => row[c] === keyRow[c])) {\n return row;\n }\n }\n return undefined;\n }\n\n #addToIndexes(row: Row): void {\n for (const data of this.#indexes.values()) {\n data.add(row);\n }\n }\n\n #removeFromIndexes(row: Row): void {\n for (const data of this.#indexes.values()) {\n data.delete(row);\n }\n }\n\n #getOrCreateIndex(sort: Ordering): BTreeSet<Row> {\n const indexKey = JSON.stringify(sort);\n let data = this.#indexes.get(indexKey);\n if (data === undefined) {\n data = new BTreeSet<Row>(makeBoundComparator(sort) as Comparator);\n for (const row of this.#byKey.values()) {\n if (row !== undefined) {\n data.add(row);\n }\n }\n this.#indexes.set(indexKey, data);\n this.#indexBytes += 128 + estimateBytes(indexKey) + estimateBytes(sort);\n }\n return data;\n }\n\n /**\n * The live rows this batch contributes to a fetch, in the same order the\n * backing SQL query returns its rows, so the two streams can be merged.\n *\n * `constraint`, `multiConstraints` and `filterPredicate` are the ones SQL\n * already applied to the base rows; they are applied here so the delta rows\n * are subject to the same query. `start` is the fetch's start row: the scan\n * begins there rather than at the start of the constraint span. It is\n * inclusive, so the caller still applies an `after` basis.\n */\n *rowsFor(\n sort: Ordering,\n constraint: Constraint | undefined,\n reverse: boolean | undefined,\n filterPredicate: ((row: Row) => boolean | undefined) | undefined,\n multiConstraints: readonly MultiConstraint[] | undefined,\n start?: Row | undefined,\n ): Iterable<Row> {\n if (this.#liveCount === 0) {\n return;\n }\n\n // Lead the index with the constraint keys so a constrained fetch scans\n // only the matching span; within that span rows come out in `sort` order,\n // which is the order SQL returned the base rows in.\n const indexSort: OrderPart[] = [];\n if (constraint) {\n for (const key of Object.keys(constraint)) {\n indexSort.push([key, 'asc']);\n }\n }\n // Constraining by the whole primary key admits at most one row, so the\n // requested sort adds nothing.\n const sorted =\n !constraint || !constraintMatchesPrimaryKey(constraint, this.#primaryKey);\n if (sorted) {\n indexSort.push(...sort);\n }\n\n const data = this.#getOrCreateIndex(indexSort);\n\n let scanStart: RowBound | undefined;\n if (\n start !== undefined &&\n sorted &&\n (!constraint || constraintMatchesRow(constraint, start))\n ) {\n // `start` carries every index column, and within the constraint span it\n // agrees with the constraint, so it is the scan's bound as it stands.\n // A `start` outside the span bounds nothing the scan can use.\n scanStart = start;\n } else if (constraint) {\n // The first row matching the constraint is not simply the constraint\n // values with everything else absent: a `desc` part puts absent values\n // last. The min/max sentinels say \"the first row with these constraint\n // values\" regardless of direction. Same construction as `MemorySource`.\n scanStart = {};\n for (const [key, dir] of indexSort) {\n if (hasOwn(constraint, key)) {\n scanStart[key] = constraint[key] as Value;\n } else if (reverse) {\n scanStart[key] = dir === 'asc' ? maxValue : minValue;\n } else {\n scanStart[key] = dir === 'asc' ? minValue : maxValue;\n }\n }\n }\n\n for (const row of generateRows(data, scanStart, reverse)) {\n if (constraint && !constraintMatchesRow(constraint, row)) {\n // Rows are sorted by the constraint keys first, so matches are\n // contiguous and the first miss ends the span.\n break;\n }\n if (multiConstraints && !matchesMultiConstraints(row, multiConstraints)) {\n continue;\n }\n if (filterPredicate && !filterPredicate(row)) {\n continue;\n }\n yield row;\n }\n }\n\n /**\n * A row with the primary key of each row the batch has touched, removed\n * rows included. A live row is returned as is.\n */\n *touchedKeys(): Iterable<Row> {\n const single = this.#singleColumnKey;\n for (const [key, row] of this.#byKey) {\n if (row !== undefined) {\n yield row;\n } else if (single !== undefined) {\n yield {[single]: key as Value};\n } else {\n const values = JSON.parse(key as string) as Value[];\n yield Object.fromEntries(\n this.#primaryKey.map((k, i) => [k, values[i]]),\n );\n }\n }\n }\n\n /** The rows the batch has added or edited, and not since removed. */\n *liveRows(): Iterable<Row> {\n for (const row of this.#byKey.values()) {\n if (row !== undefined) {\n yield row;\n }\n }\n }\n\n /** Drops the batch. Called when the source moves to a snapshot that has it. */\n clear(): void {\n this.#byKey.clear();\n this.#firstKeyValues.clear();\n this.#indexes.clear();\n this.#liveCount = 0;\n this.#rowBytes = 0;\n this.#indexBytes = 0;\n }\n}\n\n// Allow for object/property storage and UTF-16 strings without allocating a\n// serialized copy. Shared values may be counted more than once intentionally.\nfunction estimateBytes(value: Value): number {\n if (typeof value === 'string') {\n return 24 + value.length * 2;\n }\n if (value === null || typeof value !== 'object') {\n return 8;\n }\n let bytes = 32;\n if (Array.isArray(value)) {\n for (const item of value) {\n bytes += 8 + estimateBytes(item);\n }\n } else {\n for (const key in value) {\n bytes += 16 + estimateBytes(key) + estimateBytes((value as Row)[key]);\n }\n }\n return bytes;\n}\n\nexport const NOT_OVERRIDDEN = Symbol('not-overridden');\n\nfunction matchesMultiConstraints(\n row: Row,\n multiConstraints: readonly MultiConstraint[],\n): boolean {\n for (const mc of multiConstraints) {\n if (mc.length === 0) {\n continue;\n }\n let any = false;\n for (const c of mc) {\n if (constraintMatchesRow(c, row)) {\n any = true;\n break;\n }\n }\n if (!any) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Merges a batch's rows into an ordered base stream and drops the base rows\n * the batch overrides.\n *\n * Both streams must already be in `compare` order. A delta row that ties with\n * a base row is the *same* row by primary key -- every fetch ordering includes\n * the primary key -- so the base copy is suppressed and the delta's value\n * takes its place at that position.\n */\nexport function* generateWithPendingDelta(\n baseRows: Iterable<Row>,\n deltaRows: Iterable<Row>,\n delta: PendingDelta,\n compare: Comparator,\n): IterableIterator<Row> {\n const deltaIter = deltaRows[Symbol.iterator]();\n let pending = deltaIter.next();\n try {\n for (const row of baseRows) {\n while (!pending.done && compare(pending.value, row) < 0) {\n yield pending.value;\n pending = deltaIter.next();\n }\n if (!delta.overrides(row)) {\n yield row;\n }\n }\n while (!pending.done) {\n yield pending.value;\n pending = deltaIter.next();\n }\n } finally {\n // Propagate early termination so the delta iterator can release the BTree\n // cursor it is walking, the same contract `mergeSortedStreams` documents.\n if (!pending.done) {\n deltaIter.return?.(undefined);\n }\n }\n}\n\n/**\n * The unordered counterpart. Nothing downstream depends on position, so the\n * surviving base rows are emitted first and the batch's rows follow.\n */\nexport function* generateWithPendingDeltaUnordered(\n baseRows: Iterable<Row>,\n deltaRows: Iterable<Row>,\n delta: PendingDelta,\n): IterableIterator<Row> {\n for (const row of baseRows) {\n if (!delta.overrides(row)) {\n yield row;\n }\n }\n yield* deltaRows;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"pending-delta.js","names":[],"sources":["../../../../zqlite/src/pending-delta.ts"],"sourcesContent":["import {BTreeSet} from '../../shared/src/btree-set.ts';\nimport {hasOwn} from '../../shared/src/has-own.ts';\nimport {assignProperty} from '../../shared/src/objects.ts';\nimport type {Ordering, OrderPart} from '../../zero-protocol/src/ast.ts';\nimport type {Row, Value} from '../../zero-protocol/src/data.ts';\nimport type {PrimaryKey} from '../../zero-protocol/src/primary-key.ts';\nimport {\n constraintMatchesPrimaryKey,\n constraintMatchesRow,\n type Constraint,\n} from '../../zql/src/ivm/constraint.ts';\nimport type {Comparator} from '../../zql/src/ivm/data.ts';\nimport {\n generateRows,\n makeBoundComparator,\n maxValue,\n minValue,\n type RowBound,\n} from '../../zql/src/ivm/memory-source.ts';\nimport type {MultiConstraint} from '../../zql/src/ivm/operator.ts';\n\n/**\n * The batch overlay that lets a `TableSource` derive a transaction without\n * writing to the database it is reading from.\n *\n * A `TableSource` normally makes each change durable in its backing SQLite\n * connection as soon as it has been vended to every output, because change\n * *k+1* has to read a base that already includes changes *1..k* -- IVM's\n * joins fetch from the source mid-push. On the server that backing connection\n * is a `BEGIN CONCURRENT` snapshot that is never committed and always rolled\n * back, so those writes exist only to serve reads for the rest of the pass.\n *\n * A `PendingDelta` holds them in memory instead. The base stays pinned at the\n * state it had when the pass began and this object supplies *1..k*, merged\n * into every leaf scan. The durable copy comes from the replicator's own\n * commit, which the source picks up when it leapfrogs to the next snapshot.\n *\n * State is coalesced by primary key: whatever the batch did to a row, all that\n * matters downstream is the row's final value, or that it is gone. A key that\n * appears here overrides the base unconditionally -- an added row has no base\n * to override, an edited row's base copy is suppressed in favor of the new\n * value, and a removed row's base copy is suppressed with nothing to put in\n * its place.\n *\n * Live rows are additionally kept in lazily built sorted indexes, one per\n * `[...constraintKeys, ...sort]` shape a fetch has asked for, so that merging\n * the delta into a constrained scan costs `O(log D + matches)` rather than a\n * walk of the whole delta. This mirrors `MemorySource`'s index handling; see\n * its `#fetch` for the bound construction the scans here reproduce.\n */\nexport class PendingDelta {\n readonly #primaryKey: PrimaryKey;\n readonly #singleColumnKey: string | undefined;\n\n /**\n * For a composite primary key, the first key column's value of every key in\n * `#byKey`. {@link overrides} runs for every base row of a merged fetch, and\n * building a composite key allocates, so this rules most rows out first.\n */\n readonly #firstKeyValues = new Set<Value>();\n\n /**\n * The coalesced net state, keyed by primary key. A `undefined` value is a\n * tombstone: the batch removed the row, so the base copy is suppressed and\n * nothing replaces it. Membership alone is what suppresses a base row, so\n * this map is also the \"is this key overridden\" test.\n */\n readonly #byKey = new Map<unknown, Row | undefined>();\n\n /** Sorted views over the live (non-tombstone) rows, keyed by `JSON(sort)`. */\n readonly #indexes = new Map<string, BTreeSet<Row>>();\n\n #liveCount = 0;\n #rowBytes = 0;\n #indexBytes = 0;\n\n constructor(primaryKey: PrimaryKey) {\n this.#primaryKey = primaryKey;\n this.#singleColumnKey = primaryKey.length === 1 ? primaryKey[0] : undefined;\n }\n\n /**\n * True when the source can take its untouched fast path: no suppression\n * test per base row, no merge, no index maintenance.\n */\n get isEmpty(): boolean {\n return this.#byKey.size === 0;\n }\n\n /** The number of rows the batch has touched, tombstones included. */\n get size(): number {\n return this.#byKey.size;\n }\n\n /**\n * Estimated retained bytes, including keys, tombstones, and sorted indexes.\n * This is a budgeting heuristic, not a measurement of the JavaScript heap.\n */\n get estimatedBytes(): number {\n // Budget 32 bytes per live row per index for references and B-tree nodes.\n return (\n this.#rowBytes +\n this.#indexBytes +\n this.#liveCount * this.#indexes.size * 32\n );\n }\n\n #key(row: Row): unknown {\n const single = this.#singleColumnKey;\n if (single !== undefined) {\n return row[single];\n }\n const key = this.#primaryKey.map(k => row[k]);\n return JSON.stringify(key);\n }\n\n #track(row: Row, key: unknown): void {\n if (this.#byKey.has(key)) {\n return;\n }\n this.#rowBytes += 64 + estimateBytes(key as Value);\n if (this.#singleColumnKey === undefined) {\n this.#firstKeyValues.add(row[this.#primaryKey[0]]);\n }\n }\n\n /** Records that `row` is now present with this value. */\n set(row: Row): void {\n const key = this.#key(row);\n const existing = this.#byKey.get(key);\n this.#track(row, key);\n this.#rowBytes +=\n estimateBytes(row) -\n (existing === undefined ? 0 : estimateBytes(existing));\n if (existing !== undefined) {\n // A live row for this key is already indexed under its old value, which\n // may sort differently. Retract it before inserting the new one.\n this.#removeFromIndexes(existing);\n this.#liveCount--;\n }\n this.#byKey.set(key, row);\n this.#addToIndexes(row);\n this.#liveCount++;\n }\n\n /** Records that `row` is now absent. */\n delete(row: Row): void {\n const key = this.#key(row);\n const existing = this.#byKey.get(key);\n this.#track(row, key);\n if (existing !== undefined) {\n this.#rowBytes -= estimateBytes(existing);\n this.#removeFromIndexes(existing);\n this.#liveCount--;\n }\n this.#byKey.set(key, undefined);\n }\n\n /**\n * Whether the batch overrides this base row. Callers use it to suppress base\n * rows during a merge, so it must be answered by primary key -- the value\n * carried by the base row is exactly what the delta is replacing.\n */\n overrides(row: Row): boolean {\n if (\n this.#singleColumnKey === undefined &&\n !this.#firstKeyValues.has(row[this.#primaryKey[0]])\n ) {\n return false;\n }\n return this.#byKey.has(this.#key(row));\n }\n\n /**\n * The batch's value for a row, by primary key. Returns `NOT_OVERRIDDEN` when\n * the batch has not touched the key at all (so the caller should consult the\n * base) and `undefined` when the batch removed it.\n */\n get(row: Row): Row | undefined | typeof NOT_OVERRIDDEN {\n const key = this.#key(row);\n if (!this.#byKey.has(key)) {\n return NOT_OVERRIDDEN;\n }\n return this.#byKey.get(key);\n }\n\n /**\n * Looks a row up by an arbitrary (not necessarily primary) unique key. Only\n * reachable when the delta is non-empty, which is never the case for the one\n * caller that uses a non-primary key, so a walk is fine here.\n */\n getByColumns(keyCols: readonly string[], keyRow: Row): Row | undefined {\n for (const row of this.#byKey.values()) {\n if (row !== undefined && keyCols.every(c => row[c] === keyRow[c])) {\n return row;\n }\n }\n return undefined;\n }\n\n #addToIndexes(row: Row): void {\n for (const data of this.#indexes.values()) {\n data.add(row);\n }\n }\n\n #removeFromIndexes(row: Row): void {\n for (const data of this.#indexes.values()) {\n data.delete(row);\n }\n }\n\n #getOrCreateIndex(sort: Ordering): BTreeSet<Row> {\n const indexKey = JSON.stringify(sort);\n let data = this.#indexes.get(indexKey);\n if (data === undefined) {\n data = new BTreeSet<Row>(makeBoundComparator(sort) as Comparator);\n for (const row of this.#byKey.values()) {\n if (row !== undefined) {\n data.add(row);\n }\n }\n this.#indexes.set(indexKey, data);\n this.#indexBytes += 128 + estimateBytes(indexKey) + estimateBytes(sort);\n }\n return data;\n }\n\n /**\n * The live rows this batch contributes to a fetch, in the same order the\n * backing SQL query returns its rows, so the two streams can be merged.\n *\n * `constraint`, `multiConstraints` and `filterPredicate` are the ones SQL\n * already applied to the base rows; they are applied here so the delta rows\n * are subject to the same query. `start` is the fetch's start row: the scan\n * begins there rather than at the start of the constraint span. It is\n * inclusive, so the caller still applies an `after` basis.\n */\n *rowsFor(\n sort: Ordering,\n constraint: Constraint | undefined,\n reverse: boolean | undefined,\n filterPredicate: ((row: Row) => boolean | undefined) | undefined,\n multiConstraints: readonly MultiConstraint[] | undefined,\n start?: Row | undefined,\n ): Iterable<Row> {\n if (this.#liveCount === 0) {\n return;\n }\n\n // Lead the index with the constraint keys so a constrained fetch scans\n // only the matching span; within that span rows come out in `sort` order,\n // which is the order SQL returned the base rows in.\n const indexSort: OrderPart[] = [];\n if (constraint) {\n for (const key of Object.keys(constraint)) {\n indexSort.push([key, 'asc']);\n }\n }\n // Constraining by the whole primary key admits at most one row, so the\n // requested sort adds nothing.\n const sorted =\n !constraint || !constraintMatchesPrimaryKey(constraint, this.#primaryKey);\n if (sorted) {\n indexSort.push(...sort);\n }\n\n const data = this.#getOrCreateIndex(indexSort);\n\n let scanStart: RowBound | undefined;\n if (\n start !== undefined &&\n sorted &&\n (!constraint || constraintMatchesRow(constraint, start))\n ) {\n // `start` carries every index column, and within the constraint span it\n // agrees with the constraint, so it is the scan's bound as it stands.\n // A `start` outside the span bounds nothing the scan can use.\n scanStart = start;\n } else if (constraint) {\n // The first row matching the constraint is not simply the constraint\n // values with everything else absent: a `desc` part puts absent values\n // last. The min/max sentinels say \"the first row with these constraint\n // values\" regardless of direction. Same construction as `MemorySource`.\n scanStart = {};\n for (const [key, dir] of indexSort) {\n if (hasOwn(constraint, key)) {\n assignProperty(scanStart, key, constraint[key] as Value);\n } else if (reverse) {\n assignProperty(scanStart, key, dir === 'asc' ? maxValue : minValue);\n } else {\n assignProperty(scanStart, key, dir === 'asc' ? minValue : maxValue);\n }\n }\n }\n\n for (const row of generateRows(data, scanStart, reverse)) {\n if (constraint && !constraintMatchesRow(constraint, row)) {\n // Rows are sorted by the constraint keys first, so matches are\n // contiguous and the first miss ends the span.\n break;\n }\n if (multiConstraints && !matchesMultiConstraints(row, multiConstraints)) {\n continue;\n }\n if (filterPredicate && !filterPredicate(row)) {\n continue;\n }\n yield row;\n }\n }\n\n /**\n * A row with the primary key of each row the batch has touched, removed\n * rows included. A live row is returned as is.\n */\n *touchedKeys(): Iterable<Row> {\n const single = this.#singleColumnKey;\n for (const [key, row] of this.#byKey) {\n if (row !== undefined) {\n yield row;\n } else if (single !== undefined) {\n yield {[single]: key as Value};\n } else {\n const values = JSON.parse(key as string) as Value[];\n yield Object.fromEntries(\n this.#primaryKey.map((k, i) => [k, values[i]]),\n );\n }\n }\n }\n\n /** The rows the batch has added or edited, and not since removed. */\n *liveRows(): Iterable<Row> {\n for (const row of this.#byKey.values()) {\n if (row !== undefined) {\n yield row;\n }\n }\n }\n\n /** Drops the batch. Called when the source moves to a snapshot that has it. */\n clear(): void {\n this.#byKey.clear();\n this.#firstKeyValues.clear();\n this.#indexes.clear();\n this.#liveCount = 0;\n this.#rowBytes = 0;\n this.#indexBytes = 0;\n }\n}\n\n// Allow for object/property storage and UTF-16 strings without allocating a\n// serialized copy. Shared values may be counted more than once intentionally.\nfunction estimateBytes(value: Value): number {\n if (typeof value === 'string') {\n return 24 + value.length * 2;\n }\n if (value === null || typeof value !== 'object') {\n return 8;\n }\n let bytes = 32;\n if (Array.isArray(value)) {\n for (const item of value) {\n bytes += 8 + estimateBytes(item);\n }\n } else {\n for (const key in value) {\n bytes += 16 + estimateBytes(key) + estimateBytes((value as Row)[key]);\n }\n }\n return bytes;\n}\n\nexport const NOT_OVERRIDDEN = Symbol('not-overridden');\n\nfunction matchesMultiConstraints(\n row: Row,\n multiConstraints: readonly MultiConstraint[],\n): boolean {\n for (const mc of multiConstraints) {\n if (mc.length === 0) {\n continue;\n }\n let any = false;\n for (const c of mc) {\n if (constraintMatchesRow(c, row)) {\n any = true;\n break;\n }\n }\n if (!any) {\n return false;\n }\n }\n return true;\n}\n\n/**\n * Merges a batch's rows into an ordered base stream and drops the base rows\n * the batch overrides.\n *\n * Both streams must already be in `compare` order. A delta row that ties with\n * a base row is the *same* row by primary key -- every fetch ordering includes\n * the primary key -- so the base copy is suppressed and the delta's value\n * takes its place at that position.\n */\nexport function* generateWithPendingDelta(\n baseRows: Iterable<Row>,\n deltaRows: Iterable<Row>,\n delta: PendingDelta,\n compare: Comparator,\n): IterableIterator<Row> {\n const deltaIter = deltaRows[Symbol.iterator]();\n let pending = deltaIter.next();\n try {\n for (const row of baseRows) {\n while (!pending.done && compare(pending.value, row) < 0) {\n yield pending.value;\n pending = deltaIter.next();\n }\n if (!delta.overrides(row)) {\n yield row;\n }\n }\n while (!pending.done) {\n yield pending.value;\n pending = deltaIter.next();\n }\n } finally {\n // Propagate early termination so the delta iterator can release the BTree\n // cursor it is walking, the same contract `mergeSortedStreams` documents.\n if (!pending.done) {\n deltaIter.return?.(undefined);\n }\n }\n}\n\n/**\n * The unordered counterpart. Nothing downstream depends on position, so the\n * surviving base rows are emitted first and the batch's rows follow.\n */\nexport function* generateWithPendingDeltaUnordered(\n baseRows: Iterable<Row>,\n deltaRows: Iterable<Row>,\n delta: PendingDelta,\n): IterableIterator<Row> {\n for (const row of baseRows) {\n if (!delta.overrides(row)) {\n yield row;\n }\n }\n yield* deltaRows;\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { SQLQuery } from '@databases/sql';
|
|
2
|
-
import type
|
|
2
|
+
import { type Condition, type Ordering } from '../../zero-protocol/src/ast.ts';
|
|
3
3
|
import type { SchemaValue, ValueType } from '../../zero-schema/src/table-schema.ts';
|
|
4
4
|
import type { Constraint } from '../../zql/src/ivm/constraint.ts';
|
|
5
|
-
import type { MultiConstraint, Start } from '../../zql/src/ivm/operator.ts';
|
|
5
|
+
import type { FetchRequest, MultiConstraint, Start } from '../../zql/src/ivm/operator.ts';
|
|
6
6
|
/**
|
|
7
7
|
* Condition type without correlated subqueries.
|
|
8
8
|
* This matches the output of transformFilters from zql/builder/filter.ts
|
|
@@ -22,12 +22,22 @@ export type NoSubqueryCondition = Exclude<Condition, {
|
|
|
22
22
|
* rows, and a fetch that stops early never needs to run the second.
|
|
23
23
|
*/
|
|
24
24
|
export declare function buildSelectQueries(tableName: string, columns: Record<string, SchemaValue>, constraint: Constraint | undefined, filters: NoSubqueryCondition | undefined, order: Ordering | undefined, reverse: boolean | undefined, start: Start | undefined, multiConstraints?: readonly MultiConstraint[] | undefined, fetchFilters?: NoSubqueryCondition | undefined): [SQLQuery] | [SQLQuery, SQLQuery];
|
|
25
|
+
/**
|
|
26
|
+
* `SELECT COUNT(*)` over the rows a fetch with `constraint` and `filters`
|
|
27
|
+
* returns. Without an `ORDER BY`, SQLite counts entries of whichever index
|
|
28
|
+
* covers the `WHERE` rather than reading and sorting the rows.
|
|
29
|
+
*/
|
|
30
|
+
export declare function buildCountQuery(tableName: string, columns: Record<string, SchemaValue>, constraint: Constraint | undefined, filters: NoSubqueryCondition | undefined): SQLQuery;
|
|
31
|
+
/**
|
|
32
|
+
* The distinct values of `groupColumns` among the rows that pass `filters`,
|
|
33
|
+
* each followed by its number of rows, in no particular order.
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildGroupCountsQuery(tableName: string, groupColumns: readonly string[], filters: NoSubqueryCondition | undefined): SQLQuery;
|
|
25
36
|
/**
|
|
26
37
|
* {@link buildSelectQueries} for a fetch that needs only one SELECT, such as
|
|
27
38
|
* one without a start row.
|
|
28
39
|
*/
|
|
29
40
|
export declare function buildSelectQuery(...args: Parameters<typeof buildSelectQueries>): SQLQuery;
|
|
30
|
-
export declare function constraintsToSQL(constraint: Constraint | undefined, columns: Record<string, SchemaValue>): SQLQuery[];
|
|
31
41
|
/**
|
|
32
42
|
* Builds a single batched IN clause from a `MultiConstraint`. All entries
|
|
33
43
|
* are assumed to share the same shape (the keys of the first entry);
|
|
@@ -40,11 +50,20 @@ export declare function constraintsToSQL(constraint: Constraint | undefined, col
|
|
|
40
50
|
* verified via EXPLAIN QUERY PLAN — see query-builder.test.ts.
|
|
41
51
|
*/
|
|
42
52
|
export declare function multiConstraintToSQL(multiConstraint: MultiConstraint, columns: Record<string, SchemaValue>): SQLQuery;
|
|
43
|
-
export declare function orderByToSQL(order: Ordering, reverse: boolean): SQLQuery;
|
|
44
53
|
/**
|
|
45
54
|
* Converts filters (conditions) to SQL WHERE clause.
|
|
46
55
|
* This applies all filters present in the AST for a query to the source.
|
|
47
56
|
*/
|
|
48
57
|
export declare function filtersToSQL(filters: NoSubqueryCondition): SQLQuery;
|
|
49
58
|
export declare function toSQLiteType(v: unknown, type: ValueType): unknown;
|
|
59
|
+
/**
|
|
60
|
+
* A placeholder for a fetch's value that {@link buildSelectQueries} passes
|
|
61
|
+
* through to the bindings of its SELECTs, where `toSQLiteType` would convert
|
|
62
|
+
* the value itself. It lets a fetch's SQL text be built once and reused for
|
|
63
|
+
* every fetch of the same shape (see `fetch-sql.ts`).
|
|
64
|
+
*/
|
|
65
|
+
export declare class Binding {
|
|
66
|
+
readonly get: (req: FetchRequest) => unknown;
|
|
67
|
+
constructor(get: (req: FetchRequest) => unknown);
|
|
68
|
+
}
|
|
50
69
|
//# sourceMappingURL=query-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-builder.d.ts","sourceRoot":"","sources":["../../../../zqlite/src/query-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAE7C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"query-builder.d.ts","sourceRoot":"","sources":["../../../../zqlite/src/query-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EAIL,KAAK,SAAS,EAEd,KAAK,QAAQ,EAGd,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACV,MAAM,uCAAuC,CAAC;AAE/C,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EACV,YAAY,EACZ,eAAe,EACf,KAAK,EACN,MAAM,+BAA+B,CAAC;AAGvC;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,OAAO,CACvC,SAAS,EACT;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAC,CAC7B,CAAC;AAEF;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACpC,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,OAAO,EAAE,mBAAmB,GAAG,SAAS,EACxC,KAAK,EAAE,QAAQ,GAAG,SAAS,EAC3B,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,gBAAgB,CAAC,EAAE,SAAS,eAAe,EAAE,GAAG,SAAS,EACzD,YAAY,CAAC,EAAE,mBAAmB,GAAG,SAAS,GAC7C,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CA4DnC;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACpC,UAAU,EAAE,UAAU,GAAG,SAAS,EAClC,OAAO,EAAE,mBAAmB,GAAG,SAAS,GACvC,QAAQ,CASV;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,SAAS,MAAM,EAAE,EAC/B,OAAO,EAAE,mBAAmB,GAAG,SAAS,GACvC,QAAQ,CASV;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,GAC7C,QAAQ,CAOV;AA4ED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,eAAe,EAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,GACnC,QAAQ,CAyCV;AAuBD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,QAAQ,CAuBnE;AA6MD,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAWjE;AAED;;;;;GAKG;AACH,qBAAa,OAAO;IAClB,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,CAAC;IAC7C,YAAY,GAAG,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,OAAO,EAE9C;CACF"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { assert } from "../../shared/src/asserts.js";
|
|
1
|
+
import { assert, unreachable } from "../../shared/src/asserts.js";
|
|
2
|
+
import { isLikeOperator, isNegatedOperator, jsonLiteralType } from "../../zero-protocol/src/ast.js";
|
|
3
|
+
import { valueTypeOf } from "../../zero-types/src/schema-value.js";
|
|
2
4
|
import { sql } from "./internal/sql.js";
|
|
3
5
|
//#region ../zqlite/src/query-builder.ts
|
|
4
6
|
/**
|
|
@@ -43,6 +45,26 @@ function buildSelectQueries(tableName, columns, constraint, filters, order, reve
|
|
|
43
45
|
])];
|
|
44
46
|
}
|
|
45
47
|
/**
|
|
48
|
+
* `SELECT COUNT(*)` over the rows a fetch with `constraint` and `filters`
|
|
49
|
+
* returns. Without an `ORDER BY`, SQLite counts entries of whichever index
|
|
50
|
+
* covers the `WHERE` rather than reading and sorting the rows.
|
|
51
|
+
*/
|
|
52
|
+
function buildCountQuery(tableName, columns, constraint, filters) {
|
|
53
|
+
const where = constraintsToSQL(constraint, columns);
|
|
54
|
+
if (filters) where.push(filtersToSQL(filters));
|
|
55
|
+
const select = sql`SELECT COUNT(*) FROM ${sql.ident(tableName)}`;
|
|
56
|
+
return where.length > 0 ? sql`${select} WHERE ${sql.join(where, sql` AND `)}` : select;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The distinct values of `groupColumns` among the rows that pass `filters`,
|
|
60
|
+
* each followed by its number of rows, in no particular order.
|
|
61
|
+
*/
|
|
62
|
+
function buildGroupCountsQuery(tableName, groupColumns, filters) {
|
|
63
|
+
const cols = sql.join(groupColumns.map((c) => sql.ident(c)), sql`, `);
|
|
64
|
+
const select = sql`SELECT ${cols}, COUNT(*) FROM ${sql.ident(tableName)}`;
|
|
65
|
+
return filters ? sql`${select} WHERE ${filtersToSQL(filters)} GROUP BY ${cols}` : sql`${select} GROUP BY ${cols}`;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
46
68
|
* {@link buildSelectQueries} for a fetch that needs only one SELECT, such as
|
|
47
69
|
* one without a start row.
|
|
48
70
|
*/
|
|
@@ -87,7 +109,7 @@ function constraintsRejectNull(constraint, multiConstraints, field) {
|
|
|
87
109
|
function constraintsToSQL(constraint, columns) {
|
|
88
110
|
if (!constraint) return [];
|
|
89
111
|
const constraints = [];
|
|
90
|
-
for (const [key, value] of Object.entries(constraint)) constraints.push(sql`${sql.ident(key)} = ${
|
|
112
|
+
for (const [key, value] of Object.entries(constraint)) constraints.push(sql`${sql.ident(key)} = ${toSQLiteBinding(value, columns[key].type)}`);
|
|
91
113
|
return constraints;
|
|
92
114
|
}
|
|
93
115
|
/**
|
|
@@ -112,10 +134,10 @@ function multiConstraintToSQL(multiConstraint, columns) {
|
|
|
112
134
|
if (keys.length === 1) {
|
|
113
135
|
const key = keys[0];
|
|
114
136
|
const colType = columns[key].type;
|
|
115
|
-
return sql`${sql.ident(key)} IN (${sql.join(multiConstraint.map((c) => sql`${
|
|
137
|
+
return sql`${sql.ident(key)} IN (${sql.join(multiConstraint.map((c) => sql`${toSQLiteBinding(c[key], colType)}`), sql`,`)})`;
|
|
116
138
|
}
|
|
117
139
|
const colList = sql`(${sql.join(keys.map((k) => sql.ident(k)), sql`,`)})`;
|
|
118
|
-
const rows = multiConstraint.map((c) => sql`(${sql.join(keys.map((k) => sql`${
|
|
140
|
+
const rows = multiConstraint.map((c) => sql`(${sql.join(keys.map((k) => sql`${toSQLiteBinding(c[k], columns[k].type)}`), sql`,`)})`);
|
|
119
141
|
return sql`${colList} IN (VALUES ${sql.join(rows, sql`,`)})`;
|
|
120
142
|
}
|
|
121
143
|
function orderByToSQL(order, reverse) {
|
|
@@ -134,36 +156,115 @@ function filtersToSQL(filters) {
|
|
|
134
156
|
}
|
|
135
157
|
}
|
|
136
158
|
function simpleConditionToSQL(filter) {
|
|
159
|
+
if (filter.left.type === "json") {
|
|
160
|
+
const json = jsonPathConditionToSQL(filter, filter.left);
|
|
161
|
+
if (json) return json;
|
|
162
|
+
}
|
|
163
|
+
return comparisonToSQL(filter, valuePositionToSQL(filter.left));
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Renders `filter`'s operator and right operand against an already-rendered
|
|
167
|
+
* left operand.
|
|
168
|
+
*/
|
|
169
|
+
function comparisonToSQL(filter, left) {
|
|
137
170
|
const { op } = filter;
|
|
138
171
|
if (op === "IN" || op === "NOT IN") switch (filter.right.type) {
|
|
139
|
-
case "literal": return sql`${
|
|
172
|
+
case "literal": return sql`${left} ${sql.__dangerous__rawValue(filter.op)} (SELECT value FROM json_each(${JSON.stringify(filter.right.value)}))`;
|
|
140
173
|
case "static": throw new Error("Static parameters must be replaced before conversion to SQL");
|
|
141
174
|
}
|
|
142
|
-
if (op === "LIKE" || op === "NOT LIKE" || op === "ILIKE" || op === "NOT ILIKE") return likeConditionToSQL(filter);
|
|
143
|
-
if ((op === "IS" || op === "IS NOT") && filter.right.type === "literal" && filter.right.value === null) return sql`${
|
|
144
|
-
return sql`${
|
|
175
|
+
if (op === "LIKE" || op === "NOT LIKE" || op === "ILIKE" || op === "NOT ILIKE") return likeConditionToSQL(filter, left);
|
|
176
|
+
if ((op === "IS" || op === "IS NOT") && filter.right.type === "literal" && filter.right.value === null) return sql`${left} ${sql.__dangerous__rawValue(op)} NULL`;
|
|
177
|
+
return sql`${left} ${sql.__dangerous__rawValue(filter.op)} ${valuePositionToSQL(filter.right)}`;
|
|
145
178
|
}
|
|
146
|
-
function likeConditionToSQL(filter) {
|
|
179
|
+
function likeConditionToSQL(filter, left) {
|
|
147
180
|
const { op } = filter;
|
|
148
181
|
const caseInsensitive = op === "ILIKE" || op === "NOT ILIKE";
|
|
149
182
|
const negated = op === "NOT LIKE" || op === "NOT ILIKE";
|
|
150
183
|
const likeOp = sql.__dangerous__rawValue(negated ? "NOT LIKE" : "LIKE");
|
|
151
|
-
const left = valuePositionToSQL(filter.left);
|
|
152
184
|
const right = valuePositionToSQL(filter.right);
|
|
153
185
|
if (caseInsensitive) return sql`lower(${left}) ${likeOp} lower(${right}) ESCAPE '\\'`;
|
|
154
186
|
return sql`${left} ${likeOp} ${right} ESCAPE '\\'`;
|
|
155
187
|
}
|
|
188
|
+
/** The extraction of a JSON path leaf (the path string is a bound parameter). */
|
|
189
|
+
function jsonExtract(ref) {
|
|
190
|
+
return sql`json_extract(${sql.ident(ref.value.name)}, ${jsonPathExpr(ref.path)})`;
|
|
191
|
+
}
|
|
192
|
+
/** The SQLite `json_type()` names a leaf may have for a JSON literal type. */
|
|
193
|
+
function jsonTypeNames(t) {
|
|
194
|
+
switch (t) {
|
|
195
|
+
case "string": return ["text"];
|
|
196
|
+
case "number": return ["integer", "real"];
|
|
197
|
+
case "boolean": return ["true", "false"];
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Compiles a comparison whose left operand is a JSON path, type-strictly, per
|
|
202
|
+
* the semantics documented on {@link JsonPathReference} (shared with the
|
|
203
|
+
* in-memory predicate and the Postgres compiler). Returns `undefined` where
|
|
204
|
+
* the generic rendering already agrees with the predicate.
|
|
205
|
+
*
|
|
206
|
+
* A bare `json_extract` would not be strict: SQLite returns booleans as 1/0 (so
|
|
207
|
+
* `true` = 1), orders any TEXT above any number (`'n/a' > 5`), and coerces
|
|
208
|
+
* numbers for LIKE. Gating the extraction on `json_type()` makes a mismatched
|
|
209
|
+
* leaf NULL, which a positive comparison excludes. Negated operators get an
|
|
210
|
+
* explicit CASE because NULL would exclude there too, where a mismatch must
|
|
211
|
+
* match: `json_type()` is NULL for a missing key and `'null'` for a JSON null,
|
|
212
|
+
* so one `COALESCE` covers the null guard without a second extraction.
|
|
213
|
+
*
|
|
214
|
+
* `IN`/`NOT IN` with a `null` literal is constant-false (as in the predicate),
|
|
215
|
+
* and an empty `NOT IN` matches every non-null leaf (bare `NULL NOT IN ()` is
|
|
216
|
+
* TRUE).
|
|
217
|
+
*/
|
|
218
|
+
function jsonPathConditionToSQL(filter, left) {
|
|
219
|
+
const { op, right } = filter;
|
|
220
|
+
if (right.type !== "literal") return;
|
|
221
|
+
if ((op === "IN" || op === "NOT IN") && right.value === null) return sql`FALSE`;
|
|
222
|
+
const col = sql.ident(left.value.name);
|
|
223
|
+
const path = jsonPathExpr(left.path);
|
|
224
|
+
const raw = sql`json_extract(${col}, ${path})`;
|
|
225
|
+
let cond = filter;
|
|
226
|
+
let t = jsonLiteralType(right.value);
|
|
227
|
+
if (isLikeOperator(op) && right.value !== null && !Array.isArray(right.value)) {
|
|
228
|
+
t = "string";
|
|
229
|
+
cond = {
|
|
230
|
+
...filter,
|
|
231
|
+
right: {
|
|
232
|
+
type: "literal",
|
|
233
|
+
value: String(right.value)
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
if (t === void 0) return op === "NOT IN" ? sql`${raw} IS NOT NULL` : void 0;
|
|
238
|
+
const types = jsonTypeNames(t);
|
|
239
|
+
if (!isNegatedOperator(op)) {
|
|
240
|
+
const typeList = sql.join(types.map((x) => sql`${x}`), sql`, `);
|
|
241
|
+
return comparisonToSQL(cond, sql`(CASE WHEN json_type(${col}, ${path}) IN (${typeList}) THEN ${raw} END)`);
|
|
242
|
+
}
|
|
243
|
+
const cmp = comparisonToSQL(cond, raw);
|
|
244
|
+
const whens = sql.join(types.map((x) => sql`WHEN ${x} THEN ${cmp}`), sql` `);
|
|
245
|
+
return sql`(CASE COALESCE(json_type(${col}, ${path}), 'null') WHEN 'null' THEN 0 ${whens} ELSE 1 END)`;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Builds a SQLite JSON path string (e.g. `$.a.b[0]`) from a path of object
|
|
249
|
+
* keys and array indices. Object keys are emitted as JSON string literals
|
|
250
|
+
* (`JSON.stringify`): SQLite parses a double-quoted path label with JSON
|
|
251
|
+
* escapes, so `"` and `\` inside a key must be backslash-escaped. SQL-style
|
|
252
|
+
* `""` doubling is not understood and yields NULL or a "bad JSON path" error.
|
|
253
|
+
*/
|
|
254
|
+
function jsonPathExpr(path) {
|
|
255
|
+
let s = "$";
|
|
256
|
+
for (const seg of path) s += typeof seg === "number" ? `[${seg}]` : `.${JSON.stringify(seg)}`;
|
|
257
|
+
return s;
|
|
258
|
+
}
|
|
156
259
|
function valuePositionToSQL(value) {
|
|
157
260
|
switch (value.type) {
|
|
158
261
|
case "column": return sql.ident(value.name);
|
|
159
|
-
case "
|
|
262
|
+
case "json": return jsonExtract(value);
|
|
263
|
+
case "literal": return sql`${toSQLiteType(value.value, valueTypeOf(value.value))}`;
|
|
160
264
|
case "static": throw new Error("Static parameters must be replaced before conversion to SQL");
|
|
265
|
+
default: unreachable(value);
|
|
161
266
|
}
|
|
162
267
|
}
|
|
163
|
-
function getJsType(value) {
|
|
164
|
-
if (value === null) return "null";
|
|
165
|
-
return typeof value === "string" ? "string" : typeof value === "number" ? "number" : typeof value === "boolean" ? "boolean" : "json";
|
|
166
|
-
}
|
|
167
268
|
function toSQLiteType(v, type) {
|
|
168
269
|
switch (type) {
|
|
169
270
|
case "boolean": return v === null ? null : v ? 1 : 0;
|
|
@@ -173,6 +274,21 @@ function toSQLiteType(v, type) {
|
|
|
173
274
|
case "json": return JSON.stringify(v);
|
|
174
275
|
}
|
|
175
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* A placeholder for a fetch's value that {@link buildSelectQueries} passes
|
|
279
|
+
* through to the bindings of its SELECTs, where `toSQLiteType` would convert
|
|
280
|
+
* the value itself. It lets a fetch's SQL text be built once and reused for
|
|
281
|
+
* every fetch of the same shape (see `fetch-sql.ts`).
|
|
282
|
+
*/
|
|
283
|
+
var Binding = class {
|
|
284
|
+
get;
|
|
285
|
+
constructor(get) {
|
|
286
|
+
this.get = get;
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
function toSQLiteBinding(v, type) {
|
|
290
|
+
return v instanceof Binding ? v : toSQLiteType(v, type);
|
|
291
|
+
}
|
|
176
292
|
function nullableAwareEquality(field, value, columnType) {
|
|
177
293
|
if (value === null) return sql`${sql.ident(field)} IS NULL`;
|
|
178
294
|
return columnType.optional === true ? sql`${sql.ident(field)} IS ${value}` : sql`${sql.ident(field)} = ${value}`;
|
|
@@ -226,7 +342,7 @@ function gatherStartConstraints(start, reverse, order, columnTypes) {
|
|
|
226
342
|
const [iField, iDirection] = order[i];
|
|
227
343
|
for (let j = 0; j <= i; j++) if (j === i) {
|
|
228
344
|
const columnType = columnTypes[iField];
|
|
229
|
-
const constraintValue =
|
|
345
|
+
const constraintValue = toSQLiteBinding(from[iField] ?? null, columnType.type);
|
|
230
346
|
const operator = iDirection === "asc" ? reverse ? "<" : ">" : reverse ? ">" : "<";
|
|
231
347
|
let nullGroupExcluded = false;
|
|
232
348
|
if (i === 0) {
|
|
@@ -237,14 +353,14 @@ function gatherStartConstraints(start, reverse, order, columnTypes) {
|
|
|
237
353
|
} else {
|
|
238
354
|
const [jField] = order[j];
|
|
239
355
|
const columnType = columnTypes[jField];
|
|
240
|
-
const value =
|
|
356
|
+
const value = toSQLiteBinding(from[jField] ?? null, columnType.type);
|
|
241
357
|
group.push(nullableAwareEquality(jField, value, columnType));
|
|
242
358
|
}
|
|
243
359
|
constraints.push(sql`(${sql.join(group, sql` AND `)})`);
|
|
244
360
|
}
|
|
245
361
|
if (basis === "at") constraints.push(sql`(${sql.join(order.map(([field]) => {
|
|
246
362
|
const columnType = columnTypes[field];
|
|
247
|
-
return nullableAwareEquality(field,
|
|
363
|
+
return nullableAwareEquality(field, toSQLiteBinding(from[field] ?? null, columnType.type), columnType);
|
|
248
364
|
}), sql` AND `)})`);
|
|
249
365
|
const lexicographicStart = sql`(${sql.join(constraints, sql` OR `)})`;
|
|
250
366
|
if (leadingBound === void 0) return {
|
|
@@ -257,6 +373,6 @@ function gatherStartConstraints(start, reverse, order, columnTypes) {
|
|
|
257
373
|
};
|
|
258
374
|
}
|
|
259
375
|
//#endregion
|
|
260
|
-
export { buildSelectQueries, buildSelectQuery, toSQLiteType };
|
|
376
|
+
export { Binding, buildCountQuery, buildGroupCountsQuery, buildSelectQueries, buildSelectQuery, filtersToSQL, multiConstraintToSQL, toSQLiteType };
|
|
261
377
|
|
|
262
378
|
//# sourceMappingURL=query-builder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-builder.js","names":[],"sources":["../../../../zqlite/src/query-builder.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport {assert} from '../../shared/src/asserts.ts';\nimport type {\n Condition,\n Ordering,\n SimpleCondition,\n ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport type {\n SchemaValue,\n ValueType,\n} from '../../zero-schema/src/table-schema.ts';\nimport type {Constraint} from '../../zql/src/ivm/constraint.ts';\nimport type {MultiConstraint, Start} from '../../zql/src/ivm/operator.ts';\nimport {sql} from './internal/sql.ts';\n\n/**\n * Condition type without correlated subqueries.\n * This matches the output of transformFilters from zql/builder/filter.ts\n */\nexport type NoSubqueryCondition = Exclude<\n Condition,\n {type: 'correlatedSubquery'}\n>;\n\n/**\n * Builds the SELECTs for a fetch. Running them in order and concatenating\n * their rows gives the fetch's rows, in order.\n *\n * There is a second SELECT only when the fetch starts at a non-NULL value of a\n * nullable leading sort column and walks towards its NULL group. The first\n * SELECT then leaves that group out so that SQLite can seek it (see\n * `gatherStartConstraints`), and the second fetches the group. NULLs sort\n * before every other value, so the group follows all of the first SELECT's\n * rows, and a fetch that stops early never needs to run the second.\n */\nexport function buildSelectQueries(\n tableName: string,\n columns: Record<string, SchemaValue>,\n constraint: Constraint | undefined,\n filters: NoSubqueryCondition | undefined,\n order: Ordering | undefined,\n reverse: boolean | undefined,\n start: Start | undefined,\n multiConstraints?: readonly MultiConstraint[] | undefined,\n fetchFilters?: NoSubqueryCondition | undefined,\n): [SQLQuery] | [SQLQuery, SQLQuery] {\n const select = sql`SELECT ${sql.join(\n Object.keys(columns).map(c => sql.ident(c)),\n sql`,`,\n )} FROM ${sql.ident(tableName)}`;\n const leading: SQLQuery[] = constraintsToSQL(constraint, columns);\n\n if (multiConstraints) {\n for (const mc of multiConstraints) {\n if (mc.length > 0) {\n leading.push(multiConstraintToSQL(mc, columns));\n }\n }\n }\n\n const trailing: SQLQuery[] = [];\n if (filters) {\n trailing.push(filtersToSQL(filters));\n }\n\n if (fetchFilters) {\n trailing.push(filtersToSQL(fetchFilters));\n }\n\n const orderBy =\n order && order.length > 0 ? orderByToSQL(order, !!reverse) : undefined;\n const selectWhere = (constraints: SQLQuery[]) => {\n const query =\n constraints.length > 0\n ? sql`${select} WHERE ${sql.join(constraints, sql` AND `)}`\n : select;\n return orderBy ? sql`${query} ${orderBy}` : query;\n };\n\n if (!start) {\n return [selectWhere([...leading, ...trailing])];\n }\n\n assert(order !== undefined, 'start requires ordering');\n const {constraint: startConstraint, excludesNullGroup} =\n gatherStartConstraints(start, reverse, order, columns);\n const query = selectWhere([...leading, startConstraint, ...trailing]);\n const [leadingField] = order[0];\n if (\n !excludesNullGroup ||\n // The rest of the fetch would reject every row of the NULL group anyway.\n constraintsRejectNull(constraint, multiConstraints, leadingField) ||\n rejectsNull(filters, leadingField) ||\n rejectsNull(fetchFilters, leadingField)\n ) {\n return [query];\n }\n return [\n query,\n selectWhere([\n ...leading,\n sql`${sql.ident(leadingField)} IS NULL`,\n ...trailing,\n ]),\n ];\n}\n\n/**\n * {@link buildSelectQueries} for a fetch that needs only one SELECT, such as\n * one without a start row.\n */\nexport function buildSelectQuery(\n ...args: Parameters<typeof buildSelectQueries>\n): SQLQuery {\n const [query, nullGroup] = buildSelectQueries(...args);\n assert(\n nullGroup === undefined,\n 'The fetch needs a second SELECT for its NULL group; use buildSelectQueries',\n );\n return query;\n}\n\n/**\n * Whether `condition` is never true for a row whose `field` is NULL. Only a\n * comparison of `field` itself, alone or ANDed with other conditions, is\n * recognized. Every operator yields NULL for a NULL operand except `IS`,\n * `IS NOT` and `NOT IN`, which is true for an empty list.\n */\nfunction rejectsNull(\n condition: NoSubqueryCondition | undefined,\n field: string,\n): boolean {\n switch (condition?.type) {\n case undefined:\n case 'or':\n return false;\n case 'and':\n return condition.conditions.some(c =>\n rejectsNull(c as NoSubqueryCondition, field),\n );\n case 'simple': {\n const {op, left, right} = condition;\n if (left.type !== 'column' || left.name !== field) {\n return false;\n }\n switch (op) {\n case 'IS':\n return right.type === 'literal' && right.value !== null;\n case 'IS NOT':\n return right.type === 'literal' && right.value === null;\n case 'NOT IN':\n return false;\n default:\n return true;\n }\n }\n }\n}\n\n/**\n * Whether the constraints of the fetch are never true for a row whose `field`\n * is NULL. {@link constraintsToSQL} compares the field with `=` and\n * {@link multiConstraintToSQL} with `IN`, neither of which is ever true for a\n * NULL operand, so the field being constrained at all is enough.\n */\nfunction constraintsRejectNull(\n constraint: Constraint | undefined,\n multiConstraints: readonly MultiConstraint[] | undefined,\n field: string,\n): boolean {\n if (constraint && field in constraint) {\n return true;\n }\n // `multiConstraintToSQL` takes its key list from the first entry and asserts\n // that the rest match it.\n return multiConstraints?.some(mc => mc.length > 0 && field in mc[0]) === true;\n}\n\nexport function constraintsToSQL(\n constraint: Constraint | undefined,\n columns: Record<string, SchemaValue>,\n) {\n if (!constraint) {\n return [];\n }\n\n const constraints: SQLQuery[] = [];\n for (const [key, value] of Object.entries(constraint)) {\n constraints.push(\n sql`${sql.ident(key)} = ${toSQLiteType(value, columns[key].type)}`,\n );\n }\n\n return constraints;\n}\n\n/**\n * Builds a single batched IN clause from a `MultiConstraint`. All entries\n * are assumed to share the same shape (the keys of the first entry);\n * FlippedJoin derives them from the same parentKey for all children.\n *\n * Single-column form: `col IN (?, ?, ?)`\n * Compound form: `(a, b) IN (VALUES (?, ?), (?, ?), …)`\n *\n * NOTE: SQLite optimizes `col IN (literal-list)` using the column's index;\n * verified via EXPLAIN QUERY PLAN — see query-builder.test.ts.\n */\nexport function multiConstraintToSQL(\n multiConstraint: MultiConstraint,\n columns: Record<string, SchemaValue>,\n): SQLQuery {\n assert(multiConstraint.length > 0, 'multiConstraint must be non-empty');\n // All entries share the same keys; pull the column list from the first.\n const keys = Object.keys(multiConstraint[0]);\n assert(keys.length > 0, 'multiConstraint entries must have at least one key');\n // Subsequent entries must share the first entry's shape — the SQL form\n // is `(col_a, col_b, …) IN VALUES (…)`, with one binding per key per\n // entry. Heterogeneous keys would silently produce incorrect bindings.\n for (let i = 1; i < multiConstraint.length; i++) {\n const entry = multiConstraint[i];\n assert(\n Object.keys(entry).length === keys.length && keys.every(k => k in entry),\n () =>\n `multiConstraint entries must share the same keys (entry 0: [${keys.join(\n ',',\n )}], entry ${i}: [${Object.keys(entry).join(',')}])`,\n );\n }\n\n if (keys.length === 1) {\n const key = keys[0];\n const colType = columns[key].type;\n return sql`${sql.ident(key)} IN (${sql.join(\n multiConstraint.map(c => sql`${toSQLiteType(c[key], colType)}`),\n sql`,`,\n )})`;\n }\n\n // Compound: `(col_a, col_b, …) IN (VALUES (?, ?, …), …)`\n const colList = sql`(${sql.join(\n keys.map(k => sql.ident(k)),\n sql`,`,\n )})`;\n const rows = multiConstraint.map(\n c =>\n sql`(${sql.join(\n keys.map(k => sql`${toSQLiteType(c[k], columns[k].type)}`),\n sql`,`,\n )})`,\n );\n return sql`${colList} IN (VALUES ${sql.join(rows, sql`,`)})`;\n}\n\nexport function orderByToSQL(order: Ordering, reverse: boolean): SQLQuery {\n if (reverse) {\n return sql`ORDER BY ${sql.join(\n order.map(\n s =>\n sql`${sql.ident(s[0])} ${sql.__dangerous__rawValue(\n s[1] === 'asc' ? 'desc' : 'asc',\n )}`,\n ),\n sql`, `,\n )}`;\n } else {\n return sql`ORDER BY ${sql.join(\n order.map(\n s => sql`${sql.ident(s[0])} ${sql.__dangerous__rawValue(s[1])}`,\n ),\n sql`, `,\n )}`;\n }\n}\n\n/**\n * Converts filters (conditions) to SQL WHERE clause.\n * This applies all filters present in the AST for a query to the source.\n */\nexport function filtersToSQL(filters: NoSubqueryCondition): SQLQuery {\n switch (filters.type) {\n case 'simple':\n return simpleConditionToSQL(filters);\n case 'and':\n return filters.conditions.length > 0\n ? sql`(${sql.join(\n filters.conditions.map(condition =>\n filtersToSQL(condition as NoSubqueryCondition),\n ),\n sql` AND `,\n )})`\n : sql`TRUE`;\n case 'or':\n return filters.conditions.length > 0\n ? sql`(${sql.join(\n filters.conditions.map(condition =>\n filtersToSQL(condition as NoSubqueryCondition),\n ),\n sql` OR `,\n )})`\n : sql`FALSE`;\n }\n}\n\nfunction simpleConditionToSQL(filter: SimpleCondition): SQLQuery {\n const {op} = filter;\n if (op === 'IN' || op === 'NOT IN') {\n switch (filter.right.type) {\n case 'literal':\n return sql`${valuePositionToSQL(\n filter.left,\n )} ${sql.__dangerous__rawValue(\n filter.op,\n )} (SELECT value FROM json_each(${JSON.stringify(\n filter.right.value,\n )}))`;\n case 'static':\n throw new Error(\n 'Static parameters must be replaced before conversion to SQL',\n );\n }\n }\n if (\n op === 'LIKE' ||\n op === 'NOT LIKE' ||\n op === 'ILIKE' ||\n op === 'NOT ILIKE'\n ) {\n return likeConditionToSQL(filter);\n }\n\n if (\n (op === 'IS' || op === 'IS NOT') &&\n filter.right.type === 'literal' &&\n filter.right.value === null\n ) {\n return sql`${valuePositionToSQL(filter.left)} ${sql.__dangerous__rawValue(\n op,\n )} NULL`;\n }\n\n return sql`${valuePositionToSQL(filter.left)} ${sql.__dangerous__rawValue(\n filter.op,\n )} ${valuePositionToSQL(filter.right)}`;\n}\n\nfunction likeConditionToSQL(filter: SimpleCondition): SQLQuery {\n const {op} = filter;\n // Mirror Postgres pattern-matching semantics:\n // * LIKE is case-sensitive. The replica connection runs with\n // `PRAGMA case_sensitive_like = ON` (see db.ts), so the bare LIKE\n // operator is case-sensitive.\n // * ILIKE is case-insensitive. We lower() both operands using the\n // Unicode-aware lower() that @rocicorp/zero-sqlite3 provides via ICU,\n // mirroring the toLowerCase() used by the in-memory IVM matcher\n // (see zql/src/builder/like.ts).\n // * Backslash is the default escape character in Postgres and in the IVM\n // matcher, but SQLite has no default, so we specify `ESCAPE '\\'`\n // explicitly. The SQL literal '\\' is a single backslash (SQLite does not\n // process backslash escapes inside string literals).\n const caseInsensitive = op === 'ILIKE' || op === 'NOT ILIKE';\n const negated = op === 'NOT LIKE' || op === 'NOT ILIKE';\n const likeOp = sql.__dangerous__rawValue(negated ? 'NOT LIKE' : 'LIKE');\n\n const left = valuePositionToSQL(filter.left);\n const right = valuePositionToSQL(filter.right);\n if (caseInsensitive) {\n return sql`lower(${left}) ${likeOp} lower(${right}) ESCAPE '\\\\'`;\n }\n return sql`${left} ${likeOp} ${right} ESCAPE '\\\\'`;\n}\n\nfunction valuePositionToSQL(value: ValuePosition): SQLQuery {\n switch (value.type) {\n case 'column':\n return sql.ident(value.name);\n case 'literal':\n return sql`${toSQLiteType(value.value, getJsType(value.value))}`;\n case 'static':\n throw new Error(\n 'Static parameters must be replaced before conversion to SQL',\n );\n }\n}\n\nfunction getJsType(value: unknown): ValueType {\n if (value === null) {\n return 'null';\n }\n return typeof value === 'string'\n ? 'string'\n : typeof value === 'number'\n ? 'number'\n : typeof value === 'boolean'\n ? 'boolean'\n : 'json';\n}\n\nexport function toSQLiteType(v: unknown, type: ValueType): unknown {\n switch (type) {\n case 'boolean':\n return v === null ? null : v ? 1 : 0;\n case 'number':\n case 'string':\n case 'null':\n return v;\n case 'json':\n return JSON.stringify(v);\n }\n}\n\nfunction nullableAwareEquality(\n field: string,\n value: unknown,\n columnType: SchemaValue,\n): SQLQuery {\n if (value === null) {\n // A NULL bound value proves the column is nullable regardless of the\n // column metadata, and `=` never matches NULL — `IS` selects the NULL\n // tie-break group a cursor anchored on a NULL value needs.\n return sql`${sql.ident(field)} IS NULL`;\n }\n // Use = instead of IS for non-nullable columns to enable better\n // index usage in SQLite.\n return columnType.optional === true\n ? sql`${sql.ident(field)} IS ${value}`\n : sql`${sql.ident(field)} = ${value}`;\n}\n\nfunction nullableAwareRangeComparison(\n field: string,\n value: unknown,\n operator: '>' | '<',\n columnType: SchemaValue,\n /**\n * Whether an entailed bound ANDed in front of the disjunction already\n * excludes the column's NULL group, which a second SELECT then fetches (see\n * {@link gatherStartConstraints}).\n */\n nullGroupExcluded: boolean,\n): SQLQuery {\n if (value === null) {\n return operator === '>' ? sql`${sql.ident(field)} IS NOT NULL` : sql`FALSE`;\n }\n\n // For non-nullable columns, skip IS NULL checks to avoid breaking\n // SQLite's MULTI-INDEX OR optimization, which falls back to a full\n // table scan when any OR branch involves NULL.\n // See: https://github.com/rocicorp/mono/pull/5542\n const comparison = sql`${sql.ident(field)} ${sql.__dangerous__rawValue(\n operator,\n )} ${value}`;\n if (columnType.optional !== true) {\n return comparison;\n }\n\n // The bound is non-NULL here. NULLs sort before every non-NULL value, so\n // `>` already excludes them and needs no guard, while `<` must admit the\n // NULL group explicitly — a bare `col < ?` would silently drop NULL rows\n // from a backward walk. Unless the NULL group is excluded and fetched on its\n // own: the guard is dead then, and a NULL inside an OR is what costs SQLite\n // the MULTI-INDEX OR optimization in the first place.\n return operator === '>' || nullGroupExcluded\n ? comparison\n : sql`(${sql.ident(field)} IS NULL OR ${comparison})`;\n}\n\ntype SargableLeadingStartBound = {\n readonly bound: SQLQuery;\n /**\n * Whether `bound` excludes the column's NULL group, which belongs to the\n * rows the start walks over and must then be fetched separately.\n */\n readonly excludesNullGroup: boolean;\n};\n\nfunction sargableLeadingStartBound(\n field: string,\n value: unknown,\n operator: '>' | '<',\n columnType: SchemaValue,\n): SargableLeadingStartBound | undefined {\n // A NULL bound value proves the column is nullable regardless of the\n // column metadata, and a bare range bound is not sound there: `col >= NULL`\n // is never true, so instead of being redundant it would annihilate the\n // whole start constraint.\n if (value === null) {\n return undefined;\n }\n\n const inclusiveOperator = operator === '>' ? '>=' : '<=';\n return {\n bound: sql`${sql.ident(field)} ${sql.__dangerous__rawValue(\n inclusiveOperator,\n )} ${value}`,\n // For `>`, NULLs sort before the non-NULL bound, so `col >= value` remains\n // sound on a nullable column. For `<`, the rows before the bound include\n // the whole NULL group, which `col <= value` drops. SQLite cannot seek\n // `col IS NULL OR col <= value` as one index range, so the caller fetches\n // that group separately.\n excludesNullGroup: columnType.optional === true && operator === '<',\n };\n}\n\n/**\n * The ordering could be complex such as:\n * `ORDER BY a ASC, b DESC, c ASC`\n *\n * In those cases, we need to encode the constraints as various\n * `OR` clauses.\n *\n * E.g.,\n *\n * to get the row after (a = 1, b = 2, c = 3) would be:\n *\n * `WHERE a > 1 OR (a = 1 AND b < 2) OR (a = 1 AND b = 2 AND c > 3)`\n *\n * - after vs before flips the comparison operators.\n * - inclusive adds a final `OR` clause for the exact match.\n *\n * SQLite cannot seek an index with that disjunction, so a redundant, entailed\n * bound on the leading column is ANDed in front of it (e.g. `a >= 1 AND ...`).\n *\n * When the leading column is nullable and the walk heads towards lower values\n * (`<`), the rows the start walks over include the whole NULL group, which\n * that bound drops. `excludesNullGroup` is set then, and the group is left out\n * of the disjunction too — every row the returned constraint admits has\n * `a <= ?`, so it and `a IS NULL` partition those rows, and the caller fetches\n * the NULL group with a second SELECT.\n */\nfunction gatherStartConstraints(\n start: Start,\n reverse: boolean | undefined,\n order: Ordering,\n columnTypes: Record<string, SchemaValue>,\n): {readonly constraint: SQLQuery; readonly excludesNullGroup: boolean} {\n const constraints: SQLQuery[] = [];\n const {row: from, basis} = start;\n let leadingBound: SargableLeadingStartBound | undefined;\n\n for (let i = 0; i < order.length; i++) {\n const group: SQLQuery[] = [];\n const [iField, iDirection] = order[i];\n for (let j = 0; j <= i; j++) {\n if (j === i) {\n const columnType = columnTypes[iField];\n const constraintValue = toSQLiteType(\n from[iField] ?? null,\n columnType.type,\n );\n const operator =\n iDirection === 'asc' ? (reverse ? '<' : '>') : reverse ? '>' : '<';\n let nullGroupExcluded = false;\n if (i === 0) {\n leadingBound = sargableLeadingStartBound(\n iField,\n constraintValue,\n operator,\n columnType,\n );\n nullGroupExcluded = leadingBound?.excludesNullGroup === true;\n }\n group.push(\n nullableAwareRangeComparison(\n iField,\n constraintValue,\n operator,\n columnType,\n nullGroupExcluded,\n ),\n );\n } else {\n const [jField] = order[j];\n const columnType = columnTypes[jField];\n const value = toSQLiteType(from[jField] ?? null, columnType.type);\n group.push(nullableAwareEquality(jField, value, columnType));\n }\n }\n constraints.push(sql`(${sql.join(group, sql` AND `)})`);\n }\n\n if (basis === 'at') {\n constraints.push(\n sql`(${sql.join(\n order.map(([field]) => {\n const columnType = columnTypes[field];\n const value = toSQLiteType(from[field] ?? null, columnType.type);\n return nullableAwareEquality(field, value, columnType);\n }),\n sql` AND `,\n )})`,\n );\n }\n\n const lexicographicStart = sql`(${sql.join(constraints, sql` OR `)})`;\n if (leadingBound === undefined) {\n return {constraint: lexicographicStart, excludesNullGroup: false};\n }\n return {\n constraint: sql`(${leadingBound.bound} AND ${lexicographicStart})`,\n excludesNullGroup: leadingBound.excludesNullGroup,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"query-builder.js","names":[],"sources":["../../../../zqlite/src/query-builder.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n isLikeOperator,\n isNegatedOperator,\n jsonLiteralType,\n type Condition,\n type JsonPathReference,\n type Ordering,\n type SimpleCondition,\n type ValuePosition,\n} from '../../zero-protocol/src/ast.ts';\nimport type {\n SchemaValue,\n ValueType,\n} from '../../zero-schema/src/table-schema.ts';\nimport {valueTypeOf} from '../../zero-types/src/schema-value.ts';\nimport type {Constraint} from '../../zql/src/ivm/constraint.ts';\nimport type {\n FetchRequest,\n MultiConstraint,\n Start,\n} from '../../zql/src/ivm/operator.ts';\nimport {sql} from './internal/sql.ts';\n\n/**\n * Condition type without correlated subqueries.\n * This matches the output of transformFilters from zql/builder/filter.ts\n */\nexport type NoSubqueryCondition = Exclude<\n Condition,\n {type: 'correlatedSubquery'}\n>;\n\n/**\n * Builds the SELECTs for a fetch. Running them in order and concatenating\n * their rows gives the fetch's rows, in order.\n *\n * There is a second SELECT only when the fetch starts at a non-NULL value of a\n * nullable leading sort column and walks towards its NULL group. The first\n * SELECT then leaves that group out so that SQLite can seek it (see\n * `gatherStartConstraints`), and the second fetches the group. NULLs sort\n * before every other value, so the group follows all of the first SELECT's\n * rows, and a fetch that stops early never needs to run the second.\n */\nexport function buildSelectQueries(\n tableName: string,\n columns: Record<string, SchemaValue>,\n constraint: Constraint | undefined,\n filters: NoSubqueryCondition | undefined,\n order: Ordering | undefined,\n reverse: boolean | undefined,\n start: Start | undefined,\n multiConstraints?: readonly MultiConstraint[] | undefined,\n fetchFilters?: NoSubqueryCondition | undefined,\n): [SQLQuery] | [SQLQuery, SQLQuery] {\n const select = sql`SELECT ${sql.join(\n Object.keys(columns).map(c => sql.ident(c)),\n sql`,`,\n )} FROM ${sql.ident(tableName)}`;\n const leading: SQLQuery[] = constraintsToSQL(constraint, columns);\n\n if (multiConstraints) {\n for (const mc of multiConstraints) {\n if (mc.length > 0) {\n leading.push(multiConstraintToSQL(mc, columns));\n }\n }\n }\n\n const trailing: SQLQuery[] = [];\n if (filters) {\n trailing.push(filtersToSQL(filters));\n }\n\n if (fetchFilters) {\n trailing.push(filtersToSQL(fetchFilters));\n }\n\n const orderBy =\n order && order.length > 0 ? orderByToSQL(order, !!reverse) : undefined;\n const selectWhere = (constraints: SQLQuery[]) => {\n const query =\n constraints.length > 0\n ? sql`${select} WHERE ${sql.join(constraints, sql` AND `)}`\n : select;\n return orderBy ? sql`${query} ${orderBy}` : query;\n };\n\n if (!start) {\n return [selectWhere([...leading, ...trailing])];\n }\n\n assert(order !== undefined, 'start requires ordering');\n const {constraint: startConstraint, excludesNullGroup} =\n gatherStartConstraints(start, reverse, order, columns);\n const query = selectWhere([...leading, startConstraint, ...trailing]);\n const [leadingField] = order[0];\n if (\n !excludesNullGroup ||\n // The rest of the fetch would reject every row of the NULL group anyway.\n constraintsRejectNull(constraint, multiConstraints, leadingField) ||\n rejectsNull(filters, leadingField) ||\n rejectsNull(fetchFilters, leadingField)\n ) {\n return [query];\n }\n return [\n query,\n selectWhere([\n ...leading,\n sql`${sql.ident(leadingField)} IS NULL`,\n ...trailing,\n ]),\n ];\n}\n\n/**\n * `SELECT COUNT(*)` over the rows a fetch with `constraint` and `filters`\n * returns. Without an `ORDER BY`, SQLite counts entries of whichever index\n * covers the `WHERE` rather than reading and sorting the rows.\n */\nexport function buildCountQuery(\n tableName: string,\n columns: Record<string, SchemaValue>,\n constraint: Constraint | undefined,\n filters: NoSubqueryCondition | undefined,\n): SQLQuery {\n const where = constraintsToSQL(constraint, columns);\n if (filters) {\n where.push(filtersToSQL(filters));\n }\n const select = sql`SELECT COUNT(*) FROM ${sql.ident(tableName)}`;\n return where.length > 0\n ? sql`${select} WHERE ${sql.join(where, sql` AND `)}`\n : select;\n}\n\n/**\n * The distinct values of `groupColumns` among the rows that pass `filters`,\n * each followed by its number of rows, in no particular order.\n */\nexport function buildGroupCountsQuery(\n tableName: string,\n groupColumns: readonly string[],\n filters: NoSubqueryCondition | undefined,\n): SQLQuery {\n const cols = sql.join(\n groupColumns.map(c => sql.ident(c)),\n sql`, `,\n );\n const select = sql`SELECT ${cols}, COUNT(*) FROM ${sql.ident(tableName)}`;\n return filters\n ? sql`${select} WHERE ${filtersToSQL(filters)} GROUP BY ${cols}`\n : sql`${select} GROUP BY ${cols}`;\n}\n\n/**\n * {@link buildSelectQueries} for a fetch that needs only one SELECT, such as\n * one without a start row.\n */\nexport function buildSelectQuery(\n ...args: Parameters<typeof buildSelectQueries>\n): SQLQuery {\n const [query, nullGroup] = buildSelectQueries(...args);\n assert(\n nullGroup === undefined,\n 'The fetch needs a second SELECT for its NULL group; use buildSelectQueries',\n );\n return query;\n}\n\n/**\n * Whether `condition` is never true for a row whose `field` is NULL. Only a\n * comparison of `field` itself, alone or ANDed with other conditions, is\n * recognized. Every operator yields NULL for a NULL operand except `IS`,\n * `IS NOT` and `NOT IN`, which is true for an empty list.\n */\nfunction rejectsNull(\n condition: NoSubqueryCondition | undefined,\n field: string,\n): boolean {\n switch (condition?.type) {\n case undefined:\n case 'or':\n return false;\n case 'and':\n return condition.conditions.some(c =>\n rejectsNull(c as NoSubqueryCondition, field),\n );\n case 'simple': {\n const {op, left, right} = condition;\n if (left.type !== 'column' || left.name !== field) {\n return false;\n }\n switch (op) {\n case 'IS':\n return right.type === 'literal' && right.value !== null;\n case 'IS NOT':\n return right.type === 'literal' && right.value === null;\n case 'NOT IN':\n return false;\n default:\n return true;\n }\n }\n }\n}\n\n/**\n * Whether the constraints of the fetch are never true for a row whose `field`\n * is NULL. {@link constraintsToSQL} compares the field with `=` and\n * {@link multiConstraintToSQL} with `IN`, neither of which is ever true for a\n * NULL operand, so the field being constrained at all is enough.\n */\nfunction constraintsRejectNull(\n constraint: Constraint | undefined,\n multiConstraints: readonly MultiConstraint[] | undefined,\n field: string,\n): boolean {\n if (constraint && field in constraint) {\n return true;\n }\n // `multiConstraintToSQL` takes its key list from the first entry and asserts\n // that the rest match it.\n return multiConstraints?.some(mc => mc.length > 0 && field in mc[0]) === true;\n}\n\nfunction constraintsToSQL(\n constraint: Constraint | undefined,\n columns: Record<string, SchemaValue>,\n) {\n if (!constraint) {\n return [];\n }\n\n const constraints: SQLQuery[] = [];\n for (const [key, value] of Object.entries(constraint)) {\n constraints.push(\n sql`${sql.ident(key)} = ${toSQLiteBinding(value, columns[key].type)}`,\n );\n }\n\n return constraints;\n}\n\n/**\n * Builds a single batched IN clause from a `MultiConstraint`. All entries\n * are assumed to share the same shape (the keys of the first entry);\n * FlippedJoin derives them from the same parentKey for all children.\n *\n * Single-column form: `col IN (?, ?, ?)`\n * Compound form: `(a, b) IN (VALUES (?, ?), (?, ?), …)`\n *\n * NOTE: SQLite optimizes `col IN (literal-list)` using the column's index;\n * verified via EXPLAIN QUERY PLAN — see query-builder.test.ts.\n */\nexport function multiConstraintToSQL(\n multiConstraint: MultiConstraint,\n columns: Record<string, SchemaValue>,\n): SQLQuery {\n assert(multiConstraint.length > 0, 'multiConstraint must be non-empty');\n // All entries share the same keys; pull the column list from the first.\n const keys = Object.keys(multiConstraint[0]);\n assert(keys.length > 0, 'multiConstraint entries must have at least one key');\n // Subsequent entries must share the first entry's shape — the SQL form\n // is `(col_a, col_b, …) IN VALUES (…)`, with one binding per key per\n // entry. Heterogeneous keys would silently produce incorrect bindings.\n for (let i = 1; i < multiConstraint.length; i++) {\n const entry = multiConstraint[i];\n assert(\n Object.keys(entry).length === keys.length && keys.every(k => k in entry),\n () =>\n `multiConstraint entries must share the same keys (entry 0: [${keys.join(\n ',',\n )}], entry ${i}: [${Object.keys(entry).join(',')}])`,\n );\n }\n\n if (keys.length === 1) {\n const key = keys[0];\n const colType = columns[key].type;\n return sql`${sql.ident(key)} IN (${sql.join(\n multiConstraint.map(c => sql`${toSQLiteBinding(c[key], colType)}`),\n sql`,`,\n )})`;\n }\n\n // Compound: `(col_a, col_b, …) IN (VALUES (?, ?, …), …)`\n const colList = sql`(${sql.join(\n keys.map(k => sql.ident(k)),\n sql`,`,\n )})`;\n const rows = multiConstraint.map(\n c =>\n sql`(${sql.join(\n keys.map(k => sql`${toSQLiteBinding(c[k], columns[k].type)}`),\n sql`,`,\n )})`,\n );\n return sql`${colList} IN (VALUES ${sql.join(rows, sql`,`)})`;\n}\n\nfunction orderByToSQL(order: Ordering, reverse: boolean): SQLQuery {\n if (reverse) {\n return sql`ORDER BY ${sql.join(\n order.map(\n s =>\n sql`${sql.ident(s[0])} ${sql.__dangerous__rawValue(\n s[1] === 'asc' ? 'desc' : 'asc',\n )}`,\n ),\n sql`, `,\n )}`;\n } else {\n return sql`ORDER BY ${sql.join(\n order.map(\n s => sql`${sql.ident(s[0])} ${sql.__dangerous__rawValue(s[1])}`,\n ),\n sql`, `,\n )}`;\n }\n}\n\n/**\n * Converts filters (conditions) to SQL WHERE clause.\n * This applies all filters present in the AST for a query to the source.\n */\nexport function filtersToSQL(filters: NoSubqueryCondition): SQLQuery {\n switch (filters.type) {\n case 'simple':\n return simpleConditionToSQL(filters);\n case 'and':\n return filters.conditions.length > 0\n ? sql`(${sql.join(\n filters.conditions.map(condition =>\n filtersToSQL(condition as NoSubqueryCondition),\n ),\n sql` AND `,\n )})`\n : sql`TRUE`;\n case 'or':\n return filters.conditions.length > 0\n ? sql`(${sql.join(\n filters.conditions.map(condition =>\n filtersToSQL(condition as NoSubqueryCondition),\n ),\n sql` OR `,\n )})`\n : sql`FALSE`;\n }\n}\n\nfunction simpleConditionToSQL(filter: SimpleCondition): SQLQuery {\n if (filter.left.type === 'json') {\n const json = jsonPathConditionToSQL(filter, filter.left);\n if (json) {\n return json;\n }\n }\n return comparisonToSQL(filter, valuePositionToSQL(filter.left));\n}\n\n/**\n * Renders `filter`'s operator and right operand against an already-rendered\n * left operand.\n */\nfunction comparisonToSQL(filter: SimpleCondition, left: SQLQuery): SQLQuery {\n const {op} = filter;\n if (op === 'IN' || op === 'NOT IN') {\n switch (filter.right.type) {\n case 'literal':\n return sql`${left} ${sql.__dangerous__rawValue(\n filter.op,\n )} (SELECT value FROM json_each(${JSON.stringify(\n filter.right.value,\n )}))`;\n case 'static':\n throw new Error(\n 'Static parameters must be replaced before conversion to SQL',\n );\n }\n }\n if (\n op === 'LIKE' ||\n op === 'NOT LIKE' ||\n op === 'ILIKE' ||\n op === 'NOT ILIKE'\n ) {\n return likeConditionToSQL(filter, left);\n }\n\n if (\n (op === 'IS' || op === 'IS NOT') &&\n filter.right.type === 'literal' &&\n filter.right.value === null\n ) {\n return sql`${left} ${sql.__dangerous__rawValue(op)} NULL`;\n }\n\n return sql`${left} ${sql.__dangerous__rawValue(\n filter.op,\n )} ${valuePositionToSQL(filter.right)}`;\n}\n\nfunction likeConditionToSQL(filter: SimpleCondition, left: SQLQuery): SQLQuery {\n const {op} = filter;\n // Mirror Postgres pattern-matching semantics:\n // * LIKE is case-sensitive. The replica connection runs with\n // `PRAGMA case_sensitive_like = ON` (see db.ts), so the bare LIKE\n // operator is case-sensitive.\n // * ILIKE is case-insensitive. We lower() both operands using the\n // Unicode-aware lower() that @rocicorp/zero-sqlite3 provides via ICU,\n // mirroring the toLowerCase() used by the in-memory IVM matcher\n // (see zql/src/builder/like.ts).\n // * Backslash is the default escape character in Postgres and in the IVM\n // matcher, but SQLite has no default, so we specify `ESCAPE '\\'`\n // explicitly. The SQL literal '\\' is a single backslash (SQLite does not\n // process backslash escapes inside string literals).\n const caseInsensitive = op === 'ILIKE' || op === 'NOT ILIKE';\n const negated = op === 'NOT LIKE' || op === 'NOT ILIKE';\n const likeOp = sql.__dangerous__rawValue(negated ? 'NOT LIKE' : 'LIKE');\n\n const right = valuePositionToSQL(filter.right);\n if (caseInsensitive) {\n return sql`lower(${left}) ${likeOp} lower(${right}) ESCAPE '\\\\'`;\n }\n return sql`${left} ${likeOp} ${right} ESCAPE '\\\\'`;\n}\n\n/** The extraction of a JSON path leaf (the path string is a bound parameter). */\nfunction jsonExtract(ref: JsonPathReference): SQLQuery {\n return sql`json_extract(${sql.ident(ref.value.name)}, ${jsonPathExpr(\n ref.path,\n )})`;\n}\n\n/** The SQLite `json_type()` names a leaf may have for a JSON literal type. */\nfunction jsonTypeNames(\n t: 'string' | 'number' | 'boolean',\n): readonly [string, ...string[]] {\n switch (t) {\n case 'string':\n return ['text'];\n case 'number':\n return ['integer', 'real'];\n case 'boolean':\n return ['true', 'false'];\n }\n}\n\n/**\n * Compiles a comparison whose left operand is a JSON path, type-strictly, per\n * the semantics documented on {@link JsonPathReference} (shared with the\n * in-memory predicate and the Postgres compiler). Returns `undefined` where\n * the generic rendering already agrees with the predicate.\n *\n * A bare `json_extract` would not be strict: SQLite returns booleans as 1/0 (so\n * `true` = 1), orders any TEXT above any number (`'n/a' > 5`), and coerces\n * numbers for LIKE. Gating the extraction on `json_type()` makes a mismatched\n * leaf NULL, which a positive comparison excludes. Negated operators get an\n * explicit CASE because NULL would exclude there too, where a mismatch must\n * match: `json_type()` is NULL for a missing key and `'null'` for a JSON null,\n * so one `COALESCE` covers the null guard without a second extraction.\n *\n * `IN`/`NOT IN` with a `null` literal is constant-false (as in the predicate),\n * and an empty `NOT IN` matches every non-null leaf (bare `NULL NOT IN ()` is\n * TRUE).\n */\nfunction jsonPathConditionToSQL(\n filter: SimpleCondition,\n left: JsonPathReference,\n): SQLQuery | undefined {\n const {op, right} = filter;\n if (right.type !== 'literal') {\n return undefined;\n }\n if ((op === 'IN' || op === 'NOT IN') && right.value === null) {\n return sql`FALSE`;\n }\n const col = sql.ident(left.value.name);\n const path = jsonPathExpr(left.path);\n const raw = sql`json_extract(${col}, ${path})`;\n let cond = filter;\n let t = jsonLiteralType(right.value);\n if (\n isLikeOperator(op) &&\n right.value !== null &&\n !Array.isArray(right.value)\n ) {\n // The LIKE family compares text, so the leaf must be a string whatever\n // the literal's type, and the pattern is the literal's text form, as in\n // the in-memory predicate (`String(pattern)`) and the Postgres compiler.\n // Gating on the literal's type instead would let SQLite's text coercion\n // match `3 LIKE 3` on a numeric leaf that the predicate rejects.\n t = 'string';\n cond = {...filter, right: {type: 'literal', value: String(right.value)}};\n }\n if (t === undefined) {\n // Only an empty list reaches here (a null literal has no type either, but\n // the generic NULL comparison is already constant-false for it).\n return op === 'NOT IN' ? sql`${raw} IS NOT NULL` : undefined;\n }\n const types = jsonTypeNames(t);\n if (!isNegatedOperator(op)) {\n const typeList = sql.join(\n types.map(x => sql`${x}`),\n sql`, `,\n );\n return comparisonToSQL(\n cond,\n sql`(CASE WHEN json_type(${col}, ${path}) IN (${typeList}) THEN ${raw} END)`,\n );\n }\n // One WHEN per accepted type name (a number leaf is 'integer' or 'real');\n // only one branch runs per row.\n const cmp = comparisonToSQL(cond, raw);\n const whens = sql.join(\n types.map(x => sql`WHEN ${x} THEN ${cmp}`),\n sql` `,\n );\n return sql`(CASE COALESCE(json_type(${col}, ${path}), 'null') WHEN 'null' THEN 0 ${whens} ELSE 1 END)`;\n}\n\n/**\n * Builds a SQLite JSON path string (e.g. `$.a.b[0]`) from a path of object\n * keys and array indices. Object keys are emitted as JSON string literals\n * (`JSON.stringify`): SQLite parses a double-quoted path label with JSON\n * escapes, so `\"` and `\\` inside a key must be backslash-escaped. SQL-style\n * `\"\"` doubling is not understood and yields NULL or a \"bad JSON path\" error.\n */\nfunction jsonPathExpr(path: readonly (string | number)[]): string {\n let s = '$';\n for (const seg of path) {\n s += typeof seg === 'number' ? `[${seg}]` : `.${JSON.stringify(seg)}`;\n }\n return s;\n}\n\nfunction valuePositionToSQL(value: ValuePosition): SQLQuery {\n switch (value.type) {\n case 'column':\n return sql.ident(value.name);\n case 'json':\n return jsonExtract(value);\n case 'literal':\n return sql`${toSQLiteType(value.value, valueTypeOf(value.value))}`;\n case 'static':\n throw new Error(\n 'Static parameters must be replaced before conversion to SQL',\n );\n default:\n unreachable(value);\n }\n}\n\nexport function toSQLiteType(v: unknown, type: ValueType): unknown {\n switch (type) {\n case 'boolean':\n return v === null ? null : v ? 1 : 0;\n case 'number':\n case 'string':\n case 'null':\n return v;\n case 'json':\n return JSON.stringify(v);\n }\n}\n\n/**\n * A placeholder for a fetch's value that {@link buildSelectQueries} passes\n * through to the bindings of its SELECTs, where `toSQLiteType` would convert\n * the value itself. It lets a fetch's SQL text be built once and reused for\n * every fetch of the same shape (see `fetch-sql.ts`).\n */\nexport class Binding {\n readonly get: (req: FetchRequest) => unknown;\n constructor(get: (req: FetchRequest) => unknown) {\n this.get = get;\n }\n}\n\nfunction toSQLiteBinding(v: unknown, type: ValueType): unknown {\n return v instanceof Binding ? v : toSQLiteType(v, type);\n}\n\nfunction nullableAwareEquality(\n field: string,\n value: unknown,\n columnType: SchemaValue,\n): SQLQuery {\n if (value === null) {\n // A NULL bound value proves the column is nullable regardless of the\n // column metadata, and `=` never matches NULL — `IS` selects the NULL\n // tie-break group a cursor anchored on a NULL value needs.\n return sql`${sql.ident(field)} IS NULL`;\n }\n // Use = instead of IS for non-nullable columns to enable better\n // index usage in SQLite.\n return columnType.optional === true\n ? sql`${sql.ident(field)} IS ${value}`\n : sql`${sql.ident(field)} = ${value}`;\n}\n\nfunction nullableAwareRangeComparison(\n field: string,\n value: unknown,\n operator: '>' | '<',\n columnType: SchemaValue,\n /**\n * Whether an entailed bound ANDed in front of the disjunction already\n * excludes the column's NULL group, which a second SELECT then fetches (see\n * {@link gatherStartConstraints}).\n */\n nullGroupExcluded: boolean,\n): SQLQuery {\n if (value === null) {\n return operator === '>' ? sql`${sql.ident(field)} IS NOT NULL` : sql`FALSE`;\n }\n\n // For non-nullable columns, skip IS NULL checks to avoid breaking\n // SQLite's MULTI-INDEX OR optimization, which falls back to a full\n // table scan when any OR branch involves NULL.\n // See: https://github.com/rocicorp/mono/pull/5542\n const comparison = sql`${sql.ident(field)} ${sql.__dangerous__rawValue(\n operator,\n )} ${value}`;\n if (columnType.optional !== true) {\n return comparison;\n }\n\n // The bound is non-NULL here. NULLs sort before every non-NULL value, so\n // `>` already excludes them and needs no guard, while `<` must admit the\n // NULL group explicitly — a bare `col < ?` would silently drop NULL rows\n // from a backward walk. Unless the NULL group is excluded and fetched on its\n // own: the guard is dead then, and a NULL inside an OR is what costs SQLite\n // the MULTI-INDEX OR optimization in the first place.\n return operator === '>' || nullGroupExcluded\n ? comparison\n : sql`(${sql.ident(field)} IS NULL OR ${comparison})`;\n}\n\ntype SargableLeadingStartBound = {\n readonly bound: SQLQuery;\n /**\n * Whether `bound` excludes the column's NULL group, which belongs to the\n * rows the start walks over and must then be fetched separately.\n */\n readonly excludesNullGroup: boolean;\n};\n\nfunction sargableLeadingStartBound(\n field: string,\n value: unknown,\n operator: '>' | '<',\n columnType: SchemaValue,\n): SargableLeadingStartBound | undefined {\n // A NULL bound value proves the column is nullable regardless of the\n // column metadata, and a bare range bound is not sound there: `col >= NULL`\n // is never true, so instead of being redundant it would annihilate the\n // whole start constraint.\n if (value === null) {\n return undefined;\n }\n\n const inclusiveOperator = operator === '>' ? '>=' : '<=';\n return {\n bound: sql`${sql.ident(field)} ${sql.__dangerous__rawValue(\n inclusiveOperator,\n )} ${value}`,\n // For `>`, NULLs sort before the non-NULL bound, so `col >= value` remains\n // sound on a nullable column. For `<`, the rows before the bound include\n // the whole NULL group, which `col <= value` drops. SQLite cannot seek\n // `col IS NULL OR col <= value` as one index range, so the caller fetches\n // that group separately.\n excludesNullGroup: columnType.optional === true && operator === '<',\n };\n}\n\n/**\n * The ordering could be complex such as:\n * `ORDER BY a ASC, b DESC, c ASC`\n *\n * In those cases, we need to encode the constraints as various\n * `OR` clauses.\n *\n * E.g.,\n *\n * to get the row after (a = 1, b = 2, c = 3) would be:\n *\n * `WHERE a > 1 OR (a = 1 AND b < 2) OR (a = 1 AND b = 2 AND c > 3)`\n *\n * - after vs before flips the comparison operators.\n * - inclusive adds a final `OR` clause for the exact match.\n *\n * SQLite cannot seek an index with that disjunction, so a redundant, entailed\n * bound on the leading column is ANDed in front of it (e.g. `a >= 1 AND ...`).\n *\n * When the leading column is nullable and the walk heads towards lower values\n * (`<`), the rows the start walks over include the whole NULL group, which\n * that bound drops. `excludesNullGroup` is set then, and the group is left out\n * of the disjunction too — every row the returned constraint admits has\n * `a <= ?`, so it and `a IS NULL` partition those rows, and the caller fetches\n * the NULL group with a second SELECT.\n */\nfunction gatherStartConstraints(\n start: Start,\n reverse: boolean | undefined,\n order: Ordering,\n columnTypes: Record<string, SchemaValue>,\n): {readonly constraint: SQLQuery; readonly excludesNullGroup: boolean} {\n const constraints: SQLQuery[] = [];\n const {row: from, basis} = start;\n let leadingBound: SargableLeadingStartBound | undefined;\n\n for (let i = 0; i < order.length; i++) {\n const group: SQLQuery[] = [];\n const [iField, iDirection] = order[i];\n for (let j = 0; j <= i; j++) {\n if (j === i) {\n const columnType = columnTypes[iField];\n const constraintValue = toSQLiteBinding(\n from[iField] ?? null,\n columnType.type,\n );\n const operator =\n iDirection === 'asc' ? (reverse ? '<' : '>') : reverse ? '>' : '<';\n let nullGroupExcluded = false;\n if (i === 0) {\n leadingBound = sargableLeadingStartBound(\n iField,\n constraintValue,\n operator,\n columnType,\n );\n nullGroupExcluded = leadingBound?.excludesNullGroup === true;\n }\n group.push(\n nullableAwareRangeComparison(\n iField,\n constraintValue,\n operator,\n columnType,\n nullGroupExcluded,\n ),\n );\n } else {\n const [jField] = order[j];\n const columnType = columnTypes[jField];\n const value = toSQLiteBinding(from[jField] ?? null, columnType.type);\n group.push(nullableAwareEquality(jField, value, columnType));\n }\n }\n constraints.push(sql`(${sql.join(group, sql` AND `)})`);\n }\n\n if (basis === 'at') {\n constraints.push(\n sql`(${sql.join(\n order.map(([field]) => {\n const columnType = columnTypes[field];\n const value = toSQLiteBinding(from[field] ?? null, columnType.type);\n return nullableAwareEquality(field, value, columnType);\n }),\n sql` AND `,\n )})`,\n );\n }\n\n const lexicographicStart = sql`(${sql.join(constraints, sql` OR `)})`;\n if (leadingBound === undefined) {\n return {constraint: lexicographicStart, excludesNullGroup: false};\n }\n return {\n constraint: sql`(${leadingBound.bound} AND ${lexicographicStart})`,\n excludesNullGroup: leadingBound.excludesNullGroup,\n };\n}\n"],"mappings":"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"}
|