@rocicorp/zero 1.12.0-canary.3 → 1.12.0-canary.4
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.js +4 -3
- package/out/analyze-query/src/analyze-cli.js.map +1 -1
- package/out/analyze-query/src/bin-analyze.js +5 -3
- package/out/analyze-query/src/bin-analyze.js.map +1 -1
- package/out/analyze-query/src/bin-transform.js +3 -2
- package/out/analyze-query/src/bin-transform.js.map +1 -1
- package/out/ast-to-zql/src/ast-to-zql.js.map +1 -1
- package/out/ast-to-zql/src/bin.js +3 -2
- 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.js +13 -11
- 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.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.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.js +5 -2
- package/out/replicache/src/db/write.js.map +1 -1
- package/out/replicache/src/deleted-clients.js +3 -2
- 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.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.js +5 -3
- package/out/replicache/src/index-defs.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/idb-store.js +1 -1
- 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.js +1 -1
- package/out/replicache/src/kv/sqlite-store.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.js +2 -2
- 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.map +1 -1
- package/out/replicache/src/replicache-impl.js +3 -3
- 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.js +2 -4
- package/out/replicache/src/sync/patch.js.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.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/shared/src/arrays.js +4 -1
- package/out/shared/src/arrays.js.map +1 -1
- package/out/shared/src/asserts.js +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/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.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/hash.js +2 -2
- package/out/shared/src/hash.js.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 +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.js +9 -12
- package/out/shared/src/options.js.map +1 -1
- package/out/shared/src/promise-race.js.map +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/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/sorted-entries.js.map +1 -1
- package/out/shared/src/tdigest-schema.js.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.js +2 -4
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/z2s/src/sql.js +1 -1
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +212 -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/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 +10 -9
- 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.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 +5 -16
- 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 +5 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +13 -2
- 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.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/run-transaction.js.map +1 -1
- package/out/zero-cache/src/db/specs.js +7 -5
- 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 +5 -3
- 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.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 +4 -2
- 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.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.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.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +2 -1
- 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.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.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +6 -1
- 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 +1 -1
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -1
- 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.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 +3 -3
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.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 +1 -1
- 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 +4 -6
- 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/initial-sync.js +5 -3
- 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 +3 -2
- 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.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 +3 -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.js +1 -1
- 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.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 +1 -1
- 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.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.js.map +1 -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.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.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js +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 +2 -2
- 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 +5 -3
- 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 +21 -21
- 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 +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.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 +1 -1
- 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 +3 -3
- 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 +1 -1
- 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/snapshot-message.js +1 -1
- 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 +1 -1
- 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.d.ts.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 +1 -3
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +2 -2
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscribe.js +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 +2 -2
- 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.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +1 -1
- 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 +1 -1
- 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 +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +3 -2
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/plannerz.js +4 -3
- 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 +3 -2
- 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 +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.map +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 +1 -1
- 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 +1 -1
- package/out/zero-cache/src/services/replicator/reporter/recorder.js.map +1 -1
- package/out/zero-cache/src/services/replicator/reporter/report-schema.js +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 +1 -1
- 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 -7
- 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.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 +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js.map +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.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 +2 -1
- 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.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.js +24 -3
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-schema.d.ts +15 -2
- package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.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.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +10 -5
- 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.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 +5 -3
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +8 -5
- 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.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.map +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/cvr.js +1 -1
- package/out/zero-cache/src/services/view-syncer/schema/types.js +1 -1
- 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.d.ts +8 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +6 -5
- 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.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +13 -9
- 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.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.js +6 -4
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/poke-chunk.js +2 -2
- package/out/zero-cache/src/types/poke-chunk.js.map +1 -1
- package/out/zero-cache/src/types/processes.js +1 -1
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/profiler.js.map +1 -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.js +10 -9
- 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.map +1 -1
- package/out/zero-cache/src/types/timeout.js +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +1 -1
- package/out/zero-cache/src/types/ws.js +1 -1
- package/out/zero-cache/src/workers/connection.js +5 -6
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/mutator.js.map +1 -1
- 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.d.ts.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 +4 -4
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/active-clients-manager.js +1 -1
- package/out/zero-client/src/client/active-clients-manager.js.map +1 -1
- package/out/zero-client/src/client/bindings.js +11 -11
- 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.js.map +1 -1
- package/out/zero-client/src/client/crud-impl.js +1 -1
- package/out/zero-client/src/client/crud-impl.js.map +1 -1
- package/out/zero-client/src/client/crud.js +1 -1
- package/out/zero-client/src/client/crud.js.map +1 -1
- package/out/zero-client/src/client/custom.js +1 -1
- 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.js +1 -1
- package/out/zero-client/src/client/enable-analytics.js.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.js +1 -3
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/keys.js +2 -1
- 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.js.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js.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/version.js +1 -1
- package/out/zero-client/src/client/zero-poke-handler.js +1 -1
- package/out/zero-client/src/client/zero-poke-handler.js.map +1 -1
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.js +19 -11
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/mod.js +23 -23
- package/out/zero-client/src/util/nanoid.js.map +1 -1
- package/out/zero-permissions/src/permissions.js +3 -2
- package/out/zero-permissions/src/permissions.js.map +1 -1
- package/out/zero-pg/src/mod.js +9 -9
- 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.js +19 -9
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/change-desired-queries.js.map +1 -1
- package/out/zero-protocol/src/client-schema.js +1 -1
- package/out/zero-protocol/src/client-schema.js.map +1 -1
- package/out/zero-protocol/src/close-connection.js +1 -1
- package/out/zero-protocol/src/close-connection.js.map +1 -1
- package/out/zero-protocol/src/connect.js +1 -1
- package/out/zero-protocol/src/connect.js.map +1 -1
- package/out/zero-protocol/src/custom-queries.js +1 -1
- package/out/zero-protocol/src/custom-queries.js.map +1 -1
- package/out/zero-protocol/src/data.js +4 -2
- 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 +81 -81
- package/out/zero-protocol/src/inspect-down.js +1 -1
- package/out/zero-protocol/src/inspect-down.js.map +1 -1
- package/out/zero-protocol/src/inspect-up.js +1 -1
- package/out/zero-protocol/src/inspect-up.js.map +1 -1
- package/out/zero-protocol/src/mutate-server.js +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.js +1 -1
- package/out/zero-protocol/src/mutation.js.map +1 -1
- package/out/zero-protocol/src/mutations-patch.js +1 -1
- package/out/zero-protocol/src/mutations-patch.js.map +1 -1
- package/out/zero-protocol/src/ping.js +1 -1
- package/out/zero-protocol/src/ping.js.map +1 -1
- package/out/zero-protocol/src/poke.d.ts +6 -6
- 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.js +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.js +1 -0
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/pull.js +1 -1
- package/out/zero-protocol/src/pull.js.map +1 -1
- package/out/zero-protocol/src/push.js +1 -1
- package/out/zero-protocol/src/push.js.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.js.map +1 -1
- package/out/zero-protocol/src/query-hash.js +2 -2
- package/out/zero-protocol/src/query-server.js +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.map +1 -1
- package/out/zero-protocol/src/update-auth.js.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.js +1 -1
- 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/schema-builder.js +3 -2
- package/out/zero-schema/src/builder/schema-builder.js.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.js +7 -5
- package/out/zero-schema/src/name-mapper.js.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-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 +1 -1
- 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.js +2 -1
- package/out/zero-server/src/queries/process-queries.js.map +1 -1
- package/out/zero-server/src/schema.js +7 -7
- 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.js +1 -1
- 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/name-mapper.js.map +1 -1
- package/out/zql/src/builder/builder.js +15 -13
- 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/like.js +0 -1
- package/out/zql/src/builder/like.js.map +1 -1
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/constraint.js +1 -1
- package/out/zql/src/ivm/constraint.js.map +1 -1
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.js.map +1 -1
- package/out/zql/src/ivm/exists.js +20 -18
- package/out/zql/src/ivm/exists.js.map +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.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.js +1 -3
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join-index-tap.js.map +1 -1
- package/out/zql/src/ivm/join-index.js.map +1 -1
- package/out/zql/src/ivm/join-utils.js +11 -13
- package/out/zql/src/ivm/join-utils.js.map +1 -1
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.js +26 -22
- 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.js +2 -2
- package/out/zql/src/ivm/push-accumulated.js +0 -1
- package/out/zql/src/ivm/push-accumulated.js.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/take-gate.js.map +1 -1
- package/out/zql/src/ivm/take.js +1 -1
- package/out/zql/src/ivm/take.js.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.js +1 -1
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/mutate/crud.js +3 -2
- package/out/zql/src/mutate/crud.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.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-source.js.map +1 -1
- package/out/zql/src/planner/planner-terminus.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.js +1 -1
- package/out/zql/src/query/expression.js.map +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.js +1 -1
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-impl.js +3 -2
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-registry.js +1 -1
- package/out/zql/src/query/query-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/runnable-query-impl.js +3 -2
- 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.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.d.ts +27 -8
- package/out/zqlite/src/database-storage.d.ts.map +1 -1
- package/out/zqlite/src/database-storage.js +190 -53
- 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.js.map +1 -1
- 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.js.map +1 -1
- package/out/zqlite/src/query-builder.js +1 -1
- 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 +11 -0
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +62 -25
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +17 -15
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-transitions.js","names":["#bounded","#firstKey","#firstValue","#firstDelta","#first","#rest","#restSize","#maybeSweep","#sweepAt","#byHash"],"sources":["../../../../../zql/src/query/query-transitions.ts"],"sourcesContent":["import {deepEqual, type ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {getOrInsertComputed, newMap} from '../../../shared/src/map.ts';\n\n/**\n * A transition tree for interning immutable builder objects, modelled on V8's\n * hidden-class transitions.\n *\n * Each node keeps a map from a *transition* (an operation plus its arguments) to\n * the node that operation produces. Applying the same operation to the same node\n * twice therefore yields the same object both times.\n *\n * ## Why not hash?\n *\n * Hashing the resulting AST would work but is far too expensive to do on every\n * builder call. Instead a transition is identified by three things, in\n * decreasing order of how cheap they are to compare:\n *\n * 1. `key` — a short string naming the operation. Callers are expected to hand\n * in a *stable* string rather than build one per call; see below.\n * 2. `value` — the operation's varying argument, when it is a primitive, used\n * directly as a `Map` key.\n * 3. `delta` — anything left over, compared with {@link deepEqual}.\n *\n * Splitting 1 from 2 is what makes this fast. Folding the value into the key\n * instead means building a fresh string on every call, and a fresh string has to\n * be hashed from scratch before a `Map` can look it up: measured at ~148ns,\n * against ~10ns to look up the caller's own string, whose hash V8 has already\n * cached on the string object. That difference is larger than everything else a\n * transition does.\n *\n * Comparing only the delta is sound because the parent node is already canonical:\n * two children of the same parent are equal exactly when the operations that\n * produced them are equal. We never deep-compare a whole AST.\n *\n * ## Liveness\n *\n * Children point back at their parents strongly (see `QueryImpl`), so holding a\n * query holds its whole ancestor spine and re-deriving it from the root gives\n * the same object back. The other direction has to be weak, or an interned root\n * — which lives as long as its schema — would retain every query ever derived\n * from it.\n *\n * Weak is expensive, though: `new WeakRef` costs on the order of a hundred\n * nanoseconds, more than everything else a transition does put together, and it\n * adds GC work later. So the *first* transition out of a node is held strongly\n * instead, in fields on this object, with no `WeakRef` at all.\n *\n * That is safe because strong first-children form a path, not a tree: each node\n * pins at most one child, which pins at most one of its own. The retained set\n * per root is bounded by the depth of a builder chain — a handful of queries —\n * rather than by how many distinct queries an app builds. Everything past the\n * first child is weak, so the unbounded cases (a search box typing into\n * `where:title:=:s<text>`, a row id per list item) stay collectible.\n *\n * It is also where the wins are: a chain like `q.where(…).orderBy(…).limit(…)`\n * gives every node exactly one child, so building it allocates no `WeakRef`s and\n * looks up through a field compare rather than a hash lookup.\n *\n * What a collected child leaves behind is a cleared `WeakRef` and its map key. A\n * lookup drops those as it walks, which covers every key that is asked for\n * again. A key that is *never* asked for again is handled by the sweep.\n *\n * ## Best effort\n *\n * Interning is a cache, not a guarantee: a missed lookup only costs an extra\n * object. See {@link MAX_SCAN} for the one case where we deliberately give\n * up.\n *\n * ## Identity vs. hash\n *\n * Identity implies an equal query hash, but the tree alone does not give the\n * converse. `normalizeAST` sorts `related` and `and`/`or` conditions, so\n * `q.where(a).where(b)` and `q.where(b).where(a)` hash the same while being\n * distinct paths, and so distinct nodes. {@link HashIndex} is the second\n * level that folds those together once they have been hashed. Callers that\n * need the normalizing behavior for a query that may not have been must keep\n * using the hash.\n */\n\n/**\n * The delta identifying a transition, or `undefined` when the key already\n * determines the result on its own.\n */\nexport type Delta = ReadonlyJSONValue | undefined;\n\ntype Entry<T extends object> = {\n readonly delta: Delta;\n readonly ref: WeakRef<T>;\n};\n\n/**\n * A bucket holds a bare entry in the common single-entry case and is promoted to\n * a `Set` only on collision, so the usual transition allocates no container.\n *\n * A `Set` rather than an array: deleting during iteration is well defined, so a\n * lookup prunes collected entries and stops at its match in a single pass, and\n * removing an entry is O(1) rather than a scan.\n */\ntype Bucket<T extends object> = Entry<T> | Set<Entry<T>>;\n\n/** The varying argument of a transition, when it is one. */\nexport type TransitionValue = string | number | boolean | null | undefined;\n\n/**\n * The longest `deepEqual` scan we are willing to do on a lookup.\n *\n * This is a *latency* bound, not a memory bound — memory is already handled,\n * since entries are weak and are pruned both by the sweep and by any lookup that\n * walks past them, so a bucket only ever holds children that are still alive.\n *\n * Note what happens at the limit: we stop *storing*, we do not evict. Evicting\n * would de-intern objects that are still in use, and on a sequential sweep of a\n * live set larger than the limit it drives the hit rate to zero — each lookup\n * throws out the entry the next one needs. Refusing to store instead leaves\n * every already-shared sibling shared and degrades the surplus to the old\n * behavior of a fresh instance per call.\n *\n * Buckets should rarely get near this. Keys carry the discriminating value\n * wherever it is cheap to, and a key that carries it is *exact*, so it costs no\n * comparison at all: every simple comparison goes that way, and so does a\n * one-hop `exists`, via its sub-query's identity. What is left sharing a bucket\n * is two-hop `exists`, the `and`/`or` trees an expression factory builds, and\n * relationships whose callback varies.\n */\nexport const MAX_SCAN = 64;\n\n/** How large the weak map must get before its first sweep. */\nconst SWEEP_INITIAL = 64;\n\n/** The transitions out of one node. */\nexport class Transitions<T extends object> {\n // The first transition, held strongly and in place. See \"Liveness\" above.\n #firstKey: string | undefined;\n #firstValue: TransitionValue;\n #firstDelta: Delta;\n #first: T | undefined;\n\n // Transitions whose key space is finite and comes from the schema rather than\n // from user data, held strongly. See `storeBounded`.\n #bounded: Map<string, T> | undefined;\n\n // Everything else, weakly. Allocated only if there is a second. Nested so the\n // value stays a `Map` key of its own rather than part of the string.\n #rest: Map<string, Map<TransitionValue, Bucket<T>>> | undefined;\n #sweepAt = SWEEP_INITIAL;\n #restSize = 0;\n\n lookupBounded(key: string): T | undefined {\n return this.#bounded?.get(key);\n }\n\n /**\n * Records a transition whose key space is finite and schema-derived — the base\n * sub-query handed to a `related`/`exists` callback, keyed by relationship\n * name.\n *\n * These are held strongly. Retention is bounded by the number of relationships\n * on the table, so it cannot grow with what an app queries for, and in exchange\n * a relationship traversal allocates no `WeakRef`. Anything keyed by a *value*\n * — a row id, a search string, a limit — must not come through here.\n */\n storeBounded(key: string, value: T): void {\n (this.#bounded ??= new Map()).set(key, value);\n }\n\n lookup(key: string, value: TransitionValue, delta: Delta): T | undefined {\n if (\n this.#firstKey === key &&\n this.#firstValue === value &&\n deepEqual(this.#firstDelta, delta)\n ) {\n return this.#first;\n }\n const byValue = this.#rest?.get(key);\n if (byValue === undefined) {\n return undefined;\n }\n const bucket = byValue.get(value);\n if (bucket === undefined) {\n return undefined;\n }\n\n if (!(bucket instanceof Set)) {\n const found = bucket.ref.deref();\n if (found === undefined) {\n byValue.delete(value);\n this.#restSize--;\n return undefined;\n }\n // deepEqual short-circuits on reference equality, which is the fast path\n // we rely on for deltas built out of already-interned sub-queries.\n return deepEqual(bucket.delta, delta) ? found : undefined;\n }\n\n // One pass: drop what has been collected, stop at the match. Deleting from a\n // Set while iterating it is well defined — the iterator simply skips what is\n // gone — so this stays O(n) with no compaction step, and returns early on a\n // hit rather than walking the whole bucket first.\n for (const entry of bucket) {\n const found = entry.ref.deref();\n if (found === undefined) {\n bucket.delete(entry);\n this.#restSize--;\n continue;\n }\n if (deepEqual(entry.delta, delta)) {\n return found;\n }\n }\n if (bucket.size === 0) {\n byValue.delete(value);\n }\n return undefined;\n }\n\n store(key: string, value: TransitionValue, delta: Delta, node: T): void {\n if (this.#firstKey === undefined) {\n this.#firstKey = key;\n this.#firstValue = value;\n this.#firstDelta = delta;\n this.#first = node;\n return;\n }\n\n const rest = (this.#rest ??= new Map());\n const byValue = getOrInsertComputed(rest, key, newMap);\n\n const entry: Entry<T> = {delta, ref: new WeakRef(node)};\n const bucket = byValue.get(value);\n\n if (bucket === undefined) {\n byValue.set(value, entry);\n } else if (!(bucket instanceof Set)) {\n byValue.set(value, new Set([bucket, entry]));\n } else {\n if (bucket.size >= MAX_SCAN) {\n // Leave the bucket alone; see MAX_SCAN. `node` is simply not shared.\n // A store only follows a failed lookup, which has just pruned, so this\n // is measured against entries that are actually still alive.\n return;\n }\n bucket.add(entry);\n }\n this.#restSize++;\n this.#maybeSweep(rest);\n }\n\n /**\n * Re-points the transition that produced `from` at `to`, so the next lookup\n * along that path yields `to` instead. This is how {@link HashIndex}\n * converges two paths on one node: `from` keeps its identity, since it has\n * already been handed out, and its path is redirected for the rebuilds that\n * follow.\n *\n * Scans rather than taking a key. This runs once per redirected path, so a\n * walk here is cheaper than the fields every node would need to carry to\n * name its own transition.\n */\n replace(from: T, to: T): boolean {\n if (this.#first === from) {\n this.#first = to;\n return true;\n }\n const rest = this.#rest;\n if (rest === undefined) {\n return false;\n }\n for (const byValue of rest.values()) {\n for (const [value, bucket] of byValue) {\n if (!(bucket instanceof Set)) {\n if (bucket.ref.deref() === from) {\n byValue.set(value, {delta: bucket.delta, ref: new WeakRef(to)});\n return true;\n }\n continue;\n }\n for (const entry of bucket) {\n if (entry.ref.deref() === from) {\n bucket.delete(entry);\n bucket.add({delta: entry.delta, ref: new WeakRef(to)});\n return true;\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Drops entries for collected values, if the map has grown enough to be worth\n * walking.\n *\n * A lookup already prunes whatever it walks past, which covers every key that\n * is asked for again. This is for the key that is not: a miss on a fresh key\n * returns without touching any existing entry, so nothing would ever notice\n * that those had died. Doubling the threshold off whatever survives keeps this\n * amortized O(1) per insert whether or not there was anything to reclaim, and\n * it is self-limiting — only a node that keeps taking inserts can keep\n * accumulating, and taking inserts is what triggers the sweep.\n */\n #maybeSweep(rest: Map<string, Map<TransitionValue, Bucket<T>>>): void {\n if (this.#restSize < this.#sweepAt) {\n return;\n }\n let live = 0;\n for (const [key, byValue] of rest) {\n for (const [value, bucket] of byValue) {\n if (!(bucket instanceof Set)) {\n if (bucket.ref.deref() === undefined) {\n byValue.delete(value);\n } else {\n live++;\n }\n continue;\n }\n for (const entry of bucket) {\n if (entry.ref.deref() === undefined) {\n bucket.delete(entry);\n } else {\n live++;\n }\n }\n if (bucket.size === 0) {\n byValue.delete(value);\n }\n }\n if (byValue.size === 0) {\n rest.delete(key);\n }\n }\n this.#restSize = live;\n this.#sweepAt = Math.max(SWEEP_INITIAL, live * 2);\n }\n}\n\n/**\n * The second level of interning: nodes keyed by *content* rather than by the\n * path that built them.\n *\n * The transition tree cannot see that `q.where(a).where(b)` and\n * `q.where(b).where(a)` are the same query. `normalizeAST` sorts conditions\n * and `related` entries, so the two build byte-identical ASTs, but they are\n * different paths and so different nodes. This index closes that gap, keyed by\n * the query's hash.\n *\n * It is consulted when a query is *hashed*, not when it is built. Hashing on\n * every tree miss would make a cold chain pay for a hash per node, where the\n * uninterned code paid for one at the end, if at all -- and server-side queries\n * are built cold, once, per request. The consumers that key by hash already\n * hash the queries they care about, so doing the work there costs one map\n * lookup on top of a hash that was being computed anyway, and nothing at all\n * for a query nobody hashes.\n *\n * On a hit the query being hashed keeps its identity, since it has already\n * been handed out. Its *transition* is re-pointed at the existing node instead\n * (see {@link Transitions.replace}), so the next rebuild along that path\n * yields the shared instance. As with the tree this is a cache: the rebuild\n * after a redirect is what converges, not the call that found the duplicate.\n *\n * One index per root, which is what scopes it. Two roots never share an index,\n * so queries against different schemas or different delegates -- neither of\n * which the hash covers -- can never be conflated. Entries are weak: a cleared\n * one is dropped by the lookup that finds it, or by a sweep once the map has\n * doubled since the last one.\n */\nexport class HashIndex<T extends object> {\n readonly #byHash = new Map<string, WeakRef<T>>();\n #sweepAt = SWEEP_INITIAL;\n\n get(hash: string): T | undefined {\n const ref = this.#byHash.get(hash);\n if (ref === undefined) {\n return undefined;\n }\n const node = ref.deref();\n if (node === undefined) {\n this.#byHash.delete(hash);\n }\n return node;\n }\n\n set(hash: string, node: T): void {\n const byHash = this.#byHash;\n byHash.set(hash, new WeakRef(node));\n if (byHash.size < this.#sweepAt) {\n return;\n }\n for (const [h, ref] of byHash) {\n if (ref.deref() === undefined) {\n byHash.delete(h);\n }\n }\n this.#sweepAt = Math.max(SWEEP_INITIAL, byHash.size * 2);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"query-transitions.js","names":[],"sources":["../../../../../zql/src/query/query-transitions.ts"],"sourcesContent":["import {deepEqual, type ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {getOrInsertComputed, newMap} from '../../../shared/src/map.ts';\n\n/**\n * A transition tree for interning immutable builder objects, modelled on V8's\n * hidden-class transitions.\n *\n * Each node keeps a map from a *transition* (an operation plus its arguments) to\n * the node that operation produces. Applying the same operation to the same node\n * twice therefore yields the same object both times.\n *\n * ## Why not hash?\n *\n * Hashing the resulting AST would work but is far too expensive to do on every\n * builder call. Instead a transition is identified by three things, in\n * decreasing order of how cheap they are to compare:\n *\n * 1. `key` — a short string naming the operation. Callers are expected to hand\n * in a *stable* string rather than build one per call; see below.\n * 2. `value` — the operation's varying argument, when it is a primitive, used\n * directly as a `Map` key.\n * 3. `delta` — anything left over, compared with {@link deepEqual}.\n *\n * Splitting 1 from 2 is what makes this fast. Folding the value into the key\n * instead means building a fresh string on every call, and a fresh string has to\n * be hashed from scratch before a `Map` can look it up: measured at ~148ns,\n * against ~10ns to look up the caller's own string, whose hash V8 has already\n * cached on the string object. That difference is larger than everything else a\n * transition does.\n *\n * Comparing only the delta is sound because the parent node is already canonical:\n * two children of the same parent are equal exactly when the operations that\n * produced them are equal. We never deep-compare a whole AST.\n *\n * ## Liveness\n *\n * Children point back at their parents strongly (see `QueryImpl`), so holding a\n * query holds its whole ancestor spine and re-deriving it from the root gives\n * the same object back. The other direction has to be weak, or an interned root\n * — which lives as long as its schema — would retain every query ever derived\n * from it.\n *\n * Weak is expensive, though: `new WeakRef` costs on the order of a hundred\n * nanoseconds, more than everything else a transition does put together, and it\n * adds GC work later. So the *first* transition out of a node is held strongly\n * instead, in fields on this object, with no `WeakRef` at all.\n *\n * That is safe because strong first-children form a path, not a tree: each node\n * pins at most one child, which pins at most one of its own. The retained set\n * per root is bounded by the depth of a builder chain — a handful of queries —\n * rather than by how many distinct queries an app builds. Everything past the\n * first child is weak, so the unbounded cases (a search box typing into\n * `where:title:=:s<text>`, a row id per list item) stay collectible.\n *\n * It is also where the wins are: a chain like `q.where(…).orderBy(…).limit(…)`\n * gives every node exactly one child, so building it allocates no `WeakRef`s and\n * looks up through a field compare rather than a hash lookup.\n *\n * What a collected child leaves behind is a cleared `WeakRef` and its map key. A\n * lookup drops those as it walks, which covers every key that is asked for\n * again. A key that is *never* asked for again is handled by the sweep.\n *\n * ## Best effort\n *\n * Interning is a cache, not a guarantee: a missed lookup only costs an extra\n * object. See {@link MAX_SCAN} for the one case where we deliberately give\n * up.\n *\n * ## Identity vs. hash\n *\n * Identity implies an equal query hash, but the tree alone does not give the\n * converse. `normalizeAST` sorts `related` and `and`/`or` conditions, so\n * `q.where(a).where(b)` and `q.where(b).where(a)` hash the same while being\n * distinct paths, and so distinct nodes. {@link HashIndex} is the second\n * level that folds those together once they have been hashed. Callers that\n * need the normalizing behavior for a query that may not have been must keep\n * using the hash.\n */\n\n/**\n * The delta identifying a transition, or `undefined` when the key already\n * determines the result on its own.\n */\nexport type Delta = ReadonlyJSONValue | undefined;\n\ntype Entry<T extends object> = {\n readonly delta: Delta;\n readonly ref: WeakRef<T>;\n};\n\n/**\n * A bucket holds a bare entry in the common single-entry case and is promoted to\n * a `Set` only on collision, so the usual transition allocates no container.\n *\n * A `Set` rather than an array: deleting during iteration is well defined, so a\n * lookup prunes collected entries and stops at its match in a single pass, and\n * removing an entry is O(1) rather than a scan.\n */\ntype Bucket<T extends object> = Entry<T> | Set<Entry<T>>;\n\n/** The varying argument of a transition, when it is one. */\nexport type TransitionValue = string | number | boolean | null | undefined;\n\n/**\n * The longest `deepEqual` scan we are willing to do on a lookup.\n *\n * This is a *latency* bound, not a memory bound — memory is already handled,\n * since entries are weak and are pruned both by the sweep and by any lookup that\n * walks past them, so a bucket only ever holds children that are still alive.\n *\n * Note what happens at the limit: we stop *storing*, we do not evict. Evicting\n * would de-intern objects that are still in use, and on a sequential sweep of a\n * live set larger than the limit it drives the hit rate to zero — each lookup\n * throws out the entry the next one needs. Refusing to store instead leaves\n * every already-shared sibling shared and degrades the surplus to the old\n * behavior of a fresh instance per call.\n *\n * Buckets should rarely get near this. Keys carry the discriminating value\n * wherever it is cheap to, and a key that carries it is *exact*, so it costs no\n * comparison at all: every simple comparison goes that way, and so does a\n * one-hop `exists`, via its sub-query's identity. What is left sharing a bucket\n * is two-hop `exists`, the `and`/`or` trees an expression factory builds, and\n * relationships whose callback varies.\n */\nexport const MAX_SCAN = 64;\n\n/** How large the weak map must get before its first sweep. */\nconst SWEEP_INITIAL = 64;\n\n/** The transitions out of one node. */\nexport class Transitions<T extends object> {\n // The first transition, held strongly and in place. See \"Liveness\" above.\n #firstKey: string | undefined;\n #firstValue: TransitionValue;\n #firstDelta: Delta;\n #first: T | undefined;\n\n // Transitions whose key space is finite and comes from the schema rather than\n // from user data, held strongly. See `storeBounded`.\n #bounded: Map<string, T> | undefined;\n\n // Everything else, weakly. Allocated only if there is a second. Nested so the\n // value stays a `Map` key of its own rather than part of the string.\n #rest: Map<string, Map<TransitionValue, Bucket<T>>> | undefined;\n #sweepAt = SWEEP_INITIAL;\n #restSize = 0;\n\n lookupBounded(key: string): T | undefined {\n return this.#bounded?.get(key);\n }\n\n /**\n * Records a transition whose key space is finite and schema-derived — the base\n * sub-query handed to a `related`/`exists` callback, keyed by relationship\n * name.\n *\n * These are held strongly. Retention is bounded by the number of relationships\n * on the table, so it cannot grow with what an app queries for, and in exchange\n * a relationship traversal allocates no `WeakRef`. Anything keyed by a *value*\n * — a row id, a search string, a limit — must not come through here.\n */\n storeBounded(key: string, value: T): void {\n (this.#bounded ??= new Map()).set(key, value);\n }\n\n lookup(key: string, value: TransitionValue, delta: Delta): T | undefined {\n if (\n this.#firstKey === key &&\n this.#firstValue === value &&\n deepEqual(this.#firstDelta, delta)\n ) {\n return this.#first;\n }\n const byValue = this.#rest?.get(key);\n if (byValue === undefined) {\n return undefined;\n }\n const bucket = byValue.get(value);\n if (bucket === undefined) {\n return undefined;\n }\n\n if (!(bucket instanceof Set)) {\n const found = bucket.ref.deref();\n if (found === undefined) {\n byValue.delete(value);\n this.#restSize--;\n return undefined;\n }\n // deepEqual short-circuits on reference equality, which is the fast path\n // we rely on for deltas built out of already-interned sub-queries.\n return deepEqual(bucket.delta, delta) ? found : undefined;\n }\n\n // One pass: drop what has been collected, stop at the match. Deleting from a\n // Set while iterating it is well defined — the iterator simply skips what is\n // gone — so this stays O(n) with no compaction step, and returns early on a\n // hit rather than walking the whole bucket first.\n for (const entry of bucket) {\n const found = entry.ref.deref();\n if (found === undefined) {\n bucket.delete(entry);\n this.#restSize--;\n continue;\n }\n if (deepEqual(entry.delta, delta)) {\n return found;\n }\n }\n if (bucket.size === 0) {\n byValue.delete(value);\n }\n return undefined;\n }\n\n store(key: string, value: TransitionValue, delta: Delta, node: T): void {\n if (this.#firstKey === undefined) {\n this.#firstKey = key;\n this.#firstValue = value;\n this.#firstDelta = delta;\n this.#first = node;\n return;\n }\n\n const rest = (this.#rest ??= new Map());\n const byValue = getOrInsertComputed(rest, key, newMap);\n\n const entry: Entry<T> = {delta, ref: new WeakRef(node)};\n const bucket = byValue.get(value);\n\n if (bucket === undefined) {\n byValue.set(value, entry);\n } else if (!(bucket instanceof Set)) {\n byValue.set(value, new Set([bucket, entry]));\n } else {\n if (bucket.size >= MAX_SCAN) {\n // Leave the bucket alone; see MAX_SCAN. `node` is simply not shared.\n // A store only follows a failed lookup, which has just pruned, so this\n // is measured against entries that are actually still alive.\n return;\n }\n bucket.add(entry);\n }\n this.#restSize++;\n this.#maybeSweep(rest);\n }\n\n /**\n * Re-points the transition that produced `from` at `to`, so the next lookup\n * along that path yields `to` instead. This is how {@link HashIndex}\n * converges two paths on one node: `from` keeps its identity, since it has\n * already been handed out, and its path is redirected for the rebuilds that\n * follow.\n *\n * Scans rather than taking a key. This runs once per redirected path, so a\n * walk here is cheaper than the fields every node would need to carry to\n * name its own transition.\n */\n replace(from: T, to: T): boolean {\n if (this.#first === from) {\n this.#first = to;\n return true;\n }\n const rest = this.#rest;\n if (rest === undefined) {\n return false;\n }\n for (const byValue of rest.values()) {\n for (const [value, bucket] of byValue) {\n if (!(bucket instanceof Set)) {\n if (bucket.ref.deref() === from) {\n byValue.set(value, {delta: bucket.delta, ref: new WeakRef(to)});\n return true;\n }\n continue;\n }\n for (const entry of bucket) {\n if (entry.ref.deref() === from) {\n bucket.delete(entry);\n bucket.add({delta: entry.delta, ref: new WeakRef(to)});\n return true;\n }\n }\n }\n }\n return false;\n }\n\n /**\n * Drops entries for collected values, if the map has grown enough to be worth\n * walking.\n *\n * A lookup already prunes whatever it walks past, which covers every key that\n * is asked for again. This is for the key that is not: a miss on a fresh key\n * returns without touching any existing entry, so nothing would ever notice\n * that those had died. Doubling the threshold off whatever survives keeps this\n * amortized O(1) per insert whether or not there was anything to reclaim, and\n * it is self-limiting — only a node that keeps taking inserts can keep\n * accumulating, and taking inserts is what triggers the sweep.\n */\n #maybeSweep(rest: Map<string, Map<TransitionValue, Bucket<T>>>): void {\n if (this.#restSize < this.#sweepAt) {\n return;\n }\n let live = 0;\n for (const [key, byValue] of rest) {\n for (const [value, bucket] of byValue) {\n if (!(bucket instanceof Set)) {\n if (bucket.ref.deref() === undefined) {\n byValue.delete(value);\n } else {\n live++;\n }\n continue;\n }\n for (const entry of bucket) {\n if (entry.ref.deref() === undefined) {\n bucket.delete(entry);\n } else {\n live++;\n }\n }\n if (bucket.size === 0) {\n byValue.delete(value);\n }\n }\n if (byValue.size === 0) {\n rest.delete(key);\n }\n }\n this.#restSize = live;\n this.#sweepAt = Math.max(SWEEP_INITIAL, live * 2);\n }\n}\n\n/**\n * The second level of interning: nodes keyed by *content* rather than by the\n * path that built them.\n *\n * The transition tree cannot see that `q.where(a).where(b)` and\n * `q.where(b).where(a)` are the same query. `normalizeAST` sorts conditions\n * and `related` entries, so the two build byte-identical ASTs, but they are\n * different paths and so different nodes. This index closes that gap, keyed by\n * the query's hash.\n *\n * It is consulted when a query is *hashed*, not when it is built. Hashing on\n * every tree miss would make a cold chain pay for a hash per node, where the\n * uninterned code paid for one at the end, if at all -- and server-side queries\n * are built cold, once, per request. The consumers that key by hash already\n * hash the queries they care about, so doing the work there costs one map\n * lookup on top of a hash that was being computed anyway, and nothing at all\n * for a query nobody hashes.\n *\n * On a hit the query being hashed keeps its identity, since it has already\n * been handed out. Its *transition* is re-pointed at the existing node instead\n * (see {@link Transitions.replace}), so the next rebuild along that path\n * yields the shared instance. As with the tree this is a cache: the rebuild\n * after a redirect is what converges, not the call that found the duplicate.\n *\n * One index per root, which is what scopes it. Two roots never share an index,\n * so queries against different schemas or different delegates -- neither of\n * which the hash covers -- can never be conflated. Entries are weak: a cleared\n * one is dropped by the lookup that finds it, or by a sweep once the map has\n * doubled since the last one.\n */\nexport class HashIndex<T extends object> {\n readonly #byHash = new Map<string, WeakRef<T>>();\n #sweepAt = SWEEP_INITIAL;\n\n get(hash: string): T | undefined {\n const ref = this.#byHash.get(hash);\n if (ref === undefined) {\n return undefined;\n }\n const node = ref.deref();\n if (node === undefined) {\n this.#byHash.delete(hash);\n }\n return node;\n }\n\n set(hash: string, node: T): void {\n const byHash = this.#byHash;\n byHash.set(hash, new WeakRef(node));\n if (byHash.size < this.#sweepAt) {\n return;\n }\n for (const [h, ref] of byHash) {\n if (ref.deref() === undefined) {\n byHash.delete(h);\n }\n }\n this.#sweepAt = Math.max(SWEEP_INITIAL, byHash.size * 2);\n }\n}\n"],"mappings":"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"}
|
|
@@ -10,7 +10,8 @@ import { QueryImpl } from "./query-impl.js";
|
|
|
10
10
|
*/
|
|
11
11
|
var rootsByDelegate = /* @__PURE__ */ new WeakMap();
|
|
12
12
|
function newRunnableQuery(delegate, schema, table) {
|
|
13
|
-
const
|
|
13
|
+
const bySchema = getOrInsertComputed(rootsByDelegate, delegate, newWeakMap);
|
|
14
|
+
const roots = getOrInsertComputed(bySchema, schema, newMap);
|
|
14
15
|
const existing = roots.get(table)?.deref();
|
|
15
16
|
if (existing) return existing;
|
|
16
17
|
const created = new RunnableQueryImpl(delegate, schema, table, tableAST(table), defaultFormat, void 0);
|
|
@@ -43,6 +44,6 @@ var RunnableQueryImpl = class RunnableQueryImpl extends QueryImpl {
|
|
|
43
44
|
}
|
|
44
45
|
};
|
|
45
46
|
//#endregion
|
|
46
|
-
export { newRunnableQuery };
|
|
47
|
+
export { RunnableQueryImpl, newRunnableQuery };
|
|
47
48
|
|
|
48
49
|
//# sourceMappingURL=runnable-query-impl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runnable-query-impl.js","names":[
|
|
1
|
+
{"version":3,"file":"runnable-query-impl.js","names":[],"sources":["../../../../../zql/src/query/runnable-query-impl.ts"],"sourcesContent":["import {\n getOrInsertComputed,\n newMap,\n newWeakMap,\n} from '../../../shared/src/map.ts';\nimport {\n tableAST,\n type NormalizedAST,\n type System,\n} from '../../../zero-protocol/src/ast.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport {defaultFormat} from '../ivm/default-format.ts';\nimport type {Format, ViewFactory} from '../ivm/view.ts';\nimport type {CustomQueryID} from './named.ts';\nimport type {QueryDelegate} from './query-delegate.ts';\nimport {QueryImpl} from './query-impl.ts';\nimport type {\n HumanReadable,\n MaterializeOptions,\n PreloadOptions,\n PullRow,\n Query,\n RunOptions,\n} from './query.ts';\nimport type {TTL} from './ttl.ts';\nimport type {TypedView} from './typed-view.ts';\n\n/**\n * Runnable roots are interned per delegate *and* schema -- a query is only\n * interchangeable with another if it would run against the same delegate. See\n * `query-transitions.ts` for why roots need to be shared at all.\n */\nconst rootsByDelegate = new WeakMap<\n QueryDelegate,\n // oxlint-disable-next-line no-explicit-any\n WeakMap<Schema, Map<string, WeakRef<RunnableQueryImpl<any, any, any>>>>\n>();\n\nexport function newRunnableQuery<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n>(\n delegate: QueryDelegate,\n schema: TSchema,\n table: TTable,\n): Query<TTable, TSchema> {\n const bySchema = getOrInsertComputed(rootsByDelegate, delegate, newWeakMap);\n const roots = getOrInsertComputed(bySchema, schema, newMap);\n\n const existing = roots.get(table)?.deref();\n if (existing) {\n return existing as RunnableQueryImpl<TTable, TSchema>;\n }\n\n const created = new RunnableQueryImpl<TTable, TSchema>(\n delegate,\n schema,\n table,\n tableAST(table),\n defaultFormat,\n undefined,\n );\n roots.set(table, new WeakRef(created));\n return created;\n}\n\nexport class RunnableQueryImpl<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn = PullRow<TTable, TSchema>,\n>\n extends QueryImpl<TTable, TSchema, TReturn>\n implements Query<TTable, TSchema, TReturn>\n{\n readonly #delegate: QueryDelegate;\n\n constructor(\n delegate: QueryDelegate,\n schema: TSchema,\n tableName: TTable,\n ast: NormalizedAST = tableAST(tableName),\n format: Format = defaultFormat,\n system: System = 'client',\n customQueryID?: CustomQueryID,\n currentJunction?: string,\n ) {\n super(\n schema,\n tableName,\n ast,\n format,\n system,\n customQueryID,\n currentJunction,\n (tableName, ast, format, customQueryID, currentJunction) =>\n new RunnableQueryImpl(\n delegate,\n schema,\n tableName,\n ast,\n format,\n system,\n customQueryID,\n currentJunction,\n ),\n );\n this.#delegate = delegate;\n }\n\n override run(options?: RunOptions): Promise<HumanReadable<TReturn>> {\n // The type arguments on the delegate calls in this class are written out\n // because tsc 7.0.2 fails to infer them in some program layouts (the\n // packages/zero declaration build, apps/zero-throughput): inference\n // collapses TSchema to its constraint and the call misreports as a\n // TS2345 assignability error. Explicit arguments are inert where\n // inference works and correct where it does not.\n return this.#delegate.run<TTable, TSchema, TReturn>(this, options);\n }\n\n override preload(options?: PreloadOptions): {\n cleanup: () => void;\n complete: Promise<void>;\n cached: Promise<void>;\n } {\n return this.#delegate.preload<TTable, TSchema, TReturn>(this, options);\n }\n\n override materialize(ttl?: TTL): TypedView<HumanReadable<TReturn>>;\n override materialize<T>(\n factory: ViewFactory<TTable, TSchema, TReturn, T>,\n ttl?: TTL,\n ): T;\n override materialize<T>(\n factory?: unknown,\n ttl?: unknown,\n ): T | TypedView<HumanReadable<TReturn>> {\n let actualFactory: ViewFactory<TTable, TSchema, TReturn, T> | undefined;\n let options: MaterializeOptions | undefined;\n\n if (typeof factory === 'function') {\n actualFactory = factory as ViewFactory<TTable, TSchema, TReturn, T>;\n options = {ttl: ttl as TTL | undefined};\n } else {\n actualFactory = undefined;\n options = {ttl: factory as TTL | undefined};\n }\n\n return this.#delegate.materialize<TTable, TSchema, TReturn, T>(\n this,\n actualFactory,\n options,\n );\n }\n}\n"],"mappings":";;;;;;;;;;AAgCA,IAAM,kCAAkB,IAAI,QAI1B;AAEF,SAAgB,iBAId,UACA,QACA,OACwB;CACxB,MAAM,WAAW,oBAAoB,iBAAiB,UAAU,UAAU;CAC1E,MAAM,QAAQ,oBAAoB,UAAU,QAAQ,MAAM;CAE1D,MAAM,WAAW,MAAM,IAAI,KAAK,CAAC,EAAE,MAAM;CACzC,IAAI,UACF,OAAO;CAGT,MAAM,UAAU,IAAI,kBAClB,UACA,QACA,OACA,SAAS,KAAK,GACd,eACA,KAAA,CACF;CACA,MAAM,IAAI,OAAO,IAAI,QAAQ,OAAO,CAAC;CACrC,OAAO;AACT;AAEA,IAAa,oBAAb,MAAa,0BAKH,UAEV;CACE;CAEA,YACE,UACA,QACA,WACA,MAAqB,SAAS,SAAS,GACvC,SAAiB,eACjB,SAAiB,UACjB,eACA,iBACA;EACA,MACE,QACA,WACA,KACA,QACA,QACA,eACA,kBACC,WAAW,KAAK,QAAQ,eAAe,oBACtC,IAAI,kBACF,UACA,QACA,WACA,KACA,QACA,QACA,eACA,eACF,CACJ;EACA,KAAK,YAAY;CACnB;CAEA,IAAa,SAAuD;EAOlE,OAAO,KAAK,UAAU,IAA8B,MAAM,OAAO;CACnE;CAEA,QAAiB,SAIf;EACA,OAAO,KAAK,UAAU,QAAkC,MAAM,OAAO;CACvE;CAOA,YACE,SACA,KACuC;EACvC,IAAI;EACJ,IAAI;EAEJ,IAAI,OAAO,YAAY,YAAY;GACjC,gBAAgB;GAChB,UAAU,EAAM,IAAsB;EACxC,OAAO;GACL,gBAAgB,KAAA;GAChB,UAAU,EAAC,KAAK,QAA0B;EAC5C;EAEA,OAAO,KAAK,UAAU,YACpB,MACA,eACA,OACF;CACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-query.js","names":[],"sources":["../../../../../zql/src/query/static-query.ts"],"sourcesContent":["import type {Schema} from '../../../zero-types/src/schema.ts';\nimport {defaultFormat} from '../ivm/default-format.ts';\nimport {newQueryImpl, type QueryImpl} from './query-impl.ts';\nimport type {PullRow, Query} from './query.ts';\n\nexport function newStaticQuery<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn = PullRow<TTable, TSchema>,\n>(schema: TSchema, tableName: TTable): Query<TTable, TSchema, TReturn> {\n return newQueryImpl(\n schema,\n tableName,\n {table: tableName},\n defaultFormat,\n 'permissions',\n );\n}\n\nexport function newExpressionBuilder<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n>(schema: TSchema, tableName: TTable) {\n const q = newStaticQuery(schema, tableName);\n return (q as QueryImpl<TTable, TSchema>).expressionBuilder();\n}\n"],"mappings":";;;AAKA,SAAgB,eAId,QAAiB,WAAoD;CACrE,OAAO,aACL,QACA,WACA,EAAC,OAAO,UAAS,GACjB,eACA,aACF;AACF;AAEA,SAAgB,qBAGd,QAAiB,WAAmB;CAEpC,OADU,eAAe,QAAQ,SACzB,
|
|
1
|
+
{"version":3,"file":"static-query.js","names":[],"sources":["../../../../../zql/src/query/static-query.ts"],"sourcesContent":["import type {Schema} from '../../../zero-types/src/schema.ts';\nimport {defaultFormat} from '../ivm/default-format.ts';\nimport {newQueryImpl, type QueryImpl} from './query-impl.ts';\nimport type {PullRow, Query} from './query.ts';\n\nexport function newStaticQuery<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n TReturn = PullRow<TTable, TSchema>,\n>(schema: TSchema, tableName: TTable): Query<TTable, TSchema, TReturn> {\n return newQueryImpl(\n schema,\n tableName,\n {table: tableName},\n defaultFormat,\n 'permissions',\n );\n}\n\nexport function newExpressionBuilder<\n TTable extends keyof TSchema['tables'] & string,\n TSchema extends Schema,\n>(schema: TSchema, tableName: TTable) {\n const q = newStaticQuery(schema, tableName);\n return (q as QueryImpl<TTable, TSchema>).expressionBuilder();\n}\n"],"mappings":";;;AAKA,SAAgB,eAId,QAAiB,WAAoD;CACrE,OAAO,aACL,QACA,WACA,EAAC,OAAO,UAAS,GACjB,eACA,aACF;AACF;AAEA,SAAgB,qBAGd,QAAiB,WAAmB;CAEpC,OADU,eAAe,QAAQ,SACzB,CAAA,CAAiC,kBAAkB;AAC7D"}
|
package/out/zql/src/query/ttl.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
//#region ../zql/src/query/ttl.ts
|
|
2
|
-
var DEFAULT_TTL_MS =
|
|
3
|
-
var MAX_TTL_MS =
|
|
2
|
+
var DEFAULT_TTL_MS = 3e5;
|
|
3
|
+
var MAX_TTL_MS = 6e5;
|
|
4
4
|
var multiplier = {
|
|
5
5
|
s: 1e3,
|
|
6
|
-
m:
|
|
7
|
-
h:
|
|
8
|
-
d:
|
|
9
|
-
y:
|
|
6
|
+
m: 6e4,
|
|
7
|
+
h: 36e5,
|
|
8
|
+
d: 864e5,
|
|
9
|
+
y: 31536e6
|
|
10
10
|
};
|
|
11
11
|
function parseTTL(ttl) {
|
|
12
12
|
if (typeof ttl === "number") return Number.isNaN(ttl) ? 0 : !Number.isFinite(ttl) || ttl < 0 ? -1 : ttl;
|
|
@@ -42,13 +42,13 @@ function normalizeTTL(ttl) {
|
|
|
42
42
|
}
|
|
43
43
|
function clampTTL(ttl, lc) {
|
|
44
44
|
const parsedTTL = parseTTL(ttl);
|
|
45
|
-
if (parsedTTL === -1 || parsedTTL >
|
|
45
|
+
if (parsedTTL === -1 || parsedTTL > 6e5) {
|
|
46
46
|
lc?.warn?.(`TTL (${ttl}) is too high, clamping to 10m`);
|
|
47
47
|
return parseTTL("10m");
|
|
48
48
|
}
|
|
49
49
|
return parsedTTL;
|
|
50
50
|
}
|
|
51
51
|
//#endregion
|
|
52
|
-
export { DEFAULT_TTL_MS, MAX_TTL_MS, clampTTL, compareTTL, normalizeTTL };
|
|
52
|
+
export { DEFAULT_TTL_MS, MAX_TTL_MS, clampTTL, compareTTL, normalizeTTL, parseTTL };
|
|
53
53
|
|
|
54
54
|
//# sourceMappingURL=ttl.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ttl.js","names":[],"sources":["../../../../../zql/src/query/ttl.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\n\nexport type TimeUnit = 's' | 'm' | 'h' | 'd' | 'y';\n\n/**\n * Time To Live. This is used for query expiration.\n * - `forever` means the query will never expire.\n * - `none` means the query will expire immediately.\n * - A number means the query will expire after that many milliseconds.\n * - A negative number means the query will never expire, this is same as 'forever'.\n * - A string like `1s` means the query will expire after that many seconds.\n * - A string like `1m` means the query will expire after that many minutes.\n * - A string like `1h` means the query will expire after that many hours.\n * - A string like `1d` means the query will expire after that many days.\n * - A string like `1y` means the query will expire after that many years.\n */\nexport type TTL = `${number}${TimeUnit}` | 'forever' | 'none' | number;\n\nexport const DEFAULT_TTL: TTL = '5m';\nexport const DEFAULT_TTL_MS = 1_000 * 60 * 5;\n\nexport const DEFAULT_PRELOAD_TTL: TTL = 'none';\nexport const DEFAULT_PRELOAD_TTL_MS = 0;\n\nexport const MAX_TTL: TTL = '10m';\nexport const MAX_TTL_MS = 1_000 * 60 * 10;\n\nconst multiplier = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n y: 365 * 24 * 60 * 60 * 1000,\n} as const;\n\nexport function parseTTL(ttl: TTL): number {\n if (typeof ttl === 'number') {\n return Number.isNaN(ttl) ? 0 : !Number.isFinite(ttl) || ttl < 0 ? -1 : ttl;\n }\n if (ttl === 'none') {\n return 0;\n }\n if (ttl === 'forever') {\n return -1;\n }\n const multi = multiplier[ttl.at(-1) as TimeUnit];\n return Number(ttl.slice(0, -1)) * multi;\n}\n\nexport function compareTTL(a: TTL, b: TTL): number {\n const ap = parseTTL(a);\n const bp = parseTTL(b);\n if (ap === -1 && bp !== -1) {\n return 1;\n }\n if (ap !== -1 && bp === -1) {\n return -1;\n }\n return ap - bp;\n}\n\nexport function normalizeTTL(ttl: TTL): TTL {\n if (typeof ttl === 'string') {\n return ttl;\n }\n\n if (ttl < 0) {\n return 'forever';\n }\n\n if (ttl === 0) {\n return 'none';\n }\n\n let shortest = ttl.toString();\n const lengthOfNumber = shortest.length;\n for (const unit of ['y', 'd', 'h', 'm', 's'] as const) {\n const multi = multiplier[unit];\n const value = ttl / multi;\n const candidate = `${value}${unit}`;\n if (candidate.length < shortest.length) {\n shortest = candidate;\n }\n }\n\n return (shortest.length < lengthOfNumber ? shortest : ttl) as TTL;\n}\n\nexport function clampTTL(ttl: TTL, lc?: Pick<LogContext, 'warn'>): number {\n const parsedTTL = parseTTL(ttl);\n if (parsedTTL === -1 || parsedTTL > 10 * 60 * 1000) {\n // 10 minutes in milliseconds\n lc?.warn?.(`TTL (${ttl}) is too high, clamping to ${MAX_TTL}`);\n return parseTTL(MAX_TTL);\n }\n return parsedTTL;\n}\n"],"mappings":";AAmBA,IAAa,iBAAiB
|
|
1
|
+
{"version":3,"file":"ttl.js","names":[],"sources":["../../../../../zql/src/query/ttl.ts"],"sourcesContent":["import type {LogContext} from '@rocicorp/logger';\n\nexport type TimeUnit = 's' | 'm' | 'h' | 'd' | 'y';\n\n/**\n * Time To Live. This is used for query expiration.\n * - `forever` means the query will never expire.\n * - `none` means the query will expire immediately.\n * - A number means the query will expire after that many milliseconds.\n * - A negative number means the query will never expire, this is same as 'forever'.\n * - A string like `1s` means the query will expire after that many seconds.\n * - A string like `1m` means the query will expire after that many minutes.\n * - A string like `1h` means the query will expire after that many hours.\n * - A string like `1d` means the query will expire after that many days.\n * - A string like `1y` means the query will expire after that many years.\n */\nexport type TTL = `${number}${TimeUnit}` | 'forever' | 'none' | number;\n\nexport const DEFAULT_TTL: TTL = '5m';\nexport const DEFAULT_TTL_MS = 1_000 * 60 * 5;\n\nexport const DEFAULT_PRELOAD_TTL: TTL = 'none';\nexport const DEFAULT_PRELOAD_TTL_MS = 0;\n\nexport const MAX_TTL: TTL = '10m';\nexport const MAX_TTL_MS = 1_000 * 60 * 10;\n\nconst multiplier = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n y: 365 * 24 * 60 * 60 * 1000,\n} as const;\n\nexport function parseTTL(ttl: TTL): number {\n if (typeof ttl === 'number') {\n return Number.isNaN(ttl) ? 0 : !Number.isFinite(ttl) || ttl < 0 ? -1 : ttl;\n }\n if (ttl === 'none') {\n return 0;\n }\n if (ttl === 'forever') {\n return -1;\n }\n const multi = multiplier[ttl.at(-1) as TimeUnit];\n return Number(ttl.slice(0, -1)) * multi;\n}\n\nexport function compareTTL(a: TTL, b: TTL): number {\n const ap = parseTTL(a);\n const bp = parseTTL(b);\n if (ap === -1 && bp !== -1) {\n return 1;\n }\n if (ap !== -1 && bp === -1) {\n return -1;\n }\n return ap - bp;\n}\n\nexport function normalizeTTL(ttl: TTL): TTL {\n if (typeof ttl === 'string') {\n return ttl;\n }\n\n if (ttl < 0) {\n return 'forever';\n }\n\n if (ttl === 0) {\n return 'none';\n }\n\n let shortest = ttl.toString();\n const lengthOfNumber = shortest.length;\n for (const unit of ['y', 'd', 'h', 'm', 's'] as const) {\n const multi = multiplier[unit];\n const value = ttl / multi;\n const candidate = `${value}${unit}`;\n if (candidate.length < shortest.length) {\n shortest = candidate;\n }\n }\n\n return (shortest.length < lengthOfNumber ? shortest : ttl) as TTL;\n}\n\nexport function clampTTL(ttl: TTL, lc?: Pick<LogContext, 'warn'>): number {\n const parsedTTL = parseTTL(ttl);\n if (parsedTTL === -1 || parsedTTL > 10 * 60 * 1000) {\n // 10 minutes in milliseconds\n lc?.warn?.(`TTL (${ttl}) is too high, clamping to ${MAX_TTL}`);\n return parseTTL(MAX_TTL);\n }\n return parsedTTL;\n}\n"],"mappings":";AAmBA,IAAa,iBAAiB;AAM9B,IAAa,aAAa;AAE1B,IAAM,aAAa;CACjB,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;CACH,GAAG;AACL;AAEA,SAAgB,SAAS,KAAkB;CACzC,IAAI,OAAO,QAAQ,UACjB,OAAO,OAAO,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,SAAS,GAAG,KAAK,MAAM,IAAI,KAAK;CAEzE,IAAI,QAAQ,QACV,OAAO;CAET,IAAI,QAAQ,WACV,OAAO;CAET,MAAM,QAAQ,WAAW,IAAI,GAAG,EAAE;CAClC,OAAO,OAAO,IAAI,MAAM,GAAG,EAAE,CAAC,IAAI;AACpC;AAEA,SAAgB,WAAW,GAAQ,GAAgB;CACjD,MAAM,KAAK,SAAS,CAAC;CACrB,MAAM,KAAK,SAAS,CAAC;CACrB,IAAI,OAAO,MAAM,OAAO,IACtB,OAAO;CAET,IAAI,OAAO,MAAM,OAAO,IACtB,OAAO;CAET,OAAO,KAAK;AACd;AAEA,SAAgB,aAAa,KAAe;CAC1C,IAAI,OAAO,QAAQ,UACjB,OAAO;CAGT,IAAI,MAAM,GACR,OAAO;CAGT,IAAI,QAAQ,GACV,OAAO;CAGT,IAAI,WAAW,IAAI,SAAS;CAC5B,MAAM,iBAAiB,SAAS;CAChC,KAAK,MAAM,QAAQ;EAAC;EAAK;EAAK;EAAK;EAAK;CAAG,GAAY;EAGrD,MAAM,YAAY,GADJ,MADA,WAAW,QAEI;EAC7B,IAAI,UAAU,SAAS,SAAS,QAC9B,WAAW;CAEf;CAEA,OAAQ,SAAS,SAAS,iBAAiB,WAAW;AACxD;AAEA,SAAgB,SAAS,KAAU,IAAuC;CACxE,MAAM,YAAY,SAAS,GAAG;CAC9B,IAAI,cAAc,MAAM,YAAY,KAAgB;EAElD,IAAI,OAAO,QAAQ,IAAI,+BAAsC;EAC7D,OAAO,SAAA,KAAgB;CACzB;CACA,OAAO;AACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-input.js","names":[],"sources":["../../../../../zql/src/query/validate-input.ts"],"sourcesContent":["import type {StandardSchemaV1} from '@standard-schema/spec';\n\nexport class InputValidationError extends Error {\n readonly result: StandardSchemaV1.FailureResult;\n\n // will get picked up by `getErrorDetails` when mapping to an `ApplicationError`\n readonly details: {\n type: 'InputValidationError';\n result: StandardSchemaV1.FailureResult;\n };\n\n constructor(message: string, result: StandardSchemaV1.FailureResult) {\n super(message);\n this.name = 'InputValidationError';\n this.result = result;\n this.details = {type: 'InputValidationError', result};\n }\n}\n\n/**\n * Validates input using a StandardSchema validator if provided.\n * This is shared validation logic used by both defineQuery and defineMutator.\n *\n * @param name - The name of the query or mutator (for error messages)\n * @param input - The input value to validate\n * @param validator - Optional StandardSchema validator\n * @param kind - Type of definition ('query' or 'mutator') for error messages\n * @returns The validated output (either transformed by validator or input as-is)\n * @throws Error if validation fails or if an async validator is used\n * @internal\n */\nexport function validateInput<TInput, TOutput>(\n name: string,\n input: TInput,\n validator: StandardSchemaV1<TInput, TOutput> | undefined,\n kind: 'query' | 'mutator',\n): TOutput {\n if (!validator) {\n // No validator, so input and output are the same\n return input as unknown as TOutput;\n }\n\n const result = validator['~standard'].validate(input);\n if (result instanceof Promise) {\n throw new Error(\n `Async validators are not supported. ${titleCase(kind)} name ${name}`,\n );\n }\n if (result.issues) {\n throw new InputValidationError(\n `Validation failed for ${kind} ${name}: ${result.issues\n .map(issue => issue.message)\n .join(', ')}`,\n result,\n );\n }\n return result.value;\n}\n\nfunction titleCase(kind: string): string {\n return kind.charAt(0).toUpperCase() + kind.slice(1);\n}\n"],"mappings":";AAEA,IAAa,uBAAb,cAA0C,MAAM;CAC9C;CAGA;CAKA,YAAY,SAAiB,QAAwC;EACnE,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,UAAU;GAAC,MAAM;GAAwB;EAAM;CACtD;AACF;;;;;;;;;;;;;AAcA,SAAgB,cACd,MACA,OACA,WACA,MACS;CACT,IAAI,CAAC,WAEH,OAAO;CAGT,MAAM,SAAS,UAAU,
|
|
1
|
+
{"version":3,"file":"validate-input.js","names":[],"sources":["../../../../../zql/src/query/validate-input.ts"],"sourcesContent":["import type {StandardSchemaV1} from '@standard-schema/spec';\n\nexport class InputValidationError extends Error {\n readonly result: StandardSchemaV1.FailureResult;\n\n // will get picked up by `getErrorDetails` when mapping to an `ApplicationError`\n readonly details: {\n type: 'InputValidationError';\n result: StandardSchemaV1.FailureResult;\n };\n\n constructor(message: string, result: StandardSchemaV1.FailureResult) {\n super(message);\n this.name = 'InputValidationError';\n this.result = result;\n this.details = {type: 'InputValidationError', result};\n }\n}\n\n/**\n * Validates input using a StandardSchema validator if provided.\n * This is shared validation logic used by both defineQuery and defineMutator.\n *\n * @param name - The name of the query or mutator (for error messages)\n * @param input - The input value to validate\n * @param validator - Optional StandardSchema validator\n * @param kind - Type of definition ('query' or 'mutator') for error messages\n * @returns The validated output (either transformed by validator or input as-is)\n * @throws Error if validation fails or if an async validator is used\n * @internal\n */\nexport function validateInput<TInput, TOutput>(\n name: string,\n input: TInput,\n validator: StandardSchemaV1<TInput, TOutput> | undefined,\n kind: 'query' | 'mutator',\n): TOutput {\n if (!validator) {\n // No validator, so input and output are the same\n return input as unknown as TOutput;\n }\n\n const result = validator['~standard'].validate(input);\n if (result instanceof Promise) {\n throw new Error(\n `Async validators are not supported. ${titleCase(kind)} name ${name}`,\n );\n }\n if (result.issues) {\n throw new InputValidationError(\n `Validation failed for ${kind} ${name}: ${result.issues\n .map(issue => issue.message)\n .join(', ')}`,\n result,\n );\n }\n return result.value;\n}\n\nfunction titleCase(kind: string): string {\n return kind.charAt(0).toUpperCase() + kind.slice(1);\n}\n"],"mappings":";AAEA,IAAa,uBAAb,cAA0C,MAAM;CAC9C;CAGA;CAKA,YAAY,SAAiB,QAAwC;EACnE,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,UAAU;GAAC,MAAM;GAAwB;EAAM;CACtD;AACF;;;;;;;;;;;;;AAcA,SAAgB,cACd,MACA,OACA,WACA,MACS;CACT,IAAI,CAAC,WAEH,OAAO;CAGT,MAAM,SAAS,UAAU,YAAY,CAAC,SAAS,KAAK;CACpD,IAAI,kBAAkB,SACpB,MAAM,IAAI,MACR,uCAAuC,UAAU,IAAI,EAAE,QAAQ,MACjE;CAEF,IAAI,OAAO,QACT,MAAM,IAAI,qBACR,yBAAyB,KAAK,GAAG,KAAK,IAAI,OAAO,OAC9C,KAAI,UAAS,MAAM,OAAO,CAAC,CAC3B,KAAK,IAAI,KACZ,MACF;CAEF,OAAO,OAAO;AAChB;AAEA,SAAS,UAAU,MAAsB;CACvC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,MAAM,CAAC;AACpD"}
|
|
@@ -8,17 +8,36 @@ export interface ClientGroupStorage {
|
|
|
8
8
|
destroy(): void;
|
|
9
9
|
}
|
|
10
10
|
export declare const CREATE_STORAGE_TABLE = "\n CREATE TABLE storage (\n clientGroupID TEXT,\n op NUMBER,\n key TEXT,\n val TEXT,\n PRIMARY KEY(clientGroupID, op, key)\n )\n ";
|
|
11
|
+
export type DatabaseStorageOptions = {
|
|
12
|
+
commitInterval?: number | undefined;
|
|
13
|
+
compactionThresholdBytes?: number | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* The most heap bytes, as estimated from {@link getSizeOfEntry}, that the
|
|
16
|
+
* operators of all client groups keep in memory before the least recently
|
|
17
|
+
* used ones spill to SQLite. 0, the default, keeps every operator's values
|
|
18
|
+
* in SQLite.
|
|
19
|
+
*/
|
|
20
|
+
maxMemoryBytes?: number | undefined;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Operator storage for the client groups of a sync worker.
|
|
24
|
+
*
|
|
25
|
+
* Each operator keeps its values in a `Map`, so reading a key that was never
|
|
26
|
+
* written does not ask SQLite. When the values of all of the operators go
|
|
27
|
+
* over `maxMemoryBytes`, the least recently used operators spill: their
|
|
28
|
+
* values are written to SQLite, where they stay until the operator is
|
|
29
|
+
* destroyed.
|
|
30
|
+
*
|
|
31
|
+
* Like `MemoryStorage`, `get` returns the stored value itself, which
|
|
32
|
+
* operators do not mutate.
|
|
33
|
+
*/
|
|
11
34
|
export declare class DatabaseStorage {
|
|
12
35
|
#private;
|
|
13
|
-
static create(lc: LogContext, path: string, options?:
|
|
14
|
-
|
|
15
|
-
compactionThresholdBytes: number;
|
|
16
|
-
}): DatabaseStorage;
|
|
17
|
-
constructor(db: Database, options?: {
|
|
18
|
-
commitInterval: number;
|
|
19
|
-
compactionThresholdBytes: number;
|
|
20
|
-
});
|
|
36
|
+
static create(lc: LogContext, path: string, options?: DatabaseStorageOptions): DatabaseStorage;
|
|
37
|
+
constructor(db: Database, options?: DatabaseStorageOptions);
|
|
21
38
|
close(): void;
|
|
39
|
+
/** The estimated size of the values that operators keep in memory. */
|
|
40
|
+
get memoryBytes(): number;
|
|
22
41
|
createClientGroupStorage(cgID: string): ClientGroupStorage;
|
|
23
42
|
}
|
|
24
43
|
//# sourceMappingURL=database-storage.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database-storage.d.ts","sourceRoot":"","sources":["../../../../zqlite/src/database-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"database-storage.d.ts","sourceRoot":"","sources":["../../../../zqlite/src/database-storage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAIjD,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,+BAA+B,CAAC;AAG3D,OAAO,EAAC,QAAQ,EAAC,MAAM,SAAS,CAAC;AAEjC,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,aAAa,IAAI,OAAO,CAAC;IAEzB,gDAAgD;IAChD,OAAO,IAAI,IAAI,CAAC;CACjB;AAcD,eAAO,MAAM,oBAAoB,wJAQ9B,CAAC;AAsBJ,MAAM,MAAM,sBAAsB,GAAG;IACnC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,wBAAwB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9C;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC,CAAC;AA4CF;;;;;;;;;;;GAWG;AACH,qBAAa,eAAe;;IAC1B,MAAM,CAAC,MAAM,CACX,EAAE,EAAE,UAAU,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,sBAA2B,GACnC,eAAe,CAiBjB;IAgBD,YAAY,EAAE,EAAE,QAAQ,EAAE,OAAO,GAAE,sBAA2B,EAgD7D;IAED,KAAK,SAGJ;IAED,sEAAsE;IACtE,IAAI,WAAW,IAAI,MAAM,CAExB;IA+KD,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAoCzD;CACF"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getSizeOfEntry } from "../../shared/src/size-of-value.js";
|
|
2
|
+
import { compareValues } from "../../zql/src/ivm/data.js";
|
|
1
3
|
import { Database } from "./db.js";
|
|
2
4
|
//#region ../zqlite/src/database-storage.ts
|
|
3
5
|
var CREATE_STORAGE_TABLE = `
|
|
@@ -10,18 +12,72 @@ var CREATE_STORAGE_TABLE = `
|
|
|
10
12
|
)
|
|
11
13
|
`;
|
|
12
14
|
/**
|
|
13
|
-
* The most values
|
|
14
|
-
*
|
|
15
|
-
* operator are kept: profiles of the view-syncer gain as much from 64 as from
|
|
16
|
-
* 1,024.
|
|
15
|
+
* The most values the storage of a spilled operator keeps in memory. Profiles
|
|
16
|
+
* of the view-syncer gain as much from 64 as from 1,024.
|
|
17
17
|
*/
|
|
18
18
|
var MAX_CACHED_ENTRIES_PER_OP = 64;
|
|
19
|
+
/**
|
|
20
|
+
* When the operators' values go over `maxMemoryBytes`, operators are spilled
|
|
21
|
+
* until they are back under this proportion of it, so that spilling, which
|
|
22
|
+
* sorts the operators by last use, happens in batches.
|
|
23
|
+
*/
|
|
24
|
+
var SPILL_TARGET_PROPORTION = .9;
|
|
25
|
+
/**
|
|
26
|
+
* The heap bytes that operator state takes per byte of {@link getSizeOfEntry}.
|
|
27
|
+
* Measured with `heapUsed` on view-syncer operator state, mostly Cap's
|
|
28
|
+
* `{size, pks}` and Take's `{size, bound}`.
|
|
29
|
+
*/
|
|
30
|
+
var HEAP_BYTES_PER_SIZE = 2.6;
|
|
19
31
|
var defaultOptions = {
|
|
20
32
|
commitInterval: 5e3,
|
|
21
|
-
compactionThresholdBytes:
|
|
33
|
+
compactionThresholdBytes: 52428800,
|
|
34
|
+
maxMemoryBytes: 0
|
|
22
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* The storage of one operator. Its values live in `values` until the
|
|
38
|
+
* operator is spilled, and in SQLite afterwards, with the most recently used
|
|
39
|
+
* of them in `cache`.
|
|
40
|
+
*/
|
|
41
|
+
var OpStorage = class {
|
|
42
|
+
cgID;
|
|
43
|
+
opID;
|
|
44
|
+
/** `undefined` once spilled. */
|
|
45
|
+
values;
|
|
46
|
+
/** The {@link getSizeOfEntry} of `values`. */
|
|
47
|
+
size = 0;
|
|
48
|
+
lastUsed = 0;
|
|
49
|
+
/**
|
|
50
|
+
* Once spilled, the operator's most recently read and written values,
|
|
51
|
+
* `undefined` for a key known to be absent. Operators read the same key
|
|
52
|
+
* again and again (Cap and Take read their state on every fetch and push),
|
|
53
|
+
* so this saves most of the SQLite reads.
|
|
54
|
+
*/
|
|
55
|
+
cache = /* @__PURE__ */ new Map();
|
|
56
|
+
constructor(cgID, opID, inMemory) {
|
|
57
|
+
this.cgID = cgID;
|
|
58
|
+
this.opID = opID;
|
|
59
|
+
this.values = inMemory ? /* @__PURE__ */ new Map() : void 0;
|
|
60
|
+
}
|
|
61
|
+
cacheSet(key, val) {
|
|
62
|
+
const { cache } = this;
|
|
63
|
+
if (cache.size >= MAX_CACHED_ENTRIES_PER_OP && !cache.has(key)) cache.clear();
|
|
64
|
+
cache.set(key, val);
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Operator storage for the client groups of a sync worker.
|
|
69
|
+
*
|
|
70
|
+
* Each operator keeps its values in a `Map`, so reading a key that was never
|
|
71
|
+
* written does not ask SQLite. When the values of all of the operators go
|
|
72
|
+
* over `maxMemoryBytes`, the least recently used operators spill: their
|
|
73
|
+
* values are written to SQLite, where they stay until the operator is
|
|
74
|
+
* destroyed.
|
|
75
|
+
*
|
|
76
|
+
* Like `MemoryStorage`, `get` returns the stored value itself, which
|
|
77
|
+
* operators do not mutate.
|
|
78
|
+
*/
|
|
23
79
|
var DatabaseStorage = class DatabaseStorage {
|
|
24
|
-
static create(lc, path, options =
|
|
80
|
+
static create(lc, path, options = {}) {
|
|
25
81
|
const db = new Database(lc, path);
|
|
26
82
|
db.unsafeMode(true);
|
|
27
83
|
db.pragma("locking_mode = EXCLUSIVE");
|
|
@@ -37,12 +93,20 @@ var DatabaseStorage = class DatabaseStorage {
|
|
|
37
93
|
#options;
|
|
38
94
|
#db;
|
|
39
95
|
#numWrites = 0;
|
|
40
|
-
|
|
96
|
+
/** The operators whose values are in memory. */
|
|
97
|
+
#inMemory = /* @__PURE__ */ new Set();
|
|
98
|
+
/** The {@link getSizeOfEntry} of the values of the operators in `#inMemory`. */
|
|
99
|
+
#size = 0;
|
|
100
|
+
/** `maxMemoryBytes` in units of {@link getSizeOfEntry}. */
|
|
101
|
+
#maxSize;
|
|
102
|
+
/** Orders the operators by last use. */
|
|
103
|
+
#clock = 0;
|
|
104
|
+
constructor(db, options = {}) {
|
|
41
105
|
this.#stmts = {
|
|
42
106
|
get: db.prepare(`
|
|
43
107
|
SELECT val FROM storage WHERE
|
|
44
108
|
clientGroupID = ? AND op = ? AND key = ?
|
|
45
|
-
`),
|
|
109
|
+
`).pluck(true),
|
|
46
110
|
set: db.prepare(`
|
|
47
111
|
INSERT INTO storage (clientGroupID, op, key, val)
|
|
48
112
|
VALUES(?, ?, ?, ?)
|
|
@@ -57,7 +121,7 @@ var DatabaseStorage = class DatabaseStorage {
|
|
|
57
121
|
scan: db.prepare(`
|
|
58
122
|
SELECT key, val FROM storage WHERE
|
|
59
123
|
clientGroupID = ? AND op = ? AND key >= ?
|
|
60
|
-
`),
|
|
124
|
+
`).raw(true),
|
|
61
125
|
clear: db.prepare(`
|
|
62
126
|
DELETE FROM storage WHERE clientGroupID = ?
|
|
63
127
|
`),
|
|
@@ -68,29 +132,110 @@ var DatabaseStorage = class DatabaseStorage {
|
|
|
68
132
|
begin: db.prepare("BEGIN")
|
|
69
133
|
};
|
|
70
134
|
this.#stmts.begin.run();
|
|
71
|
-
this.#options =
|
|
135
|
+
this.#options = {
|
|
136
|
+
commitInterval: options.commitInterval ?? defaultOptions.commitInterval,
|
|
137
|
+
compactionThresholdBytes: options.compactionThresholdBytes ?? defaultOptions.compactionThresholdBytes,
|
|
138
|
+
maxMemoryBytes: options.maxMemoryBytes ?? defaultOptions.maxMemoryBytes
|
|
139
|
+
};
|
|
140
|
+
this.#maxSize = this.#options.maxMemoryBytes / HEAP_BYTES_PER_SIZE;
|
|
72
141
|
this.#db = db;
|
|
73
142
|
}
|
|
74
143
|
close() {
|
|
75
144
|
this.#checkpoint();
|
|
76
145
|
this.#db.close();
|
|
77
146
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return row ? JSON.parse(row.val) : void 0;
|
|
147
|
+
/** The estimated size of the values that operators keep in memory. */
|
|
148
|
+
get memoryBytes() {
|
|
149
|
+
return Math.round(this.#size * HEAP_BYTES_PER_SIZE);
|
|
82
150
|
}
|
|
83
|
-
#
|
|
84
|
-
this.#
|
|
85
|
-
|
|
151
|
+
#get(op, key, def) {
|
|
152
|
+
op.lastUsed = ++this.#clock;
|
|
153
|
+
const { values } = op;
|
|
154
|
+
if (values) {
|
|
155
|
+
const val = values.get(key);
|
|
156
|
+
return val === void 0 ? def : val;
|
|
157
|
+
}
|
|
158
|
+
let val = op.cache.get(key);
|
|
159
|
+
if (val === void 0 && !op.cache.has(key)) {
|
|
160
|
+
this.#maybeCheckpoint();
|
|
161
|
+
const json = this.#stmts.get.get(op.cgID, op.opID, key);
|
|
162
|
+
val = json === void 0 ? void 0 : JSON.parse(json);
|
|
163
|
+
op.cacheSet(key, val);
|
|
164
|
+
}
|
|
165
|
+
return val === void 0 ? def : val;
|
|
166
|
+
}
|
|
167
|
+
#set(op, key, val) {
|
|
168
|
+
op.lastUsed = ++this.#clock;
|
|
169
|
+
const { values } = op;
|
|
170
|
+
if (values) {
|
|
171
|
+
if (values.size === 0) this.#inMemory.add(op);
|
|
172
|
+
const old = values.get(key);
|
|
173
|
+
const delta = getSizeOfEntry(key, val) - (old === void 0 ? 0 : getSizeOfEntry(key, old));
|
|
174
|
+
values.set(key, val);
|
|
175
|
+
op.size += delta;
|
|
176
|
+
this.#size += delta;
|
|
177
|
+
if (this.#size > this.#maxSize) this.#spillLeastRecentlyUsed();
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
this.#write(op, key, val);
|
|
181
|
+
op.cacheSet(key, val);
|
|
86
182
|
}
|
|
87
|
-
#del(
|
|
183
|
+
#del(op, key) {
|
|
184
|
+
op.lastUsed = ++this.#clock;
|
|
185
|
+
const { values } = op;
|
|
186
|
+
if (values) {
|
|
187
|
+
const old = values.get(key);
|
|
188
|
+
if (old !== void 0) {
|
|
189
|
+
values.delete(key);
|
|
190
|
+
const size = getSizeOfEntry(key, old);
|
|
191
|
+
op.size -= size;
|
|
192
|
+
this.#size -= size;
|
|
193
|
+
}
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
88
196
|
this.#maybeCheckpoint();
|
|
89
|
-
this.#stmts.del.run(cgID, opID, key);
|
|
197
|
+
this.#stmts.del.run(op.cgID, op.opID, key);
|
|
198
|
+
op.cacheSet(key, void 0);
|
|
90
199
|
}
|
|
91
|
-
#
|
|
200
|
+
#write(op, key, val) {
|
|
92
201
|
this.#maybeCheckpoint();
|
|
93
|
-
this.#stmts.
|
|
202
|
+
this.#stmts.set.run(op.cgID, op.opID, key, JSON.stringify(val));
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Spills the least recently used operators until the values in memory are
|
|
206
|
+
* under {@link SPILL_TARGET_PROPORTION} of the budget.
|
|
207
|
+
*/
|
|
208
|
+
#spillLeastRecentlyUsed() {
|
|
209
|
+
const target = this.#maxSize * SPILL_TARGET_PROPORTION;
|
|
210
|
+
const ops = [];
|
|
211
|
+
for (const op of this.#inMemory) ops.push(op);
|
|
212
|
+
ops.sort((a, b) => a.lastUsed - b.lastUsed);
|
|
213
|
+
for (const op of ops) {
|
|
214
|
+
if (this.#size <= target) break;
|
|
215
|
+
this.#spill(op);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
#spill(op) {
|
|
219
|
+
const { values } = op;
|
|
220
|
+
if (!values) return;
|
|
221
|
+
for (const [key, val] of values) this.#write(op, key, val);
|
|
222
|
+
this.#release(op);
|
|
223
|
+
op.values = void 0;
|
|
224
|
+
}
|
|
225
|
+
/** Drops the values that `op` keeps in memory. */
|
|
226
|
+
#release(op) {
|
|
227
|
+
this.#size -= op.size;
|
|
228
|
+
op.size = 0;
|
|
229
|
+
op.values?.clear();
|
|
230
|
+
op.cache.clear();
|
|
231
|
+
this.#inMemory.delete(op);
|
|
232
|
+
}
|
|
233
|
+
#destroy(op) {
|
|
234
|
+
if (!op.values) {
|
|
235
|
+
this.#maybeCheckpoint();
|
|
236
|
+
this.#stmts.clearOp.run(op.cgID, op.opID);
|
|
237
|
+
}
|
|
238
|
+
this.#release(op);
|
|
94
239
|
}
|
|
95
240
|
/**
|
|
96
241
|
* We don't need to commit every single write to the DB
|
|
@@ -106,18 +251,29 @@ var DatabaseStorage = class DatabaseStorage {
|
|
|
106
251
|
this.#stmts.begin.run();
|
|
107
252
|
this.#numWrites = 0;
|
|
108
253
|
}
|
|
109
|
-
*#scan(
|
|
254
|
+
*#scan(op, opts = { prefix: "" }) {
|
|
110
255
|
const { prefix } = opts;
|
|
111
|
-
|
|
256
|
+
const { values } = op;
|
|
257
|
+
if (values) {
|
|
258
|
+
const keys = [];
|
|
259
|
+
for (const key of values.keys()) if (key.startsWith(prefix)) keys.push(key);
|
|
260
|
+
keys.sort(compareValues);
|
|
261
|
+
for (const key of keys) {
|
|
262
|
+
const val = this.#get(op, key);
|
|
263
|
+
if (val !== void 0) yield [key, val];
|
|
264
|
+
}
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
for (const [key, val] of this.#stmts.scan.iterate(op.cgID, op.opID, prefix)) {
|
|
112
268
|
if (!key.startsWith(prefix)) return;
|
|
113
269
|
yield [key, JSON.parse(val)];
|
|
114
270
|
}
|
|
115
271
|
}
|
|
116
272
|
createClientGroupStorage(cgID) {
|
|
117
|
-
const
|
|
273
|
+
const ops = /* @__PURE__ */ new Set();
|
|
118
274
|
const destroy = () => {
|
|
119
275
|
this.#stmts.clear.run(cgID);
|
|
120
|
-
for (const
|
|
276
|
+
for (const op of ops) this.#release(op);
|
|
121
277
|
this.#checkpoint();
|
|
122
278
|
this.#db.compact(this.#options.compactionThresholdBytes);
|
|
123
279
|
};
|
|
@@ -125,35 +281,16 @@ var DatabaseStorage = class DatabaseStorage {
|
|
|
125
281
|
let nextOpID = 1;
|
|
126
282
|
return {
|
|
127
283
|
createStorage: () => {
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
caches.add(cache);
|
|
131
|
-
const cacheSet = (key, val) => {
|
|
132
|
-
if (cache.size >= MAX_CACHED_ENTRIES_PER_OP && !cache.has(key)) cache.clear();
|
|
133
|
-
cache.set(key, val);
|
|
134
|
-
};
|
|
284
|
+
const op = new OpStorage(cgID, nextOpID++, this.#options.maxMemoryBytes > 0);
|
|
285
|
+
ops.add(op);
|
|
135
286
|
return {
|
|
136
|
-
get: (key, def) =>
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
cacheSet(key, val);
|
|
141
|
-
}
|
|
142
|
-
return val === void 0 ? def : val;
|
|
143
|
-
},
|
|
144
|
-
set: (key, val) => {
|
|
145
|
-
this.#set(cgID, opID, key, val);
|
|
146
|
-
cacheSet(key, val);
|
|
147
|
-
},
|
|
148
|
-
del: (key) => {
|
|
149
|
-
this.#del(cgID, opID, key);
|
|
150
|
-
cacheSet(key, void 0);
|
|
151
|
-
},
|
|
152
|
-
scan: (opts) => this.#scan(cgID, opID, opts),
|
|
287
|
+
get: (key, def) => this.#get(op, key, def),
|
|
288
|
+
set: (key, val) => this.#set(op, key, val),
|
|
289
|
+
del: (key) => this.#del(op, key),
|
|
290
|
+
scan: (opts) => this.#scan(op, opts),
|
|
153
291
|
destroy: () => {
|
|
154
|
-
this.#destroy(
|
|
155
|
-
|
|
156
|
-
caches.delete(cache);
|
|
292
|
+
this.#destroy(op);
|
|
293
|
+
ops.delete(op);
|
|
157
294
|
}
|
|
158
295
|
};
|
|
159
296
|
},
|
|
@@ -162,6 +299,6 @@ var DatabaseStorage = class DatabaseStorage {
|
|
|
162
299
|
}
|
|
163
300
|
};
|
|
164
301
|
//#endregion
|
|
165
|
-
export { DatabaseStorage };
|
|
302
|
+
export { CREATE_STORAGE_TABLE, DatabaseStorage };
|
|
166
303
|
|
|
167
304
|
//# sourceMappingURL=database-storage.js.map
|