@rocicorp/zero 1.11.0-canary.1 → 1.11.0-canary.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/analyze-query/src/bin-analyze.js +9 -8
- 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 +3 -6
- package/out/replicache/src/btree/node.js.map +1 -1
- package/out/replicache/src/btree/read.d.ts +12 -1
- package/out/replicache/src/btree/read.d.ts.map +1 -1
- package/out/replicache/src/btree/read.js +24 -12
- 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 +8 -11
- package/out/replicache/src/dag/gc.js.map +1 -1
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts +12 -0
- package/out/replicache/src/dag/invalid-ref-count-error.d.ts.map +1 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js +19 -0
- package/out/replicache/src/dag/invalid-ref-count-error.js.map +1 -0
- package/out/replicache/src/dag/store-impl.d.ts +12 -2
- package/out/replicache/src/dag/store-impl.d.ts.map +1 -1
- package/out/replicache/src/dag/store-impl.js +22 -8
- package/out/replicache/src/dag/store-impl.js.map +1 -1
- package/out/replicache/src/db/rebase.d.ts +14 -2
- package/out/replicache/src/db/rebase.d.ts.map +1 -1
- package/out/replicache/src/db/rebase.js +27 -5
- package/out/replicache/src/db/rebase.js.map +1 -1
- package/out/replicache/src/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 +28 -5
- package/out/replicache/src/kv/expo-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/idb-store-with-mem-fallback.d.ts +15 -5
- 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 +9 -0
- package/out/replicache/src/kv/idb-store.d.ts.map +1 -1
- package/out/replicache/src/kv/idb-store.js +14 -2
- package/out/replicache/src/kv/idb-store.js.map +1 -1
- package/out/replicache/src/kv/mem-store.d.ts +1 -0
- package/out/replicache/src/kv/mem-store.d.ts.map +1 -1
- package/out/replicache/src/kv/mem-store.js +3 -0
- package/out/replicache/src/kv/mem-store.js.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.d.ts.map +1 -1
- package/out/replicache/src/kv/op-sqlite/store.js +1 -1
- package/out/replicache/src/kv/op-sqlite/store.js.map +1 -1
- package/out/replicache/src/kv/sqlite-store.d.ts +13 -1
- package/out/replicache/src/kv/sqlite-store.d.ts.map +1 -1
- package/out/replicache/src/kv/sqlite-store.js +73 -6
- package/out/replicache/src/kv/sqlite-store.js.map +1 -1
- package/out/replicache/src/kv/store.d.ts +6 -0
- package/out/replicache/src/kv/store.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.d.ts +10 -5
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.js +16 -9
- 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 +13 -6
- package/out/replicache/src/persist/persist.js.map +1 -1
- package/out/replicache/src/persist/refresh.js +6 -2
- package/out/replicache/src/persist/refresh.js.map +1 -1
- package/out/replicache/src/replicache-impl.d.ts +14 -3
- package/out/replicache/src/replicache-impl.d.ts.map +1 -1
- package/out/replicache/src/replicache-impl.js +118 -11
- package/out/replicache/src/replicache-impl.js.map +1 -1
- package/out/replicache/src/replicache-options.d.ts +9 -0
- package/out/replicache/src/replicache-options.d.ts.map +1 -1
- package/out/replicache/src/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 +5 -0
- package/out/shared/src/arrays.d.ts.map +1 -1
- package/out/shared/src/arrays.js +8 -10
- package/out/shared/src/arrays.js.map +1 -1
- package/out/shared/src/error.d.ts +11 -0
- package/out/shared/src/error.d.ts.map +1 -1
- package/out/shared/src/error.js +35 -1
- package/out/shared/src/error.js.map +1 -1
- package/out/shared/src/iterables.d.ts +2 -0
- package/out/shared/src/iterables.d.ts.map +1 -1
- package/out/shared/src/iterables.js +18 -1
- package/out/shared/src/iterables.js.map +1 -1
- package/out/shared/src/map.d.ts +24 -2
- package/out/shared/src/map.d.ts.map +1 -1
- package/out/shared/src/map.js +18 -4
- package/out/shared/src/map.js.map +1 -1
- package/out/shared/src/ring-buffer.d.ts +8 -0
- package/out/shared/src/ring-buffer.d.ts.map +1 -1
- package/out/shared/src/ring-buffer.js +22 -1
- package/out/shared/src/ring-buffer.js.map +1 -1
- package/out/z2s/src/compiler.js +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 -4
- package/out/zero/package.js.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +1 -0
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js +25 -1
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +48 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +130 -5
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/db/lite-tables.d.ts.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js +3 -4
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/observability/events.js +4 -1
- package/out/zero-cache/src/observability/events.js.map +1 -1
- package/out/zero-cache/src/observability/metrics.d.ts.map +1 -1
- package/out/zero-cache/src/observability/metrics.js +2 -7
- package/out/zero-cache/src/observability/metrics.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +27 -10
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts +18 -2
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +22 -15
- 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 +8 -1
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/mutator.js +2 -0
- package/out/zero-cache/src/server/mutator.js.map +1 -1
- package/out/zero-cache/src/server/reaper.d.ts.map +1 -1
- package/out/zero-cache/src/server/reaper.js +2 -0
- package/out/zero-cache/src/server/reaper.js.map +1 -1
- package/out/zero-cache/src/server/replicator.d.ts.map +1 -1
- package/out/zero-cache/src/server/replicator.js +12 -3
- 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 +3 -0
- package/out/zero-cache/src/server/runner/zero-dispatcher.js.map +1 -1
- package/out/zero-cache/src/server/syncer-assigner.d.ts +14 -0
- package/out/zero-cache/src/server/syncer-assigner.d.ts.map +1 -0
- package/out/zero-cache/src/server/syncer-assigner.js +72 -0
- package/out/zero-cache/src/server/syncer-assigner.js.map +1 -0
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +5 -1
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.d.ts.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +21 -4
- package/out/zero-cache/src/server/worker-dispatcher.js.map +1 -1
- package/out/zero-cache/src/services/analyze.d.ts.map +1 -1
- package/out/zero-cache/src/services/analyze.js +11 -9
- package/out/zero-cache/src/services/analyze.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +15 -3
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/change-stream-multiplexer.js +15 -3
- 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/replica-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js +2 -39
- package/out/zero-cache/src/services/change-source/common/replica-schema.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts +156 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.js +15 -0
- package/out/zero-cache/src/services/change-source/pg/backfill-resume.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts +25 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js +202 -0
- package/out/zero-cache/src/services/change-source/pg/change-source-init.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts +14 -16
- 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 +64 -143
- 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 +28 -2
- package/out/zero-cache/src/services/change-source/pg/initial-sync.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js +44 -21
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts +16 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js +113 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slot-cleanup-monitor.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts +21 -15
- package/out/zero-cache/src/services/change-source/pg/replication-slots.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js +86 -23
- package/out/zero-cache/src/services/change-source/pg/replication-slots.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js +68 -8
- package/out/zero-cache/src/services/change-source/pg/schema/index-predicate.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +32 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts +10 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.d.ts.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js +6 -0
- package/out/zero-cache/src/services/change-source/pg/schema/replica-stage-enum.js.map +1 -0
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +50 -27
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +100 -34
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +58 -7
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts +8 -2
- package/out/zero-cache/src/services/change-streamer/broadcast.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/broadcast.js +24 -4
- package/out/zero-cache/src/services/change-streamer/broadcast.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts +19 -4
- package/out/zero-cache/src/services/change-streamer/change-log-codec.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js +28 -8
- package/out/zero-cache/src/services/change-streamer/change-log-codec.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +5 -2
- 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 +21 -14
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts +11 -0
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js +97 -63
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +12 -8
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts +3 -3
- package/out/zero-cache/src/services/change-streamer/forwarder.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/forwarder.js +36 -5
- package/out/zero-cache/src/services/change-streamer/forwarder.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/schema/tables.js +4 -4
- package/out/zero-cache/src/services/change-streamer/schema/tables.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js +15 -3
- package/out/zero-cache/src/services/change-streamer/snapshot-reservations.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts +21 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/snapshot.js +61 -21
- package/out/zero-cache/src/services/change-streamer/snapshot.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts +6 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js +27 -9
- package/out/zero-cache/src/services/change-streamer/sqlite-change-log-writer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +2 -2
- package/out/zero-cache/src/services/change-streamer/storer.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/storer.js +8 -5
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts +4 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/subscriber.js +42 -0
- package/out/zero-cache/src/services/change-streamer/subscriber.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts +17 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js +19 -3
- package/out/zero-cache/src/services/change-streamer/upstream-acker.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js +1 -0
- package/out/zero-cache/src/services/change-streamer/vfs-watermark-poller.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +3 -1
- package/out/zero-cache/src/services/life-cycle.js.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 -1
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/litestream/config-v5.yml +3 -4
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js +51 -24
- package/out/zero-cache/src/services/litestream/litestream-checkpointer.js.map +1 -1
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts +24 -0
- package/out/zero-cache/src/services/litestream/restore-progress.d.ts.map +1 -0
- package/out/zero-cache/src/services/litestream/restore-progress.js +91 -0
- package/out/zero-cache/src/services/litestream/restore-progress.js.map +1 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts +5 -0
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +7 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +5 -6
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/profz.d.ts +7 -0
- package/out/zero-cache/src/services/profz.d.ts.map +1 -0
- package/out/zero-cache/src/services/profz.js +105 -0
- package/out/zero-cache/src/services/profz.js.map +1 -0
- 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.d.ts +5 -4
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js +20 -22
- package/out/zero-cache/src/services/replicator/change-log-stream-writer.js.map +1 -1
- package/out/zero-cache/src/services/replicator/change-processor.js +1 -0
- package/out/zero-cache/src/services/replicator/change-processor.js.map +1 -1
- package/out/zero-cache/src/services/replicator/incremental-sync.d.ts +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 +57 -17
- package/out/zero-cache/src/services/replicator/incremental-sync.js.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts +35 -1
- package/out/zero-cache/src/services/replicator/replication-status.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/replication-status.js +96 -6
- 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/sqlite-change-log-observability.d.ts +6 -6
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.d.ts.map +1 -1
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js +19 -14
- package/out/zero-cache/src/services/replicator/sqlite-change-log-observability.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.d.ts +4 -4
- 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 -2
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +10 -4
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts +12 -0
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +26 -14
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/runner.d.ts +2 -1
- package/out/zero-cache/src/services/runner.d.ts.map +1 -1
- package/out/zero-cache/src/services/runner.js +10 -2
- package/out/zero-cache/src/services/runner.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +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 +36 -31
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts +45 -0
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +133 -1
- 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 +14 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +30 -4
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts +33 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js +62 -0
- package/out/zero-cache/src/services/view-syncer/hydration-budget.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts +51 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js +78 -0
- package/out/zero-cache/src/services/view-syncer/hydration-circuit-breaker.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/inspect-handler.d.ts +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 +14 -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 +64 -30
- 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 +2 -6
- package/out/zero-cache/src/services/view-syncer/query-covering.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts +95 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.d.ts.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js +155 -0
- package/out/zero-cache/src/services/view-syncer/snapshot-row-cache.js.map +1 -0
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts +48 -4
- package/out/zero-cache/src/services/view-syncer/snapshotter.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +125 -28
- 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 +11 -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 +512 -98
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +39 -0
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js +43 -4
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/profiler.d.ts +12 -0
- package/out/zero-cache/src/types/profiler.d.ts.map +1 -1
- package/out/zero-cache/src/types/profiler.js +46 -1
- package/out/zero-cache/src/types/profiler.js.map +1 -1
- package/out/zero-cache/src/types/row-key.d.ts.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/types/streams.d.ts +25 -9
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +118 -34
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +4 -0
- package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
- package/out/zero-cache/src/types/subscription.js +71 -0
- package/out/zero-cache/src/types/subscription.js.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +18 -9
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/types/ws.d.ts.map +1 -1
- package/out/zero-cache/src/types/ws.js +23 -8
- package/out/zero-cache/src/types/ws.js.map +1 -1
- package/out/zero-cache/src/workers/connect-params.d.ts +1 -0
- package/out/zero-cache/src/workers/connect-params.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connect-params.js.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js +21 -16
- package/out/zero-cache/src/workers/syncer-ws-message-handler.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +55 -4
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +20 -0
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.js +77 -13
- package/out/zero-client/src/client/connection-manager.js.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.d.ts +2 -0
- package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.js +3 -1
- package/out/zero-client/src/client/connection-status-enum.js.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +6 -0
- package/out/zero-client/src/client/connection.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.js +2 -1
- package/out/zero-client/src/client/connection.js.map +1 -1
- package/out/zero-client/src/client/context.d.ts +27 -2
- package/out/zero-client/src/client/context.d.ts.map +1 -1
- package/out/zero-client/src/client/context.js +112 -1
- 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 +20 -3
- package/out/zero-client/src/client/ivm-branch.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 +2 -1
- package/out/zero-client/src/client/mutator-proxy.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +3 -0
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/options.js.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.js +44 -11
- 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 +1 -0
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.js +9 -6
- package/out/zero-client/src/client/zero-rep.js.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +18 -3
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +120 -32
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-client/src/types/query-result.d.ts +2 -0
- package/out/zero-client/src/types/query-result.d.ts.map +1 -1
- package/out/zero-events/src/status.d.ts +58 -0
- package/out/zero-events/src/status.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.d.ts.map +1 -1
- package/out/zero-protocol/src/ast.js +13 -14
- package/out/zero-protocol/src/ast.js.map +1 -1
- package/out/zero-protocol/src/poke.d.ts +6 -6
- package/out/zero-protocol/src/query-hash.d.ts.map +1 -1
- package/out/zero-protocol/src/query-hash.js +2 -5
- package/out/zero-protocol/src/query-hash.js.map +1 -1
- package/out/zero-react/src/use-query.d.ts +5 -4
- package/out/zero-react/src/use-query.d.ts.map +1 -1
- package/out/zero-react/src/use-query.js +86 -9
- package/out/zero-react/src/use-query.js.map +1 -1
- package/out/zero-server/src/adapters/drizzle.d.ts +2 -1
- package/out/zero-server/src/adapters/drizzle.d.ts.map +1 -1
- package/out/zero-server/src/adapters/drizzle.js +12 -7
- package/out/zero-server/src/adapters/drizzle.js.map +1 -1
- package/out/zero-server/src/adapters/kysely.d.ts +2 -1
- package/out/zero-server/src/adapters/kysely.d.ts.map +1 -1
- package/out/zero-server/src/adapters/kysely.js +8 -2
- package/out/zero-server/src/adapters/kysely.js.map +1 -1
- package/out/zero-server/src/adapters/pg.d.ts +1 -0
- package/out/zero-server/src/adapters/pg.d.ts.map +1 -1
- package/out/zero-server/src/adapters/pg.js +8 -2
- package/out/zero-server/src/adapters/pg.js.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.d.ts +1 -0
- package/out/zero-server/src/adapters/postgresjs.d.ts.map +1 -1
- package/out/zero-server/src/adapters/postgresjs.js +7 -1
- package/out/zero-server/src/adapters/postgresjs.js.map +1 -1
- package/out/zero-server/src/adapters/prisma.d.ts +3 -2
- package/out/zero-server/src/adapters/prisma.d.ts.map +1 -1
- package/out/zero-server/src/adapters/prisma.js +8 -2
- package/out/zero-server/src/adapters/prisma.js.map +1 -1
- package/out/zero-server/src/custom.d.ts +5 -1
- package/out/zero-server/src/custom.d.ts.map +1 -1
- package/out/zero-server/src/custom.js +6 -3
- package/out/zero-server/src/custom.js.map +1 -1
- package/out/zero-server/src/mod.d.ts +1 -1
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.d.ts +2 -2
- package/out/zero-server/src/pg-query-executor.d.ts.map +1 -1
- package/out/zero-server/src/pg-query-executor.js +2 -2
- package/out/zero-server/src/pg-query-executor.js.map +1 -1
- package/out/zero-server/src/schema.d.ts +2 -2
- package/out/zero-server/src/schema.d.ts.map +1 -1
- package/out/zero-server/src/schema.js +2 -2
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-server/src/zql-database.d.ts +21 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js +33 -2
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +17 -0
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +39 -1
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zero-solid/src/use-query.js +5 -3
- package/out/zero-solid/src/use-query.js.map +1 -1
- package/out/zql/src/builder/builder.d.ts +19 -0
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +38 -12
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts +43 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.d.ts.map +1 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.js +161 -0
- package/out/zql/src/builder/correlated-predicate-pushdown.js.map +1 -0
- package/out/zql/src/builder/debug-delegate.d.ts +6 -1
- package/out/zql/src/builder/debug-delegate.d.ts.map +1 -1
- package/out/zql/src/builder/debug-delegate.js +14 -2
- package/out/zql/src/builder/debug-delegate.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts +29 -0
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +63 -12
- 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 +10 -4
- package/out/zql/src/ivm/cap.js.map +1 -1
- package/out/zql/src/ivm/connection-index.d.ts +68 -0
- package/out/zql/src/ivm/connection-index.d.ts.map +1 -0
- package/out/zql/src/ivm/connection-index.js +149 -0
- package/out/zql/src/ivm/connection-index.js.map +1 -0
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js +8 -3
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/deferred-input.d.ts +44 -0
- package/out/zql/src/ivm/deferred-input.d.ts.map +1 -0
- package/out/zql/src/ivm/deferred-input.js +89 -0
- package/out/zql/src/ivm/deferred-input.js.map +1 -0
- 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 +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 +6 -5
- 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 -6
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js +10 -8
- 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 +7 -4
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts +6 -4
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +20 -33
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join-utils.d.ts +10 -0
- package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
- package/out/zql/src/ivm/join-utils.js +23 -1
- package/out/zql/src/ivm/join-utils.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts +5 -1
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +91 -13
- package/out/zql/src/ivm/join.js.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.d.ts.map +1 -1
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js +6 -4
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +15 -3
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +40 -19
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/take-gate.d.ts +35 -0
- package/out/zql/src/ivm/take-gate.d.ts.map +1 -0
- package/out/zql/src/ivm/take-gate.js +81 -0
- package/out/zql/src/ivm/take-gate.js.map +1 -0
- package/out/zql/src/ivm/take.d.ts +6 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +104 -88
- 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 +9 -7
- 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 +9 -4
- package/out/zql/src/ivm/view-apply-change.js.map +1 -1
- package/out/zql/src/ivm/view.d.ts +15 -0
- package/out/zql/src/ivm/view.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.d.ts +24 -1
- package/out/zql/src/mutate/custom.d.ts.map +1 -1
- package/out/zql/src/mutate/custom.js.map +1 -1
- package/out/zql/src/mutate/mutator-registry.d.ts.map +1 -1
- package/out/zql/src/mutate/mutator-registry.js +2 -2
- package/out/zql/src/mutate/mutator-registry.js.map +1 -1
- package/out/zql/src/planner/planner-builder.d.ts +12 -3
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -1
- package/out/zql/src/planner/planner-builder.js +27 -17
- package/out/zql/src/planner/planner-builder.js.map +1 -1
- package/out/zql/src/planner/planner-connection.d.ts +15 -2
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -1
- package/out/zql/src/planner/planner-connection.js +73 -8
- package/out/zql/src/planner/planner-connection.js.map +1 -1
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js +3 -8
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-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 +9 -1
- package/out/zql/src/query/query-delegate-base.d.ts.map +1 -1
- package/out/zql/src/query/query-delegate-base.js +129 -33
- package/out/zql/src/query/query-delegate-base.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +50 -1
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +13 -11
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js +366 -60
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query-transitions.d.ts +171 -0
- package/out/zql/src/query/query-transitions.d.ts.map +1 -0
- package/out/zql/src/query/query-transitions.js +204 -0
- package/out/zql/src/query/query-transitions.js.map +1 -0
- package/out/zql/src/query/query.d.ts +11 -2
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.d.ts +1 -0
- package/out/zql/src/query/runnable-query-impl.d.ts.map +1 -1
- package/out/zql/src/query/runnable-query-impl.js +13 -1
- 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 +9 -1
- package/out/zqlite/src/db.d.ts.map +1 -1
- package/out/zqlite/src/db.js +8 -2
- package/out/zqlite/src/db.js.map +1 -1
- package/out/zqlite/src/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-delegate.js +5 -6
- package/out/zqlite/src/query-delegate.js.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.d.ts.map +1 -1
- package/out/zqlite/src/sqlite-stat-fanout.js +3 -5
- package/out/zqlite/src/sqlite-stat-fanout.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts +15 -2
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +21 -10
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +3 -4
package/out/z2s/src/sql.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assert, unreachable } from "../../shared/src/asserts.js";
|
|
2
|
+
import { getOrInsertComputed } from "../../shared/src/map.js";
|
|
2
3
|
import { isPgNativeStringType, isPgNumberType, isPgStringType, isPgTextRepresentedType } from "../../zero-cache/src/types/pg-data-type.js";
|
|
3
4
|
import { escapePostgresIdentifier } from "@databases/escape-identifier";
|
|
4
5
|
import sql, { SQLItemType } from "@databases/sql";
|
|
@@ -160,8 +161,7 @@ function formatFn(items, { escapeIdentifier, formatValue }) {
|
|
|
160
161
|
const names = item.names.length === 1 && typeof item.names[0] === "string" && item.names[0].includes(".") ? item.names[0].split(".") : item.names;
|
|
161
162
|
text += names.map((name) => {
|
|
162
163
|
if (typeof name === "string") return escapeIdentifier(name);
|
|
163
|
-
|
|
164
|
-
return escapeIdentifier(localIdentifiers.get(name));
|
|
164
|
+
return escapeIdentifier(getOrInsertComputed(localIdentifiers, name, () => `__local_${localIdentifiers.size}__`));
|
|
165
165
|
}).join(".");
|
|
166
166
|
break;
|
|
167
167
|
}
|
package/out/z2s/src/sql.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql.js","names":["#seen","#size"],"sources":["../../../../z2s/src/sql.ts"],"sourcesContent":["import {\n escapePostgresIdentifier,\n escapeSQLiteIdentifier,\n} from '@databases/escape-identifier';\nimport type {FormatConfig, SQLItem, SQLQuery} from '@databases/sql';\nimport sql, {SQLItemType} from '@databases/sql';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {\n isPgNativeStringType,\n isPgNumberType,\n isPgStringType,\n isPgTextRepresentedType,\n} from '../../zero-cache/src/types/pg-data-type.ts';\nimport type {LiteralValue} from '../../zero-protocol/src/ast.ts';\nimport type {ServerColumnSchema} from '../../zero-types/src/server-schema.ts';\n\nexport function formatPg(sql: SQLQuery) {\n const format = new ReusingFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatPgInternalConvert(sql: SQLQuery) {\n const format = new SQLConvertFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatSqlite(sql: SQLQuery) {\n const format = new ReusingFormat(escapeSQLiteIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nconst sqlConvert = Symbol('fromJson');\n\nexport type LiteralType = 'boolean' | 'number' | 'string' | 'null';\nexport type PluralLiteralType = Exclude<LiteralType, 'null'>;\n\ntype ColumnSqlConvertArg = {\n [sqlConvert]: 'column';\n type: string;\n value: unknown;\n plural: boolean;\n isEnum: boolean;\n isComparison: boolean;\n};\n\ntype SqlConvertArg =\n | ColumnSqlConvertArg\n | {\n [sqlConvert]: 'literal';\n type: LiteralType;\n value: LiteralValue;\n plural: boolean;\n };\n\nfunction isSqlConvert(value: unknown): value is SqlConvertArg {\n return value !== null && typeof value === 'object' && sqlConvert in value;\n}\n\nexport function sqlConvertSingularLiteralArg(\n value: string | boolean | number | null,\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type: value === null ? 'null' : (typeof value as LiteralType),\n value,\n plural: false,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertPluralLiteralArg(\n type: PluralLiteralType,\n value: PluralLiteralType[],\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type,\n value,\n plural: true,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertColumnArg(\n serverColumnSchema: ServerColumnSchema,\n value: unknown,\n plural: boolean,\n isComparison: boolean,\n): SQLQuery {\n return sql.value({\n [sqlConvert]: 'column',\n type: serverColumnSchema.type,\n isEnum: serverColumnSchema.isEnum,\n value,\n plural: plural || serverColumnSchema.isArray,\n isComparison,\n });\n}\n\nclass ReusingFormat implements FormatConfig {\n readonly #seen: Map<unknown, number> = new Map();\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n if (this.#seen.has(value)) {\n return {\n placeholder: `$${this.#seen.get(value)}`,\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#seen.set(value, this.#seen.size + 1);\n return {placeholder: `$${this.#seen.size}`, value};\n };\n}\n\nfunction stringify(arg: SqlConvertArg): string | null {\n if (arg.value === null) {\n return null;\n }\n if (arg.plural) {\n return JSON.stringify(arg.value);\n }\n if (arg[sqlConvert] === 'literal' && arg.type === 'string') {\n return arg.value as unknown as string;\n }\n if (\n arg[sqlConvert] === 'column' &&\n (arg.isEnum || isPgStringType(arg.type))\n ) {\n return arg.value as string;\n }\n return JSON.stringify(arg.value);\n}\n\nclass SQLConvertFormat implements FormatConfig {\n readonly #seen: Map<unknown, Map<string, number>> = new Map();\n #size = 0;\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n assert(isSqlConvert(value), 'JsonPackedFormat can only take JsonPackArgs.');\n const byType = this.#seen.get(value.value);\n if (byType?.has(value.type)) {\n return {\n placeholder: createPlaceholder(byType.get(value.type)!, value),\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#size++;\n if (byType) {\n byType.set(value.type, this.#size);\n } else {\n this.#seen.set(value.value, new Map([[value.type, this.#size]]));\n }\n return {\n placeholder: createPlaceholder(this.#size, value),\n value: stringify(value),\n };\n };\n}\n\nfunction createPlaceholder(index: number, arg: SqlConvertArg) {\n if (arg.type === 'null') {\n assert(arg.value === null, \"Args of type 'null' must have value null\");\n assert(!arg.plural, \"Args of type 'null' must not be plural\");\n return `$${index}`;\n }\n\n if (arg.value === null && arg.plural) {\n return `$${index}`;\n }\n\n if (arg[sqlConvert] === 'literal') {\n const {value} = arg;\n if (Array.isArray(value)) {\n const elType = pgTypeForLiteralType(arg.type);\n return formatPlural(index, `value::${elType}`);\n }\n return `$${index}::text::${pgTypeForLiteralType(arg.type)}`;\n }\n\n const common = formatCommonToSingularAndPlural(index, arg);\n return arg.plural ? formatPlural(index, common) : common;\n}\n\nfunction formatCommonToSingularAndPlural(\n index: number,\n arg: ColumnSqlConvertArg,\n) {\n // Ok, so what is with all the `::text` casts\n // before the final cast?\n // This is to force the statement to describe its arguments\n // as being text. Without the text cast the args are described as\n // being bool/json/numeric/whatever and the bindings try to coerce\n // the inputs to those types.\n const valuePlaceholder = arg.plural ? 'value' : `$${index}`;\n let atTimeZone = ` AT TIME ZONE 'UTC'`;\n switch (arg.type) {\n case 'timestamptz':\n // @ts-expect-error Fallthrough intended\n case 'timestamp with time zone':\n atTimeZone = '';\n // fallthrough\n\n case 'date':\n case 'timestamp':\n case 'timestamp without time zone':\n return `to_timestamp(${valuePlaceholder}::text::numeric / 1000.0)${atTimeZone}`;\n\n case 'timetz':\n // @ts-expect-error Fallthrough intended\n case 'time with time zone':\n atTimeZone = '';\n // fallthrough\n\n case 'time':\n case 'time without time zone':\n return `(${valuePlaceholder}::text::int * interval'1ms')::time${atTimeZone}`;\n\n // uuid: cast to native uuid type for proper comparison and index usage\n case 'uuid':\n return `${valuePlaceholder}::text::uuid`;\n }\n if (arg.isEnum) {\n return `${valuePlaceholder}::text::\"${arg.type}\"`;\n }\n if (isPgNativeStringType(arg.type)) {\n // For comparison cast to the general `text` type, not the\n // specific column type (i.e. `arg.type`), because we don't want to\n // force the value being compared to the size/max-size of the column\n // type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n if (isPgTextRepresentedType(arg.type)) {\n return `${valuePlaceholder}::text::${arg.type}`;\n }\n if (isPgNumberType(arg.type)) {\n // For comparison cast to `double precision` which uses IEEE 754 (the same\n // representation as JavaScript numbers which will accurately\n // represent any number value from zql) not the specific column type\n // (i.e. `arg.type`), because we don't want to force the value being\n // compared to the range and precision of the column type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text::double precision`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n return `${valuePlaceholder}::text::${arg.type}`;\n}\n\nfunction formatPlural(index: number, select: string) {\n return `ARRAY(\n SELECT ${select} FROM jsonb_array_elements_text($${index}::text::jsonb)\n )`;\n}\n\nfunction pgTypeForLiteralType(type: Exclude<LiteralType, 'null'>) {\n switch (type) {\n case 'boolean':\n return 'boolean';\n case 'number':\n // `double precision` uses IEEE 754, the same representation as JavaScript\n // numbers, and so this will accurately represent any number value\n // from zql\n return 'double precision';\n case 'string':\n return 'text';\n default:\n unreachable(type);\n }\n}\n\nexport {sql};\n\nconst PREVIOUSLY_SEEN_VALUE = Symbol('PREVIOUSLY_SEEN_VALUE');\n\nconst whitespacePrefixRe = /^\\s*/;\n\nfunction formatFn(\n items: readonly SQLItem[],\n {escapeIdentifier, formatValue}: FormatConfig,\n): {\n text: string;\n values: unknown[];\n} {\n // Create an empty query object.\n let text = '';\n const values = [];\n\n const localIdentifiers = new Map<unknown, string>();\n\n for (const item of items) {\n switch (item.type) {\n // If this is just raw text, we add it directly to the query text.\n case SQLItemType.RAW: {\n text += item.text;\n break;\n }\n\n // If we got a value SQL item, add a placeholder and add the value to our\n // placeholder values array.\n case SQLItemType.VALUE: {\n const {placeholder, value} = formatValue(item.value, values.length);\n text += placeholder;\n if (value !== PREVIOUSLY_SEEN_VALUE) {\n values.push(value);\n }\n\n break;\n }\n\n // If we got an identifier type, escape the strings and get a local\n // identifier for non-string identifiers.\n case SQLItemType.IDENTIFIER: {\n // This is a specific addition for Zero as Zero\n // does not support dots in identifiers.\n // If a dot is found, we assume it is a namespace\n // and split the identifier into its parts.\n const names =\n item.names.length === 1 &&\n typeof item.names[0] === 'string' &&\n item.names[0].includes('.')\n ? item.names[0].split('.')\n : item.names;\n\n text += names\n .map((name): string => {\n if (typeof name === 'string') return escapeIdentifier(name);\n\n if (!localIdentifiers.has(name)) {\n localIdentifiers.set(name, `__local_${localIdentifiers.size}__`);\n }\n\n return escapeIdentifier(localIdentifiers.get(name)!);\n })\n .join('.');\n break;\n }\n }\n }\n\n if (text.trim()) {\n const lines = text.split('\\n');\n const min = Math.min(\n ...lines\n .filter(l => l.trim() !== '')\n .map(l => whitespacePrefixRe.exec(l)![0].length),\n );\n if (min) {\n text = lines.map(line => line.substr(min)).join('\\n');\n }\n }\n return {\n text: text.trim(),\n values,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sql.js","names":["#seen","#size"],"sources":["../../../../z2s/src/sql.ts"],"sourcesContent":["import {\n escapePostgresIdentifier,\n escapeSQLiteIdentifier,\n} from '@databases/escape-identifier';\nimport type {FormatConfig, SQLItem, SQLQuery} from '@databases/sql';\nimport sql, {SQLItemType} from '@databases/sql';\nimport {assert, unreachable} from '../../shared/src/asserts.ts';\nimport {getOrInsertComputed} from '../../shared/src/map.ts';\nimport {\n isPgNativeStringType,\n isPgNumberType,\n isPgStringType,\n isPgTextRepresentedType,\n} from '../../zero-cache/src/types/pg-data-type.ts';\nimport type {LiteralValue} from '../../zero-protocol/src/ast.ts';\nimport type {ServerColumnSchema} from '../../zero-types/src/server-schema.ts';\n\nexport function formatPg(sql: SQLQuery) {\n const format = new ReusingFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatPgInternalConvert(sql: SQLQuery) {\n const format = new SQLConvertFormat(escapePostgresIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nexport function formatSqlite(sql: SQLQuery) {\n const format = new ReusingFormat(escapeSQLiteIdentifier);\n return sql.format((items: readonly SQLItem[]) => formatFn(items, format));\n}\n\nconst sqlConvert = Symbol('fromJson');\n\nexport type LiteralType = 'boolean' | 'number' | 'string' | 'null';\nexport type PluralLiteralType = Exclude<LiteralType, 'null'>;\n\ntype ColumnSqlConvertArg = {\n [sqlConvert]: 'column';\n type: string;\n value: unknown;\n plural: boolean;\n isEnum: boolean;\n isComparison: boolean;\n};\n\ntype SqlConvertArg =\n | ColumnSqlConvertArg\n | {\n [sqlConvert]: 'literal';\n type: LiteralType;\n value: LiteralValue;\n plural: boolean;\n };\n\nfunction isSqlConvert(value: unknown): value is SqlConvertArg {\n return value !== null && typeof value === 'object' && sqlConvert in value;\n}\n\nexport function sqlConvertSingularLiteralArg(\n value: string | boolean | number | null,\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type: value === null ? 'null' : (typeof value as LiteralType),\n value,\n plural: false,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertPluralLiteralArg(\n type: PluralLiteralType,\n value: PluralLiteralType[],\n): SQLQuery {\n const arg: SqlConvertArg = {\n [sqlConvert]: 'literal',\n type,\n value,\n plural: true,\n };\n return sql.value(arg);\n}\n\nexport function sqlConvertColumnArg(\n serverColumnSchema: ServerColumnSchema,\n value: unknown,\n plural: boolean,\n isComparison: boolean,\n): SQLQuery {\n return sql.value({\n [sqlConvert]: 'column',\n type: serverColumnSchema.type,\n isEnum: serverColumnSchema.isEnum,\n value,\n plural: plural || serverColumnSchema.isArray,\n isComparison,\n });\n}\n\nclass ReusingFormat implements FormatConfig {\n readonly #seen: Map<unknown, number> = new Map();\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n if (this.#seen.has(value)) {\n return {\n placeholder: `$${this.#seen.get(value)}`,\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#seen.set(value, this.#seen.size + 1);\n return {placeholder: `$${this.#seen.size}`, value};\n };\n}\n\nfunction stringify(arg: SqlConvertArg): string | null {\n if (arg.value === null) {\n return null;\n }\n if (arg.plural) {\n return JSON.stringify(arg.value);\n }\n if (arg[sqlConvert] === 'literal' && arg.type === 'string') {\n return arg.value as unknown as string;\n }\n if (\n arg[sqlConvert] === 'column' &&\n (arg.isEnum || isPgStringType(arg.type))\n ) {\n return arg.value as string;\n }\n return JSON.stringify(arg.value);\n}\n\nclass SQLConvertFormat implements FormatConfig {\n readonly #seen: Map<unknown, Map<string, number>> = new Map();\n #size = 0;\n readonly escapeIdentifier: (str: string) => string;\n\n constructor(escapeIdentifier: (str: string) => string) {\n this.escapeIdentifier = escapeIdentifier;\n }\n\n formatValue = (value: unknown) => {\n assert(isSqlConvert(value), 'JsonPackedFormat can only take JsonPackArgs.');\n const byType = this.#seen.get(value.value);\n if (byType?.has(value.type)) {\n return {\n placeholder: createPlaceholder(byType.get(value.type)!, value),\n value: PREVIOUSLY_SEEN_VALUE,\n };\n }\n this.#size++;\n if (byType) {\n byType.set(value.type, this.#size);\n } else {\n this.#seen.set(value.value, new Map([[value.type, this.#size]]));\n }\n return {\n placeholder: createPlaceholder(this.#size, value),\n value: stringify(value),\n };\n };\n}\n\nfunction createPlaceholder(index: number, arg: SqlConvertArg) {\n if (arg.type === 'null') {\n assert(arg.value === null, \"Args of type 'null' must have value null\");\n assert(!arg.plural, \"Args of type 'null' must not be plural\");\n return `$${index}`;\n }\n\n if (arg.value === null && arg.plural) {\n return `$${index}`;\n }\n\n if (arg[sqlConvert] === 'literal') {\n const {value} = arg;\n if (Array.isArray(value)) {\n const elType = pgTypeForLiteralType(arg.type);\n return formatPlural(index, `value::${elType}`);\n }\n return `$${index}::text::${pgTypeForLiteralType(arg.type)}`;\n }\n\n const common = formatCommonToSingularAndPlural(index, arg);\n return arg.plural ? formatPlural(index, common) : common;\n}\n\nfunction formatCommonToSingularAndPlural(\n index: number,\n arg: ColumnSqlConvertArg,\n) {\n // Ok, so what is with all the `::text` casts\n // before the final cast?\n // This is to force the statement to describe its arguments\n // as being text. Without the text cast the args are described as\n // being bool/json/numeric/whatever and the bindings try to coerce\n // the inputs to those types.\n const valuePlaceholder = arg.plural ? 'value' : `$${index}`;\n let atTimeZone = ` AT TIME ZONE 'UTC'`;\n switch (arg.type) {\n case 'timestamptz':\n // @ts-expect-error Fallthrough intended\n case 'timestamp with time zone':\n atTimeZone = '';\n // fallthrough\n\n case 'date':\n case 'timestamp':\n case 'timestamp without time zone':\n return `to_timestamp(${valuePlaceholder}::text::numeric / 1000.0)${atTimeZone}`;\n\n case 'timetz':\n // @ts-expect-error Fallthrough intended\n case 'time with time zone':\n atTimeZone = '';\n // fallthrough\n\n case 'time':\n case 'time without time zone':\n return `(${valuePlaceholder}::text::int * interval'1ms')::time${atTimeZone}`;\n\n // uuid: cast to native uuid type for proper comparison and index usage\n case 'uuid':\n return `${valuePlaceholder}::text::uuid`;\n }\n if (arg.isEnum) {\n return `${valuePlaceholder}::text::\"${arg.type}\"`;\n }\n if (isPgNativeStringType(arg.type)) {\n // For comparison cast to the general `text` type, not the\n // specific column type (i.e. `arg.type`), because we don't want to\n // force the value being compared to the size/max-size of the column\n // type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n if (isPgTextRepresentedType(arg.type)) {\n return `${valuePlaceholder}::text::${arg.type}`;\n }\n if (isPgNumberType(arg.type)) {\n // For comparison cast to `double precision` which uses IEEE 754 (the same\n // representation as JavaScript numbers which will accurately\n // represent any number value from zql) not the specific column type\n // (i.e. `arg.type`), because we don't want to force the value being\n // compared to the range and precision of the column type before comparison.\n return arg.isComparison\n ? `${valuePlaceholder}::text::double precision`\n : `${valuePlaceholder}::text::${arg.type}`;\n }\n return `${valuePlaceholder}::text::${arg.type}`;\n}\n\nfunction formatPlural(index: number, select: string) {\n return `ARRAY(\n SELECT ${select} FROM jsonb_array_elements_text($${index}::text::jsonb)\n )`;\n}\n\nfunction pgTypeForLiteralType(type: Exclude<LiteralType, 'null'>) {\n switch (type) {\n case 'boolean':\n return 'boolean';\n case 'number':\n // `double precision` uses IEEE 754, the same representation as JavaScript\n // numbers, and so this will accurately represent any number value\n // from zql\n return 'double precision';\n case 'string':\n return 'text';\n default:\n unreachable(type);\n }\n}\n\nexport {sql};\n\nconst PREVIOUSLY_SEEN_VALUE = Symbol('PREVIOUSLY_SEEN_VALUE');\n\nconst whitespacePrefixRe = /^\\s*/;\n\nfunction formatFn(\n items: readonly SQLItem[],\n {escapeIdentifier, formatValue}: FormatConfig,\n): {\n text: string;\n values: unknown[];\n} {\n // Create an empty query object.\n let text = '';\n const values = [];\n\n const localIdentifiers = new Map<unknown, string>();\n\n for (const item of items) {\n switch (item.type) {\n // If this is just raw text, we add it directly to the query text.\n case SQLItemType.RAW: {\n text += item.text;\n break;\n }\n\n // If we got a value SQL item, add a placeholder and add the value to our\n // placeholder values array.\n case SQLItemType.VALUE: {\n const {placeholder, value} = formatValue(item.value, values.length);\n text += placeholder;\n if (value !== PREVIOUSLY_SEEN_VALUE) {\n values.push(value);\n }\n\n break;\n }\n\n // If we got an identifier type, escape the strings and get a local\n // identifier for non-string identifiers.\n case SQLItemType.IDENTIFIER: {\n // This is a specific addition for Zero as Zero\n // does not support dots in identifiers.\n // If a dot is found, we assume it is a namespace\n // and split the identifier into its parts.\n const names =\n item.names.length === 1 &&\n typeof item.names[0] === 'string' &&\n item.names[0].includes('.')\n ? item.names[0].split('.')\n : item.names;\n\n text += names\n .map((name): string => {\n if (typeof name === 'string') return escapeIdentifier(name);\n\n return escapeIdentifier(\n getOrInsertComputed(\n localIdentifiers,\n name,\n () => `__local_${localIdentifiers.size}__`,\n ),\n );\n })\n .join('.');\n break;\n }\n }\n }\n\n if (text.trim()) {\n const lines = text.split('\\n');\n const min = Math.min(\n ...lines\n .filter(l => l.trim() !== '')\n .map(l => whitespacePrefixRe.exec(l)![0].length),\n );\n if (min) {\n text = lines.map(line => line.substr(min)).join('\\n');\n }\n }\n return {\n text: text.trim(),\n values,\n };\n}\n"],"mappings":"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"}
|
package/out/zero/package.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var package_default = {
|
|
2
2
|
name: "@rocicorp/zero",
|
|
3
|
-
version: "1.11.0-canary.
|
|
3
|
+
version: "1.11.0-canary.11",
|
|
4
4
|
description: "Zero is a web framework for serverless web development.",
|
|
5
5
|
homepage: "https://zero.rocicorp.dev",
|
|
6
6
|
bugs: { "url": "https://bugs.rocicorp.dev" },
|
|
@@ -146,7 +146,7 @@ var package_default = {
|
|
|
146
146
|
"cloudevents": "^10.0.0",
|
|
147
147
|
"command-line-args": "^6.0.1",
|
|
148
148
|
"command-line-usage": "^7.0.3",
|
|
149
|
-
"compare-utf8": "^0.2.
|
|
149
|
+
"compare-utf8": "^0.2.3",
|
|
150
150
|
"defu": "^6.1.4",
|
|
151
151
|
"eventemitter3": "^5.0.1",
|
|
152
152
|
"fastify": "^5.0.0",
|
|
@@ -166,7 +166,6 @@ var package_default = {
|
|
|
166
166
|
},
|
|
167
167
|
devDependencies: {
|
|
168
168
|
"@op-engineering/op-sqlite": ">=15",
|
|
169
|
-
"@vitest/runner": "^4.1.6",
|
|
170
169
|
"analyze-query": "workspace:*",
|
|
171
170
|
"ast-to-zql": "workspace:*",
|
|
172
171
|
"expo-sqlite": ">=15",
|
|
@@ -177,7 +176,7 @@ var package_default = {
|
|
|
177
176
|
"typedoc": "^0.28.17",
|
|
178
177
|
"typescript": "~7.0.2",
|
|
179
178
|
"vite": "^8.0.13",
|
|
180
|
-
"vitest": "^
|
|
179
|
+
"vitest": "^5.0.0",
|
|
181
180
|
"zero-cache": "workspace:*",
|
|
182
181
|
"zero-client": "workspace:*",
|
|
183
182
|
"zero-pg": "workspace:*",
|
package/out/zero/package.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.11.0-canary.
|
|
1
|
+
{"version":3,"file":"package.js","names":[],"sources":["../../package.json"],"sourcesContent":["{\n \"name\": \"@rocicorp/zero\",\n \"version\": \"1.11.0-canary.11\",\n \"description\": \"Zero is a web framework for serverless web development.\",\n \"homepage\": \"https://zero.rocicorp.dev\",\n \"bugs\": {\n \"url\": \"https://bugs.rocicorp.dev\"\n },\n \"license\": \"Apache-2.0\",\n \"author\": \"Rocicorp, Inc.\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/rocicorp/mono.git\",\n \"directory\": \"packages/zero\"\n },\n \"bin\": {\n \"analyze-query\": \"./out/zero/src/analyze-query.js\",\n \"ast-to-zql\": \"./out/zero/src/ast-to-zql.js\",\n \"transform-query\": \"./out/zero/src/transform-query.js\",\n \"zero-build-schema\": \"./out/zero/src/build-schema.js\",\n \"zero-cache\": \"./out/zero/src/cli.js\",\n \"zero-cache-dev\": \"./out/zero/src/zero-cache-dev.js\",\n \"zero-deploy-permissions\": \"./out/zero/src/deploy-permissions.js\",\n \"zero-out\": \"./out/zero/src/zero-out.js\"\n },\n \"files\": [\n \"out\",\n \"!*.tsbuildinfo\"\n ],\n \"type\": \"module\",\n \"main\": \"out/zero/src/zero.js\",\n \"module\": \"out/zero/src/zero.js\",\n \"types\": \"out/zero/src/zero.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./out/zero/src/zero.d.ts\",\n \"default\": \"./out/zero/src/zero.js\"\n },\n \"./analyze\": {\n \"types\": \"./out/zero/src/analyze.d.ts\",\n \"default\": \"./out/zero/src/analyze.js\"\n },\n \"./bindings\": {\n \"types\": \"./out/zero/src/bindings.d.ts\",\n \"default\": \"./out/zero/src/bindings.js\"\n },\n \"./change-protocol/v0\": {\n \"types\": \"./out/zero/src/change-protocol/v0.d.ts\",\n \"default\": \"./out/zero/src/change-protocol/v0.js\"\n },\n \"./expo-sqlite\": {\n \"types\": \"./out/zero/src/expo-sqlite.d.ts\",\n \"default\": \"./out/zero/src/expo-sqlite.js\"\n },\n \"./op-sqlite\": {\n \"types\": \"./out/zero/src/op-sqlite.d.ts\",\n \"default\": \"./out/zero/src/op-sqlite.js\"\n },\n \"./pg\": {\n \"types\": \"./out/zero/src/pg.d.ts\",\n \"default\": \"./out/zero/src/pg.js\"\n },\n \"./react\": {\n \"types\": \"./out/zero/src/react.d.ts\",\n \"default\": \"./out/zero/src/react.js\"\n },\n \"./react-native\": {\n \"types\": \"./out/zero/src/react-native.d.ts\",\n \"default\": \"./out/zero/src/react-native.js\"\n },\n \"./server\": {\n \"types\": \"./out/zero/src/server.d.ts\",\n \"default\": \"./out/zero/src/server.js\"\n },\n \"./server/adapters/drizzle\": {\n \"types\": \"./out/zero/src/adapters/drizzle.d.ts\",\n \"default\": \"./out/zero/src/adapters/drizzle.js\"\n },\n \"./server/adapters/kysely\": {\n \"types\": \"./out/zero/src/adapters/kysely.d.ts\",\n \"default\": \"./out/zero/src/adapters/kysely.js\"\n },\n \"./server/adapters/prisma\": {\n \"types\": \"./out/zero/src/adapters/prisma.d.ts\",\n \"default\": \"./out/zero/src/adapters/prisma.js\"\n },\n \"./server/adapters/pg\": {\n \"types\": \"./out/zero/src/adapters/pg.d.ts\",\n \"default\": \"./out/zero/src/adapters/pg.js\"\n },\n \"./server/adapters/postgresjs\": {\n \"types\": \"./out/zero/src/adapters/postgresjs.d.ts\",\n \"default\": \"./out/zero/src/adapters/postgresjs.js\"\n },\n \"./solid\": {\n \"types\": \"./out/zero/src/solid.d.ts\",\n \"default\": \"./out/zero/src/solid.js\"\n },\n \"./sqlite\": {\n \"types\": \"./out/zero/src/sqlite.d.ts\",\n \"default\": \"./out/zero/src/sqlite.js\"\n },\n \"./zqlite\": {\n \"types\": \"./out/zero/src/zqlite.d.ts\",\n \"default\": \"./out/zero/src/zqlite.js\"\n }\n },\n \"scripts\": {\n \"build\": \"node --experimental-strip-types --no-warnings tool/build.ts\",\n \"build:watch\": \"node --experimental-strip-types --no-warnings tool/build.ts --watch\",\n \"check-types\": \"tsc -p tsconfig.client.json && tsc -p tsconfig.server.json\",\n \"check-types:client:watch\": \"tsc -p tsconfig.client.json --watch\",\n \"check-types:server:watch\": \"tsc -p tsconfig.server.json --watch\",\n \"format\": \"oxfmt .\",\n \"check-format\": \"oxfmt --check .\",\n \"lint\": \"oxlint --quiet --config ../../oxlint.config.ts src/\",\n \"docs\": \"node --experimental-strip-types --no-warnings tool/generate-docs.ts\",\n \"docs:server\": \"node --watch --experimental-strip-types --no-warnings tool/generate-docs.ts --server\",\n \"fmt\": \"oxfmt .\",\n \"check-fmt\": \"oxfmt --check .\"\n },\n \"dependencies\": {\n \"@badrap/valita\": \"0.3.11\",\n \"@databases/escape-identifier\": \"^1.0.3\",\n \"@databases/sql\": \"^3.3.0\",\n \"@dotenvx/dotenvx\": \"^1.39.0\",\n \"@drdgvhbh/postgres-error-codes\": \"^0.0.6\",\n \"@fastify/cors\": \"^10.0.0\",\n \"@fastify/websocket\": \"^11.0.0\",\n \"@google-cloud/precise-date\": \"^4.0.0\",\n \"@opentelemetry/api\": \"^1.9.0\",\n \"@opentelemetry/api-logs\": \"^0.218.0\",\n \"@opentelemetry/auto-instrumentations-node\": \"^0.76.0\",\n \"@opentelemetry/exporter-metrics-otlp-http\": \"^0.218.0\",\n \"@opentelemetry/resources\": \"^2.7.1\",\n \"@opentelemetry/sdk-metrics\": \"^2.7.1\",\n \"@opentelemetry/sdk-node\": \"^0.218.0\",\n \"@opentelemetry/sdk-trace-node\": \"^2.7.1\",\n \"@opentelemetry/semantic-conventions\": \"^1.41.1\",\n \"@postgresql-typed/oids\": \"^0.2.0\",\n \"@rocicorp/lock\": \"^1.0.4\",\n \"@rocicorp/logger\": \"^6.1.0\",\n \"@rocicorp/resolver\": \"^1.0.2\",\n \"@rocicorp/zero-sqlite3\": \"^1.1.4\",\n \"@standard-schema/spec\": \"^1.0.0\",\n \"@types/basic-auth\": \"^1.1.8\",\n \"@types/ws\": \"^8.5.12\",\n \"basic-auth\": \"^2.0.1\",\n \"chalk-template\": \"^1.1.0\",\n \"chokidar\": \"^4.0.1\",\n \"cloudevents\": \"^10.0.0\",\n \"command-line-args\": \"^6.0.1\",\n \"command-line-usage\": \"^7.0.3\",\n \"compare-utf8\": \"^0.2.3\",\n \"defu\": \"^6.1.4\",\n \"eventemitter3\": \"^5.0.1\",\n \"fastify\": \"^5.0.0\",\n \"is-in-subnet\": \"^4.0.1\",\n \"jose\": \"^5.9.3\",\n \"json-custom-numbers\": \"^3.1.1\",\n \"kasi\": \"^1.1.0\",\n \"nanoid\": \"^5.1.2\",\n \"oxfmt\": \"^0.65.0\",\n \"parse-prometheus-text-format\": \"^1.1.1\",\n \"pg-format\": \"npm:pg-format-fix@^1.0.5\",\n \"postgres\": \"3.4.7\",\n \"semver\": \"^7.5.4\",\n \"url-pattern\": \"^1.0.3\",\n \"urlpattern-polyfill\": \"^10.1.0\",\n \"ws\": \"^8.18.1\"\n },\n \"devDependencies\": {\n \"@op-engineering/op-sqlite\": \">=15\",\n \"analyze-query\": \"workspace:*\",\n \"ast-to-zql\": \"workspace:*\",\n \"expo-sqlite\": \">=15\",\n \"oxc-parser\": \"^0.129.0\",\n \"replicache\": \"workspace:*\",\n \"shared\": \"workspace:*\",\n \"syncpack\": \"^14.3.0\",\n \"typedoc\": \"^0.28.17\",\n \"typescript\": \"~7.0.2\",\n \"vite\": \"^8.0.13\",\n \"vitest\": \"^5.0.0\",\n \"zero-cache\": \"workspace:*\",\n \"zero-client\": \"workspace:*\",\n \"zero-pg\": \"workspace:*\",\n \"zero-react\": \"workspace:*\",\n \"zero-server\": \"workspace:*\",\n \"zero-solid\": \"workspace:*\",\n \"zqlite\": \"workspace:*\"\n },\n \"engines\": {\n \"node\": \">=22\"\n },\n \"packageManager\": \"pnpm@11.11.0\"\n}\n"],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-authorizer.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/write-authorizer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,MAAM,CAAC;AAMrC,OAAO,KAAK,EACV,MAAM,EAIN,QAAQ,EACT,MAAM,wCAAwC,CAAC;AAsBhD,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAC;AAMxD,OAAO,KAAK,EAAY,UAAU,EAAC,MAAM,0BAA0B,CAAC;AAapE,MAAM,WAAW,eAAe;IAC9B,cAAc,CACZ,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,eAAe,CACb,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,iBAAiB,IAAI,IAAI,CAAC;IAC1B,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;IAEzD;;;OAGG;IACH,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACzC;AAED,qBAAa,mBAAoB,YAAW,eAAe;;IAezD,YACE,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"write-authorizer.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/auth/write-authorizer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,MAAM,CAAC;AAMrC,OAAO,KAAK,EACV,MAAM,EAIN,QAAQ,EACT,MAAM,wCAAwC,CAAC;AAsBhD,OAAO,KAAK,EAEV,eAAe,EAChB,MAAM,yCAAyC,CAAC;AACjD,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,2BAA2B,CAAC;AAMxD,OAAO,KAAK,EAAY,UAAU,EAAC,MAAM,0BAA0B,CAAC;AAapE,MAAM,WAAW,eAAe;IAC9B,cAAc,CACZ,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,eAAe,CACb,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAC/B,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,iBAAiB,IAAI,IAAI,CAAC;IAC1B,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;IAEzD;;;OAGG;IACH,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACzC;AAED,qBAAa,mBAAoB,YAAW,eAAe;;IAezD,YACE,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,iBAAiB,EAAE,eAAe,EAwBnC;IAED,iBAAiB,SAQhB;IAED,OAAO,SAEN;IAEK,cAAc,CAClB,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,oBAoBjC;IAEK,eAAe,CACnB,QAAQ,EAAE,UAAU,GAAG,SAAS,EAChC,GAAG,EAAE,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,oBAwEjC;IAED,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAqBvD;IAED,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAMtC;CA4TF"}
|
|
@@ -37,6 +37,7 @@ var WriteAuthorizerImpl = class {
|
|
|
37
37
|
this.#replica = replica;
|
|
38
38
|
this.#cgStorage = writeAuthzStorage.createClientGroupStorage(cgID);
|
|
39
39
|
this.#builderDelegate = {
|
|
40
|
+
disableCorrelatedPredicatePushdown: config.enableCorrelatedPredicatePushdown === false,
|
|
40
41
|
getSource: (name) => this.#getSource(name),
|
|
41
42
|
createStorage: () => this.#cgStorage.createStorage(),
|
|
42
43
|
decorateSourceInput: (input) => input,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write-authorizer.js","names":["#schema","#replica","#builderDelegate","#tableSpecs","#tables","#statementRunner","#lc","#appID","#logConfig","#cgStorage","#config","#getSource","#loadedPermissions","#canUpdate","#canDelete","#requirePreMutationRow","#canInsert","#getPreMutationRow","#timedCanDo","#canDo","#getPrimaryKey","#passesPolicyGroup","#passesPolicy"],"sources":["../../../../../zero-cache/src/auth/write-authorizer.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport type {MaybePromise} from '@opentelemetry/resources';\nimport type {LogContext} from '@rocicorp/logger';\nimport type {JWTPayload} from 'jose';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport type {JSONValue, ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport * as v from '../../../shared/src/valita.ts';\nimport type {Condition} from '../../../zero-protocol/src/ast.ts';\nimport type {\n CRUDOp,\n DeleteOp,\n InsertOp,\n UpdateOp,\n UpsertOp,\n} from '../../../zero-protocol/src/mutation.ts';\nimport {\n primaryKeyValueSchema,\n type PrimaryKeyValue,\n} from '../../../zero-protocol/src/primary-key.ts';\nimport type {Policy} from '../../../zero-schema/src/compiled-permissions.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {BuilderDelegate} from '../../../zql/src/builder/builder.ts';\nimport {\n bindStaticParameters,\n buildPipeline,\n} from '../../../zql/src/builder/builder.ts';\nimport {\n makeSourceChangeAdd,\n makeSourceChangeEdit,\n makeSourceChangeRemove,\n} from '../../../zql/src/ivm/source.ts';\nimport {consume} from '../../../zql/src/ivm/stream.ts';\nimport {simplifyCondition} from '../../../zql/src/query/expression.ts';\nimport {asQueryInternals} from '../../../zql/src/query/query-internals.ts';\nimport type {Query} from '../../../zql/src/query/query.ts';\nimport {newStaticQuery} from '../../../zql/src/query/static-query.ts';\nimport type {\n ClientGroupStorage,\n DatabaseStorage,\n} from '../../../zqlite/src/database-storage.ts';\nimport type {Database} from '../../../zqlite/src/db.ts';\nimport {compile, sql} from '../../../zqlite/src/internal/sql.ts';\nimport {\n fromSQLiteTypes,\n TableSource,\n} from '../../../zqlite/src/table-source.ts';\nimport type {LogConfig, ZeroConfig} from '../config/zero-config.ts';\nimport {computeZqlSpecs} from '../db/lite-tables.ts';\nimport type {LiteAndZqlSpec} from '../db/specs.ts';\nimport {StatementRunner} from '../db/statements.ts';\nimport {mapLiteDataTypeToZqlSchemaValue} from '../types/lite.ts';\nimport {\n getSchema,\n reloadPermissionsIfChanged,\n type LoadedPermissions,\n} from './load-permissions.ts';\n\ntype Phase = 'preMutation' | 'postMutation';\n\nexport interface WriteAuthorizer {\n canPreMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ): Promise<boolean>;\n canPostMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ): Promise<boolean>;\n reloadPermissions(): void;\n normalizeOps(ops: CRUDOp[]): Exclude<CRUDOp, UpsertOp>[];\n\n /**\n * Validates that all table names in the operations exist in the schema.\n * @throws Error if any table name is invalid\n */\n validateTableNames(ops: CRUDOp[]): void;\n}\n\nexport class WriteAuthorizerImpl implements WriteAuthorizer {\n readonly #schema: Schema;\n readonly #replica: Database;\n readonly #builderDelegate: BuilderDelegate;\n readonly #tableSpecs: Map<string, LiteAndZqlSpec>;\n readonly #tables = new Map<string, TableSource>();\n readonly #statementRunner: StatementRunner;\n readonly #lc: LogContext;\n readonly #appID: string;\n readonly #logConfig: LogConfig;\n readonly #cgStorage: ClientGroupStorage;\n readonly #config: ZeroConfig;\n\n #loadedPermissions: LoadedPermissions | null = null;\n\n constructor(\n lc: LogContext,\n config: ZeroConfig,\n replica: Database,\n appID: string,\n cgID: string,\n writeAuthzStorage: DatabaseStorage,\n ) {\n this.#appID = appID;\n this.#config = config;\n this.#lc = lc.withContext('class', 'WriteAuthorizerImpl');\n this.#logConfig = config.log;\n this.#schema = getSchema(this.#lc, replica);\n this.#replica = replica;\n this.#cgStorage = writeAuthzStorage.createClientGroupStorage(cgID);\n this.#builderDelegate = {\n getSource: name => this.#getSource(name),\n createStorage: () => this.#cgStorage.createStorage(),\n decorateSourceInput: input => input,\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n };\n this.#tableSpecs = computeZqlSpecs(this.#lc, replica, {\n includeBackfillingColumns: false,\n });\n this.#statementRunner = new StatementRunner(replica);\n this.reloadPermissions();\n }\n\n reloadPermissions() {\n this.#loadedPermissions = reloadPermissionsIfChanged(\n this.#lc,\n this.#statementRunner,\n this.#appID,\n this.#loadedPermissions,\n this.#config,\n ).permissions;\n }\n\n destroy() {\n this.#cgStorage.destroy();\n }\n\n async canPreMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ) {\n for (const op of ops) {\n switch (op.op) {\n case 'insert':\n // insert does not run pre-mutation checks\n break;\n case 'update':\n if (!(await this.#canUpdate('preMutation', authData, op))) {\n return false;\n }\n break;\n case 'delete':\n if (!(await this.#canDelete('preMutation', authData, op))) {\n return false;\n }\n break;\n }\n }\n return true;\n }\n\n async canPostMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ) {\n this.#statementRunner.beginConcurrent();\n let opError: unknown;\n try {\n for (const op of ops) {\n const source = this.#getSource(op.tableName);\n switch (op.op) {\n case 'insert': {\n consume(source.push(makeSourceChangeAdd(op.value)));\n break;\n }\n // TODO(mlaw): what if someone updates the same thing twice?\n // TODO(aa): It seems like it will just work? source.push()\n // is going to push the row into the table source, and then the\n // next requirePreMutationRow will just return the row that was\n // pushed in.\n case 'update': {\n consume(\n source.push(\n makeSourceChangeEdit(op.value, this.#requirePreMutationRow(op)),\n ),\n );\n break;\n }\n case 'delete': {\n consume(\n source.push(\n makeSourceChangeRemove(this.#requirePreMutationRow(op)),\n ),\n );\n break;\n }\n }\n }\n\n for (const op of ops) {\n switch (op.op) {\n case 'insert':\n if (!(await this.#canInsert('postMutation', authData, op))) {\n return false;\n }\n break;\n case 'update':\n if (!(await this.#canUpdate('postMutation', authData, op))) {\n return false;\n }\n break;\n case 'delete':\n // delete does not run post-mutation checks.\n break;\n }\n }\n } catch (e) {\n opError = e;\n throw e;\n } finally {\n try {\n this.#statementRunner.rollback();\n } catch (rollbackError) {\n if (opError !== undefined) {\n const combinedError = new Error(\n `canPostMutation failed and rollback also failed: operation error = ${String(opError)}; rollback error = ${String(rollbackError)}`,\n );\n combinedError.cause = opError;\n throw combinedError;\n }\n throw rollbackError;\n }\n }\n\n return true;\n }\n\n normalizeOps(ops: CRUDOp[]): Exclude<CRUDOp, UpsertOp>[] {\n return ops.map(op => {\n if (op.op === 'upsert') {\n const preMutationRow = this.#getPreMutationRow(op);\n if (preMutationRow) {\n return {\n op: 'update',\n tableName: op.tableName,\n primaryKey: op.primaryKey,\n value: op.value,\n };\n }\n return {\n op: 'insert',\n tableName: op.tableName,\n primaryKey: op.primaryKey,\n value: op.value,\n };\n }\n return op;\n });\n }\n\n validateTableNames(ops: CRUDOp[]): void {\n for (const op of ops) {\n if (!this.#tableSpecs.has(op.tableName)) {\n throw new Error(`Table '${op.tableName}' is not a valid table.`);\n }\n }\n }\n\n #canInsert(phase: Phase, authData: JWTPayload | undefined, op: InsertOp) {\n return this.#timedCanDo(phase, 'insert', authData, op);\n }\n\n #canUpdate(phase: Phase, authData: JWTPayload | undefined, op: UpdateOp) {\n return this.#timedCanDo(phase, 'update', authData, op);\n }\n\n #canDelete(phase: Phase, authData: JWTPayload | undefined, op: DeleteOp) {\n return this.#timedCanDo(phase, 'delete', authData, op);\n }\n\n /**\n * Gets schema-defined primary key and validates that operation contains required PK values.\n *\n * @returns Record where keys are column names and values are client-provided values\n * @throws Error if operation value is missing required primary key columns\n */\n #getPrimaryKey(\n tableName: string,\n opValue: Record<string, ReadonlyJSONValue | undefined>,\n ): Record<string, ReadonlyJSONValue> {\n const tableSpec = this.#tableSpecs.get(tableName);\n if (!tableSpec) {\n throw new Error(`Table ${tableName} not found`);\n }\n const columns = tableSpec.tableSpec.primaryKey;\n\n // Extract primary key values from operation value and validate they exist\n const values: Record<string, ReadonlyJSONValue> = {};\n for (const col of columns) {\n const val = opValue[col];\n if (val === undefined) {\n throw new Error(\n `Primary key column '${col}' is missing from operation value for table ${tableName}`,\n );\n }\n values[col] = val;\n }\n\n return values;\n }\n\n #getSource(tableName: string) {\n let source = this.#tables.get(tableName);\n if (source) {\n return source;\n }\n const tableSpec = this.#tableSpecs.get(tableName);\n if (!tableSpec) {\n throw new Error(`Table ${tableName} not found`);\n }\n const {columns, primaryKey} = tableSpec.tableSpec;\n assert(\n primaryKey.length,\n () => `Table ${tableName} must have a primary key`,\n );\n source = new TableSource(\n this.#lc,\n this.#logConfig,\n this.#replica,\n tableName,\n Object.fromEntries(\n Object.entries(columns).map(([name, {dataType}]) => [\n name,\n mapLiteDataTypeToZqlSchemaValue(dataType),\n ]),\n ),\n [primaryKey[0], ...primaryKey.slice(1)],\n );\n this.#tables.set(tableName, source);\n\n return source;\n }\n\n async #timedCanDo<A extends keyof ActionOpMap>(\n phase: Phase,\n action: A,\n authData: JWTPayload | undefined,\n op: ActionOpMap[A],\n ) {\n const start = performance.now();\n try {\n const ret = await this.#canDo(phase, action, authData, op);\n return ret;\n } finally {\n this.#lc.info?.(\n 'action:',\n action,\n 'duration:',\n performance.now() - start,\n 'tableName:',\n op.tableName,\n 'primaryKey:',\n op.primaryKey,\n );\n }\n }\n\n /**\n * Evaluation order is from static to dynamic, broad to specific.\n * table -> column -> row -> cell.\n *\n * If any step fails, the entire operation is denied.\n *\n * That is, table rules supersede column rules, which supersede row rules,\n *\n * All steps must allow for the operation to be allowed.\n */\n async #canDo<A extends keyof ActionOpMap>(\n phase: Phase,\n action: A,\n authData: JWTPayload | undefined,\n op: ActionOpMap[A],\n ) {\n const rules = must(this.#loadedPermissions)?.permissions?.tables?.[\n op.tableName\n ];\n const rowPolicies = rules?.row;\n let rowQuery = newStaticQuery(this.#schema, op.tableName);\n\n const primaryKeyValues = this.#getPrimaryKey(op.tableName, op.value);\n\n for (const pk in primaryKeyValues) {\n rowQuery = rowQuery.where(pk, '=', primaryKeyValues[pk]);\n }\n\n let applicableRowPolicy: Policy | undefined;\n switch (action) {\n case 'insert':\n if (phase === 'postMutation') {\n applicableRowPolicy = rowPolicies?.insert;\n }\n break;\n case 'update':\n if (phase === 'preMutation') {\n applicableRowPolicy = rowPolicies?.update?.preMutation;\n } else if (phase === 'postMutation') {\n applicableRowPolicy = rowPolicies?.update?.postMutation;\n }\n break;\n case 'delete':\n if (phase === 'preMutation') {\n applicableRowPolicy = rowPolicies?.delete;\n }\n break;\n }\n\n const cellPolicies = rules?.cell;\n const applicableCellPolicies: Policy[] = [];\n if (cellPolicies) {\n for (const [column, policy] of Object.entries(cellPolicies)) {\n if (action === 'update' && op.value[column] === undefined) {\n // If the cell is not being updated, we do not need to check\n // the cell rules.\n continue;\n }\n switch (action) {\n case 'insert':\n if (policy.insert && phase === 'postMutation') {\n applicableCellPolicies.push(policy.insert);\n }\n break;\n case 'update':\n if (phase === 'preMutation' && policy.update?.preMutation) {\n applicableCellPolicies.push(policy.update.preMutation);\n }\n if (phase === 'postMutation' && policy.update?.postMutation) {\n applicableCellPolicies.push(policy.update.postMutation);\n }\n break;\n case 'delete':\n if (policy.delete && phase === 'preMutation') {\n applicableCellPolicies.push(policy.delete);\n }\n break;\n }\n }\n }\n\n if (\n !(await this.#passesPolicyGroup(\n applicableRowPolicy,\n applicableCellPolicies,\n authData,\n rowQuery,\n ))\n ) {\n // `op.value` is the row being written and `authData` is the decoded\n // JWT payload, so neither can go into the log. Column names and policy\n // counts are enough to debug a failed permission check.\n this.#lc.warn?.('Permission check failed', {\n action,\n phase,\n tableName: op.tableName,\n columns: Object.keys(op.value),\n rowPolicy: applicableRowPolicy !== undefined,\n cellPolicyCount: applicableCellPolicies.length,\n });\n return false;\n }\n\n return true;\n }\n\n #getPreMutationRow(op: UpsertOp | UpdateOp | DeleteOp) {\n const {value} = op;\n\n const primaryKeyValues = this.#getPrimaryKey(op.tableName, value);\n\n const spec = this.#tableSpecs.get(op.tableName);\n if (!spec) {\n throw new Error(`Table ${op.tableName} not found`);\n }\n\n const conditions: SQLQuery[] = [];\n const values: PrimaryKeyValue[] = [];\n for (const pk in primaryKeyValues) {\n conditions.push(sql`${sql.ident(pk)}=?`);\n values.push(v.parse(primaryKeyValues[pk], primaryKeyValueSchema));\n }\n\n const ret = this.#statementRunner.get(\n compile(\n sql`SELECT ${sql.join(\n Object.keys(spec.zqlSpec).map(c => sql.ident(c)),\n sql`,`,\n )} FROM ${sql.ident(op.tableName)} WHERE ${sql.join(\n conditions,\n sql` AND `,\n )}`,\n ),\n ...values,\n );\n if (ret === undefined) {\n return ret;\n }\n return fromSQLiteTypes(spec.zqlSpec, ret, op.tableName);\n }\n\n #requirePreMutationRow(op: UpdateOp | DeleteOp) {\n const ret = this.#getPreMutationRow(op);\n assert(\n ret !== undefined,\n () => `Pre-mutation row not found for ${JSON.stringify(op.value)}`,\n );\n return ret;\n }\n\n async #passesPolicyGroup(\n applicableRowPolicy: Policy | undefined,\n applicableCellPolicies: Policy[],\n authData: JWTPayload | undefined,\n rowQuery: Query<string, Schema>,\n ) {\n if (!(await this.#passesPolicy(applicableRowPolicy, authData, rowQuery))) {\n return false;\n }\n\n for (const policy of applicableCellPolicies) {\n if (!(await this.#passesPolicy(policy, authData, rowQuery))) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Defaults to *false* if the policy is empty. At least one rule has to pass\n * for the policy to pass.\n */\n #passesPolicy(\n policy: Policy | undefined,\n authData: JWTPayload | undefined,\n rowQuery: Query<string, Schema>,\n ): MaybePromise<boolean> {\n if (policy === undefined) {\n return false;\n }\n if (policy.length === 0) {\n return false;\n }\n let rowQueryAst = asQueryInternals(rowQuery).ast;\n rowQueryAst = bindStaticParameters(\n {\n ...rowQueryAst,\n where: updateWhere(rowQueryAst.where, policy),\n },\n {\n authData: authData as Record<string, JSONValue>,\n preMutationRow: undefined,\n },\n );\n\n // call the compiler directly\n // run the sql against upstream.\n // remove the collecting into json? just need to know if a row comes back.\n\n const input = buildPipeline(rowQueryAst, this.#builderDelegate, 'query-id');\n try {\n const res = input.fetch({});\n for (const _ of res) {\n // if any row is returned at all, the\n // rule passes.\n return true;\n }\n } finally {\n input.destroy();\n }\n\n // no rows returned by any rules? The policy fails.\n return false;\n }\n}\n\nfunction updateWhere(where: Condition | undefined, policy: Policy) {\n assert(where, 'A where condition must exist for RowQuery');\n\n return simplifyCondition({\n type: 'and',\n conditions: [\n where,\n {\n type: 'or',\n conditions: policy.map(([action, rule]) => {\n assert(action, 'action must be defined in policy');\n return rule;\n }),\n },\n ],\n });\n}\n\ntype ActionOpMap = {\n insert: InsertOp;\n update: UpdateOp;\n delete: DeleteOp;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"write-authorizer.js","names":["#schema","#replica","#builderDelegate","#tableSpecs","#tables","#statementRunner","#lc","#appID","#logConfig","#cgStorage","#config","#getSource","#loadedPermissions","#canUpdate","#canDelete","#requirePreMutationRow","#canInsert","#getPreMutationRow","#timedCanDo","#canDo","#getPrimaryKey","#passesPolicyGroup","#passesPolicy"],"sources":["../../../../../zero-cache/src/auth/write-authorizer.ts"],"sourcesContent":["import type {SQLQuery} from '@databases/sql';\nimport type {MaybePromise} from '@opentelemetry/resources';\nimport type {LogContext} from '@rocicorp/logger';\nimport type {JWTPayload} from 'jose';\nimport {assert} from '../../../shared/src/asserts.ts';\nimport type {JSONValue, ReadonlyJSONValue} from '../../../shared/src/json.ts';\nimport {must} from '../../../shared/src/must.ts';\nimport * as v from '../../../shared/src/valita.ts';\nimport type {Condition} from '../../../zero-protocol/src/ast.ts';\nimport type {\n CRUDOp,\n DeleteOp,\n InsertOp,\n UpdateOp,\n UpsertOp,\n} from '../../../zero-protocol/src/mutation.ts';\nimport {\n primaryKeyValueSchema,\n type PrimaryKeyValue,\n} from '../../../zero-protocol/src/primary-key.ts';\nimport type {Policy} from '../../../zero-schema/src/compiled-permissions.ts';\nimport type {Schema} from '../../../zero-types/src/schema.ts';\nimport type {BuilderDelegate} from '../../../zql/src/builder/builder.ts';\nimport {\n bindStaticParameters,\n buildPipeline,\n} from '../../../zql/src/builder/builder.ts';\nimport {\n makeSourceChangeAdd,\n makeSourceChangeEdit,\n makeSourceChangeRemove,\n} from '../../../zql/src/ivm/source.ts';\nimport {consume} from '../../../zql/src/ivm/stream.ts';\nimport {simplifyCondition} from '../../../zql/src/query/expression.ts';\nimport {asQueryInternals} from '../../../zql/src/query/query-internals.ts';\nimport type {Query} from '../../../zql/src/query/query.ts';\nimport {newStaticQuery} from '../../../zql/src/query/static-query.ts';\nimport type {\n ClientGroupStorage,\n DatabaseStorage,\n} from '../../../zqlite/src/database-storage.ts';\nimport type {Database} from '../../../zqlite/src/db.ts';\nimport {compile, sql} from '../../../zqlite/src/internal/sql.ts';\nimport {\n fromSQLiteTypes,\n TableSource,\n} from '../../../zqlite/src/table-source.ts';\nimport type {LogConfig, ZeroConfig} from '../config/zero-config.ts';\nimport {computeZqlSpecs} from '../db/lite-tables.ts';\nimport type {LiteAndZqlSpec} from '../db/specs.ts';\nimport {StatementRunner} from '../db/statements.ts';\nimport {mapLiteDataTypeToZqlSchemaValue} from '../types/lite.ts';\nimport {\n getSchema,\n reloadPermissionsIfChanged,\n type LoadedPermissions,\n} from './load-permissions.ts';\n\ntype Phase = 'preMutation' | 'postMutation';\n\nexport interface WriteAuthorizer {\n canPreMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ): Promise<boolean>;\n canPostMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ): Promise<boolean>;\n reloadPermissions(): void;\n normalizeOps(ops: CRUDOp[]): Exclude<CRUDOp, UpsertOp>[];\n\n /**\n * Validates that all table names in the operations exist in the schema.\n * @throws Error if any table name is invalid\n */\n validateTableNames(ops: CRUDOp[]): void;\n}\n\nexport class WriteAuthorizerImpl implements WriteAuthorizer {\n readonly #schema: Schema;\n readonly #replica: Database;\n readonly #builderDelegate: BuilderDelegate;\n readonly #tableSpecs: Map<string, LiteAndZqlSpec>;\n readonly #tables = new Map<string, TableSource>();\n readonly #statementRunner: StatementRunner;\n readonly #lc: LogContext;\n readonly #appID: string;\n readonly #logConfig: LogConfig;\n readonly #cgStorage: ClientGroupStorage;\n readonly #config: ZeroConfig;\n\n #loadedPermissions: LoadedPermissions | null = null;\n\n constructor(\n lc: LogContext,\n config: ZeroConfig,\n replica: Database,\n appID: string,\n cgID: string,\n writeAuthzStorage: DatabaseStorage,\n ) {\n this.#appID = appID;\n this.#config = config;\n this.#lc = lc.withContext('class', 'WriteAuthorizerImpl');\n this.#logConfig = config.log;\n this.#schema = getSchema(this.#lc, replica);\n this.#replica = replica;\n this.#cgStorage = writeAuthzStorage.createClientGroupStorage(cgID);\n this.#builderDelegate = {\n disableCorrelatedPredicatePushdown:\n config.enableCorrelatedPredicatePushdown === false,\n getSource: name => this.#getSource(name),\n createStorage: () => this.#cgStorage.createStorage(),\n decorateSourceInput: input => input,\n decorateInput: input => input,\n addEdge() {},\n decorateFilterInput: input => input,\n };\n this.#tableSpecs = computeZqlSpecs(this.#lc, replica, {\n includeBackfillingColumns: false,\n });\n this.#statementRunner = new StatementRunner(replica);\n this.reloadPermissions();\n }\n\n reloadPermissions() {\n this.#loadedPermissions = reloadPermissionsIfChanged(\n this.#lc,\n this.#statementRunner,\n this.#appID,\n this.#loadedPermissions,\n this.#config,\n ).permissions;\n }\n\n destroy() {\n this.#cgStorage.destroy();\n }\n\n async canPreMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ) {\n for (const op of ops) {\n switch (op.op) {\n case 'insert':\n // insert does not run pre-mutation checks\n break;\n case 'update':\n if (!(await this.#canUpdate('preMutation', authData, op))) {\n return false;\n }\n break;\n case 'delete':\n if (!(await this.#canDelete('preMutation', authData, op))) {\n return false;\n }\n break;\n }\n }\n return true;\n }\n\n async canPostMutation(\n authData: JWTPayload | undefined,\n ops: Exclude<CRUDOp, UpsertOp>[],\n ) {\n this.#statementRunner.beginConcurrent();\n let opError: unknown;\n try {\n for (const op of ops) {\n const source = this.#getSource(op.tableName);\n switch (op.op) {\n case 'insert': {\n consume(source.push(makeSourceChangeAdd(op.value)));\n break;\n }\n // TODO(mlaw): what if someone updates the same thing twice?\n // TODO(aa): It seems like it will just work? source.push()\n // is going to push the row into the table source, and then the\n // next requirePreMutationRow will just return the row that was\n // pushed in.\n case 'update': {\n consume(\n source.push(\n makeSourceChangeEdit(op.value, this.#requirePreMutationRow(op)),\n ),\n );\n break;\n }\n case 'delete': {\n consume(\n source.push(\n makeSourceChangeRemove(this.#requirePreMutationRow(op)),\n ),\n );\n break;\n }\n }\n }\n\n for (const op of ops) {\n switch (op.op) {\n case 'insert':\n if (!(await this.#canInsert('postMutation', authData, op))) {\n return false;\n }\n break;\n case 'update':\n if (!(await this.#canUpdate('postMutation', authData, op))) {\n return false;\n }\n break;\n case 'delete':\n // delete does not run post-mutation checks.\n break;\n }\n }\n } catch (e) {\n opError = e;\n throw e;\n } finally {\n try {\n this.#statementRunner.rollback();\n } catch (rollbackError) {\n if (opError !== undefined) {\n const combinedError = new Error(\n `canPostMutation failed and rollback also failed: operation error = ${String(opError)}; rollback error = ${String(rollbackError)}`,\n );\n combinedError.cause = opError;\n throw combinedError;\n }\n throw rollbackError;\n }\n }\n\n return true;\n }\n\n normalizeOps(ops: CRUDOp[]): Exclude<CRUDOp, UpsertOp>[] {\n return ops.map(op => {\n if (op.op === 'upsert') {\n const preMutationRow = this.#getPreMutationRow(op);\n if (preMutationRow) {\n return {\n op: 'update',\n tableName: op.tableName,\n primaryKey: op.primaryKey,\n value: op.value,\n };\n }\n return {\n op: 'insert',\n tableName: op.tableName,\n primaryKey: op.primaryKey,\n value: op.value,\n };\n }\n return op;\n });\n }\n\n validateTableNames(ops: CRUDOp[]): void {\n for (const op of ops) {\n if (!this.#tableSpecs.has(op.tableName)) {\n throw new Error(`Table '${op.tableName}' is not a valid table.`);\n }\n }\n }\n\n #canInsert(phase: Phase, authData: JWTPayload | undefined, op: InsertOp) {\n return this.#timedCanDo(phase, 'insert', authData, op);\n }\n\n #canUpdate(phase: Phase, authData: JWTPayload | undefined, op: UpdateOp) {\n return this.#timedCanDo(phase, 'update', authData, op);\n }\n\n #canDelete(phase: Phase, authData: JWTPayload | undefined, op: DeleteOp) {\n return this.#timedCanDo(phase, 'delete', authData, op);\n }\n\n /**\n * Gets schema-defined primary key and validates that operation contains required PK values.\n *\n * @returns Record where keys are column names and values are client-provided values\n * @throws Error if operation value is missing required primary key columns\n */\n #getPrimaryKey(\n tableName: string,\n opValue: Record<string, ReadonlyJSONValue | undefined>,\n ): Record<string, ReadonlyJSONValue> {\n const tableSpec = this.#tableSpecs.get(tableName);\n if (!tableSpec) {\n throw new Error(`Table ${tableName} not found`);\n }\n const columns = tableSpec.tableSpec.primaryKey;\n\n // Extract primary key values from operation value and validate they exist\n const values: Record<string, ReadonlyJSONValue> = {};\n for (const col of columns) {\n const val = opValue[col];\n if (val === undefined) {\n throw new Error(\n `Primary key column '${col}' is missing from operation value for table ${tableName}`,\n );\n }\n values[col] = val;\n }\n\n return values;\n }\n\n #getSource(tableName: string) {\n let source = this.#tables.get(tableName);\n if (source) {\n return source;\n }\n const tableSpec = this.#tableSpecs.get(tableName);\n if (!tableSpec) {\n throw new Error(`Table ${tableName} not found`);\n }\n const {columns, primaryKey} = tableSpec.tableSpec;\n assert(\n primaryKey.length,\n () => `Table ${tableName} must have a primary key`,\n );\n source = new TableSource(\n this.#lc,\n this.#logConfig,\n this.#replica,\n tableName,\n Object.fromEntries(\n Object.entries(columns).map(([name, {dataType}]) => [\n name,\n mapLiteDataTypeToZqlSchemaValue(dataType),\n ]),\n ),\n [primaryKey[0], ...primaryKey.slice(1)],\n );\n this.#tables.set(tableName, source);\n\n return source;\n }\n\n async #timedCanDo<A extends keyof ActionOpMap>(\n phase: Phase,\n action: A,\n authData: JWTPayload | undefined,\n op: ActionOpMap[A],\n ) {\n const start = performance.now();\n try {\n const ret = await this.#canDo(phase, action, authData, op);\n return ret;\n } finally {\n this.#lc.info?.(\n 'action:',\n action,\n 'duration:',\n performance.now() - start,\n 'tableName:',\n op.tableName,\n 'primaryKey:',\n op.primaryKey,\n );\n }\n }\n\n /**\n * Evaluation order is from static to dynamic, broad to specific.\n * table -> column -> row -> cell.\n *\n * If any step fails, the entire operation is denied.\n *\n * That is, table rules supersede column rules, which supersede row rules,\n *\n * All steps must allow for the operation to be allowed.\n */\n async #canDo<A extends keyof ActionOpMap>(\n phase: Phase,\n action: A,\n authData: JWTPayload | undefined,\n op: ActionOpMap[A],\n ) {\n const rules = must(this.#loadedPermissions)?.permissions?.tables?.[\n op.tableName\n ];\n const rowPolicies = rules?.row;\n let rowQuery = newStaticQuery(this.#schema, op.tableName);\n\n const primaryKeyValues = this.#getPrimaryKey(op.tableName, op.value);\n\n for (const pk in primaryKeyValues) {\n rowQuery = rowQuery.where(pk, '=', primaryKeyValues[pk]);\n }\n\n let applicableRowPolicy: Policy | undefined;\n switch (action) {\n case 'insert':\n if (phase === 'postMutation') {\n applicableRowPolicy = rowPolicies?.insert;\n }\n break;\n case 'update':\n if (phase === 'preMutation') {\n applicableRowPolicy = rowPolicies?.update?.preMutation;\n } else if (phase === 'postMutation') {\n applicableRowPolicy = rowPolicies?.update?.postMutation;\n }\n break;\n case 'delete':\n if (phase === 'preMutation') {\n applicableRowPolicy = rowPolicies?.delete;\n }\n break;\n }\n\n const cellPolicies = rules?.cell;\n const applicableCellPolicies: Policy[] = [];\n if (cellPolicies) {\n for (const [column, policy] of Object.entries(cellPolicies)) {\n if (action === 'update' && op.value[column] === undefined) {\n // If the cell is not being updated, we do not need to check\n // the cell rules.\n continue;\n }\n switch (action) {\n case 'insert':\n if (policy.insert && phase === 'postMutation') {\n applicableCellPolicies.push(policy.insert);\n }\n break;\n case 'update':\n if (phase === 'preMutation' && policy.update?.preMutation) {\n applicableCellPolicies.push(policy.update.preMutation);\n }\n if (phase === 'postMutation' && policy.update?.postMutation) {\n applicableCellPolicies.push(policy.update.postMutation);\n }\n break;\n case 'delete':\n if (policy.delete && phase === 'preMutation') {\n applicableCellPolicies.push(policy.delete);\n }\n break;\n }\n }\n }\n\n if (\n !(await this.#passesPolicyGroup(\n applicableRowPolicy,\n applicableCellPolicies,\n authData,\n rowQuery,\n ))\n ) {\n // `op.value` is the row being written and `authData` is the decoded\n // JWT payload, so neither can go into the log. Column names and policy\n // counts are enough to debug a failed permission check.\n this.#lc.warn?.('Permission check failed', {\n action,\n phase,\n tableName: op.tableName,\n columns: Object.keys(op.value),\n rowPolicy: applicableRowPolicy !== undefined,\n cellPolicyCount: applicableCellPolicies.length,\n });\n return false;\n }\n\n return true;\n }\n\n #getPreMutationRow(op: UpsertOp | UpdateOp | DeleteOp) {\n const {value} = op;\n\n const primaryKeyValues = this.#getPrimaryKey(op.tableName, value);\n\n const spec = this.#tableSpecs.get(op.tableName);\n if (!spec) {\n throw new Error(`Table ${op.tableName} not found`);\n }\n\n const conditions: SQLQuery[] = [];\n const values: PrimaryKeyValue[] = [];\n for (const pk in primaryKeyValues) {\n conditions.push(sql`${sql.ident(pk)}=?`);\n values.push(v.parse(primaryKeyValues[pk], primaryKeyValueSchema));\n }\n\n const ret = this.#statementRunner.get(\n compile(\n sql`SELECT ${sql.join(\n Object.keys(spec.zqlSpec).map(c => sql.ident(c)),\n sql`,`,\n )} FROM ${sql.ident(op.tableName)} WHERE ${sql.join(\n conditions,\n sql` AND `,\n )}`,\n ),\n ...values,\n );\n if (ret === undefined) {\n return ret;\n }\n return fromSQLiteTypes(spec.zqlSpec, ret, op.tableName);\n }\n\n #requirePreMutationRow(op: UpdateOp | DeleteOp) {\n const ret = this.#getPreMutationRow(op);\n assert(\n ret !== undefined,\n () => `Pre-mutation row not found for ${JSON.stringify(op.value)}`,\n );\n return ret;\n }\n\n async #passesPolicyGroup(\n applicableRowPolicy: Policy | undefined,\n applicableCellPolicies: Policy[],\n authData: JWTPayload | undefined,\n rowQuery: Query<string, Schema>,\n ) {\n if (!(await this.#passesPolicy(applicableRowPolicy, authData, rowQuery))) {\n return false;\n }\n\n for (const policy of applicableCellPolicies) {\n if (!(await this.#passesPolicy(policy, authData, rowQuery))) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Defaults to *false* if the policy is empty. At least one rule has to pass\n * for the policy to pass.\n */\n #passesPolicy(\n policy: Policy | undefined,\n authData: JWTPayload | undefined,\n rowQuery: Query<string, Schema>,\n ): MaybePromise<boolean> {\n if (policy === undefined) {\n return false;\n }\n if (policy.length === 0) {\n return false;\n }\n let rowQueryAst = asQueryInternals(rowQuery).ast;\n rowQueryAst = bindStaticParameters(\n {\n ...rowQueryAst,\n where: updateWhere(rowQueryAst.where, policy),\n },\n {\n authData: authData as Record<string, JSONValue>,\n preMutationRow: undefined,\n },\n );\n\n // call the compiler directly\n // run the sql against upstream.\n // remove the collecting into json? just need to know if a row comes back.\n\n const input = buildPipeline(rowQueryAst, this.#builderDelegate, 'query-id');\n try {\n const res = input.fetch({});\n for (const _ of res) {\n // if any row is returned at all, the\n // rule passes.\n return true;\n }\n } finally {\n input.destroy();\n }\n\n // no rows returned by any rules? The policy fails.\n return false;\n }\n}\n\nfunction updateWhere(where: Condition | undefined, policy: Policy) {\n assert(where, 'A where condition must exist for RowQuery');\n\n return simplifyCondition({\n type: 'and',\n conditions: [\n where,\n {\n type: 'or',\n conditions: policy.map(([action, rule]) => {\n assert(action, 'action must be defined in policy');\n return rule;\n }),\n },\n ],\n });\n}\n\ntype ActionOpMap = {\n insert: InsertOp;\n update: UpdateOp;\n delete: DeleteOp;\n};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAIjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,qEAAqE;AACrE,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,GAAG,EAAE;QACH,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;AAElE,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AASD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAG9D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,IAAI,oBAAoB,
|
|
1
|
+
{"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/normalize.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAIjD,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,qEAAqE;AACrE,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,GAAG,EAAE;QACH,EAAE,EAAE,MAAM,CAAC;KACZ,CAAC;IACF,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;AAElE,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AASD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAG9D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,MAAM,IAAI,oBAAoB,CAkHxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,UAAU,EAClB,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,aAAa,CAAC,EAAE,MAAM,GACrB,oBAAoB,CAmGtB"}
|
|
@@ -22,13 +22,21 @@ function assertNormalized(config) {
|
|
|
22
22
|
assert(config.taskID, "missing --task-id");
|
|
23
23
|
assert(config.changeStreamer.port, "missing --change-streamer-port");
|
|
24
24
|
assert(config.changeStreamer.address, "missing --change-streamer-address");
|
|
25
|
-
const {
|
|
25
|
+
const { pgReplicationSlotPerReplica } = config.upstream;
|
|
26
|
+
const { pgChangeLogEnabled, sqliteChangeLogMode, sqliteChangeLogReadPercent, sqliteChangeLogColdReadPercent, sqliteChangeLogComparePercent, sqliteChangeLogRetentionMs, sqliteChangeLogReadBatchRows, sqliteChangeLogPurgeBatchRows, sqliteChangeLogBarrierTimeoutMs } = config.changeStreamer;
|
|
26
27
|
assert(Number.isSafeInteger(sqliteChangeLogReadPercent) && sqliteChangeLogReadPercent >= 0 && sqliteChangeLogReadPercent <= 100, "--change-streamer-sqlite-change-log-read-percent must be an integer between 0 and 100");
|
|
27
28
|
assert(Number.isSafeInteger(sqliteChangeLogColdReadPercent) && sqliteChangeLogColdReadPercent >= 0 && sqliteChangeLogColdReadPercent <= 100, "--change-streamer-sqlite-change-log-cold-read-percent must be an integer between 0 and 100");
|
|
28
29
|
assert(Number.isSafeInteger(sqliteChangeLogComparePercent) && sqliteChangeLogComparePercent >= 0 && sqliteChangeLogComparePercent <= 100, "--change-streamer-sqlite-change-log-compare-percent must be an integer between 0 and 100");
|
|
29
30
|
assert(sqliteChangeLogMode === "serve" || sqliteChangeLogReadPercent === 0, "--change-streamer-sqlite-change-log-read-percent must be 0 unless --change-streamer-sqlite-change-log-mode=serve");
|
|
30
31
|
assert(sqliteChangeLogMode === "serve" || sqliteChangeLogColdReadPercent === 0, "--change-streamer-sqlite-change-log-cold-read-percent must be 0 unless --change-streamer-sqlite-change-log-mode=serve");
|
|
31
32
|
assert(sqliteChangeLogReadPercent > 0 || sqliteChangeLogColdReadPercent === 0, "--change-streamer-sqlite-change-log-cold-read-percent must be 0 when --change-streamer-sqlite-change-log-read-percent is 0");
|
|
33
|
+
if (pgReplicationSlotPerReplica) assert(!pgChangeLogEnabled, `--upstream-pg-replication-slot-per-replica=true requires --change-streamer-pg-change-log-enabled=false`);
|
|
34
|
+
if (!pgChangeLogEnabled) {
|
|
35
|
+
assert(sqliteChangeLogMode === "serve", "--change-streamer-pg-change-log-enabled=false requires --change-streamer-sqlite-change-log-mode=serve");
|
|
36
|
+
assert(sqliteChangeLogReadPercent === 100, "--change-streamer-pg-change-log-enabled=false requires --change-streamer-sqlite-change-log-read-percent=100");
|
|
37
|
+
assert(sqliteChangeLogColdReadPercent === 100, "--change-streamer-pg-change-log-enabled=false requires --change-streamer-sqlite-change-log-cold-read-percent=100");
|
|
38
|
+
assert(config.litestream.backupURL && config.litestream.backupUsingV5, "--change-streamer-pg-change-log-enabled=false requires a litestream v5 backup");
|
|
39
|
+
}
|
|
32
40
|
for (const [flag, value] of [
|
|
33
41
|
["retention-ms", sqliteChangeLogRetentionMs],
|
|
34
42
|
["read-batch-rows", sqliteChangeLogReadBatchRows],
|
|
@@ -91,6 +99,22 @@ function normalizeZeroConfig(lc, config, env, defaultTaskID) {
|
|
|
91
99
|
config.keepaliveTimeoutMs = DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS;
|
|
92
100
|
env["ZERO_KEEPALIVE_TIMEOUT_MS"] = String(DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS);
|
|
93
101
|
}
|
|
102
|
+
if (config.upstream.pgHighAvailabilityReplication) {
|
|
103
|
+
config.upstream.pgReplicationSlotPerReplica = true;
|
|
104
|
+
env["ZERO_UPSTREAM_PG_REPLICATION_SLOT_PER_REPLICA"] = "true";
|
|
105
|
+
config.litestream.restoreUsingV5 = true;
|
|
106
|
+
config.litestream.backupUsingV5 = true;
|
|
107
|
+
env["ZERO_LITESTREAM_RESTORE_USING_V5"] = "true";
|
|
108
|
+
env["ZERO_LITESTREAM_BACKUP_USING_V5"] = "true";
|
|
109
|
+
config.changeStreamer.sqliteChangeLogMode = "serve";
|
|
110
|
+
env["ZERO_CHANGE_STREAMER_SQLITE_CHANGE_LOG_MODE"] = "serve";
|
|
111
|
+
config.changeStreamer.sqliteChangeLogReadPercent = 100;
|
|
112
|
+
config.changeStreamer.sqliteChangeLogColdReadPercent = 100;
|
|
113
|
+
env["ZERO_CHANGE_STREAMER_SQLITE_CHANGE_LOG_READ_PERCENT"] = "100";
|
|
114
|
+
env["ZERO_CHANGE_STREAMER_SQLITE_CHANGE_LOG_COLD_READ_PERCENT"] = "100";
|
|
115
|
+
config.changeStreamer.pgChangeLogEnabled = false;
|
|
116
|
+
env["ZERO_CHANGE_STREAMER_PG_CHANGE_LOG_ENABLED"] = "false";
|
|
117
|
+
}
|
|
94
118
|
lc.info?.(`runtime env: taskID=${config.taskID}, hostIP=${hostIP}`);
|
|
95
119
|
return {
|
|
96
120
|
...config,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"normalize.js","names":[],"sources":["../../../../../zero-cache/src/config/normalize.ts"],"sourcesContent":["import {availableParallelism} from 'node:os';\nimport type {LogContext} from '@rocicorp/logger';\nimport {nanoid} from 'nanoid';\nimport {assert, assertNotUndefined} from '../../../shared/src/asserts.ts';\nimport {getHostIp} from './network.ts';\nimport type {ZeroConfig} from './zero-config.ts';\n\n/** {@link ZeroConfig} with defaults set per option documentation. */\nexport type NormalizedZeroConfig = ZeroConfig & {\n taskID: string;\n changeStreamer: {\n port: number;\n address: string;\n };\n change: {\n db: string;\n };\n cvr: {\n db: string;\n };\n litestream: {\n port: number;\n };\n numSyncWorkers: number;\n};\n\nexport type LitestreamConfig = NormalizedZeroConfig['litestream'];\n\nexport function isDevelopmentMode(): boolean {\n return process.env.NODE_ENV === 'development';\n}\n\nfunction isRunningInECS(): boolean {\n // https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-environment-variables.html\n return process.env.ECS_CONTAINER_METADATA_URI_V4 !== undefined;\n}\n\nconst DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS = 20_000;\n\n/**\n * Whether this process tree runs the change-streamer, as opposed to connecting\n * to one that another task runs.\n */\nexport function runsChangeStreamer(config: ZeroConfig): boolean {\n const {mode, uri} = config.changeStreamer;\n return mode === 'dedicated' && uri === undefined;\n}\n\nexport function assertNormalized(\n config: ZeroConfig,\n): asserts config is NormalizedZeroConfig {\n assert(config.taskID, 'missing --task-id');\n assert(config.changeStreamer.port, 'missing --change-streamer-port');\n assert(config.changeStreamer.address, 'missing --change-streamer-address');\n const {\n sqliteChangeLogMode,\n sqliteChangeLogReadPercent,\n sqliteChangeLogColdReadPercent,\n sqliteChangeLogComparePercent,\n sqliteChangeLogRetentionMs,\n sqliteChangeLogReadBatchRows,\n sqliteChangeLogPurgeBatchRows,\n sqliteChangeLogBarrierTimeoutMs,\n } = config.changeStreamer;\n assert(\n Number.isSafeInteger(sqliteChangeLogReadPercent) &&\n sqliteChangeLogReadPercent >= 0 &&\n sqliteChangeLogReadPercent <= 100,\n '--change-streamer-sqlite-change-log-read-percent must be an integer between 0 and 100',\n );\n assert(\n Number.isSafeInteger(sqliteChangeLogColdReadPercent) &&\n sqliteChangeLogColdReadPercent >= 0 &&\n sqliteChangeLogColdReadPercent <= 100,\n '--change-streamer-sqlite-change-log-cold-read-percent must be an integer between 0 and 100',\n );\n // This setting has no mode restriction. Comparison starts in `compare` mode.\n assert(\n Number.isSafeInteger(sqliteChangeLogComparePercent) &&\n sqliteChangeLogComparePercent >= 0 &&\n sqliteChangeLogComparePercent <= 100,\n '--change-streamer-sqlite-change-log-compare-percent must be an integer between 0 and 100',\n );\n assert(\n sqliteChangeLogMode === 'serve' || sqliteChangeLogReadPercent === 0,\n '--change-streamer-sqlite-change-log-read-percent must be 0 unless --change-streamer-sqlite-change-log-mode=serve',\n );\n assert(\n sqliteChangeLogMode === 'serve' || sqliteChangeLogColdReadPercent === 0,\n '--change-streamer-sqlite-change-log-cold-read-percent must be 0 unless --change-streamer-sqlite-change-log-mode=serve',\n );\n // The cold gate only admits a task to the read gate; it never serves one on\n // its own. A nonzero cold percentage with a zero read percentage is a\n // silent no-op, which is the shape of a rollout that looks enabled and\n // serves nothing.\n assert(\n sqliteChangeLogReadPercent > 0 || sqliteChangeLogColdReadPercent === 0,\n '--change-streamer-sqlite-change-log-cold-read-percent must be 0 when --change-streamer-sqlite-change-log-read-percent is 0',\n );\n for (const [flag, value] of [\n ['retention-ms', sqliteChangeLogRetentionMs],\n ['read-batch-rows', sqliteChangeLogReadBatchRows],\n ['purge-batch-rows', sqliteChangeLogPurgeBatchRows],\n ['barrier-timeout-ms', sqliteChangeLogBarrierTimeoutMs],\n ] as const) {\n assert(\n Number.isSafeInteger(value) && value > 0,\n `--change-streamer-sqlite-change-log-${flag} must be a positive integer`,\n );\n }\n assert(config.litestream.port, 'missing --litestream-port');\n assert(\n !config.litestream.backupUsingV5 || config.litestream.restoreUsingV5,\n '--litestream-backup-using-v5 requires --litestream-restore-using-v5',\n );\n assert(\n !config.litestream.backupURL ||\n config.litestream.executableV5 ||\n !(config.litestream.restoreUsingV5 || config.litestream.backupUsingV5),\n '--litestream-restore-using-v5 and --litestream-backup-using-v5 ' +\n 'require --litestream-executable-v5 to be specified',\n );\n assert(\n !config.litestream.backupURL ||\n !config.litestream.backupUsingV5 ||\n config.litestream.vfsQueryExecutable,\n '--litestream-backup-using-v5 requires --litestream-vfs-query-executable to be specified',\n );\n assert(config.change.db, 'missing --change-db');\n assert(config.cvr.db, 'missing --cvr-db');\n assertNotUndefined(config.numSyncWorkers, 'missing --num-sync-workers');\n\n if (!isDevelopmentMode()) {\n assert(\n config.adminPassword,\n 'missing --admin-password: required in production mode',\n );\n }\n}\n\n/**\n * Normalizes the parsed `config` by setting defaults from the environment\n * or from other options as documented. When defaults are applied, the\n * corresponding `env` variable is updated so that the settings are propagated\n * to spawned child workers. Child workers can then call\n * {@link assertNormalized} to verify that the expected defaults have been set.\n */\nexport function normalizeZeroConfig(\n lc: LogContext,\n config: ZeroConfig,\n env: NodeJS.ProcessEnv,\n defaultTaskID?: string,\n): NormalizedZeroConfig {\n if (!config.taskID) {\n const taskID = defaultTaskID ?? nanoid();\n config.taskID = taskID;\n env['ZERO_TASK_ID'] = taskID;\n }\n if (!config.changeStreamer.port) {\n const port = config.port + 1;\n config.changeStreamer.port = port;\n env['ZERO_CHANGE_STREAMER_PORT'] = String(port);\n }\n if (!config.litestream.port) {\n const port = config.port + 2;\n config.litestream.port = port;\n env['ZERO_LITESTREAM_PORT'] = String(port);\n }\n if (config.numSyncWorkers === undefined) {\n // Reserve 1 core for the replicator. The change-streamer is not CPU heavy.\n const numSyncers = Math.max(1, availableParallelism() - 1);\n config.numSyncWorkers = numSyncers;\n env['ZERO_NUM_SYNC_WORKERS'] = String(numSyncers);\n }\n\n const hostIP = getHostIp(\n lc,\n config.changeStreamer.discoveryInterfacePreferences,\n );\n if (!config.changeStreamer.address) {\n const {port} = config.changeStreamer;\n const address = `${hostIP}:${port}`;\n config.changeStreamer.address = address;\n env['ZERO_CHANGE_STREAMER_ADDRESS'] = address;\n }\n\n if (!config.change.db) {\n config.change.db = config.upstream.db;\n env['ZERO_CHANGE_DB'] = config.upstream.db;\n }\n\n if (!config.cvr.db) {\n config.cvr.db = config.upstream.db;\n env['ZERO_CVR_DB'] = config.upstream.db;\n }\n\n if (!config.keepaliveTimeoutMs && isRunningInECS()) {\n config.keepaliveTimeoutMs = DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS;\n env['ZERO_KEEPALIVE_TIMEOUT_MS'] = String(DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS);\n }\n\n lc.info?.(`runtime env: taskID=${config.taskID}, hostIP=${hostIP}`);\n\n return {\n ...config,\n taskID: config.taskID,\n\n changeStreamer: {\n ...config.changeStreamer,\n port: config.changeStreamer.port,\n address: config.changeStreamer.address,\n },\n\n litestream: {\n ...config.litestream,\n port: config.litestream.port,\n },\n\n change: {\n ...config.change,\n db: config.change.db,\n },\n\n cvr: {\n ...config.cvr,\n db: config.cvr.db,\n },\n\n numSyncWorkers: config.numSyncWorkers,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"normalize.js","names":[],"sources":["../../../../../zero-cache/src/config/normalize.ts"],"sourcesContent":["import {availableParallelism} from 'node:os';\nimport type {LogContext} from '@rocicorp/logger';\nimport {nanoid} from 'nanoid';\nimport {assert, assertNotUndefined} from '../../../shared/src/asserts.ts';\nimport {getHostIp} from './network.ts';\nimport type {ZeroConfig} from './zero-config.ts';\n\n/** {@link ZeroConfig} with defaults set per option documentation. */\nexport type NormalizedZeroConfig = ZeroConfig & {\n taskID: string;\n changeStreamer: {\n port: number;\n address: string;\n };\n change: {\n db: string;\n };\n cvr: {\n db: string;\n };\n litestream: {\n port: number;\n };\n numSyncWorkers: number;\n};\n\nexport type LitestreamConfig = NormalizedZeroConfig['litestream'];\n\nexport function isDevelopmentMode(): boolean {\n return process.env.NODE_ENV === 'development';\n}\n\nfunction isRunningInECS(): boolean {\n // https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-environment-variables.html\n return process.env.ECS_CONTAINER_METADATA_URI_V4 !== undefined;\n}\n\nconst DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS = 20_000;\n\n/**\n * Whether this process tree runs the change-streamer, as opposed to connecting\n * to one that another task runs.\n */\nexport function runsChangeStreamer(config: ZeroConfig): boolean {\n const {mode, uri} = config.changeStreamer;\n return mode === 'dedicated' && uri === undefined;\n}\n\nexport function assertNormalized(\n config: ZeroConfig,\n): asserts config is NormalizedZeroConfig {\n assert(config.taskID, 'missing --task-id');\n assert(config.changeStreamer.port, 'missing --change-streamer-port');\n assert(config.changeStreamer.address, 'missing --change-streamer-address');\n const {pgReplicationSlotPerReplica} = config.upstream;\n const {\n pgChangeLogEnabled,\n sqliteChangeLogMode,\n sqliteChangeLogReadPercent,\n sqliteChangeLogColdReadPercent,\n sqliteChangeLogComparePercent,\n sqliteChangeLogRetentionMs,\n sqliteChangeLogReadBatchRows,\n sqliteChangeLogPurgeBatchRows,\n sqliteChangeLogBarrierTimeoutMs,\n } = config.changeStreamer;\n assert(\n Number.isSafeInteger(sqliteChangeLogReadPercent) &&\n sqliteChangeLogReadPercent >= 0 &&\n sqliteChangeLogReadPercent <= 100,\n '--change-streamer-sqlite-change-log-read-percent must be an integer between 0 and 100',\n );\n assert(\n Number.isSafeInteger(sqliteChangeLogColdReadPercent) &&\n sqliteChangeLogColdReadPercent >= 0 &&\n sqliteChangeLogColdReadPercent <= 100,\n '--change-streamer-sqlite-change-log-cold-read-percent must be an integer between 0 and 100',\n );\n // This setting has no mode restriction. Comparison starts in `compare` mode.\n assert(\n Number.isSafeInteger(sqliteChangeLogComparePercent) &&\n sqliteChangeLogComparePercent >= 0 &&\n sqliteChangeLogComparePercent <= 100,\n '--change-streamer-sqlite-change-log-compare-percent must be an integer between 0 and 100',\n );\n assert(\n sqliteChangeLogMode === 'serve' || sqliteChangeLogReadPercent === 0,\n '--change-streamer-sqlite-change-log-read-percent must be 0 unless --change-streamer-sqlite-change-log-mode=serve',\n );\n assert(\n sqliteChangeLogMode === 'serve' || sqliteChangeLogColdReadPercent === 0,\n '--change-streamer-sqlite-change-log-cold-read-percent must be 0 unless --change-streamer-sqlite-change-log-mode=serve',\n );\n // The cold gate only admits a task to the read gate; it never serves one on\n // its own. A nonzero cold percentage with a zero read percentage is a\n // silent no-op, which is the shape of a rollout that looks enabled and\n // serves nothing.\n assert(\n sqliteChangeLogReadPercent > 0 || sqliteChangeLogColdReadPercent === 0,\n '--change-streamer-sqlite-change-log-cold-read-percent must be 0 when --change-streamer-sqlite-change-log-read-percent is 0',\n );\n if (pgReplicationSlotPerReplica) {\n assert(\n !pgChangeLogEnabled,\n `--upstream-pg-replication-slot-per-replica=true requires --change-streamer-pg-change-log-enabled=false`,\n );\n }\n if (!pgChangeLogEnabled) {\n assert(\n sqliteChangeLogMode === 'serve',\n '--change-streamer-pg-change-log-enabled=false requires --change-streamer-sqlite-change-log-mode=serve',\n );\n assert(\n sqliteChangeLogReadPercent === 100,\n '--change-streamer-pg-change-log-enabled=false requires --change-streamer-sqlite-change-log-read-percent=100',\n );\n assert(\n sqliteChangeLogColdReadPercent === 100,\n '--change-streamer-pg-change-log-enabled=false requires --change-streamer-sqlite-change-log-cold-read-percent=100',\n );\n assert(\n config.litestream.backupURL && config.litestream.backupUsingV5,\n '--change-streamer-pg-change-log-enabled=false requires a litestream v5 backup',\n );\n }\n for (const [flag, value] of [\n ['retention-ms', sqliteChangeLogRetentionMs],\n ['read-batch-rows', sqliteChangeLogReadBatchRows],\n ['purge-batch-rows', sqliteChangeLogPurgeBatchRows],\n ['barrier-timeout-ms', sqliteChangeLogBarrierTimeoutMs],\n ] as const) {\n assert(\n Number.isSafeInteger(value) && value > 0,\n `--change-streamer-sqlite-change-log-${flag} must be a positive integer`,\n );\n }\n assert(config.litestream.port, 'missing --litestream-port');\n assert(\n !config.litestream.backupUsingV5 || config.litestream.restoreUsingV5,\n '--litestream-backup-using-v5 requires --litestream-restore-using-v5',\n );\n assert(\n !config.litestream.backupURL ||\n config.litestream.executableV5 ||\n !(config.litestream.restoreUsingV5 || config.litestream.backupUsingV5),\n '--litestream-restore-using-v5 and --litestream-backup-using-v5 ' +\n 'require --litestream-executable-v5 to be specified',\n );\n assert(\n !config.litestream.backupURL ||\n !config.litestream.backupUsingV5 ||\n config.litestream.vfsQueryExecutable,\n '--litestream-backup-using-v5 requires --litestream-vfs-query-executable to be specified',\n );\n assert(config.change.db, 'missing --change-db');\n assert(config.cvr.db, 'missing --cvr-db');\n assertNotUndefined(config.numSyncWorkers, 'missing --num-sync-workers');\n\n if (!isDevelopmentMode()) {\n assert(\n config.adminPassword,\n 'missing --admin-password: required in production mode',\n );\n }\n}\n\n/**\n * Normalizes the parsed `config` by setting defaults from the environment\n * or from other options as documented. When defaults are applied, the\n * corresponding `env` variable is updated so that the settings are propagated\n * to spawned child workers. Child workers can then call\n * {@link assertNormalized} to verify that the expected defaults have been set.\n */\nexport function normalizeZeroConfig(\n lc: LogContext,\n config: ZeroConfig,\n env: NodeJS.ProcessEnv,\n defaultTaskID?: string,\n): NormalizedZeroConfig {\n if (!config.taskID) {\n const taskID = defaultTaskID ?? nanoid();\n config.taskID = taskID;\n env['ZERO_TASK_ID'] = taskID;\n }\n if (!config.changeStreamer.port) {\n const port = config.port + 1;\n config.changeStreamer.port = port;\n env['ZERO_CHANGE_STREAMER_PORT'] = String(port);\n }\n if (!config.litestream.port) {\n const port = config.port + 2;\n config.litestream.port = port;\n env['ZERO_LITESTREAM_PORT'] = String(port);\n }\n if (config.numSyncWorkers === undefined) {\n // Reserve 1 core for the replicator. The change-streamer is not CPU heavy.\n const numSyncers = Math.max(1, availableParallelism() - 1);\n config.numSyncWorkers = numSyncers;\n env['ZERO_NUM_SYNC_WORKERS'] = String(numSyncers);\n }\n\n const hostIP = getHostIp(\n lc,\n config.changeStreamer.discoveryInterfacePreferences,\n );\n if (!config.changeStreamer.address) {\n const {port} = config.changeStreamer;\n const address = `${hostIP}:${port}`;\n config.changeStreamer.address = address;\n env['ZERO_CHANGE_STREAMER_ADDRESS'] = address;\n }\n\n if (!config.change.db) {\n config.change.db = config.upstream.db;\n env['ZERO_CHANGE_DB'] = config.upstream.db;\n }\n\n if (!config.cvr.db) {\n config.cvr.db = config.upstream.db;\n env['ZERO_CVR_DB'] = config.upstream.db;\n }\n\n if (!config.keepaliveTimeoutMs && isRunningInECS()) {\n config.keepaliveTimeoutMs = DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS;\n env['ZERO_KEEPALIVE_TIMEOUT_MS'] = String(DEFAULT_ECS_KEEPALIVE_TIMEOUT_MS);\n }\n\n if (config.upstream.pgHighAvailabilityReplication) {\n config.upstream.pgReplicationSlotPerReplica = true;\n env['ZERO_UPSTREAM_PG_REPLICATION_SLOT_PER_REPLICA'] = 'true';\n\n config.litestream.restoreUsingV5 = true;\n config.litestream.backupUsingV5 = true;\n env['ZERO_LITESTREAM_RESTORE_USING_V5'] = 'true';\n env['ZERO_LITESTREAM_BACKUP_USING_V5'] = 'true';\n\n config.changeStreamer.sqliteChangeLogMode = 'serve';\n env['ZERO_CHANGE_STREAMER_SQLITE_CHANGE_LOG_MODE'] = 'serve';\n\n config.changeStreamer.sqliteChangeLogReadPercent = 100;\n config.changeStreamer.sqliteChangeLogColdReadPercent = 100;\n env['ZERO_CHANGE_STREAMER_SQLITE_CHANGE_LOG_READ_PERCENT'] = '100';\n env['ZERO_CHANGE_STREAMER_SQLITE_CHANGE_LOG_COLD_READ_PERCENT'] = '100';\n\n config.changeStreamer.pgChangeLogEnabled = false;\n env['ZERO_CHANGE_STREAMER_PG_CHANGE_LOG_ENABLED'] = 'false';\n }\n\n lc.info?.(`runtime env: taskID=${config.taskID}, hostIP=${hostIP}`);\n\n return {\n ...config,\n taskID: config.taskID,\n\n changeStreamer: {\n ...config.changeStreamer,\n port: config.changeStreamer.port,\n address: config.changeStreamer.address,\n },\n\n litestream: {\n ...config.litestream,\n port: config.litestream.port,\n },\n\n change: {\n ...config.change,\n db: config.change.db,\n },\n\n cvr: {\n ...config.cvr,\n db: config.cvr.db,\n },\n\n numSyncWorkers: config.numSyncWorkers,\n };\n}\n"],"mappings":"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"}
|
|
@@ -111,6 +111,26 @@ export declare const zeroOptions: {
|
|
|
111
111
|
type: v.Optional<boolean>;
|
|
112
112
|
desc: string[];
|
|
113
113
|
};
|
|
114
|
+
pgReplicationSlotPerReplica: {
|
|
115
|
+
type: v.Type<boolean>;
|
|
116
|
+
desc: string[];
|
|
117
|
+
hidden: boolean;
|
|
118
|
+
};
|
|
119
|
+
pgHighAvailabilityReplication: {
|
|
120
|
+
type: v.Optional<boolean>;
|
|
121
|
+
desc: string[];
|
|
122
|
+
hidden: boolean;
|
|
123
|
+
};
|
|
124
|
+
pgResumeOrphanedSlotGracePeriodMs: {
|
|
125
|
+
type: v.Type<number>;
|
|
126
|
+
desc: string[];
|
|
127
|
+
hidden: boolean;
|
|
128
|
+
};
|
|
129
|
+
pgReplicationEpoch: {
|
|
130
|
+
type: v.Type<number>;
|
|
131
|
+
desc: string[];
|
|
132
|
+
hidden: boolean;
|
|
133
|
+
};
|
|
114
134
|
pgPartialIndexTriggers: {
|
|
115
135
|
type: v.Type<boolean>;
|
|
116
136
|
hidden: boolean;
|
|
@@ -273,10 +293,25 @@ export declare const zeroOptions: {
|
|
|
273
293
|
desc: string[];
|
|
274
294
|
hidden: boolean;
|
|
275
295
|
};
|
|
296
|
+
snapshotRowCacheSize: {
|
|
297
|
+
type: v.Type<number>;
|
|
298
|
+
desc: string[];
|
|
299
|
+
hidden: boolean;
|
|
300
|
+
};
|
|
276
301
|
enableQueryPlanner: {
|
|
277
302
|
type: v.Type<boolean>;
|
|
278
303
|
desc: string[];
|
|
279
304
|
};
|
|
305
|
+
enableCorrelatedPredicatePushdown: {
|
|
306
|
+
type: v.Type<boolean>;
|
|
307
|
+
desc: string[];
|
|
308
|
+
hidden: boolean;
|
|
309
|
+
};
|
|
310
|
+
enablePlannerAwarePushdown: {
|
|
311
|
+
type: v.Type<boolean>;
|
|
312
|
+
desc: string[];
|
|
313
|
+
hidden: boolean;
|
|
314
|
+
};
|
|
280
315
|
enableQueryCovering: {
|
|
281
316
|
type: v.Type<boolean>;
|
|
282
317
|
desc: string[];
|
|
@@ -285,6 +320,14 @@ export declare const zeroOptions: {
|
|
|
285
320
|
type: v.Type<number>;
|
|
286
321
|
desc: string[];
|
|
287
322
|
};
|
|
323
|
+
viewSyncerHydrationBudgetMs: {
|
|
324
|
+
type: v.Type<number>;
|
|
325
|
+
desc: string[];
|
|
326
|
+
};
|
|
327
|
+
viewSyncerQueryHydrationTimeoutMs: {
|
|
328
|
+
type: v.Type<number>;
|
|
329
|
+
desc: string[];
|
|
330
|
+
};
|
|
288
331
|
change: {
|
|
289
332
|
db: {
|
|
290
333
|
type: v.Optional<string>;
|
|
@@ -439,6 +482,11 @@ export declare const zeroOptions: {
|
|
|
439
482
|
desc: string[];
|
|
440
483
|
hidden: boolean;
|
|
441
484
|
};
|
|
485
|
+
pgChangeLogEnabled: {
|
|
486
|
+
type: v.Type<boolean>;
|
|
487
|
+
desc: string[];
|
|
488
|
+
hidden: boolean;
|
|
489
|
+
};
|
|
442
490
|
sqliteChangeLogReadPercent: {
|
|
443
491
|
type: v.Type<number>;
|
|
444
492
|
desc: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zero-config.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/zero-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,+BAA+B,CAAC;AAUnD,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAC,SAAS,EAAC,MAAM,kCAAkC,CAAC;AAEhE,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C,eAAO,MAAM,UAAU;IACrB,EAAE;QACA,IAAI;QAIJ,IAAI;;IAuBN,YAAY;QACV,IAAI;QACJ,IAAI;;CAgBP,CAAC;AAEF,eAAO,MAAM,YAAY;IACvB,EAAE;QACA,IAAI;QASJ,MAAM;;IAGR,GAAG;QACD,IAAI;QACJ,IAAI;QAMJ,MAAM;;CAET,CAAC;AAEF,QAAA,MAAM,cAAc;IAClB,IAAI;QACF,IAAI;QACJ,IAAI;;IAON,mBAAmB;QACjB,IAAI;QACJ,IAAI;;CAOP,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,QAAA,MAAM,oBAAoB;IACxB,GAAG;QACD,IAAI;QACJ,IAAI;;IAKN,QAAQ;QACN,IAAI;QACJ,IAAI;;CAIP,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE5D,QAAA,MAAM,WAAW;IACf,GAAG;QACD,IAAI;QACJ,IAAI;QAGJ,UAAU;;IAIZ,OAAO;QACL,IAAI;QACJ,IAAI;QAGJ,UAAU;;IAIZ,MAAM;QACJ,IAAI;QACJ,IAAI;QAGJ,UAAU;;IAIZ,MAAM;QACJ,IAAI;QACJ,IAAI;QAIJ,UAAU;;IAIZ,QAAQ;QACN,IAAI;QACJ,IAAI;QAIJ,UAAU;;IAIZ,yBAAyB;QACvB,IAAI;QACJ,IAAI;;IAKN,0BAA0B;QACxB,IAAI;QACJ,IAAI;;CAKP,CAAC;AA0HF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAEpD,+DAA+D;AAC/D,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,UAAU,EACV,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CACrD,CAAC;AAKF,eAAO,MAAM,WAAW;;QAEpB,EAAE;YACA,IAAI;YACJ,IAAI;;QAMN,IAAI;YACF,IAAI;YACJ,IAAI;YAMJ,MAAM;;QAGR,QAAQ;YACN,IAAI;YACJ,IAAI;;QAWN,iBAAiB;YACf,IAAI;YACJ,MAAM;;QAGR,yBAAyB;YACvB,IAAI;YACJ,IAAI;;
|
|
1
|
+
{"version":3,"file":"zero-config.d.ts","sourceRoot":"","sources":["../../../../../zero-cache/src/config/zero-config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAGL,KAAK,MAAM,EACX,KAAK,YAAY,EAClB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,CAAC,MAAM,+BAA+B,CAAC;AAUnD,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAC,SAAS,EAAC,MAAM,kCAAkC,CAAC;AAEhE,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C,eAAO,MAAM,UAAU;IACrB,EAAE;QACA,IAAI;QAIJ,IAAI;;IAuBN,YAAY;QACV,IAAI;QACJ,IAAI;;CAgBP,CAAC;AAEF,eAAO,MAAM,YAAY;IACvB,EAAE;QACA,IAAI;QASJ,MAAM;;IAGR,GAAG;QACD,IAAI;QACJ,IAAI;QAMJ,MAAM;;CAET,CAAC;AAEF,QAAA,MAAM,cAAc;IAClB,IAAI;QACF,IAAI;QACJ,IAAI;;IAON,mBAAmB;QACjB,IAAI;QACJ,IAAI;;CAOP,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,QAAA,MAAM,oBAAoB;IACxB,GAAG;QACD,IAAI;QACJ,IAAI;;IAKN,QAAQ;QACN,IAAI;QACJ,IAAI;;CAIP,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAE5D,QAAA,MAAM,WAAW;IACf,GAAG;QACD,IAAI;QACJ,IAAI;QAGJ,UAAU;;IAIZ,OAAO;QACL,IAAI;QACJ,IAAI;QAGJ,UAAU;;IAIZ,MAAM;QACJ,IAAI;QACJ,IAAI;QAGJ,UAAU;;IAIZ,MAAM;QACJ,IAAI;QACJ,IAAI;QAIJ,UAAU;;IAIZ,QAAQ;QACN,IAAI;QACJ,IAAI;QAIJ,UAAU;;IAIZ,yBAAyB;QACvB,IAAI;QACJ,IAAI;;IAKN,0BAA0B;QACxB,IAAI;QACJ,IAAI;;CAKP,CAAC;AA0HF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAEpD,+DAA+D;AAC/D,MAAM,MAAM,mBAAmB,GAAG,IAAI,CACpC,UAAU,EACV,KAAK,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CACrD,CAAC;AAKF,eAAO,MAAM,WAAW;;QAEpB,EAAE;YACA,IAAI;YACJ,IAAI;;QAMN,IAAI;YACF,IAAI;YACJ,IAAI;YAMJ,MAAM;;QAGR,QAAQ;YACN,IAAI;YACJ,IAAI;;QAWN,iBAAiB;YACf,IAAI;YACJ,MAAM;;QAGR,yBAAyB;YACvB,IAAI;YACJ,IAAI;;QAYN,2BAA2B;YACzB,IAAI;YACJ,IAAI;YAIJ,MAAM;;QAGR,6BAA6B;YAC3B,IAAI;YACJ,IAAI;YAiBJ,MAAM;;QAGR,iCAAiC;YAC/B,IAAI;YACJ,IAAI;YAUJ,MAAM;;QAGR,kBAAkB;YAChB,IAAI;YACJ,IAAI;YAeJ,MAAM;;QAMR,sBAAsB;YACpB,IAAI;YACJ,MAAM;;QAGR,wBAAwB;YACtB,IAAI;YACJ,IAAI;;;IAqBR,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAGlB,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAKhB,IAAI;QACJ,IAAI;;;QAQJ,IAAI;QACJ,IAAI;;;QAQJ,EAAE;YACA,IAAI;YACJ,IAAI;;QAON,QAAQ;YACN,IAAI;YACJ,IAAI;;QASN,iBAAiB;YACf,IAAI;YACJ,MAAM;;QAGR,yCAAyC;YACvC,IAAI;YACJ,IAAI;;QAUN,uCAAuC;YACrC,IAAI;YACJ,IAAI;;QAON,iCAAiC;YAC/B,IAAI;YACJ,IAAI;;;;QAWN,IAAI;QACJ,IAAI;;;QAQJ,IAAI;QACJ,IAAI;QAIJ,MAAM;;;QAIN,IAAI;QACJ,IAAI;QASJ,MAAM;;;QAIN,IAAI;QACJ,IAAI;;;QAWJ,IAAI;QACJ,IAAI;QAOJ,MAAM;;;QAIN,IAAI;QACJ,IAAI;QAOJ,MAAM;;;QAIN,IAAI;QACJ,IAAI;;;QAWJ,IAAI;QACJ,IAAI;;;QASJ,IAAI;QAOJ,IAAI;;;QAYJ,IAAI;QAOJ,IAAI;;;QAYJ,EAAE;YACA,IAAI;YACJ,IAAI;;QAON,kBAAkB;QAClB,QAAQ;YACN,IAAI;YACJ,UAAU;YAIV,MAAM;;QAGR,kBAAkB;YAChB,IAAI;YACJ,IAAI;YAMJ,MAAM;;QAGR,YAAY;YACV,IAAI;YAOJ,IAAI;YAQJ,MAAM;;;;;YAnoBR,IAAI;YACJ,IAAI;;;YAQJ,IAAI;YACJ,IAAI;;;;;;;;;;;;;;;;;;;;;;;;YArFJ,IAAI;YAIJ,IAAI;;;YAwBJ,IAAI;YACJ,IAAI;;;;;YAoBJ,IAAI;YASJ,MAAM;;;YAIN,IAAI;YACJ,IAAI;YAMJ,MAAM;;;;;YA+CN,IAAI;YACJ,IAAI;YAGJ,UAAU;;;YAKV,IAAI;YACJ,IAAI;YAGJ,UAAU;;;YAKV,IAAI;YACJ,IAAI;YAGJ,UAAU;;;YAKV,IAAI;YACJ,IAAI;YAIJ,UAAU;;;YAKV,IAAI;YACJ,IAAI;YAIJ,UAAU;;;YAKV,IAAI;YACJ,IAAI;;;YAMJ,IAAI;YACJ,IAAI;;;;QAkjBJ,IAAI;QACJ,IAAI;;;QAIJ,IAAI;QACJ,IAAI;;;QAoBJ,GAAG;YACD,IAAI;YACJ,IAAI;;QAQN,IAAI;YACF,IAAI;YACJ,IAAI;;QAaN,IAAI;YACF,IAAI;YACJ,IAAI;;QASN,kBAAkB;QAClB,OAAO;YACL,IAAI;YACJ,UAAU;YAGV,MAAM;;QAGR,kBAAkB;QAClB,QAAQ;YACN,IAAI;YACJ,UAAU;YAGV,MAAM;;QAGR,6BAA6B;YAC3B,IAAI;YACJ,IAAI;YASJ,MAAM;;QAGR,cAAc;YACZ,IAAI;YACJ,IAAI;;QASN,mBAAmB;YACjB,IAAI;YACJ,IAAI;YAIJ,MAAM;;QAGR,kBAAkB;YAChB,IAAI;YACJ,IAAI;YAKJ,MAAM;;QAGR,0BAA0B;YACxB,IAAI;YACJ,IAAI;YAGJ,MAAM;;QAGR,8BAA8B;YAC5B,IAAI;YACJ,IAAI;YAQJ,MAAM;;QAGR,6BAA6B;YAC3B,IAAI;YACJ,IAAI;YAIJ,MAAM;;QAGR,0BAA0B;YACxB,IAAI;YACJ,IAAI;YACJ,MAAM;;QAGR,4BAA4B;YAC1B,IAAI;YACJ,IAAI;YACJ,MAAM;;QAGR,6BAA6B;YAC3B,IAAI;YACJ,IAAI;YACJ,MAAM;;QAGR,+BAA+B;YAC7B,IAAI;YACJ,IAAI;YAQJ,MAAM;;QAGR,+BAA+B;YAC7B,IAAI;YACJ,IAAI;;QAsBN,qCAAqC;YACnC,IAAI;YACJ,IAAI;;QA0BN,2CAA2C;YACzC,IAAI;YACJ,IAAI;;;;QA2BN,IAAI;QACJ,IAAI;;;;YAt4BJ,IAAI;YACJ,IAAI;;;YAMJ,IAAI;YACJ,IAAI;;;;QA04BJ,IAAI;QACJ,IAAI;;;QASJ,IAAI;QACJ,IAAI;;;QAgBJ,gBAAgB;YACd,IAAI;YACJ,IAAI;;;;QAaN,IAAI;QACJ,IAAI;;;QASJ,IAAI;QACJ,IAAI;;;QAWJ,IAAI;QACJ,IAAI;;;QAYJ,IAAI;QACJ,IAAI;;;QASJ,UAAU;YACR,IAAI;YACJ,IAAI;;QAON,YAAY;YACV,IAAI;YACJ,IAAI;;QASN,cAAc;YACZ,IAAI;YACJ,IAAI;;QAON,aAAa;YACX,IAAI;YACJ,IAAI;;QAQN,UAAU;YACR,IAAI;YACJ,IAAI;;QAWN,YAAY;YACV,IAAI;YACJ,IAAI;;QAWN,kBAAkB;YAChB,IAAI;YACJ,IAAI;;QAMN,iBAAiB;YACf,IAAI;YACJ,IAAI;;QASN,gBAAgB;YACd,IAAI;YACJ,IAAI;;QAKN,UAAU;YACR,IAAI;YACJ,IAAI;;QAMN,QAAQ;YACN,IAAI;;QAGN,SAAS;YACP,IAAI;YACJ,IAAI;;QAON,QAAQ;YACN,IAAI;YACJ,IAAI;;QAMN,MAAM;YACJ,IAAI;YACJ,IAAI;;QAON,IAAI;YACF,IAAI;YACJ,IAAI;;QAQN,qBAAqB;YACnB,IAAI;YACJ,IAAI;;QAUN,sBAAsB;YACpB,IAAI;YACJ,UAAU;YACV,MAAM;;QAGR,sBAAsB;YACpB,IAAI;YACJ,IAAI;;QAUN,0BAA0B;YACxB,IAAI;YACJ,IAAI;;QAqBN,YAAY;YACV,IAAI;YACJ,IAAI;;QAgBN,gCAAgC;YAC9B,IAAI;YACJ,IAAI;;QAYN,2BAA2B;YACzB,IAAI;YACJ,IAAI;;QAaN,gCAAgC;YAC9B,IAAI;YACJ,IAAI;;QAcN,6BAA6B;YAC3B,IAAI;YACJ,IAAI;;QAuBN,kBAAkB;YAChB,IAAI;YACJ,IAAI;;QAMN,oBAAoB;YAClB,IAAI;YACJ,IAAI;;QAMN,aAAa;YACX,IAAI;YACJ,IAAI;;;;QASN,IAAI;QACJ,IAAI;;;QAMJ,gBAAgB;YACd,IAAI;YACJ,IAAI;;QASN,WAAW;YACT,IAAI;YACJ,MAAM;YACN,IAAI;;QAMN,QAAQ;YACN,IAAI;YACJ,IAAI;;;;QASN,OAAO;YACL,IAAI;YACJ,IAAI;;QASN,aAAa;YACX,IAAI;YACJ,IAAI;;QASN,UAAU;YACR,IAAI;YACJ,IAAI;;QAON,eAAe;YACb,IAAI;YACJ,IAAI;;;IAOR,kBAAkB;;QAEhB,IAAI;QACJ,UAAU;QAKV,MAAM;;;QAIN,IAAI;QACJ,IAAI;;;QAWJ,IAAI;QACJ,IAAI;;;QAIJ,IAAI;QACJ,IAAI;;;QASJ,OAAO;YACL,IAAI;YACJ,IAAI;;QAYN,qBAAqB;YACnB,IAAI;YACJ,IAAI;;;CAST,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAIpD,wBAAgB,aAAa,CAC3B,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAM,GAC7C,UAAU,CAaZ;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,GAAE,IAAI,CAAC,YAAY,EAAE,eAAe,CAAM,GAC7C,oBAAoB,CAItB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG,SAAS,GACpD,MAAM,CAER;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,UAAU,EACd,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,eAAe,CAAC,EACnD,QAAQ,EAAE,MAAM,GAAG,SAAS,WAwC7B;AAYD,wBAAgB,kBAAkB,SAEjC"}
|