@rocicorp/zero 1.10.0-canary.24 → 1.10.0-canary.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/analyze-query/src/bin-analyze.js +8 -9
- package/out/analyze-query/src/bin-analyze.js.map +1 -1
- package/out/replicache/src/btree/node.d.ts.map +1 -1
- package/out/replicache/src/btree/node.js +6 -3
- package/out/replicache/src/btree/node.js.map +1 -1
- package/out/replicache/src/btree/read.d.ts +1 -12
- package/out/replicache/src/btree/read.d.ts.map +1 -1
- package/out/replicache/src/btree/read.js +12 -24
- package/out/replicache/src/btree/read.js.map +1 -1
- package/out/replicache/src/dag/gc.d.ts.map +1 -1
- package/out/replicache/src/dag/gc.js +11 -8
- package/out/replicache/src/dag/gc.js.map +1 -1
- package/out/replicache/src/dag/store-impl.d.ts +2 -12
- package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
- package/out/replicache/src/dag/store-impl.js +8 -22
- package/out/replicache/src/dag/store-impl.js.map +1 -1
- package/out/replicache/src/db/rebase.d.ts +2 -14
- package/out/replicache/src/db/rebase.d.ts.map +1 -1
- package/out/replicache/src/db/rebase.js +5 -27
- package/out/replicache/src/db/rebase.js.map +1 -1
- package/out/replicache/src/db/write.js.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/expo-sqlite/store.js +5 -28
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +5 -15
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts.map +1 -1
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js +25 -25
- package/out/replicache/src/kv/idb-store-with-mem-fallback.js.map +1 -1
- package/out/replicache/src/kv/idb-store.d.ts +0 -9
- package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
- package/out/replicache/src/kv/idb-store.js +2 -14
- package/out/replicache/src/kv/idb-store.js.map +1 -1
- package/out/replicache/src/kv/mem-store.d.ts +0 -1
- package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
- package/out/replicache/src/kv/mem-store.js +0 -3
- package/out/replicache/src/kv/mem-store.js.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.js +1 -1
- package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts +1 -13
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +6 -73
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/kv/store.d.ts +0 -6
- package/out/replicache/src/kv/store.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.d.ts +5 -10
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.js +9 -16
- package/out/replicache/src/persist/collect-idb-databases.js.map +1 -1
- package/out/replicache/src/persist/persist.d.ts.map +1 -1
- package/out/replicache/src/persist/persist.js +6 -13
- package/out/replicache/src/persist/persist.js.map +1 -1
- package/out/replicache/src/persist/refresh.js +2 -6
- package/out/replicache/src/persist/refresh.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +3 -14
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +11 -118
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/replicache-options.d.ts +0 -9
- package/out/replicache/src/replicache-options.d.ts.map +1 -1
- package/out/replicache/src/transactions.d.ts.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.d.ts +0 -5
- package/out/shared/src/arrays.d.ts.map +1 -1
- package/out/shared/src/arrays.js +24 -8
- package/out/shared/src/arrays.js.map +1 -1
- package/out/shared/src/base64.d.ts +19 -0
- package/out/shared/src/base64.d.ts.map +1 -0
- package/out/shared/src/base64.js +40 -0
- package/out/shared/src/base64.js.map +1 -0
- package/out/shared/src/error.d.ts +0 -11
- package/out/shared/src/error.d.ts.map +1 -1
- package/out/shared/src/error.js +1 -35
- package/out/shared/src/error.js.map +1 -1
- package/out/shared/src/hash.d.ts +0 -1
- package/out/shared/src/hash.d.ts.map +1 -1
- package/out/shared/src/hash.js +10 -87
- package/out/shared/src/hash.js.map +1 -1
- package/out/shared/src/iterables.d.ts +0 -2
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js +1 -18
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/json.d.ts.map +1 -1
- package/out/shared/src/json.js +2 -2
- package/out/shared/src/json.js.map +1 -1
- package/out/shared/src/map.d.ts +2 -24
- package/out/shared/src/map.d.ts.map +1 -1
- package/out/shared/src/map.js +4 -18
- package/out/shared/src/map.js.map +1 -1
- package/out/shared/src/ring-buffer.d.ts +0 -8
- package/out/shared/src/ring-buffer.d.ts.map +1 -1
- package/out/shared/src/ring-buffer.js +1 -22
- package/out/shared/src/ring-buffer.js.map +1 -1
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +2 -2
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +3 -2
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/auth/read-authorizer.js +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +0 -1
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +2 -42
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +28 -149
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js +1 -1
- package/out/zero-cache/src/db/create.d.ts.map +1 -1
- package/out/zero-cache/src/db/create.js +1 -4
- package/out/zero-cache/src/db/create.js.map +1 -1
- package/out/zero-cache/src/db/lite-tables.d.ts +2 -10
- package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js +6 -10
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/db/specs.d.ts +0 -41
- package/out/zero-cache/src/db/specs.d.ts.map +1 -1
- package/out/zero-cache/src/db/specs.js +3 -30
- package/out/zero-cache/src/db/specs.js.map +1 -1
- package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/observability/metrics.js +7 -2
- package/out/zero-cache/src/observability/metrics.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +4 -13
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +2 -18
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +17 -25
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +1 -8
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/mutator.js +0 -2
- package/out/zero-cache/src/server/mutator.js.map +1 -1
- package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
- package/out/zero-cache/src/server/reaper.js +0 -2
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +2 -8
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/runner/zero-dispatcher.js +0 -3
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +1 -5
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +9 -11
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -14
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +3 -15
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +1 -11
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +2 -21
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts +0 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +7 -8
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +229 -1513
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +2 -2
- 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/init.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +6 -15
- 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.d.ts +20 -137
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.js +13 -82
- 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/shard.d.ts +21 -128
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +5 -5
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +0 -2
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +0 -3
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +0 -3
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +1 -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.d.ts +0 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +3 -8
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +1 -15
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +0 -5
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +1 -7
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +119 -119
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +6 -5
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +16 -16
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js +0 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +2 -27
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js +2 -3
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +5 -24
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts +0 -12
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +15 -27
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/runner.d.ts.map +1 -1
- package/out/zero-cache/src/services/runner.js +1 -1
- package/out/zero-cache/src/services/runner.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +0 -45
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +1 -133
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts +1 -14
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +4 -30
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +2 -2
- 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 +1 -2
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +27 -48
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/query-covering.js +6 -2
- package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +4 -42
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +28 -117
- package/out/zero-cache/src/services/view-syncer/snapshotter.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts +1 -11
- 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 +95 -466
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +0 -32
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +4 -43
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/profiler.d.ts +0 -12
- package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
- package/out/zero-cache/src/types/profiler.js +1 -46
- package/out/zero-cache/src/types/profiler.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts.map +1 -1
- package/out/zero-cache/src/types/row-key.js +5 -5
- package/out/zero-cache/src/types/row-key.js.map +1 -1
- package/out/zero-cache/src/workers/connect-params.d.ts +7 -0
- package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connect-params.js +20 -1
- package/out/zero-cache/src/workers/connect-params.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +4 -4
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +8 -8
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/replicator.d.ts +0 -1
- package/out/zero-cache/src/workers/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/workers/replicator.js +2 -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 +16 -21
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +1 -10
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +0 -20
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +13 -77
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.d.ts +0 -2
- package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.js +1 -3
- package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +0 -6
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js +1 -2
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +2 -27
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +1 -112
- package/out/zero-client/src/client/context.js.map +1 -1
- package/out/zero-client/src/client/custom.js +2 -2
- package/out/zero-client/src/client/custom.js.map +1 -1
- package/out/zero-client/src/client/error.js +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +2 -2
- package/out/zero-client/src/client/inspector/lazy-inspector.js.map +1 -1
- package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
- package/out/zero-client/src/client/ivm-branch.js +3 -20
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.js +1 -1
- package/out/zero-client/src/client/mutation-tracker.js.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.d.ts.map +1 -1
- package/out/zero-client/src/client/mutator-proxy.js +1 -2
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +0 -3
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts +0 -2
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.js +14 -50
- package/out/zero-client/src/client/query-manager.js.map +1 -1
- package/out/zero-client/src/client/version.js +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts +0 -1
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +6 -9
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +3 -18
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +36 -123
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/types/query-result.d.ts +0 -2
- package/out/zero-client/src/types/query-result.d.ts.map +1 -1
- package/out/zero-protocol/src/analyze-query-result.d.ts +5 -5
- package/out/zero-protocol/src/analyze-query-result.d.ts.map +1 -1
- 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/ast.d.ts +1 -64
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +54 -225
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/connect.d.ts +13 -0
- package/out/zero-protocol/src/connect.d.ts.map +1 -1
- package/out/zero-protocol/src/connect.js +30 -1
- package/out/zero-protocol/src/connect.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +2 -2
- package/out/zero-protocol/src/error.d.ts +1 -1
- package/out/zero-protocol/src/inspect-down.d.ts +6 -6
- package/out/zero-protocol/src/poke.d.ts +11 -4
- package/out/zero-protocol/src/poke.d.ts.map +1 -1
- package/out/zero-protocol/src/poke.js +3 -2
- package/out/zero-protocol/src/poke.js.map +1 -1
- package/out/zero-protocol/src/protocol-flag-enum.d.ts +7 -0
- package/out/zero-protocol/src/protocol-flag-enum.d.ts.map +1 -0
- package/out/zero-protocol/src/protocol-flag-enum.js +7 -0
- package/out/zero-protocol/src/protocol-flag-enum.js.map +1 -0
- package/out/zero-protocol/src/protocol-flag.d.ts +14 -0
- package/out/zero-protocol/src/protocol-flag.d.ts.map +1 -0
- package/out/zero-protocol/src/protocol-flag.js +8 -0
- package/out/zero-protocol/src/protocol-flag.js.map +1 -0
- package/out/zero-protocol/src/protocol-version.d.ts +30 -6
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js +1 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/query-hash.d.ts +2 -7
- package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
- package/out/zero-protocol/src/query-hash.js +10 -10
- package/out/zero-protocol/src/query-hash.js.map +1 -1
- package/out/zero-react/src/use-query.d.ts +4 -5
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +9 -86
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +0 -17
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +1 -39
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-query.js +3 -5
- package/out/zero-solid/src/use-query.js.map +1 -1
- package/out/zql/src/builder/builder.d.ts +0 -19
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +11 -28
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/builder/debug-delegate.d.ts +1 -6
- package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
- package/out/zql/src/builder/debug-delegate.js +2 -14
- package/out/zql/src/builder/debug-delegate.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts +0 -29
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +12 -63
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/cap.d.ts.map +1 -1
- package/out/zql/src/ivm/cap.js +3 -5
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +3 -8
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/exists.d.ts +1 -1
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +2 -2
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js +5 -6
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +2 -2
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +6 -7
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +12 -29
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +2 -2
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js +4 -7
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +2 -2
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +4 -6
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +3 -15
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +23 -57
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +0 -40
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +4 -3
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +7 -9
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.d.ts.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +4 -9
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/ivm/view.d.ts +0 -15
- package/out/zql/src/ivm/view.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +2 -2
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/planner/planner-builder.d.ts +3 -12
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
- package/out/zql/src/planner/planner-builder.js +20 -40
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-connection.d.ts +2 -28
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
- package/out/zql/src/planner/planner-connection.js +8 -108
- package/out/zql/src/planner/planner-connection.js.map +1 -1
- package/out/zql/src/planner/planner-debug.d.ts +1 -1
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js +8 -3
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-fan-out.d.ts +0 -1
- package/out/zql/src/planner/planner-fan-out.d.ts.map +1 -1
- package/out/zql/src/planner/planner-fan-out.js +0 -3
- package/out/zql/src/planner/planner-fan-out.js.map +1 -1
- package/out/zql/src/planner/planner-graph.d.ts +0 -2
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
- package/out/zql/src/planner/planner-graph.js +0 -2
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zql/src/planner/planner-join.d.ts +0 -2
- package/out/zql/src/planner/planner-join.d.ts.map +1 -1
- package/out/zql/src/planner/planner-join.js +0 -7
- package/out/zql/src/planner/planner-join.js.map +1 -1
- package/out/zql/src/planner/planner-node.d.ts +1 -2
- package/out/zql/src/planner/planner-node.d.ts.map +1 -1
- package/out/zql/src/planner/planner-node.js.map +1 -1
- package/out/zql/src/planner/planner-source.d.ts +2 -2
- package/out/zql/src/planner/planner-source.d.ts.map +1 -1
- package/out/zql/src/planner/planner-source.js +2 -2
- package/out/zql/src/planner/planner-source.js.map +1 -1
- package/out/zql/src/query/query-delegate-base.d.ts +1 -9
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +36 -132
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +1 -50
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +14 -25
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +94 -397
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-internals.d.ts +11 -21
- package/out/zql/src/query/query-internals.d.ts.map +1 -1
- package/out/zql/src/query/query-internals.js.map +1 -1
- package/out/zql/src/query/query.d.ts +2 -11
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +2 -3
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js +2 -15
- package/out/zql/src/query/runnable-query-impl.js.map +1 -1
- package/out/zql/src/query/typed-view.d.ts +1 -1
- package/out/zql/src/query/typed-view.d.ts.map +1 -1
- package/out/zqlite/src/db.d.ts +1 -9
- package/out/zqlite/src/db.d.ts.map +1 -1
- package/out/zqlite/src/db.js +2 -8
- package/out/zqlite/src/db.js.map +1 -1
- package/out/zqlite/src/query-builder.d.ts +1 -1
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js +2 -4
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-delegate.js +6 -5
- package/out/zqlite/src/query-delegate.js.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.js +30 -2
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +5 -4
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +3 -16
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +14 -33
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +3 -2
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts +0 -12
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +0 -1
- package/out/replicache/src/dag/invalid-ref-count-error.js +0 -19
- package/out/replicache/src/dag/invalid-ref-count-error.js.map +0 -1
- package/out/shared/src/xxhash32.d.ts +0 -36
- package/out/shared/src/xxhash32.d.ts.map +0 -1
- package/out/shared/src/xxhash32.js +0 -51
- package/out/shared/src/xxhash32.js.map +0 -1
- package/out/zero-cache/src/db/index-predicate.d.ts +0 -4
- package/out/zero-cache/src/db/index-predicate.d.ts.map +0 -1
- package/out/zero-cache/src/db/index-predicate.js +0 -46
- package/out/zero-cache/src/db/index-predicate.js.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts +0 -19
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +0 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +0 -581
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +0 -1
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +0 -131
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +0 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts +0 -70
- package/out/zero-cache/src/services/litestream/litestream-controller.d.ts.map +0 -1
- package/out/zero-cache/src/services/litestream/litestream-controller.js +0 -101
- package/out/zero-cache/src/services/litestream/litestream-controller.js.map +0 -1
- package/out/zero-cache/src/services/profz.d.ts +0 -7
- package/out/zero-cache/src/services/profz.d.ts.map +0 -1
- package/out/zero-cache/src/services/profz.js +0 -103
- package/out/zero-cache/src/services/profz.js.map +0 -1
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +0 -33
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js +0 -62
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +0 -1
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +0 -51
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +0 -78
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +0 -1
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +0 -95
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +0 -1
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +0 -155
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +0 -1
- package/out/zero-protocol/src/query-hash-visitor.d.ts +0 -81
- package/out/zero-protocol/src/query-hash-visitor.d.ts.map +0 -1
- package/out/zero-protocol/src/query-hash-visitor.js +0 -324
- package/out/zero-protocol/src/query-hash-visitor.js.map +0 -1
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +0 -43
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +0 -1
- package/out/zql/src/builder/correlated-predicate-pushdown.js +0 -161
- package/out/zql/src/builder/correlated-predicate-pushdown.js.map +0 -1
- package/out/zql/src/ivm/connection-index.d.ts +0 -68
- package/out/zql/src/ivm/connection-index.d.ts.map +0 -1
- package/out/zql/src/ivm/connection-index.js +0 -149
- package/out/zql/src/ivm/connection-index.js.map +0 -1
- package/out/zql/src/ivm/deferred-input.d.ts +0 -44
- package/out/zql/src/ivm/deferred-input.d.ts.map +0 -1
- package/out/zql/src/ivm/deferred-input.js +0 -89
- package/out/zql/src/ivm/deferred-input.js.map +0 -1
- package/out/zql/src/planner/planner-filter.d.ts +0 -59
- package/out/zql/src/planner/planner-filter.d.ts.map +0 -1
- package/out/zql/src/planner/planner-filter.js +0 -116
- package/out/zql/src/planner/planner-filter.js.map +0 -1
- package/out/zql/src/query/query-transitions.d.ts +0 -171
- package/out/zql/src/query/query-transitions.d.ts.map +0 -1
- package/out/zql/src/query/query-transitions.js +0 -204
- package/out/zql/src/query/query-transitions.js.map +0 -1
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import type { MonotonicClock } from './hydration-budget.ts';
|
|
2
|
-
/**
|
|
3
|
-
* How long a tripped query stays rejected before a retry is allowed.
|
|
4
|
-
*
|
|
5
|
-
* A query that blows the timeout is almost always slow because of the shape
|
|
6
|
-
* of its data rather than because of transient load, so retrying it on every
|
|
7
|
-
* reconnect would burn a full timeout each time. The cooldown keeps that cost
|
|
8
|
-
* to at most one timeout per cooldown period per query.
|
|
9
|
-
*/
|
|
10
|
-
export declare const DEFAULT_CIRCUIT_BREAKER_OPEN_MS: number;
|
|
11
|
-
/**
|
|
12
|
-
* A per-query circuit breaker for view-syncer hydration.
|
|
13
|
-
*
|
|
14
|
-
* Hydration of a single query is aborted once its processing time exceeds
|
|
15
|
-
* {@link timeoutMs}. Callers check {@link exceeded} at the yield points of a
|
|
16
|
-
* hydration, so a query is only ever aborted between time slices.
|
|
17
|
-
*
|
|
18
|
-
* Once a query has been aborted the breaker is "open" for its transformation
|
|
19
|
-
* hash: {@link isOpen} reports true for {@link openMs}, and callers reject the
|
|
20
|
-
* query up front instead of hydrating it again. After that the breaker is
|
|
21
|
-
* implicitly half-open: the next hydration attempt runs, and either succeeds
|
|
22
|
-
* or trips the breaker again.
|
|
23
|
-
*
|
|
24
|
-
* The breaker is keyed by transformation hash rather than query hash because
|
|
25
|
-
* the transformation (permissions, auth context) determines the pipeline that
|
|
26
|
-
* runs, and a different transformation of the same query may well be fast.
|
|
27
|
-
*/
|
|
28
|
-
export declare class HydrationCircuitBreaker {
|
|
29
|
-
#private;
|
|
30
|
-
readonly timeoutMs: number;
|
|
31
|
-
readonly openMs: number;
|
|
32
|
-
constructor(timeoutMs: number, openMs?: number, now?: MonotonicClock);
|
|
33
|
-
/** Whether the breaker does anything at all. */
|
|
34
|
-
get enabled(): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Whether a hydration that has consumed `elapsedMs` of processing time must
|
|
37
|
-
* be aborted. Always false when the breaker is disabled.
|
|
38
|
-
*/
|
|
39
|
-
exceeded(elapsedMs: number): boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Records that hydrating `transformationHash` was aborted.
|
|
42
|
-
*
|
|
43
|
-
* Trips are rare, so this is also when expired entries are swept, which
|
|
44
|
-
* keeps the map bounded by the number of hashes tripped within one cooldown
|
|
45
|
-
* rather than by every hash ever tripped.
|
|
46
|
-
*/
|
|
47
|
-
trip(transformationHash: string): void;
|
|
48
|
-
/** Whether `transformationHash` is currently rejected. */
|
|
49
|
-
isOpen(transformationHash: string): boolean;
|
|
50
|
-
}
|
|
51
|
-
//# sourceMappingURL=hydration-circuit-breaker.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hydration-circuit-breaker.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/hydration-circuit-breaker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,uBAAuB,CAAC;AAE1D;;;;;;;GAOG;AACH,eAAO,MAAM,+BAA+B,QAAa,CAAC;AAE1D;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,uBAAuB;;IAClC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAKtB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAAwC,EAChD,GAAG,GAAE,cAAkD;IAYzD,gDAAgD;IAChD,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIpC;;;;;;OAMG;IACH,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI;IAUtC,0DAA0D;IAC1D,MAAM,CAAC,kBAAkB,EAAE,MAAM,GAAG,OAAO;CAW5C"}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { assert } from "../../../../shared/src/asserts.js";
|
|
2
|
-
//#region ../zero-cache/src/services/view-syncer/hydration-circuit-breaker.ts
|
|
3
|
-
/**
|
|
4
|
-
* How long a tripped query stays rejected before a retry is allowed.
|
|
5
|
-
*
|
|
6
|
-
* A query that blows the timeout is almost always slow because of the shape
|
|
7
|
-
* of its data rather than because of transient load, so retrying it on every
|
|
8
|
-
* reconnect would burn a full timeout each time. The cooldown keeps that cost
|
|
9
|
-
* to at most one timeout per cooldown period per query.
|
|
10
|
-
*/
|
|
11
|
-
var DEFAULT_CIRCUIT_BREAKER_OPEN_MS = 5 * 6e4;
|
|
12
|
-
/**
|
|
13
|
-
* A per-query circuit breaker for view-syncer hydration.
|
|
14
|
-
*
|
|
15
|
-
* Hydration of a single query is aborted once its processing time exceeds
|
|
16
|
-
* {@link timeoutMs}. Callers check {@link exceeded} at the yield points of a
|
|
17
|
-
* hydration, so a query is only ever aborted between time slices.
|
|
18
|
-
*
|
|
19
|
-
* Once a query has been aborted the breaker is "open" for its transformation
|
|
20
|
-
* hash: {@link isOpen} reports true for {@link openMs}, and callers reject the
|
|
21
|
-
* query up front instead of hydrating it again. After that the breaker is
|
|
22
|
-
* implicitly half-open: the next hydration attempt runs, and either succeeds
|
|
23
|
-
* or trips the breaker again.
|
|
24
|
-
*
|
|
25
|
-
* The breaker is keyed by transformation hash rather than query hash because
|
|
26
|
-
* the transformation (permissions, auth context) determines the pipeline that
|
|
27
|
-
* runs, and a different transformation of the same query may well be fast.
|
|
28
|
-
*/
|
|
29
|
-
var HydrationCircuitBreaker = class {
|
|
30
|
-
timeoutMs;
|
|
31
|
-
openMs;
|
|
32
|
-
#now;
|
|
33
|
-
#openedAt = /* @__PURE__ */ new Map();
|
|
34
|
-
constructor(timeoutMs, openMs = DEFAULT_CIRCUIT_BREAKER_OPEN_MS, now = performance.now.bind(performance)) {
|
|
35
|
-
assert(Number.isSafeInteger(timeoutMs) && timeoutMs >= 0, "Hydration timeout must be a nonnegative integer");
|
|
36
|
-
assert(openMs >= 0, "Circuit breaker open duration must be nonnegative");
|
|
37
|
-
this.timeoutMs = timeoutMs;
|
|
38
|
-
this.openMs = openMs;
|
|
39
|
-
this.#now = now;
|
|
40
|
-
}
|
|
41
|
-
/** Whether the breaker does anything at all. */
|
|
42
|
-
get enabled() {
|
|
43
|
-
return this.timeoutMs > 0;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Whether a hydration that has consumed `elapsedMs` of processing time must
|
|
47
|
-
* be aborted. Always false when the breaker is disabled.
|
|
48
|
-
*/
|
|
49
|
-
exceeded(elapsedMs) {
|
|
50
|
-
return this.enabled && elapsedMs >= this.timeoutMs;
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Records that hydrating `transformationHash` was aborted.
|
|
54
|
-
*
|
|
55
|
-
* Trips are rare, so this is also when expired entries are swept, which
|
|
56
|
-
* keeps the map bounded by the number of hashes tripped within one cooldown
|
|
57
|
-
* rather than by every hash ever tripped.
|
|
58
|
-
*/
|
|
59
|
-
trip(transformationHash) {
|
|
60
|
-
const now = this.#now();
|
|
61
|
-
for (const [hash, openedAt] of this.#openedAt) if (now - openedAt >= this.openMs) this.#openedAt.delete(hash);
|
|
62
|
-
this.#openedAt.set(transformationHash, now);
|
|
63
|
-
}
|
|
64
|
-
/** Whether `transformationHash` is currently rejected. */
|
|
65
|
-
isOpen(transformationHash) {
|
|
66
|
-
const openedAt = this.#openedAt.get(transformationHash);
|
|
67
|
-
if (openedAt === void 0) return false;
|
|
68
|
-
if (this.#now() - openedAt >= this.openMs) {
|
|
69
|
-
this.#openedAt.delete(transformationHash);
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
return true;
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
//#endregion
|
|
76
|
-
export { HydrationCircuitBreaker };
|
|
77
|
-
|
|
78
|
-
//# sourceMappingURL=hydration-circuit-breaker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"hydration-circuit-breaker.js","names":["#now","#openedAt"],"sources":["../../../../../../zero-cache/src/services/view-syncer/hydration-circuit-breaker.ts"],"sourcesContent":["import {assert} from '../../../../shared/src/asserts.ts';\nimport type {MonotonicClock} from './hydration-budget.ts';\n\n/**\n * How long a tripped query stays rejected before a retry is allowed.\n *\n * A query that blows the timeout is almost always slow because of the shape\n * of its data rather than because of transient load, so retrying it on every\n * reconnect would burn a full timeout each time. The cooldown keeps that cost\n * to at most one timeout per cooldown period per query.\n */\nexport const DEFAULT_CIRCUIT_BREAKER_OPEN_MS = 5 * 60_000;\n\n/**\n * A per-query circuit breaker for view-syncer hydration.\n *\n * Hydration of a single query is aborted once its processing time exceeds\n * {@link timeoutMs}. Callers check {@link exceeded} at the yield points of a\n * hydration, so a query is only ever aborted between time slices.\n *\n * Once a query has been aborted the breaker is \"open\" for its transformation\n * hash: {@link isOpen} reports true for {@link openMs}, and callers reject the\n * query up front instead of hydrating it again. After that the breaker is\n * implicitly half-open: the next hydration attempt runs, and either succeeds\n * or trips the breaker again.\n *\n * The breaker is keyed by transformation hash rather than query hash because\n * the transformation (permissions, auth context) determines the pipeline that\n * runs, and a different transformation of the same query may well be fast.\n */\nexport class HydrationCircuitBreaker {\n readonly timeoutMs: number;\n readonly openMs: number;\n readonly #now: MonotonicClock;\n readonly #openedAt = new Map<string, number>();\n\n constructor(\n timeoutMs: number,\n openMs: number = DEFAULT_CIRCUIT_BREAKER_OPEN_MS,\n now: MonotonicClock = performance.now.bind(performance),\n ) {\n assert(\n Number.isSafeInteger(timeoutMs) && timeoutMs >= 0,\n 'Hydration timeout must be a nonnegative integer',\n );\n assert(openMs >= 0, 'Circuit breaker open duration must be nonnegative');\n this.timeoutMs = timeoutMs;\n this.openMs = openMs;\n this.#now = now;\n }\n\n /** Whether the breaker does anything at all. */\n get enabled(): boolean {\n return this.timeoutMs > 0;\n }\n\n /**\n * Whether a hydration that has consumed `elapsedMs` of processing time must\n * be aborted. Always false when the breaker is disabled.\n */\n exceeded(elapsedMs: number): boolean {\n return this.enabled && elapsedMs >= this.timeoutMs;\n }\n\n /**\n * Records that hydrating `transformationHash` was aborted.\n *\n * Trips are rare, so this is also when expired entries are swept, which\n * keeps the map bounded by the number of hashes tripped within one cooldown\n * rather than by every hash ever tripped.\n */\n trip(transformationHash: string): void {\n const now = this.#now();\n for (const [hash, openedAt] of this.#openedAt) {\n if (now - openedAt >= this.openMs) {\n this.#openedAt.delete(hash);\n }\n }\n this.#openedAt.set(transformationHash, now);\n }\n\n /** Whether `transformationHash` is currently rejected. */\n isOpen(transformationHash: string): boolean {\n const openedAt = this.#openedAt.get(transformationHash);\n if (openedAt === undefined) {\n return false;\n }\n if (this.#now() - openedAt >= this.openMs) {\n this.#openedAt.delete(transformationHash);\n return false;\n }\n return true;\n }\n}\n"],"mappings":";;;;;;;;;;AAWA,IAAa,kCAAkC,IAAI;;;;;;;;;;;;;;;;;;AAmBnD,IAAa,0BAAb,MAAqC;CACnC;CACA;CACA;CACA,4BAAqB,IAAI,IAAoB;CAE7C,YACE,WACA,SAAiB,iCACjB,MAAsB,YAAY,IAAI,KAAK,WAAW,GACtD;EACA,OACE,OAAO,cAAc,SAAS,KAAK,aAAa,GAChD,iDACF;EACA,OAAO,UAAU,GAAG,mDAAmD;EACvE,KAAK,YAAY;EACjB,KAAK,SAAS;EACd,KAAKA,OAAO;CACd;;CAGA,IAAI,UAAmB;EACrB,OAAO,KAAK,YAAY;CAC1B;;;;;CAMA,SAAS,WAA4B;EACnC,OAAO,KAAK,WAAW,aAAa,KAAK;CAC3C;;;;;;;;CASA,KAAK,oBAAkC;EACrC,MAAM,MAAM,KAAKA,KAAK;EACtB,KAAK,MAAM,CAAC,MAAM,aAAa,KAAKC,WAClC,IAAI,MAAM,YAAY,KAAK,QACzB,KAAKA,UAAU,OAAO,IAAI;EAG9B,KAAKA,UAAU,IAAI,oBAAoB,GAAG;CAC5C;;CAGA,OAAO,oBAAqC;EAC1C,MAAM,WAAW,KAAKA,UAAU,IAAI,kBAAkB;EACtD,IAAI,aAAa,KAAA,GACf,OAAO;EAET,IAAI,KAAKD,KAAK,IAAI,YAAY,KAAK,QAAQ;GACzC,KAAKC,UAAU,OAAO,kBAAkB;GACxC,OAAO;EACT;EACA,OAAO;CACT;AACF"}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The default maximum number of entries retained by a {@link SnapshotRowCache}.
|
|
3
|
-
*
|
|
4
|
-
* Each entry is a raw SQLite row (or the list of rows conflicting with
|
|
5
|
-
* a row on its unique keys) read while computing a snapshot diff. A
|
|
6
|
-
* replicated transaction of N rows produces up to 2N entries (the new value
|
|
7
|
-
* and the previous value(s) of each row), so the cache should be large enough
|
|
8
|
-
* to hold the largest transactions that are commonly replicated in order for
|
|
9
|
-
* all of the client groups on a worker to share the reads.
|
|
10
|
-
*/
|
|
11
|
-
export declare const DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES = 50000;
|
|
12
|
-
/**
|
|
13
|
-
* How a statement's results are read: a single row (`Statement.get()`) or
|
|
14
|
-
* all rows (`Statement.all()`).
|
|
15
|
-
*/
|
|
16
|
-
export type ReadMode = 'get' | 'all';
|
|
17
|
-
/**
|
|
18
|
-
* The maximum number of distinct SQL statements interned by a
|
|
19
|
-
* {@link SnapshotRowCache} before it is cleared. There is one per table and
|
|
20
|
-
* lookup shape, so this is only reached after many schema changes.
|
|
21
|
-
*/
|
|
22
|
-
export declare const MAX_INTERNED_STATEMENTS = 10000;
|
|
23
|
-
/**
|
|
24
|
-
* A worker-wide, bounded cache of the rows that a `Snapshotter` reads from
|
|
25
|
-
* replica snapshots when computing the diff between two versions of the
|
|
26
|
-
* replica.
|
|
27
|
-
*
|
|
28
|
-
* Every client group (i.e. view-syncer) on a sync worker computes its own
|
|
29
|
-
* diff from the shared `_zero.changeLog2`, and each change in the diff costs
|
|
30
|
-
* two SQLite reads: the new value of the row (from the `curr` snapshot) and
|
|
31
|
-
* the previous value(s) that it replaces (from the `prev` snapshot). The
|
|
32
|
-
* reads for a given change are identical for every client group that
|
|
33
|
-
* traverses it, so a replicated transaction of N rows costs N × 2 × (client
|
|
34
|
-
* groups) reads per worker, most of which are redundant. This cache lets the
|
|
35
|
-
* client groups on a worker share those reads.
|
|
36
|
-
*
|
|
37
|
-
* ### Keys
|
|
38
|
-
*
|
|
39
|
-
* Entries are keyed by the exact SQL statement and arguments of the read
|
|
40
|
-
* (which encodes the table, the selected columns and the lookup keys), plus
|
|
41
|
-
* a `tag` supplied by the caller that pins the result to a version of the
|
|
42
|
-
* replica:
|
|
43
|
-
*
|
|
44
|
-
* - The new value of a row is the row as of the `stateVersion` recorded in
|
|
45
|
-
* its change log entry (its `_0_version` is asserted to equal that
|
|
46
|
-
* version), and is tagged with that `stateVersion`. It is thus shareable
|
|
47
|
-
* by all client groups regardless of the snapshots they are advancing
|
|
48
|
-
* between.
|
|
49
|
-
* - Previous values are read from the `prev` snapshot at its version, and
|
|
50
|
-
* are tagged with that version (and, when the result can depend on the
|
|
51
|
-
* changes applied to the snapshot before the read, the `curr` version
|
|
52
|
-
* as well). See `Diff` in `snapshotter.ts` for the details.
|
|
53
|
-
*
|
|
54
|
-
* Because every key includes the version(s) that the result depends on,
|
|
55
|
-
* entries never go stale and are never invalidated; they are only evicted.
|
|
56
|
-
*
|
|
57
|
-
* ### Eviction
|
|
58
|
-
*
|
|
59
|
-
* The cache is bounded by entry count and evicts in insertion (FIFO) order
|
|
60
|
-
* rather than by recency. Diffs are traversed in change log order by every
|
|
61
|
-
* client group, so the entries that will not be needed again are those that
|
|
62
|
-
* were inserted the earliest (all groups have moved past them), while the
|
|
63
|
-
* most recently inserted entries are the ones that the trailing groups have
|
|
64
|
-
* yet to reach. Refreshing an entry on a hit would evict exactly the wrong
|
|
65
|
-
* entries when a trailing group catches up.
|
|
66
|
-
*
|
|
67
|
-
* ### Sharing
|
|
68
|
-
*
|
|
69
|
-
* Cached values are shared by reference across client groups and must
|
|
70
|
-
* therefore never be mutated by callers.
|
|
71
|
-
*/
|
|
72
|
-
export declare class SnapshotRowCache {
|
|
73
|
-
#private;
|
|
74
|
-
constructor(maxEntries?: number);
|
|
75
|
-
get size(): number;
|
|
76
|
-
get maxEntries(): number;
|
|
77
|
-
stats(): {
|
|
78
|
-
hits: number;
|
|
79
|
-
misses: number;
|
|
80
|
-
size: number;
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* Returns the cached result of the read identified by `tag`, `sql`, `mode`
|
|
84
|
-
* and `args`, or performs the read via `read()`, caching and returning its
|
|
85
|
-
* result. `undefined` results (i.e. a missing row) are not cached.
|
|
86
|
-
*
|
|
87
|
-
* `mode` is part of the key because the same statement can be read both
|
|
88
|
-
* ways: for a table whose only unique key is its primary key, `getRow()`
|
|
89
|
-
* and `getRows()` produce identical SQL, args and tags, but the former
|
|
90
|
-
* caches a row and the latter an array of rows.
|
|
91
|
-
*/
|
|
92
|
-
getOrRead<T>(tag: string, sql: string, mode: ReadMode, args: unknown[], read: () => T): T;
|
|
93
|
-
clear(): void;
|
|
94
|
-
}
|
|
95
|
-
//# sourceMappingURL=snapshot-row-cache.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot-row-cache.d.ts","sourceRoot":"","sources":["../../../../../../zero-cache/src/services/view-syncer/snapshot-row-cache.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,eAAO,MAAM,sCAAsC,QAAS,CAAC;AAwB7D;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;AAErC;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,QAAS,CAAC;AAK9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,qBAAa,gBAAgB;;gBAmBf,UAAU,SAAyC;IAI/D,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,KAAK,IAAI;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC;IAIrD;;;;;;;;;OASG;IACH,SAAS,CAAC,CAAC,EACT,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,OAAO,EAAE,EACf,IAAI,EAAE,MAAM,CAAC,GACZ,CAAC;IAsBJ,KAAK,IAAI,IAAI;CA0Bd"}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import { getOrInsert } from "../../../../shared/src/map.js";
|
|
2
|
-
import { must } from "../../../../shared/src/must.js";
|
|
3
|
-
import { stringify } from "../../../../shared/src/bigint-json.js";
|
|
4
|
-
import { getOrCreateCounter } from "../../observability/metrics.js";
|
|
5
|
-
import { RingBuffer } from "../../../../shared/src/ring-buffer.js";
|
|
6
|
-
//#region ../zero-cache/src/services/view-syncer/snapshot-row-cache.ts
|
|
7
|
-
/**
|
|
8
|
-
* The default maximum number of entries retained by a {@link SnapshotRowCache}.
|
|
9
|
-
*
|
|
10
|
-
* Each entry is a raw SQLite row (or the list of rows conflicting with
|
|
11
|
-
* a row on its unique keys) read while computing a snapshot diff. A
|
|
12
|
-
* replicated transaction of N rows produces up to 2N entries (the new value
|
|
13
|
-
* and the previous value(s) of each row), so the cache should be large enough
|
|
14
|
-
* to hold the largest transactions that are commonly replicated in order for
|
|
15
|
-
* all of the client groups on a worker to share the reads.
|
|
16
|
-
*/
|
|
17
|
-
var DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES = 5e4;
|
|
18
|
-
/**
|
|
19
|
-
* Serializes a lookup key value (i.e. a SQLite-bound parameter). Numbers and
|
|
20
|
-
* bigints serialize identically, as row keys parsed from the change log are
|
|
21
|
-
* JSON numbers whereas the values read from SQLite are bigints; both address
|
|
22
|
-
* the same row. Strings are prefixed to distinguish them from numbers.
|
|
23
|
-
*/
|
|
24
|
-
function serialize(v) {
|
|
25
|
-
switch (typeof v) {
|
|
26
|
-
case "string": return "s" + v;
|
|
27
|
-
case "number":
|
|
28
|
-
case "bigint": return String(v);
|
|
29
|
-
case "boolean": return v ? "true" : "false";
|
|
30
|
-
case "object": return v === null ? "null" : "o" + stringify(v);
|
|
31
|
-
default: return "u" + String(v);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
var HIT = { result: "hit" };
|
|
35
|
-
var MISS = { result: "miss" };
|
|
36
|
-
/**
|
|
37
|
-
* A worker-wide, bounded cache of the rows that a `Snapshotter` reads from
|
|
38
|
-
* replica snapshots when computing the diff between two versions of the
|
|
39
|
-
* replica.
|
|
40
|
-
*
|
|
41
|
-
* Every client group (i.e. view-syncer) on a sync worker computes its own
|
|
42
|
-
* diff from the shared `_zero.changeLog2`, and each change in the diff costs
|
|
43
|
-
* two SQLite reads: the new value of the row (from the `curr` snapshot) and
|
|
44
|
-
* the previous value(s) that it replaces (from the `prev` snapshot). The
|
|
45
|
-
* reads for a given change are identical for every client group that
|
|
46
|
-
* traverses it, so a replicated transaction of N rows costs N × 2 × (client
|
|
47
|
-
* groups) reads per worker, most of which are redundant. This cache lets the
|
|
48
|
-
* client groups on a worker share those reads.
|
|
49
|
-
*
|
|
50
|
-
* ### Keys
|
|
51
|
-
*
|
|
52
|
-
* Entries are keyed by the exact SQL statement and arguments of the read
|
|
53
|
-
* (which encodes the table, the selected columns and the lookup keys), plus
|
|
54
|
-
* a `tag` supplied by the caller that pins the result to a version of the
|
|
55
|
-
* replica:
|
|
56
|
-
*
|
|
57
|
-
* - The new value of a row is the row as of the `stateVersion` recorded in
|
|
58
|
-
* its change log entry (its `_0_version` is asserted to equal that
|
|
59
|
-
* version), and is tagged with that `stateVersion`. It is thus shareable
|
|
60
|
-
* by all client groups regardless of the snapshots they are advancing
|
|
61
|
-
* between.
|
|
62
|
-
* - Previous values are read from the `prev` snapshot at its version, and
|
|
63
|
-
* are tagged with that version (and, when the result can depend on the
|
|
64
|
-
* changes applied to the snapshot before the read, the `curr` version
|
|
65
|
-
* as well). See `Diff` in `snapshotter.ts` for the details.
|
|
66
|
-
*
|
|
67
|
-
* Because every key includes the version(s) that the result depends on,
|
|
68
|
-
* entries never go stale and are never invalidated; they are only evicted.
|
|
69
|
-
*
|
|
70
|
-
* ### Eviction
|
|
71
|
-
*
|
|
72
|
-
* The cache is bounded by entry count and evicts in insertion (FIFO) order
|
|
73
|
-
* rather than by recency. Diffs are traversed in change log order by every
|
|
74
|
-
* client group, so the entries that will not be needed again are those that
|
|
75
|
-
* were inserted the earliest (all groups have moved past them), while the
|
|
76
|
-
* most recently inserted entries are the ones that the trailing groups have
|
|
77
|
-
* yet to reach. Refreshing an entry on a hit would evict exactly the wrong
|
|
78
|
-
* entries when a trailing group catches up.
|
|
79
|
-
*
|
|
80
|
-
* ### Sharing
|
|
81
|
-
*
|
|
82
|
-
* Cached values are shared by reference across client groups and must
|
|
83
|
-
* therefore never be mutated by callers.
|
|
84
|
-
*/
|
|
85
|
-
var SnapshotRowCache = class {
|
|
86
|
-
#maxEntries;
|
|
87
|
-
#entries = /* @__PURE__ */ new Map();
|
|
88
|
-
#keys = new RingBuffer();
|
|
89
|
-
#sqlIDs = /* @__PURE__ */ new Map();
|
|
90
|
-
#reads = getOrCreateCounter("sync", "ivm.snapshot-row-reads", "Row reads performed while computing snapshot diffs for IVM, labeled by whether the read was served by the worker-wide snapshot row cache.");
|
|
91
|
-
#hits = 0;
|
|
92
|
-
#misses = 0;
|
|
93
|
-
constructor(maxEntries = DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES) {
|
|
94
|
-
this.#maxEntries = Math.max(0, maxEntries);
|
|
95
|
-
}
|
|
96
|
-
get size() {
|
|
97
|
-
return this.#entries.size;
|
|
98
|
-
}
|
|
99
|
-
get maxEntries() {
|
|
100
|
-
return this.#maxEntries;
|
|
101
|
-
}
|
|
102
|
-
stats() {
|
|
103
|
-
return {
|
|
104
|
-
hits: this.#hits,
|
|
105
|
-
misses: this.#misses,
|
|
106
|
-
size: this.#entries.size
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Returns the cached result of the read identified by `tag`, `sql`, `mode`
|
|
111
|
-
* and `args`, or performs the read via `read()`, caching and returning its
|
|
112
|
-
* result. `undefined` results (i.e. a missing row) are not cached.
|
|
113
|
-
*
|
|
114
|
-
* `mode` is part of the key because the same statement can be read both
|
|
115
|
-
* ways: for a table whose only unique key is its primary key, `getRow()`
|
|
116
|
-
* and `getRows()` produce identical SQL, args and tags, but the former
|
|
117
|
-
* caches a row and the latter an array of rows.
|
|
118
|
-
*/
|
|
119
|
-
getOrRead(tag, sql, mode, args, read) {
|
|
120
|
-
const key = this.#key(tag, sql, mode, args);
|
|
121
|
-
const cached = this.#entries.get(key);
|
|
122
|
-
if (cached !== void 0) {
|
|
123
|
-
this.#hits++;
|
|
124
|
-
this.#reads.add(1, HIT);
|
|
125
|
-
return cached;
|
|
126
|
-
}
|
|
127
|
-
this.#misses++;
|
|
128
|
-
this.#reads.add(1, MISS);
|
|
129
|
-
const value = read();
|
|
130
|
-
if (value !== void 0 && this.#maxEntries > 0) {
|
|
131
|
-
this.#entries.set(key, value);
|
|
132
|
-
this.#keys.push(key);
|
|
133
|
-
if (this.#keys.size > this.#maxEntries) this.#entries.delete(must(this.#keys.shift()));
|
|
134
|
-
}
|
|
135
|
-
return value;
|
|
136
|
-
}
|
|
137
|
-
clear() {
|
|
138
|
-
this.#entries.clear();
|
|
139
|
-
this.#keys.clear();
|
|
140
|
-
this.#sqlIDs.clear();
|
|
141
|
-
}
|
|
142
|
-
#key(tag, sql, mode, args) {
|
|
143
|
-
if (this.#sqlIDs.size >= 1e4 && !this.#sqlIDs.has(sql)) this.clear();
|
|
144
|
-
let key = `${tag}\0${mode}${getOrInsert(this.#sqlIDs, sql, this.#sqlIDs.size)}`;
|
|
145
|
-
for (const arg of args) {
|
|
146
|
-
const serialized = serialize(arg);
|
|
147
|
-
key += `\0${serialized.length}:${serialized}`;
|
|
148
|
-
}
|
|
149
|
-
return key;
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
//#endregion
|
|
153
|
-
export { SnapshotRowCache };
|
|
154
|
-
|
|
155
|
-
//# sourceMappingURL=snapshot-row-cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot-row-cache.js","names":["#maxEntries","#entries","#keys","#sqlIDs","#reads","#hits","#misses","#key"],"sources":["../../../../../../zero-cache/src/services/view-syncer/snapshot-row-cache.ts"],"sourcesContent":["import {stringify} from '../../../../shared/src/bigint-json.ts';\nimport {getOrInsert} from '../../../../shared/src/map.ts';\nimport {must} from '../../../../shared/src/must.ts';\nimport {RingBuffer} from '../../../../shared/src/ring-buffer.ts';\nimport {getOrCreateCounter} from '../../observability/metrics.ts';\n\n/**\n * The default maximum number of entries retained by a {@link SnapshotRowCache}.\n *\n * Each entry is a raw SQLite row (or the list of rows conflicting with\n * a row on its unique keys) read while computing a snapshot diff. A\n * replicated transaction of N rows produces up to 2N entries (the new value\n * and the previous value(s) of each row), so the cache should be large enough\n * to hold the largest transactions that are commonly replicated in order for\n * all of the client groups on a worker to share the reads.\n */\nexport const DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES = 50_000;\n\n/**\n * Serializes a lookup key value (i.e. a SQLite-bound parameter). Numbers and\n * bigints serialize identically, as row keys parsed from the change log are\n * JSON numbers whereas the values read from SQLite are bigints; both address\n * the same row. Strings are prefixed to distinguish them from numbers.\n */\nfunction serialize(v: unknown): string {\n switch (typeof v) {\n case 'string':\n return 's' + v;\n case 'number':\n case 'bigint':\n return String(v);\n case 'boolean':\n return v ? 'true' : 'false';\n case 'object':\n return v === null ? 'null' : 'o' + stringify(v);\n default:\n return 'u' + String(v);\n }\n}\n\n/**\n * How a statement's results are read: a single row (`Statement.get()`) or\n * all rows (`Statement.all()`).\n */\nexport type ReadMode = 'get' | 'all';\n\n/**\n * The maximum number of distinct SQL statements interned by a\n * {@link SnapshotRowCache} before it is cleared. There is one per table and\n * lookup shape, so this is only reached after many schema changes.\n */\nexport const MAX_INTERNED_STATEMENTS = 10_000;\n\nconst HIT = {result: 'hit'} as const;\nconst MISS = {result: 'miss'} as const;\n\n/**\n * A worker-wide, bounded cache of the rows that a `Snapshotter` reads from\n * replica snapshots when computing the diff between two versions of the\n * replica.\n *\n * Every client group (i.e. view-syncer) on a sync worker computes its own\n * diff from the shared `_zero.changeLog2`, and each change in the diff costs\n * two SQLite reads: the new value of the row (from the `curr` snapshot) and\n * the previous value(s) that it replaces (from the `prev` snapshot). The\n * reads for a given change are identical for every client group that\n * traverses it, so a replicated transaction of N rows costs N × 2 × (client\n * groups) reads per worker, most of which are redundant. This cache lets the\n * client groups on a worker share those reads.\n *\n * ### Keys\n *\n * Entries are keyed by the exact SQL statement and arguments of the read\n * (which encodes the table, the selected columns and the lookup keys), plus\n * a `tag` supplied by the caller that pins the result to a version of the\n * replica:\n *\n * - The new value of a row is the row as of the `stateVersion` recorded in\n * its change log entry (its `_0_version` is asserted to equal that\n * version), and is tagged with that `stateVersion`. It is thus shareable\n * by all client groups regardless of the snapshots they are advancing\n * between.\n * - Previous values are read from the `prev` snapshot at its version, and\n * are tagged with that version (and, when the result can depend on the\n * changes applied to the snapshot before the read, the `curr` version\n * as well). See `Diff` in `snapshotter.ts` for the details.\n *\n * Because every key includes the version(s) that the result depends on,\n * entries never go stale and are never invalidated; they are only evicted.\n *\n * ### Eviction\n *\n * The cache is bounded by entry count and evicts in insertion (FIFO) order\n * rather than by recency. Diffs are traversed in change log order by every\n * client group, so the entries that will not be needed again are those that\n * were inserted the earliest (all groups have moved past them), while the\n * most recently inserted entries are the ones that the trailing groups have\n * yet to reach. Refreshing an entry on a hit would evict exactly the wrong\n * entries when a trailing group catches up.\n *\n * ### Sharing\n *\n * Cached values are shared by reference across client groups and must\n * therefore never be mutated by callers.\n */\nexport class SnapshotRowCache {\n readonly #maxEntries: number;\n readonly #entries = new Map<string, unknown>();\n // The keys of #entries in insertion order, so that the oldest can be\n // evicted in O(1). (Finding the oldest key with a fresh Map iterator\n // instead costs O(evictions) per insert, as V8 leaves deleted entries in\n // the table until it is compacted and every new iterator walks over them.)\n readonly #keys = new RingBuffer<string>();\n // Interns the SQL text of each distinct read so that entry keys\n // do not repeat the (long) column list of every statement.\n readonly #sqlIDs = new Map<string, number>();\n readonly #reads = getOrCreateCounter(\n 'sync',\n 'ivm.snapshot-row-reads',\n 'Row reads performed while computing snapshot diffs for IVM, labeled by whether the read was served by the worker-wide snapshot row cache.',\n );\n #hits = 0;\n #misses = 0;\n\n constructor(maxEntries = DEFAULT_MAX_SNAPSHOT_ROW_CACHE_ENTRIES) {\n this.#maxEntries = Math.max(0, maxEntries);\n }\n\n get size(): number {\n return this.#entries.size;\n }\n\n get maxEntries(): number {\n return this.#maxEntries;\n }\n\n stats(): {hits: number; misses: number; size: number} {\n return {hits: this.#hits, misses: this.#misses, size: this.#entries.size};\n }\n\n /**\n * Returns the cached result of the read identified by `tag`, `sql`, `mode`\n * and `args`, or performs the read via `read()`, caching and returning its\n * result. `undefined` results (i.e. a missing row) are not cached.\n *\n * `mode` is part of the key because the same statement can be read both\n * ways: for a table whose only unique key is its primary key, `getRow()`\n * and `getRows()` produce identical SQL, args and tags, but the former\n * caches a row and the latter an array of rows.\n */\n getOrRead<T>(\n tag: string,\n sql: string,\n mode: ReadMode,\n args: unknown[],\n read: () => T,\n ): T {\n const key = this.#key(tag, sql, mode, args);\n const cached = this.#entries.get(key);\n if (cached !== undefined) {\n this.#hits++;\n this.#reads.add(1, HIT);\n return cached as T;\n }\n this.#misses++;\n this.#reads.add(1, MISS);\n const value = read();\n if (value !== undefined && this.#maxEntries > 0) {\n // `key` is not in #entries (this is a miss), so it is always added.\n this.#entries.set(key, value);\n this.#keys.push(key);\n if (this.#keys.size > this.#maxEntries) {\n this.#entries.delete(must(this.#keys.shift()));\n }\n }\n return value;\n }\n\n clear(): void {\n this.#entries.clear();\n this.#keys.clear();\n this.#sqlIDs.clear();\n }\n\n #key(tag: string, sql: string, mode: ReadMode, args: unknown[]): string {\n if (\n this.#sqlIDs.size >= MAX_INTERNED_STATEMENTS &&\n !this.#sqlIDs.has(sql)\n ) {\n // Statements are only added (e.g. when schema changes produce new\n // column lists), so bound them by starting over. The entries refer to\n // statements by ID and are cleared with them.\n this.clear();\n }\n const sqlID = getOrInsert(this.#sqlIDs, sql, this.#sqlIDs.size);\n let key = `${tag}\\0${mode}${sqlID}`;\n // Include each value's length so separators inside string values cannot\n // make different argument arrays produce the same key.\n for (const arg of args) {\n const serialized = serialize(arg);\n key += `\\0${serialized.length}:${serialized}`;\n }\n return key;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,IAAa,yCAAyC;;;;;;;AAQtD,SAAS,UAAU,GAAoB;CACrC,QAAQ,OAAO,GAAf;EACE,KAAK,UACH,OAAO,MAAM;EACf,KAAK;EACL,KAAK,UACH,OAAO,OAAO,CAAC;EACjB,KAAK,WACH,OAAO,IAAI,SAAS;EACtB,KAAK,UACH,OAAO,MAAM,OAAO,SAAS,MAAM,UAAU,CAAC;EAChD,SACE,OAAO,MAAM,OAAO,CAAC;CACzB;AACF;AAeA,IAAM,MAAM,EAAC,QAAQ,MAAK;AAC1B,IAAM,OAAO,EAAC,QAAQ,OAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmD5B,IAAa,mBAAb,MAA8B;CAC5B;CACA,2BAAoB,IAAI,IAAqB;CAK7C,QAAiB,IAAI,WAAmB;CAGxC,0BAAmB,IAAI,IAAoB;CAC3C,SAAkB,mBAChB,QACA,0BACA,2IACF;CACA,QAAQ;CACR,UAAU;CAEV,YAAY,aAAa,wCAAwC;EAC/D,KAAKA,cAAc,KAAK,IAAI,GAAG,UAAU;CAC3C;CAEA,IAAI,OAAe;EACjB,OAAO,KAAKC,SAAS;CACvB;CAEA,IAAI,aAAqB;EACvB,OAAO,KAAKD;CACd;CAEA,QAAsD;EACpD,OAAO;GAAC,MAAM,KAAKK;GAAO,QAAQ,KAAKC;GAAS,MAAM,KAAKL,SAAS;EAAI;CAC1E;;;;;;;;;;;CAYA,UACE,KACA,KACA,MACA,MACA,MACG;EACH,MAAM,MAAM,KAAKM,KAAK,KAAK,KAAK,MAAM,IAAI;EAC1C,MAAM,SAAS,KAAKN,SAAS,IAAI,GAAG;EACpC,IAAI,WAAW,KAAA,GAAW;GACxB,KAAKI;GACL,KAAKD,OAAO,IAAI,GAAG,GAAG;GACtB,OAAO;EACT;EACA,KAAKE;EACL,KAAKF,OAAO,IAAI,GAAG,IAAI;EACvB,MAAM,QAAQ,KAAK;EACnB,IAAI,UAAU,KAAA,KAAa,KAAKJ,cAAc,GAAG;GAE/C,KAAKC,SAAS,IAAI,KAAK,KAAK;GAC5B,KAAKC,MAAM,KAAK,GAAG;GACnB,IAAI,KAAKA,MAAM,OAAO,KAAKF,aACzB,KAAKC,SAAS,OAAO,KAAK,KAAKC,MAAM,MAAM,CAAC,CAAC;EAEjD;EACA,OAAO;CACT;CAEA,QAAc;EACZ,KAAKD,SAAS,MAAM;EACpB,KAAKC,MAAM,MAAM;EACjB,KAAKC,QAAQ,MAAM;CACrB;CAEA,KAAK,KAAa,KAAa,MAAgB,MAAyB;EACtE,IACE,KAAKA,QAAQ,QAAA,OACb,CAAC,KAAKA,QAAQ,IAAI,GAAG,GAKrB,KAAK,MAAM;EAGb,IAAI,MAAM,GAAG,IAAI,IAAI,OADP,YAAY,KAAKA,SAAS,KAAK,KAAKA,QAAQ,IAC9B;EAG5B,KAAK,MAAM,OAAO,MAAM;GACtB,MAAM,aAAa,UAAU,GAAG;GAChC,OAAO,KAAK,WAAW,OAAO,GAAG;EACnC;EACA,OAAO;CACT;AACF"}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { Format } from '../../zero-types/src/format.ts';
|
|
2
|
-
/**
|
|
3
|
-
* Hashes a normalized AST by visiting it, rather than by rendering it to JSON
|
|
4
|
-
* and hashing the bytes. `hashOfAST` and `hashOfNameAndArgs` in
|
|
5
|
-
* `query-hash.ts` are both built on this, so these digests are the query IDs
|
|
6
|
-
* the client registers and the transformation hashes the server stores.
|
|
7
|
-
*
|
|
8
|
-
* The pipeline this replaced was
|
|
9
|
-
* `h64(JSON.stringify(normalizeAST(ast))).toString(36)`, which materialized
|
|
10
|
-
* the whole AST as a string, UTF-8 encoded it, and only then hashed it — three
|
|
11
|
-
* passes over the data, two of which existed purely to produce bytes to hash.
|
|
12
|
-
*
|
|
13
|
-
* A visitor can fold values into the hash state as it walks, so nothing is
|
|
14
|
-
* materialized at all. The primitives that make that pay off:
|
|
15
|
-
*
|
|
16
|
-
* - Two 32-bit accumulators held in module-level `let`s, so the "state" is
|
|
17
|
-
* plain numbers in registers rather than an object being threaded through
|
|
18
|
-
* the walk.
|
|
19
|
-
* - xxHash32's own round and final mix, shared with `shared/src/hash.ts` via
|
|
20
|
-
* `shared/src/xxhash32.ts`. Only the ingestion differs: that one feeds them
|
|
21
|
-
* UTF-8 bytes, this one feeds them words straight out of the structure.
|
|
22
|
-
* - Strings folded straight from `charCodeAt`, two UTF-16 units at a time, into
|
|
23
|
-
* one 32-bit word. No UTF-8 encoding, and half the loop iterations a
|
|
24
|
-
* byte-oriented hash would need over ASCII.
|
|
25
|
-
*
|
|
26
|
-
* These digests do not agree with xxHash32 over the old JSON encoding, and are
|
|
27
|
-
* not meant to: nothing recomputes a hash produced elsewhere and compares it,
|
|
28
|
-
* so the encoding is free to change as long as every writer moves together.
|
|
29
|
-
* What it does have to give is distinct words for structurally distinct
|
|
30
|
-
* queries — a 64-bit digest cannot promise that absolutely, but every field
|
|
31
|
-
* and node kind must at least reach the mixer, and no two of them may be
|
|
32
|
-
* written so as to be confusable. `query-hash-visitor.test.ts` holds that
|
|
33
|
-
* line with a corpus and a per-field mutation test.
|
|
34
|
-
*
|
|
35
|
-
* The walk is deliberately specialized to the AST shape rather than written as
|
|
36
|
-
* a generic JSON-value walk. That is not premature: a generic version was
|
|
37
|
-
* measured alongside this one and came out ~2.4x slower, no better than the
|
|
38
|
-
* `JSON.stringify` it was meant to replace, because `for...in` and the
|
|
39
|
-
* megamorphic property loads cost about what the native stringify costs. Only
|
|
40
|
-
* `visitValue` below stays generic, for the two places an AST holds arbitrary
|
|
41
|
-
* JSON: a literal's value and a bound's row.
|
|
42
|
-
*/
|
|
43
|
-
import type { AST, System } from './ast.ts';
|
|
44
|
-
export declare function hashAST(ast: AST): string;
|
|
45
|
-
/**
|
|
46
|
-
* The identity of a custom query: its name and its arguments.
|
|
47
|
-
*
|
|
48
|
-
* Same walk, entered at a different node. `args` is arbitrary JSON, which is
|
|
49
|
-
* what `visitValue` already exists to handle. The leading tag keeps this hash
|
|
50
|
-
* space disjoint from `hashAST`'s -- both produce query IDs that live in the
|
|
51
|
-
* same namespace, so an AST must not be able to fold to the same words as some
|
|
52
|
-
* name and args.
|
|
53
|
-
*/
|
|
54
|
-
export declare function hashNameAndArgs(name: string, args: readonly unknown[]): string;
|
|
55
|
-
/**
|
|
56
|
-
* The identity of a query as the client sees it: its AST, the shape it returns,
|
|
57
|
-
* the system it was built for, and -- for a custom query -- the name and
|
|
58
|
-
* arguments it was declared with.
|
|
59
|
-
*
|
|
60
|
-
* Everything past the AST is here because it is part of what makes two queries
|
|
61
|
-
* different while leaving no trace, or an incomplete one, in the AST itself:
|
|
62
|
-
*
|
|
63
|
-
* - **name and args**: `nameAndArgs` reuses the AST it is given and only
|
|
64
|
-
* attaches a `CustomQueryID`, so without these two different named queries
|
|
65
|
-
* over the same table would be indistinguishable.
|
|
66
|
-
* - **system**: a query stamps it onto every `related` entry and every `exists`
|
|
67
|
-
* correlation it builds, so it is already hashed via
|
|
68
|
-
* {@link visitCorrelatedSubquery} -- but a query with neither has nowhere to
|
|
69
|
-
* put it, and would otherwise hash the same whether it was built for the
|
|
70
|
-
* client or for permissions.
|
|
71
|
-
* - **currentJunction**: builder state, set on the sub-query handed to a
|
|
72
|
-
* two-hop relationship's callback, which makes `limit` and `orderBy` throw.
|
|
73
|
-
* It leaves no trace in the AST at all, so two queries that differ only in
|
|
74
|
-
* whether those methods work would otherwise be indistinguishable.
|
|
75
|
-
*
|
|
76
|
-
* The name and args are taken apart rather than as a `CustomQueryID` because
|
|
77
|
-
* that type lives in `zql`, which is above this package; `hashNameAndArgs`
|
|
78
|
-
* splits them the same way.
|
|
79
|
-
*/
|
|
80
|
-
export declare function hashOfQueryInternals(ast: AST, format: Format, system: System, currentJunction: string | undefined, customQueryName: string | undefined, customQueryArgs: readonly unknown[] | undefined): string;
|
|
81
|
-
//# sourceMappingURL=query-hash-visitor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"query-hash-visitor.d.ts","sourceRoot":"","sources":["../../../../zero-protocol/src/query-hash-visitor.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,gCAAgC,CAAC;AAE3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,OAAO,KAAK,EACV,GAAG,EAIH,MAAM,EAEP,MAAM,UAAU,CAAC;AA8UlB,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAcxC;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,MAAM,CAaR;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,eAAe,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,GAC9C,MAAM,CA2BR"}
|