@rocicorp/zero 1.3.0 → 1.4.0-canary.1
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/analyze-cli.d.ts +24 -0
- package/out/analyze-query/src/analyze-cli.d.ts.map +1 -0
- package/out/analyze-query/src/analyze-cli.js +289 -0
- package/out/analyze-query/src/analyze-cli.js.map +1 -0
- package/out/analyze-query/src/bin-analyze.js +6 -6
- package/out/analyze-query/src/bin-transform.js +2 -2
- package/out/ast-to-zql/src/bin.js +1 -1
- package/out/shared/src/logging.d.ts.map +1 -1
- package/out/shared/src/logging.js +1 -1
- package/out/shared/src/logging.js.map +1 -1
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/options.js +1 -1
- package/out/shared/src/options.js.map +1 -1
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +4 -1
- package/out/z2s/src/compiler.js.map +1 -1
- package/out/z2s/src/sql.d.ts.map +1 -1
- package/out/z2s/src/sql.js +1 -0
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.js +95 -89
- package/out/zero/package.js.map +1 -1
- package/out/zero/src/analyze.d.ts +2 -0
- package/out/zero/src/analyze.d.ts.map +1 -0
- package/out/zero/src/analyze.js +2 -0
- package/out/zero/src/bindings.js +1 -1
- package/out/zero/src/zero-cache-dev.js +1 -1
- package/out/zero/src/zero-cache-dev.js.map +1 -1
- package/out/zero/src/zero-out.js +1 -1
- package/out/zero-cache/src/auth/auth.d.ts.map +1 -1
- package/out/zero-cache/src/auth/auth.js.map +1 -1
- package/out/zero-cache/src/auth/load-permissions.js +2 -2
- package/out/zero-cache/src/auth/write-authorizer.d.ts.map +1 -1
- package/out/zero-cache/src/auth/write-authorizer.js +5 -14
- package/out/zero-cache/src/auth/write-authorizer.js.map +1 -1
- package/out/zero-cache/src/config/network.d.ts +1 -1
- package/out/zero-cache/src/config/network.d.ts.map +1 -1
- package/out/zero-cache/src/config/network.js +1 -1
- package/out/zero-cache/src/config/network.js.map +1 -1
- package/out/zero-cache/src/config/normalize.d.ts.map +1 -1
- package/out/zero-cache/src/config/normalize.js.map +1 -1
- package/out/zero-cache/src/config/zero-config.d.ts +5 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +16 -3
- 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 -3
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.d.ts +43 -40
- package/out/zero-cache/src/db/transaction-pool.d.ts.map +1 -1
- package/out/zero-cache/src/db/transaction-pool.js +76 -56
- package/out/zero-cache/src/db/transaction-pool.js.map +1 -1
- package/out/zero-cache/src/observability/events.d.ts.map +1 -1
- package/out/zero-cache/src/observability/events.js +1 -1
- package/out/zero-cache/src/observability/events.js.map +1 -1
- package/out/zero-cache/src/scripts/decommission.js +1 -1
- package/out/zero-cache/src/scripts/deploy-permissions.js +2 -2
- package/out/zero-cache/src/scripts/permissions.js +1 -1
- package/out/zero-cache/src/server/anonymous-otel-start.d.ts.map +1 -1
- package/out/zero-cache/src/server/anonymous-otel-start.js +4 -4
- package/out/zero-cache/src/server/anonymous-otel-start.js.map +1 -1
- package/out/zero-cache/src/server/change-streamer.d.ts +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 -12
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/logging.d.ts +1 -3
- package/out/zero-cache/src/server/logging.d.ts.map +1 -1
- package/out/zero-cache/src/server/logging.js +6 -3
- package/out/zero-cache/src/server/logging.js.map +1 -1
- package/out/zero-cache/src/server/main.d.ts.map +1 -1
- package/out/zero-cache/src/server/main.js +26 -26
- package/out/zero-cache/src/server/main.js.map +1 -1
- package/out/zero-cache/src/server/mutator.js +4 -2
- package/out/zero-cache/src/server/mutator.js.map +1 -1
- package/out/zero-cache/src/server/otel-log-sink.d.ts.map +1 -1
- package/out/zero-cache/src/server/otel-log-sink.js +0 -2
- package/out/zero-cache/src/server/otel-log-sink.js.map +1 -1
- package/out/zero-cache/src/server/otel-start.d.ts +1 -1
- package/out/zero-cache/src/server/otel-start.d.ts.map +1 -1
- package/out/zero-cache/src/server/otel-start.js +7 -3
- package/out/zero-cache/src/server/otel-start.js.map +1 -1
- package/out/zero-cache/src/server/reaper.js +6 -6
- 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 +5 -3
- package/out/zero-cache/src/server/replicator.js.map +1 -1
- package/out/zero-cache/src/server/runner/run-worker.js +2 -2
- package/out/zero-cache/src/server/runner/run-worker.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +13 -12
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/server/worker-dispatcher.js +1 -1
- package/out/zero-cache/src/services/analyze.js +1 -1
- package/out/zero-cache/src/services/change-source/common/backfill-manager.js +1 -1
- package/out/zero-cache/src/services/change-source/common/replica-schema.js +1 -1
- package/out/zero-cache/src/services/change-source/custom/change-source.js +2 -2
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js +4 -1
- package/out/zero-cache/src/services/change-source/pg/backfill-stream.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +19 -23
- 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 +58 -3
- 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 +209 -52
- package/out/zero-cache/src/services/change-source/pg/initial-sync.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/stream.js +2 -2
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +24 -15
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js +35 -58
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/init.js +2 -2
- package/out/zero-cache/src/services/change-source/pg/schema/init.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +1 -2
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/published.js +15 -18
- package/out/zero-cache/src/services/change-source/pg/schema/published.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/shard.js +1 -1
- package/out/zero-cache/src/services/change-source/protocol/current/data.js +1 -1
- package/out/zero-cache/src/services/change-streamer/backup-monitor.js +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js +1 -1
- 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 +5 -1
- 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 +10 -7
- package/out/zero-cache/src/services/change-streamer/change-streamer-service.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/replica-monitor.js +2 -2
- package/out/zero-cache/src/services/change-streamer/storer.d.ts +19 -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 +70 -6
- package/out/zero-cache/src/services/change-streamer/storer.js.map +1 -1
- package/out/zero-cache/src/services/heapz.d.ts.map +1 -1
- package/out/zero-cache/src/services/heapz.js +1 -1
- package/out/zero-cache/src/services/heapz.js.map +1 -1
- package/out/zero-cache/src/services/life-cycle.d.ts +2 -1
- package/out/zero-cache/src/services/life-cycle.d.ts.map +1 -1
- package/out/zero-cache/src/services/life-cycle.js +10 -7
- package/out/zero-cache/src/services/life-cycle.js.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.d.ts +15 -4
- package/out/zero-cache/src/services/litestream/commands.d.ts.map +1 -1
- package/out/zero-cache/src/services/litestream/commands.js +40 -34
- package/out/zero-cache/src/services/litestream/commands.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +3 -3
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +28 -28
- package/out/zero-cache/src/services/replicator/change-processor.js +2 -2
- package/out/zero-cache/src/services/replicator/incremental-sync.js +1 -1
- package/out/zero-cache/src/services/replicator/schema/replication-state.js +1 -1
- package/out/zero-cache/src/services/replicator/write-worker-client.js.map +1 -1
- package/out/zero-cache/src/services/replicator/write-worker.js +3 -3
- package/out/zero-cache/src/services/replicator/write-worker.js.map +1 -1
- package/out/zero-cache/src/services/run-ast.d.ts.map +1 -1
- package/out/zero-cache/src/services/run-ast.js +3 -3
- package/out/zero-cache/src/services/run-ast.js.map +1 -1
- package/out/zero-cache/src/services/statz.d.ts.map +1 -1
- package/out/zero-cache/src/services/statz.js +3 -3
- package/out/zero-cache/src/services/statz.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/active-users-gauge.js +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts +2 -2
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/connection-context-manager.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-purger.js +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +3 -3
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +1 -1
- package/out/zero-cache/src/services/view-syncer/inspect-handler.js +2 -2
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +6 -16
- 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 +31 -39
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js +4 -4
- package/out/zero-cache/src/services/view-syncer/row-record-cache.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/snapshotter.js +2 -2
- 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 +6 -6
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/profiler.d.ts.map +1 -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.map +1 -1
- package/out/zero-cache/src/types/streams.d.ts +1 -1
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.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 +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +1 -1
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js.map +1 -1
- package/out/zero-cache/src/workers/mutator.js.map +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts +1 -1
- package/out/zero-cache/src/workers/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/workers/syncer.js +3 -3
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/bindings.js +1 -1
- package/out/zero-client/src/client/crud-impl.d.ts.map +1 -1
- package/out/zero-client/src/client/crud-impl.js +4 -13
- package/out/zero-client/src/client/crud-impl.js.map +1 -1
- package/out/zero-client/src/client/inspector/inspector.d.ts +24 -0
- package/out/zero-client/src/client/inspector/inspector.d.ts.map +1 -1
- package/out/zero-client/src/client/inspector/inspector.js +28 -0
- package/out/zero-client/src/client/inspector/inspector.js.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.d.ts +9 -0
- package/out/zero-client/src/client/inspector/lazy-inspector.d.ts.map +1 -1
- package/out/zero-client/src/client/inspector/lazy-inspector.js +28 -1
- 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 +4 -13
- package/out/zero-client/src/client/ivm-branch.js.map +1 -1
- package/out/zero-client/src/client/log-options.d.ts +1 -0
- package/out/zero-client/src/client/log-options.d.ts.map +1 -1
- package/out/zero-client/src/client/log-options.js +3 -2
- package/out/zero-client/src/client/log-options.js.map +1 -1
- package/out/zero-client/src/client/options.d.ts +13 -1
- 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/version.js +1 -1
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.js +2 -1
- package/out/zero-client/src/client/zero.js.map +1 -1
- package/out/zero-protocol/src/error.d.ts.map +1 -1
- package/out/zero-protocol/src/error.js +1 -1
- package/out/zero-protocol/src/error.js.map +1 -1
- package/out/zero-react/src/bindings.js +1 -1
- package/out/zero-solid/src/bindings.js +1 -1
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.js +14 -14
- package/out/zero-solid/src/solid-view.js.map +1 -1
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/ivm/array-view.d.ts.map +1 -1
- package/out/zql/src/ivm/array-view.js +27 -2
- package/out/zql/src/ivm/array-view.js.map +1 -1
- package/out/zql/src/ivm/change-index-enum.d.ts +9 -0
- package/out/zql/src/ivm/change-index-enum.d.ts.map +1 -0
- package/out/zql/src/ivm/change-index.d.ts +5 -0
- package/out/zql/src/ivm/change-index.d.ts.map +1 -0
- package/out/zql/src/ivm/change-type-enum.d.ts +9 -0
- package/out/zql/src/ivm/change-type-enum.d.ts.map +1 -0
- package/out/zql/src/ivm/change-type.d.ts +5 -0
- package/out/zql/src/ivm/change-type.d.ts.map +1 -0
- package/out/zql/src/ivm/change.d.ts +20 -22
- package/out/zql/src/ivm/change.d.ts.map +1 -1
- package/out/zql/src/ivm/change.js +33 -0
- package/out/zql/src/ivm/change.js.map +1 -0
- package/out/zql/src/ivm/exists.d.ts.map +1 -1
- package/out/zql/src/ivm/exists.js +27 -38
- package/out/zql/src/ivm/exists.js.map +1 -1
- package/out/zql/src/ivm/fan-in.d.ts +3 -2
- package/out/zql/src/ivm/fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-in.js.map +1 -1
- package/out/zql/src/ivm/fan-out.d.ts +1 -1
- package/out/zql/src/ivm/fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/fan-out.js +1 -1
- package/out/zql/src/ivm/fan-out.js.map +1 -1
- package/out/zql/src/ivm/filter-operators.d.ts +3 -3
- package/out/zql/src/ivm/filter-operators.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-operators.js.map +1 -1
- package/out/zql/src/ivm/filter-push.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-push.js +7 -7
- package/out/zql/src/ivm/filter-push.js.map +1 -1
- package/out/zql/src/ivm/filter.d.ts +1 -1
- package/out/zql/src/ivm/filter.d.ts.map +1 -1
- package/out/zql/src/ivm/filter.js.map +1 -1
- package/out/zql/src/ivm/flipped-join.d.ts.map +1 -1
- package/out/zql/src/ivm/flipped-join.js +49 -58
- package/out/zql/src/ivm/flipped-join.js.map +1 -1
- package/out/zql/src/ivm/join-utils.d.ts +2 -6
- package/out/zql/src/ivm/join-utils.d.ts.map +1 -1
- package/out/zql/src/ivm/join-utils.js +25 -25
- package/out/zql/src/ivm/join-utils.js.map +1 -1
- package/out/zql/src/ivm/join.d.ts.map +1 -1
- package/out/zql/src/ivm/join.js +32 -51
- 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 +5 -10
- package/out/zql/src/ivm/maybe-split-and-push-edit-change.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js +52 -60
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/operator.d.ts +1 -1
- package/out/zql/src/ivm/operator.d.ts.map +1 -1
- package/out/zql/src/ivm/operator.js +2 -4
- package/out/zql/src/ivm/operator.js.map +1 -1
- package/out/zql/src/ivm/push-accumulated.d.ts +3 -2
- package/out/zql/src/ivm/push-accumulated.d.ts.map +1 -1
- package/out/zql/src/ivm/push-accumulated.js +98 -122
- package/out/zql/src/ivm/push-accumulated.js.map +1 -1
- package/out/zql/src/ivm/skip-yields.d.ts +4 -0
- package/out/zql/src/ivm/skip-yields.d.ts.map +1 -0
- package/out/zql/src/ivm/skip-yields.js +33 -0
- package/out/zql/src/ivm/skip-yields.js.map +1 -0
- package/out/zql/src/ivm/skip.d.ts +1 -1
- package/out/zql/src/ivm/skip.d.ts.map +1 -1
- package/out/zql/src/ivm/skip.js +2 -2
- package/out/zql/src/ivm/skip.js.map +1 -1
- package/out/zql/src/ivm/source-change-index-enum.d.ts +7 -0
- package/out/zql/src/ivm/source-change-index-enum.d.ts.map +1 -0
- package/out/zql/src/ivm/source-change-index.d.ts +5 -0
- package/out/zql/src/ivm/source-change-index.d.ts.map +1 -0
- package/out/zql/src/ivm/source.d.ts +11 -13
- package/out/zql/src/ivm/source.d.ts.map +1 -1
- package/out/zql/src/ivm/source.js +26 -0
- package/out/zql/src/ivm/source.js.map +1 -0
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js +27 -50
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/ivm/union-fan-in.d.ts +2 -1
- package/out/zql/src/ivm/union-fan-in.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-in.js +3 -3
- package/out/zql/src/ivm/union-fan-in.js.map +1 -1
- package/out/zql/src/ivm/union-fan-out.d.ts.map +1 -1
- package/out/zql/src/ivm/union-fan-out.js +1 -1
- package/out/zql/src/ivm/union-fan-out.js.map +1 -1
- package/out/zql/src/ivm/view-apply-change.js +1 -1
- package/out/zql/src/planner/planner-debug.d.ts +2 -2
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -1
- package/out/zql/src/planner/planner-debug.js.map +1 -1
- package/out/zql/src/planner/planner-graph.d.ts +1 -1
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -1
- package/out/zql/src/planner/planner-graph.js.map +1 -1
- package/out/zqlite/src/internal/sql-inline.d.ts.map +1 -1
- package/out/zqlite/src/internal/sql-inline.js.map +1 -1
- package/out/zqlite/src/query-builder.d.ts.map +1 -1
- package/out/zqlite/src/query-builder.js.map +1 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js +11 -11
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +99 -93
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change.js","names":[],"sources":["../../../../../zql/src/ivm/change.ts"],"sourcesContent":["import {ChangeType} from './change-type.ts';\nimport type {Node} from './data.ts';\n\n/**\n * The `child` payload carried by a {@linkcode ChildChange}.\n */\nexport type ChildData = {\n relationshipName: string;\n change: Change;\n};\n\nexport type Change = AddChange | RemoveChange | ChildChange | EditChange;\n\n/**\n * Represents a node (and all its children) getting added to the result.\n */\nexport type AddChange = [type: ChangeType.ADD, node: Node, extra: null];\n\n/**\n * Represents a node (and all its children) getting removed from the result.\n */\nexport type RemoveChange = [type: ChangeType.REMOVE, node: Node, extra: null];\n\n/**\n * The node's row is unchanged, but one of its descendants has changed.\n * The node's relationships will reflect the change, `child` specifies the\n * specific descendant change.\n */\nexport type ChildChange = [\n type: ChangeType.CHILD,\n node: Node,\n child: ChildData,\n];\n\n/**\n * The row changed (in a way that the {@linkcode Source} determines). Most\n * likely the PK stayed the same but there is really no restriction in how it\n * can change.\n *\n * The edit changes flows down in a {@linkcode Output.push}.\n * There are cases where an edit change gets split into a remove and/or an add\n * change.\n * 1. when the presence of the row in the result changes (for example the row\n * is no longer present due to a filter)\n * 2. the edit results in the rows relationships changing\n *\n * If an edit is not split, the relationships of node and oldNode must\n * be the same, just the Row has changed.\n *\n * NOTE: It would be cleaner to just have the relationships once,\n * since they must be the same, however relationship Streams are single use\n * and if an Edit needs to be split into a remove and add a single map\n * of relationship Streams could not be used for the both the remove and\n * the add. This cleanup could be done if we move to multi-use Streams\n * for relationships.\n */\nexport type EditChange = [type: ChangeType.EDIT, node: Node, oldNode: Node];\n\n// Factory functions — prefer these over constructing tuple literals directly.\n\nexport function makeAddChange(node: Node): AddChange {\n return [ChangeType.ADD, node, null];\n}\n\nexport function makeRemoveChange(node: Node): RemoveChange {\n return [ChangeType.REMOVE, node, null];\n}\n\nexport function makeChildChange(node: Node, child: ChildData): ChildChange {\n return [ChangeType.CHILD, node, child];\n}\n\nexport function makeEditChange(node: Node, oldNode: Node): EditChange {\n return [ChangeType.EDIT, node, oldNode];\n}\n"],"mappings":";AA4DA,SAAgB,cAAc,MAAuB;AACnD,QAAO;EAAC;EAAgB;EAAM;EAAK;;AAGrC,SAAgB,iBAAiB,MAA0B;AACzD,QAAO;EAAC;EAAmB;EAAM;EAAK;;AAGxC,SAAgB,gBAAgB,MAAY,OAA+B;AACzE,QAAO;EAAC;EAAkB;EAAM;EAAM;;AAGxC,SAAgB,eAAe,MAAY,SAA2B;AACpE,QAAO;EAAC;EAAiB;EAAM;EAAQ"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exists.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/exists.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"exists.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/exists.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mCAAmC,CAAC;AAGnE,OAAO,EAAkC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AACzE,OAAO,EAAqB,KAAK,IAAI,EAAuB,MAAM,WAAW,CAAC;AAC9E,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC;;;GAGG;AACH,qBAAa,MAAO,YAAW,cAAc;;gBAqBzC,KAAK,EAAE,WAAW,EAClB,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,WAAW,EAC1B,IAAI,EAAE,QAAQ,GAAG,YAAY,EAC7B,wBAAwB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;IAqBhD,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI3C,WAAW;IAIX,SAAS;IAKR,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAqBhD,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;CA4JvC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { assert, unreachable } from "../../../shared/src/asserts.js";
|
|
2
2
|
import { areEqual } from "../../../shared/src/arrays.js";
|
|
3
|
+
import { makeAddChange, makeRemoveChange } from "./change.js";
|
|
3
4
|
import { normalizeUndefined } from "./data.js";
|
|
4
5
|
import { throwFilterOutput } from "./filter-operators.js";
|
|
5
6
|
//#region ../zql/src/ivm/exists.ts
|
|
@@ -68,53 +69,41 @@ var Exists = class {
|
|
|
68
69
|
assert(!this.#inPush, "Unexpected re-entrancy");
|
|
69
70
|
this.#inPush = true;
|
|
70
71
|
try {
|
|
71
|
-
switch (change
|
|
72
|
-
case
|
|
73
|
-
case
|
|
74
|
-
case
|
|
72
|
+
switch (change[0]) {
|
|
73
|
+
case 0:
|
|
74
|
+
case 2:
|
|
75
|
+
case 1:
|
|
75
76
|
yield* this.#pushWithFilter(change);
|
|
76
77
|
return;
|
|
77
|
-
case
|
|
78
|
-
if (change.
|
|
78
|
+
case 3:
|
|
79
|
+
if (change[2].relationshipName !== this.#relationshipName || change[2].change[0] === 2 || change[2].change[0] === 3) {
|
|
79
80
|
yield* this.#pushWithFilter(change);
|
|
80
81
|
return;
|
|
81
82
|
}
|
|
82
|
-
switch (change.
|
|
83
|
-
case
|
|
84
|
-
const size = yield* this.#fetchSize(change
|
|
85
|
-
if (size === 1) if (this.#not) yield* this.#output.push({
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
...change.node.relationships,
|
|
91
|
-
[this.#relationshipName]: () => []
|
|
92
|
-
}
|
|
83
|
+
switch (change[2].change[0]) {
|
|
84
|
+
case 0: {
|
|
85
|
+
const size = yield* this.#fetchSize(change[1]);
|
|
86
|
+
if (size === 1) if (this.#not) yield* this.#output.push(makeRemoveChange({
|
|
87
|
+
row: change[1].row,
|
|
88
|
+
relationships: {
|
|
89
|
+
...change[1].relationships,
|
|
90
|
+
[this.#relationshipName]: () => []
|
|
93
91
|
}
|
|
94
|
-
}, this);
|
|
95
|
-
else yield* this.#output.push(
|
|
96
|
-
type: "add",
|
|
97
|
-
node: change.node
|
|
98
|
-
}, this);
|
|
92
|
+
}), this);
|
|
93
|
+
else yield* this.#output.push(makeAddChange(change[1]), this);
|
|
99
94
|
else yield* this.#pushWithFilter(change, size > 0);
|
|
100
95
|
return;
|
|
101
96
|
}
|
|
102
|
-
case
|
|
103
|
-
const size = yield* this.#fetchSize(change
|
|
104
|
-
if (size === 0) if (this.#not) yield* this.#output.push(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
node: {
|
|
111
|
-
row: change.node.row,
|
|
112
|
-
relationships: {
|
|
113
|
-
...change.node.relationships,
|
|
114
|
-
[this.#relationshipName]: () => [change.child.change.node]
|
|
115
|
-
}
|
|
97
|
+
case 1: {
|
|
98
|
+
const size = yield* this.#fetchSize(change[1]);
|
|
99
|
+
if (size === 0) if (this.#not) yield* this.#output.push(makeAddChange(change[1]), this);
|
|
100
|
+
else yield* this.#output.push(makeRemoveChange({
|
|
101
|
+
row: change[1].row,
|
|
102
|
+
relationships: {
|
|
103
|
+
...change[1].relationships,
|
|
104
|
+
[this.#relationshipName]: () => [change[2].change[1]]
|
|
116
105
|
}
|
|
117
|
-
}, this);
|
|
106
|
+
}), this);
|
|
118
107
|
else yield* this.#pushWithFilter(change, size > 0);
|
|
119
108
|
return;
|
|
120
109
|
}
|
|
@@ -148,7 +137,7 @@ var Exists = class {
|
|
|
148
137
|
* Pushes a change if this.#filter is true for its row.
|
|
149
138
|
*/
|
|
150
139
|
*#pushWithFilter(change, exists) {
|
|
151
|
-
if (yield* this.#filter(change
|
|
140
|
+
if (yield* this.#filter(change[1], exists)) yield* this.#output.push(change, this);
|
|
152
141
|
}
|
|
153
142
|
*#fetchExists(node) {
|
|
154
143
|
return (yield* this.#fetchSize(node)) > 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exists.js","names":["#input","#relationshipName","#not","#parentJoinKey","#noSizeReuse","#cache","#cacheHitCountsForTesting","#output","#inPush","#getCacheKey","#fetchExists","#filter","#pushWithFilter","#fetchSize"],"sources":["../../../../../zql/src/ivm/exists.ts"],"sourcesContent":["import {areEqual} from '../../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {CompoundKey} from '../../../zero-protocol/src/ast.ts';\nimport {type Change} from './change.ts';\nimport {normalizeUndefined, type Node, type NormalizedValue} from './data.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\n\n/**\n * The Exists operator filters data based on whether or not a relationship is\n * non-empty.\n */\nexport class Exists implements FilterOperator {\n readonly #input: FilterInput;\n readonly #relationshipName: string;\n readonly #not: boolean;\n readonly #parentJoinKey: CompoundKey;\n readonly #noSizeReuse: boolean;\n #cache: Map<string, boolean>;\n #cacheHitCountsForTesting: Map<string, number> | undefined;\n #output: FilterOutput = throwFilterOutput;\n\n /**\n * This instance variable is `true` when this operator is processing a `push`,\n * and is used to disable reuse of cached sizes across rows with the\n * same parent join key value.\n * This is necessary because during a push relationships can be inconsistent\n * due to push communicating changes (which may change multiple Nodes) one\n * Node at a time.\n */\n #inPush = false;\n\n constructor(\n input: FilterInput,\n relationshipName: string,\n parentJoinKey: CompoundKey,\n type: 'EXISTS' | 'NOT EXISTS',\n cacheHitCountsForTesting?: Map<string, number>,\n ) {\n this.#input = input;\n this.#relationshipName = relationshipName;\n this.#input.setFilterOutput(this);\n this.#cache = new Map();\n this.#cacheHitCountsForTesting = cacheHitCountsForTesting;\n assert(\n this.#input.getSchema().relationships[relationshipName],\n `Input schema missing ${relationshipName}`,\n );\n this.#not = type === 'NOT EXISTS';\n this.#parentJoinKey = parentJoinKey;\n\n // If the parentJoinKey is the primary key, no sense in trying to reuse.\n this.#noSizeReuse = areEqual(\n parentJoinKey,\n this.#input.getSchema().primaryKey,\n );\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#output = output;\n }\n\n beginFilter() {\n this.#output.beginFilter();\n }\n\n endFilter() {\n this.#cache = new Map();\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n let exists: boolean | undefined;\n if (!this.#noSizeReuse && !this.#inPush) {\n const key = this.#getCacheKey(node, this.#parentJoinKey);\n exists = this.#cache.get(key);\n if (exists === undefined) {\n exists = yield* this.#fetchExists(node);\n this.#cache.set(key, exists);\n } else if (this.#cacheHitCountsForTesting) {\n this.#cacheHitCountsForTesting.set(\n key,\n (this.#cacheHitCountsForTesting.get(key) ?? 0) + 1,\n );\n }\n }\n\n const result =\n (yield* this.#filter(node, exists)) && (yield* this.#output.filter(node));\n return result;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change): Stream<'yield'> {\n assert(!this.#inPush, 'Unexpected re-entrancy');\n this.#inPush = true;\n try {\n switch (change.type) {\n // add, remove and edit cannot change the size of the\n // this.#relationshipName relationship, so simply #pushWithFilter\n case 'add':\n case 'edit':\n case 'remove': {\n yield* this.#pushWithFilter(change);\n return;\n }\n case 'child':\n // Only add and remove child changes for the\n // this.#relationshipName relationship, can change the size\n // of the this.#relationshipName relationship, for other\n // child changes simply #pushWithFilter\n if (\n change.child.relationshipName !== this.#relationshipName ||\n change.child.change.type === 'edit' ||\n change.child.change.type === 'child'\n ) {\n yield* this.#pushWithFilter(change);\n return;\n }\n switch (change.child.change.type) {\n case 'add': {\n const size = yield* this.#fetchSize(change.node);\n if (size === 1) {\n if (this.#not) {\n // Since the add child change currently being processed is not\n // pushed to output, the added child needs to be excluded from\n // the remove being pushed to output (since the child has\n // never been added to the output).\n yield* this.#output.push(\n {\n type: 'remove',\n node: {\n row: change.node.row,\n relationships: {\n ...change.node.relationships,\n [this.#relationshipName]: () => [],\n },\n },\n },\n this,\n );\n } else {\n yield* this.#output.push(\n {\n type: 'add',\n node: change.node,\n },\n this,\n );\n }\n } else {\n yield* this.#pushWithFilter(change, size > 0);\n }\n return;\n }\n case 'remove': {\n const size = yield* this.#fetchSize(change.node);\n if (size === 0) {\n if (this.#not) {\n yield* this.#output.push(\n {\n type: 'add',\n node: change.node,\n },\n this,\n );\n } else {\n // Since the remove child change currently being processed is\n // not pushed to output, the removed child needs to be added to\n // the remove being pushed to output.\n yield* this.#output.push(\n {\n type: 'remove',\n node: {\n row: change.node.row,\n relationships: {\n ...change.node.relationships,\n [this.#relationshipName]: () => [\n change.child.change.node,\n ],\n },\n },\n },\n this,\n );\n }\n } else {\n yield* this.#pushWithFilter(change, size > 0);\n }\n return;\n }\n }\n return;\n default:\n unreachable(change);\n }\n } finally {\n this.#inPush = false;\n }\n }\n\n /**\n * Returns whether or not the node's this.#relationshipName\n * relationship passes the exist/not exists filter condition.\n * If the optional `size` is passed it is used.\n * Otherwise, if there is a stored size for the row it is used.\n * Otherwise the size is computed by streaming the node's\n * relationship with this.#relationshipName (this computed size is also\n * stored).\n */\n *#filter(node: Node, exists?: boolean): Generator<'yield', boolean> {\n exists = exists ?? (yield* this.#fetchExists(node));\n return this.#not ? !exists : exists;\n }\n\n #getCacheKey(node: Node, def: CompoundKey): string {\n const values: NormalizedValue[] = [];\n for (const key of def) {\n values.push(normalizeUndefined(node.row[key]));\n }\n return JSON.stringify(values);\n }\n\n /**\n * Pushes a change if this.#filter is true for its row.\n */\n *#pushWithFilter(change: Change, exists?: boolean): Stream<'yield'> {\n if (yield* this.#filter(change.node, exists)) {\n yield* this.#output.push(change, this);\n }\n }\n\n *#fetchExists(node: Node): Generator<'yield', boolean> {\n // While it seems like this should be able to fetch just 1 node\n // to check for exists, we can't because Take does not support\n // early return during initial fetch.\n return (yield* this.#fetchSize(node)) > 0;\n }\n\n *#fetchSize(node: Node): Generator<'yield', number> {\n const relationship = node.relationships[this.#relationshipName];\n assert(\n relationship,\n () =>\n `Exists: relationship \"${this.#relationshipName}\" not found on node`,\n );\n let size = 0;\n for (const n of relationship()) {\n if (n === 'yield') {\n yield 'yield';\n } else {\n size++;\n }\n }\n return size;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"exists.js","names":["#input","#relationshipName","#not","#parentJoinKey","#noSizeReuse","#cache","#cacheHitCountsForTesting","#output","#inPush","#getCacheKey","#fetchExists","#filter","#pushWithFilter","#fetchSize"],"sources":["../../../../../zql/src/ivm/exists.ts"],"sourcesContent":["import {areEqual} from '../../../shared/src/arrays.ts';\nimport {assert, unreachable} from '../../../shared/src/asserts.ts';\nimport type {CompoundKey} from '../../../zero-protocol/src/ast.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {ChangeType} from './change-type.ts';\nimport {makeAddChange, makeRemoveChange, type Change} from './change.ts';\nimport {normalizeUndefined, type Node, type NormalizedValue} from './data.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\n\n/**\n * The Exists operator filters data based on whether or not a relationship is\n * non-empty.\n */\nexport class Exists implements FilterOperator {\n readonly #input: FilterInput;\n readonly #relationshipName: string;\n readonly #not: boolean;\n readonly #parentJoinKey: CompoundKey;\n readonly #noSizeReuse: boolean;\n #cache: Map<string, boolean>;\n #cacheHitCountsForTesting: Map<string, number> | undefined;\n #output: FilterOutput = throwFilterOutput;\n\n /**\n * This instance variable is `true` when this operator is processing a `push`,\n * and is used to disable reuse of cached sizes across rows with the\n * same parent join key value.\n * This is necessary because during a push relationships can be inconsistent\n * due to push communicating changes (which may change multiple Nodes) one\n * Node at a time.\n */\n #inPush = false;\n\n constructor(\n input: FilterInput,\n relationshipName: string,\n parentJoinKey: CompoundKey,\n type: 'EXISTS' | 'NOT EXISTS',\n cacheHitCountsForTesting?: Map<string, number>,\n ) {\n this.#input = input;\n this.#relationshipName = relationshipName;\n this.#input.setFilterOutput(this);\n this.#cache = new Map();\n this.#cacheHitCountsForTesting = cacheHitCountsForTesting;\n assert(\n this.#input.getSchema().relationships[relationshipName],\n `Input schema missing ${relationshipName}`,\n );\n this.#not = type === 'NOT EXISTS';\n this.#parentJoinKey = parentJoinKey;\n\n // If the parentJoinKey is the primary key, no sense in trying to reuse.\n this.#noSizeReuse = areEqual(\n parentJoinKey,\n this.#input.getSchema().primaryKey,\n );\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#output = output;\n }\n\n beginFilter() {\n this.#output.beginFilter();\n }\n\n endFilter() {\n this.#cache = new Map();\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n let exists: boolean | undefined;\n if (!this.#noSizeReuse && !this.#inPush) {\n const key = this.#getCacheKey(node, this.#parentJoinKey);\n exists = this.#cache.get(key);\n if (exists === undefined) {\n exists = yield* this.#fetchExists(node);\n this.#cache.set(key, exists);\n } else if (this.#cacheHitCountsForTesting) {\n this.#cacheHitCountsForTesting.set(\n key,\n (this.#cacheHitCountsForTesting.get(key) ?? 0) + 1,\n );\n }\n }\n\n const result =\n (yield* this.#filter(node, exists)) && (yield* this.#output.filter(node));\n return result;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change): Stream<'yield'> {\n assert(!this.#inPush, 'Unexpected re-entrancy');\n this.#inPush = true;\n try {\n switch (change[ChangeIndex.TYPE]) {\n // add, remove and edit cannot change the size of the\n // this.#relationshipName relationship, so simply #pushWithFilter\n case ChangeType.ADD:\n case ChangeType.EDIT:\n case ChangeType.REMOVE: {\n yield* this.#pushWithFilter(change);\n return;\n }\n case ChangeType.CHILD:\n // Only add and remove child changes for the\n // this.#relationshipName relationship, can change the size\n // of the this.#relationshipName relationship, for other\n // child changes simply #pushWithFilter\n if (\n change[ChangeIndex.CHILD_DATA].relationshipName !==\n this.#relationshipName ||\n change[ChangeIndex.CHILD_DATA].change[ChangeIndex.TYPE] ===\n ChangeType.EDIT ||\n change[ChangeIndex.CHILD_DATA].change[ChangeIndex.TYPE] ===\n ChangeType.CHILD\n ) {\n yield* this.#pushWithFilter(change);\n return;\n }\n switch (change[ChangeIndex.CHILD_DATA].change[ChangeIndex.TYPE]) {\n case ChangeType.ADD: {\n const size = yield* this.#fetchSize(change[ChangeIndex.NODE]);\n if (size === 1) {\n if (this.#not) {\n // Since the add child change currently being processed is not\n // pushed to output, the added child needs to be excluded from\n // the remove being pushed to output (since the child has\n // never been added to the output).\n yield* this.#output.push(\n makeRemoveChange({\n row: change[ChangeIndex.NODE].row,\n relationships: {\n ...change[ChangeIndex.NODE].relationships,\n [this.#relationshipName]: () => [],\n },\n }),\n this,\n );\n } else {\n yield* this.#output.push(\n makeAddChange(change[ChangeIndex.NODE]),\n this,\n );\n }\n } else {\n yield* this.#pushWithFilter(change, size > 0);\n }\n return;\n }\n case ChangeType.REMOVE: {\n const size = yield* this.#fetchSize(change[ChangeIndex.NODE]);\n if (size === 0) {\n if (this.#not) {\n yield* this.#output.push(\n makeAddChange(change[ChangeIndex.NODE]),\n this,\n );\n } else {\n // Since the remove child change currently being processed is\n // not pushed to output, the removed child needs to be added to\n // the remove being pushed to output.\n yield* this.#output.push(\n makeRemoveChange({\n row: change[ChangeIndex.NODE].row,\n relationships: {\n ...change[ChangeIndex.NODE].relationships,\n [this.#relationshipName]: () => [\n change[ChangeIndex.CHILD_DATA].change[\n ChangeIndex.NODE\n ],\n ],\n },\n }),\n this,\n );\n }\n } else {\n yield* this.#pushWithFilter(change, size > 0);\n }\n return;\n }\n }\n return;\n default:\n unreachable(change);\n }\n } finally {\n this.#inPush = false;\n }\n }\n\n /**\n * Returns whether or not the node's this.#relationshipName\n * relationship passes the exist/not exists filter condition.\n * If the optional `size` is passed it is used.\n * Otherwise, if there is a stored size for the row it is used.\n * Otherwise the size is computed by streaming the node's\n * relationship with this.#relationshipName (this computed size is also\n * stored).\n */\n *#filter(node: Node, exists?: boolean): Generator<'yield', boolean> {\n exists = exists ?? (yield* this.#fetchExists(node));\n return this.#not ? !exists : exists;\n }\n\n #getCacheKey(node: Node, def: CompoundKey): string {\n const values: NormalizedValue[] = [];\n for (const key of def) {\n values.push(normalizeUndefined(node.row[key]));\n }\n return JSON.stringify(values);\n }\n\n /**\n * Pushes a change if this.#filter is true for its row.\n */\n *#pushWithFilter(change: Change, exists?: boolean): Stream<'yield'> {\n if (yield* this.#filter(change[ChangeIndex.NODE], exists)) {\n yield* this.#output.push(change, this);\n }\n }\n\n *#fetchExists(node: Node): Generator<'yield', boolean> {\n // While it seems like this should be able to fetch just 1 node\n // to check for exists, we can't because Take does not support\n // early return during initial fetch.\n return (yield* this.#fetchSize(node)) > 0;\n }\n\n *#fetchSize(node: Node): Generator<'yield', number> {\n const relationship = node.relationships[this.#relationshipName];\n assert(\n relationship,\n () =>\n `Exists: relationship \"${this.#relationshipName}\" not found on node`,\n );\n let size = 0;\n for (const n of relationship()) {\n if (n === 'yield') {\n yield 'yield';\n } else {\n size++;\n }\n }\n return size;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ChangeType } from './change-type.ts';
|
|
2
|
+
import { type Change } from './change.ts';
|
|
2
3
|
import { type Node } from './data.ts';
|
|
3
4
|
import type { FanOut } from './fan-out.ts';
|
|
4
5
|
import { type FilterInput, type FilterOperator, type FilterOutput } from './filter-operators.ts';
|
|
@@ -27,6 +28,6 @@ export declare class FanIn implements FilterOperator {
|
|
|
27
28
|
endFilter(): void;
|
|
28
29
|
filter(node: Node): Generator<'yield', boolean>;
|
|
29
30
|
push(change: Change): readonly never[];
|
|
30
|
-
fanOutDonePushingToAllBranches(fanOutChangeType:
|
|
31
|
+
fanOutDonePushingToAllBranches(fanOutChangeType: ChangeType): Generator<"yield", void, any>;
|
|
31
32
|
}
|
|
32
33
|
//# sourceMappingURL=fan-in.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fan-in.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/fan-in.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACzC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;;;;GAaG;AACH,qBAAa,KAAM,YAAW,cAAc;;gBAM9B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE;IASjD,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAMf,SAAS;IAIT,WAAW,IAAI,IAAI;IAInB,SAAS,IAAI,IAAI;IAIhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAIhD,IAAI,CAAC,MAAM,EAAE,MAAM;IAKlB,8BAA8B,CAAC,gBAAgB,EAAE,
|
|
1
|
+
{"version":3,"file":"fan-in.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/fan-in.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AACzC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;;;;;;;;;;GAaG;AACH,qBAAa,KAAM,YAAW,cAAc;;gBAM9B,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE;IASjD,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAMf,SAAS;IAIT,WAAW,IAAI,IAAI;IAInB,SAAS,IAAI,IAAI;IAIhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAIhD,IAAI,CAAC,MAAM,EAAE,MAAM;IAKlB,8BAA8B,CAAC,gBAAgB,EAAE,UAAU;CAkB7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fan-in.js","names":["#inputs","#schema","#output","#accumulatedPushes"],"sources":["../../../../../zql/src/ivm/fan-in.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {emptyArray, identity} from '../../../shared/src/sentinels.ts';\nimport type {Change} from './change.ts';\nimport {type Node} from './data.ts';\nimport type {FanOut} from './fan-out.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport {pushAccumulatedChanges} from './push-accumulated.ts';\nimport type {SourceSchema} from './schema.ts';\n\n/**\n * The FanIn operator merges multiple streams into one.\n * It eliminates duplicates and must be paired with a fan-out operator\n * somewhere upstream of the fan-in.\n *\n * issue\n * |\n * fan-out\n * / \\\n * a b\n * \\ /\n * fan-in\n * |\n */\nexport class FanIn implements FilterOperator {\n readonly #inputs: readonly FilterInput[];\n readonly #schema: SourceSchema;\n #output: FilterOutput = throwFilterOutput;\n #accumulatedPushes: Change[] = [];\n\n constructor(fanOut: FanOut, inputs: FilterInput[]) {\n this.#inputs = inputs;\n this.#schema = fanOut.getSchema();\n for (const input of inputs) {\n input.setFilterOutput(this);\n assert(this.#schema === input.getSchema(), `Schema mismatch in fan-in`);\n }\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#output = output;\n }\n\n destroy(): void {\n for (const input of this.#inputs) {\n input.destroy();\n }\n }\n\n getSchema() {\n return this.#schema;\n }\n\n beginFilter(): void {\n this.#output.beginFilter();\n }\n\n endFilter(): void {\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n return yield* this.#output.filter(node);\n }\n\n push(change: Change) {\n this.#accumulatedPushes.push(change);\n return emptyArray;\n }\n\n *fanOutDonePushingToAllBranches(fanOutChangeType:
|
|
1
|
+
{"version":3,"file":"fan-in.js","names":["#inputs","#schema","#output","#accumulatedPushes"],"sources":["../../../../../zql/src/ivm/fan-in.ts"],"sourcesContent":["import {assert} from '../../../shared/src/asserts.ts';\nimport {emptyArray, identity} from '../../../shared/src/sentinels.ts';\nimport type {ChangeType} from './change-type.ts';\nimport {type Change} from './change.ts';\nimport {type Node} from './data.ts';\nimport type {FanOut} from './fan-out.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport {pushAccumulatedChanges} from './push-accumulated.ts';\nimport type {SourceSchema} from './schema.ts';\n\n/**\n * The FanIn operator merges multiple streams into one.\n * It eliminates duplicates and must be paired with a fan-out operator\n * somewhere upstream of the fan-in.\n *\n * issue\n * |\n * fan-out\n * / \\\n * a b\n * \\ /\n * fan-in\n * |\n */\nexport class FanIn implements FilterOperator {\n readonly #inputs: readonly FilterInput[];\n readonly #schema: SourceSchema;\n #output: FilterOutput = throwFilterOutput;\n #accumulatedPushes: Change[] = [];\n\n constructor(fanOut: FanOut, inputs: FilterInput[]) {\n this.#inputs = inputs;\n this.#schema = fanOut.getSchema();\n for (const input of inputs) {\n input.setFilterOutput(this);\n assert(this.#schema === input.getSchema(), `Schema mismatch in fan-in`);\n }\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#output = output;\n }\n\n destroy(): void {\n for (const input of this.#inputs) {\n input.destroy();\n }\n }\n\n getSchema() {\n return this.#schema;\n }\n\n beginFilter(): void {\n this.#output.beginFilter();\n }\n\n endFilter(): void {\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n return yield* this.#output.filter(node);\n }\n\n push(change: Change) {\n this.#accumulatedPushes.push(change);\n return emptyArray;\n }\n\n *fanOutDonePushingToAllBranches(fanOutChangeType: ChangeType) {\n if (this.#inputs.length === 0) {\n assert(\n this.#accumulatedPushes.length === 0,\n 'If there are no inputs then fan-in should not receive any pushes.',\n );\n return;\n }\n\n yield* pushAccumulatedChanges(\n this.#accumulatedPushes,\n this.#output,\n this,\n fanOutChangeType,\n identity,\n identity,\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AA6BA,IAAa,QAAb,MAA6C;CAC3C;CACA;CACA,UAAwB;CACxB,qBAA+B,EAAE;CAEjC,YAAY,QAAgB,QAAuB;AACjD,QAAA,SAAe;AACf,QAAA,SAAe,OAAO,WAAW;AACjC,OAAK,MAAM,SAAS,QAAQ;AAC1B,SAAM,gBAAgB,KAAK;AAC3B,UAAO,MAAA,WAAiB,MAAM,WAAW,EAAE,4BAA4B;;;CAI3E,gBAAgB,QAA4B;AAC1C,QAAA,SAAe;;CAGjB,UAAgB;AACd,OAAK,MAAM,SAAS,MAAA,OAClB,OAAM,SAAS;;CAInB,YAAY;AACV,SAAO,MAAA;;CAGT,cAAoB;AAClB,QAAA,OAAa,aAAa;;CAG5B,YAAkB;AAChB,QAAA,OAAa,WAAW;;CAG1B,CAAC,OAAO,MAAyC;AAC/C,SAAO,OAAO,MAAA,OAAa,OAAO,KAAK;;CAGzC,KAAK,QAAgB;AACnB,QAAA,kBAAwB,KAAK,OAAO;AACpC,SAAO;;CAGT,CAAC,+BAA+B,kBAA8B;AAC5D,MAAI,MAAA,OAAa,WAAW,GAAG;AAC7B,UACE,MAAA,kBAAwB,WAAW,GACnC,oEACD;AACD;;AAGF,SAAO,uBACL,MAAA,mBACA,MAAA,QACA,MACA,kBACA,UACA,SACD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Change } from './change.ts';
|
|
2
|
-
import type { FanIn } from './fan-in.ts';
|
|
3
2
|
import type { Node } from './data.ts';
|
|
3
|
+
import type { FanIn } from './fan-in.ts';
|
|
4
4
|
import type { FilterInput, FilterOperator, FilterOutput } from './filter-operators.ts';
|
|
5
5
|
/**
|
|
6
6
|
* Forks a stream into multiple streams.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fan-out.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/fan-out.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fan-out.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/fan-out.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,KAAK,EAAC,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,YAAY,EACb,MAAM,uBAAuB,CAAC;AAE/B;;;;GAIG;AACH,qBAAa,MAAO,YAAW,cAAc;;gBAM/B,KAAK,EAAE,WAAW;IAK9B,QAAQ,CAAC,KAAK,EAAE,KAAK;IAIrB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAI3C,OAAO,IAAI,IAAI;IAWf,SAAS;IAIT,WAAW,IAAI,IAAI;IAMnB,SAAS,IAAI,IAAI;IAMhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAW/C,IAAI,CAAC,MAAM,EAAE,MAAM;CASrB"}
|
|
@@ -45,7 +45,7 @@ var FanOut = class {
|
|
|
45
45
|
}
|
|
46
46
|
*push(change) {
|
|
47
47
|
for (const out of this.#outputs) yield* out.push(change, this);
|
|
48
|
-
yield* must(this.#fanIn, "fan-out must have a corresponding fan-in set!").fanOutDonePushingToAllBranches(change
|
|
48
|
+
yield* must(this.#fanIn, "fan-out must have a corresponding fan-in set!").fanOutDonePushingToAllBranches(change[0]);
|
|
49
49
|
}
|
|
50
50
|
};
|
|
51
51
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fan-out.js","names":["#input","#outputs","#fanIn","#destroyCount"],"sources":["../../../../../zql/src/ivm/fan-out.ts"],"sourcesContent":["import {must} from '../../../shared/src/must.ts';\nimport type {Change} from './change.ts';\nimport type {
|
|
1
|
+
{"version":3,"file":"fan-out.js","names":["#input","#outputs","#fanIn","#destroyCount"],"sources":["../../../../../zql/src/ivm/fan-out.ts"],"sourcesContent":["import {must} from '../../../shared/src/must.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport type {Change} from './change.ts';\nimport type {Node} from './data.ts';\nimport type {FanIn} from './fan-in.ts';\nimport type {\n FilterInput,\n FilterOperator,\n FilterOutput,\n} from './filter-operators.ts';\n\n/**\n * Forks a stream into multiple streams.\n * Is meant to be paired with a `FanIn` operator which will\n * later merge the forks back together.\n */\nexport class FanOut implements FilterOperator {\n readonly #input: FilterInput;\n readonly #outputs: FilterOutput[] = [];\n #fanIn: FanIn | undefined;\n #destroyCount: number = 0;\n\n constructor(input: FilterInput) {\n this.#input = input;\n input.setFilterOutput(this);\n }\n\n setFanIn(fanIn: FanIn) {\n this.#fanIn = fanIn;\n }\n\n setFilterOutput(output: FilterOutput): void {\n this.#outputs.push(output);\n }\n\n destroy(): void {\n if (this.#destroyCount < this.#outputs.length) {\n ++this.#destroyCount;\n if (this.#destroyCount === this.#outputs.length) {\n this.#input.destroy();\n }\n } else {\n throw new Error('FanOut already destroyed once for each output');\n }\n }\n\n getSchema() {\n return this.#input.getSchema();\n }\n\n beginFilter(): void {\n for (const output of this.#outputs) {\n output.beginFilter();\n }\n }\n\n endFilter(): void {\n for (const output of this.#outputs) {\n output.endFilter();\n }\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n let result = false;\n for (const output of this.#outputs) {\n result = (yield* output.filter(node)) || result;\n if (result) {\n return true;\n }\n }\n return result;\n }\n\n *push(change: Change) {\n for (const out of this.#outputs) {\n yield* out.push(change, this);\n }\n yield* must(\n this.#fanIn,\n 'fan-out must have a corresponding fan-in set!',\n ).fanOutDonePushingToAllBranches(change[ChangeIndex.TYPE]);\n }\n}\n"],"mappings":";;;;;;;AAgBA,IAAa,SAAb,MAA8C;CAC5C;CACA,WAAoC,EAAE;CACtC;CACA,gBAAwB;CAExB,YAAY,OAAoB;AAC9B,QAAA,QAAc;AACd,QAAM,gBAAgB,KAAK;;CAG7B,SAAS,OAAc;AACrB,QAAA,QAAc;;CAGhB,gBAAgB,QAA4B;AAC1C,QAAA,QAAc,KAAK,OAAO;;CAG5B,UAAgB;AACd,MAAI,MAAA,eAAqB,MAAA,QAAc,QAAQ;AAC7C,KAAE,MAAA;AACF,OAAI,MAAA,iBAAuB,MAAA,QAAc,OACvC,OAAA,MAAY,SAAS;QAGvB,OAAM,IAAI,MAAM,gDAAgD;;CAIpE,YAAY;AACV,SAAO,MAAA,MAAY,WAAW;;CAGhC,cAAoB;AAClB,OAAK,MAAM,UAAU,MAAA,QACnB,QAAO,aAAa;;CAIxB,YAAkB;AAChB,OAAK,MAAM,UAAU,MAAA,QACnB,QAAO,WAAW;;CAItB,CAAC,OAAO,MAAyC;EAC/C,IAAI,SAAS;AACb,OAAK,MAAM,UAAU,MAAA,SAAe;AAClC,aAAU,OAAO,OAAO,OAAO,KAAK,KAAK;AACzC,OAAI,OACF,QAAO;;AAGX,SAAO;;CAGT,CAAC,KAAK,QAAgB;AACpB,OAAK,MAAM,OAAO,MAAA,QAChB,QAAO,IAAI,KAAK,QAAQ,KAAK;AAE/B,SAAO,KACL,MAAA,OACA,gDACD,CAAC,+BAA+B,OAAO,GAAkB"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { type Node } from './data.ts';
|
|
1
|
+
import type { BuilderDelegate } from '../builder/builder.ts';
|
|
3
2
|
import type { Change } from './change.ts';
|
|
3
|
+
import { type Node } from './data.ts';
|
|
4
|
+
import type { FetchRequest, Input, InputBase, Output } from './operator.ts';
|
|
4
5
|
import type { SourceSchema } from './schema.ts';
|
|
5
6
|
import { type Stream } from './stream.ts';
|
|
6
|
-
import type { BuilderDelegate } from '../builder/builder.ts';
|
|
7
7
|
/**
|
|
8
8
|
* The `where` clause of a ZQL query is implemented using a sub-graph of
|
|
9
9
|
* `FilterOperators`. This sub-graph starts with a `FilterStart` operator,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-operators.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter-operators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"filter-operators.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter-operators.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,EAAC,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AAC1E,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,+CAA+C;IAC/C,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,YAAa,SAAQ,MAAM;IAI1C,WAAW,IAAI,IAAI,CAAC;IACpB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,SAAS,IAAI,IAAI,CAAC;CACnB;AAED,MAAM,WAAW,cAAe,SAAQ,WAAW,EAAE,YAAY;CAAG;AAEpE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,YAW/B,CAAC;AAEF,qBAAa,WAAY,YAAW,WAAW,EAAE,MAAM;;gBAIzC,KAAK,EAAE,KAAK;IAKxB,eAAe,CAAC,MAAM,EAAE,YAAY;IAIpC,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;IAInB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;CAkBlD;AAED,qBAAa,SAAU,YAAW,KAAK,EAAE,YAAY;;gBAMvC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW;IAMjD,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;IAMjD,WAAW;IACX,SAAS;IAER,MAAM,CAAC,KAAK,EAAE,IAAI;IAInB,SAAS,CAAC,MAAM,EAAE,MAAM;IAIxB,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;CAGrB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,CAAC,WAAW,EAAE,WAAW,KAAK,WAAW,GAClD,KAAK,CAQP"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-operators.js","names":["#input","#output","#start"],"sources":["../../../../../zql/src/ivm/filter-operators.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"filter-operators.js","names":["#input","#output","#start"],"sources":["../../../../../zql/src/ivm/filter-operators.ts"],"sourcesContent":["import type {BuilderDelegate} from '../builder/builder.ts';\nimport type {Change} from './change.ts';\nimport {type Node} from './data.ts';\nimport type {FetchRequest, Input, InputBase, Output} from './operator.ts';\nimport type {SourceSchema} from './schema.ts';\nimport {type Stream} from './stream.ts';\n\n/**\n * The `where` clause of a ZQL query is implemented using a sub-graph of\n * `FilterOperators`. This sub-graph starts with a `FilterStart` operator,\n * that adapts from the normal `Operator` `Output`, to the\n * `FilterOperator` `FilterInput`, and ends with a `FilterEnd` operator that\n * adapts from a `FilterOperator` `FilterOutput` to a normal `Operator` `Input`.\n * `FilterOperator`'s do not have `fetch` instead they have a\n * `filter(node: Node): boolean` method.\n * They also have `push` which is just like normal `Operator` push.\n * Not having a `fetch` means these `FilterOperator`'s cannot modify\n * `Node` `row`s or `relationship`s, but they shouldn't, they should just\n * filter.\n *\n * This `FilterOperator` abstraction enables much more efficient processing of\n * `fetch` for `where` clauses containing OR conditions.\n *\n * See https://github.com/rocicorp/mono/pull/4339\n */\n\nexport interface FilterInput extends InputBase {\n /** Tell the input where to send its output. */\n setFilterOutput(output: FilterOutput): void;\n}\n\nexport interface FilterOutput extends Output {\n // Lets the operator know that we're in a loop of filtering\n // nodes. E.g., so the operator can cache results for the\n // duration of the loop.\n beginFilter(): void;\n filter(node: Node): Generator<'yield', boolean>;\n endFilter(): void;\n}\n\nexport interface FilterOperator extends FilterInput, FilterOutput {}\n\n/**\n * An implementation of FilterOutput that throws if push or filter is called.\n * It is used as the initial value for for an operator's output before it is\n * set.\n */\nexport const throwFilterOutput: FilterOutput = {\n *push(_change: Change): Stream<'yield'> {\n throw new Error('Output not set');\n },\n\n *filter(_node: Node): Generator<'yield', boolean> {\n throw new Error('Output not set');\n },\n\n beginFilter() {},\n endFilter() {},\n};\n\nexport class FilterStart implements FilterInput, Output {\n readonly #input: Input;\n #output: FilterOutput = throwFilterOutput;\n\n constructor(input: Input) {\n this.#input = input;\n input.setOutput(this);\n }\n\n setFilterOutput(output: FilterOutput) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* this.#output.push(change, this);\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n this.#output.beginFilter();\n try {\n for (const node of this.#input.fetch(req)) {\n if (node === 'yield') {\n yield node;\n continue;\n }\n if (yield* this.#output.filter(node)) {\n yield node;\n }\n }\n } finally {\n // finally is important if an exception is thrown or\n // if the stream is not fully consumed.\n this.#output.endFilter();\n }\n }\n}\n\nexport class FilterEnd implements Input, FilterOutput {\n readonly #start: FilterStart;\n readonly #input: FilterInput;\n\n #output: Output = throwFilterOutput;\n\n constructor(start: FilterStart, input: FilterInput) {\n this.#start = start;\n this.#input = input;\n input.setFilterOutput(this);\n }\n\n *fetch(req: FetchRequest): Stream<Node | 'yield'> {\n for (const node of this.#start.fetch(req)) {\n yield node;\n }\n }\n\n beginFilter() {}\n endFilter() {}\n\n *filter(_node: Node) {\n return true;\n }\n\n setOutput(output: Output) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* this.#output.push(change, this);\n }\n}\n\nexport function buildFilterPipeline(\n input: Input,\n delegate: BuilderDelegate,\n pipeline: (filterInput: FilterInput) => FilterInput,\n): Input {\n const filterStart = new FilterStart(input);\n delegate.addEdge(input, filterStart);\n const middle = pipeline(filterStart);\n delegate.addEdge(filterStart, middle);\n const filterEnd = new FilterEnd(filterStart, middle);\n delegate.addEdge(middle, filterEnd);\n return filterEnd;\n}\n"],"mappings":";;;;;;;AA+CA,IAAa,oBAAkC;CAC7C,CAAC,KAAK,SAAkC;AACtC,QAAM,IAAI,MAAM,iBAAiB;;CAGnC,CAAC,OAAO,OAA0C;AAChD,QAAM,IAAI,MAAM,iBAAiB;;CAGnC,cAAc;CACd,YAAY;CACb;AAED,IAAa,cAAb,MAAwD;CACtD;CACA,UAAwB;CAExB,YAAY,OAAc;AACxB,QAAA,QAAc;AACd,QAAM,UAAU,KAAK;;CAGvB,gBAAgB,QAAsB;AACpC,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;CAGxC,CAAC,MAAM,KAA2C;AAChD,QAAA,OAAa,aAAa;AAC1B,MAAI;AACF,QAAK,MAAM,QAAQ,MAAA,MAAY,MAAM,IAAI,EAAE;AACzC,QAAI,SAAS,SAAS;AACpB,WAAM;AACN;;AAEF,QAAI,OAAO,MAAA,OAAa,OAAO,KAAK,CAClC,OAAM;;YAGF;AAGR,SAAA,OAAa,WAAW;;;;AAK9B,IAAa,YAAb,MAAsD;CACpD;CACA;CAEA,UAAkB;CAElB,YAAY,OAAoB,OAAoB;AAClD,QAAA,QAAc;AACd,QAAA,QAAc;AACd,QAAM,gBAAgB,KAAK;;CAG7B,CAAC,MAAM,KAA2C;AAChD,OAAK,MAAM,QAAQ,MAAA,MAAY,MAAM,IAAI,CACvC,OAAM;;CAIV,cAAc;CACd,YAAY;CAEZ,CAAC,OAAO,OAAa;AACnB,SAAO;;CAGT,UAAU,QAAgB;AACxB,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,MAAA,OAAa,KAAK,QAAQ,KAAK;;;AAI1C,SAAgB,oBACd,OACA,UACA,UACO;CACP,MAAM,cAAc,IAAI,YAAY,MAAM;AAC1C,UAAS,QAAQ,OAAO,YAAY;CACpC,MAAM,SAAS,SAAS,YAAY;AACpC,UAAS,QAAQ,aAAa,OAAO;CACrC,MAAM,YAAY,IAAI,UAAU,aAAa,OAAO;AACpD,UAAS,QAAQ,QAAQ,UAAU;AACnC,QAAO"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-push.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter-push.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"filter-push.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter-push.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAG5D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,OAAO,KAAK,EAAC,SAAS,EAAE,MAAM,EAAC,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,wBAAiB,UAAU,CACzB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACjB,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,GAChC,MAAM,CAAC,OAAO,CAAC,CAuBjB"}
|
|
@@ -6,15 +6,15 @@ function* filterPush(change, output, pusher, predicate) {
|
|
|
6
6
|
yield* output.push(change, pusher);
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
|
-
switch (change
|
|
10
|
-
case
|
|
11
|
-
case
|
|
12
|
-
if (predicate(change.
|
|
9
|
+
switch (change[0]) {
|
|
10
|
+
case 0:
|
|
11
|
+
case 1:
|
|
12
|
+
if (predicate(change[1].row)) yield* output.push(change, pusher);
|
|
13
13
|
break;
|
|
14
|
-
case
|
|
15
|
-
if (predicate(change.
|
|
14
|
+
case 3:
|
|
15
|
+
if (predicate(change[1].row)) yield* output.push(change, pusher);
|
|
16
16
|
break;
|
|
17
|
-
case
|
|
17
|
+
case 2:
|
|
18
18
|
yield* maybeSplitAndPushEditChange(change, predicate, output, pusher);
|
|
19
19
|
break;
|
|
20
20
|
default: unreachable(change);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-push.js","names":[],"sources":["../../../../../zql/src/ivm/filter-push.ts"],"sourcesContent":["import {unreachable} from '../../../shared/src/asserts.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport type {Change} from './change.ts';\nimport {maybeSplitAndPushEditChange} from './maybe-split-and-push-edit-change.ts';\nimport type {InputBase, Output} from './operator.ts';\nimport type {Stream} from './stream.ts';\n\nexport function* filterPush(\n change: Change,\n output: Output,\n pusher: InputBase,\n predicate?: (row: Row) => boolean,\n): Stream<'yield'> {\n if (!predicate) {\n yield* output.push(change, pusher);\n return;\n }\n switch (change.
|
|
1
|
+
{"version":3,"file":"filter-push.js","names":[],"sources":["../../../../../zql/src/ivm/filter-push.ts"],"sourcesContent":["import {unreachable} from '../../../shared/src/asserts.ts';\nimport type {Row} from '../../../zero-protocol/src/data.ts';\nimport {ChangeIndex} from './change-index.ts';\nimport {ChangeType} from './change-type.ts';\nimport type {Change} from './change.ts';\nimport {maybeSplitAndPushEditChange} from './maybe-split-and-push-edit-change.ts';\nimport type {InputBase, Output} from './operator.ts';\nimport type {Stream} from './stream.ts';\n\nexport function* filterPush(\n change: Change,\n output: Output,\n pusher: InputBase,\n predicate?: (row: Row) => boolean,\n): Stream<'yield'> {\n if (!predicate) {\n yield* output.push(change, pusher);\n return;\n }\n switch (change[ChangeIndex.TYPE]) {\n case ChangeType.ADD:\n case ChangeType.REMOVE:\n if (predicate(change[ChangeIndex.NODE].row)) {\n yield* output.push(change, pusher);\n }\n break;\n case ChangeType.CHILD:\n if (predicate(change[ChangeIndex.NODE].row)) {\n yield* output.push(change, pusher);\n }\n break;\n case ChangeType.EDIT:\n yield* maybeSplitAndPushEditChange(change, predicate, output, pusher);\n break;\n default:\n unreachable(change);\n }\n}\n"],"mappings":";;;AASA,UAAiB,WACf,QACA,QACA,QACA,WACiB;AACjB,KAAI,CAAC,WAAW;AACd,SAAO,OAAO,KAAK,QAAQ,OAAO;AAClC;;AAEF,SAAQ,OAAO,IAAf;EACE,KAAK;EACL,KAAK;AACH,OAAI,UAAU,OAAO,GAAkB,IAAI,CACzC,QAAO,OAAO,KAAK,QAAQ,OAAO;AAEpC;EACF,KAAK;AACH,OAAI,UAAU,OAAO,GAAkB,IAAI,CACzC,QAAO,OAAO,KAAK,QAAQ,OAAO;AAEpC;EACF,KAAK;AACH,UAAO,4BAA4B,QAAQ,WAAW,QAAQ,OAAO;AACrE;EACF,QACE,aAAY,OAAO"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Row } from '../../../zero-protocol/src/data.ts';
|
|
2
2
|
import type { Change } from './change.ts';
|
|
3
|
-
import { type FilterInput, type FilterOperator, type FilterOutput } from './filter-operators.ts';
|
|
4
3
|
import { type Node } from './data.ts';
|
|
4
|
+
import { type FilterInput, type FilterOperator, type FilterOutput } from './filter-operators.ts';
|
|
5
5
|
import type { SourceSchema } from './schema.ts';
|
|
6
6
|
/**
|
|
7
7
|
* The Filter operator filters data through a predicate. It is stateless.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,oCAAoC,CAAC;AAC5D,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,EAAC,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AACpC,OAAO,EAEL,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAE9C;;;;GAIG;AACH,qBAAa,MAAO,YAAW,cAAc;;gBAM/B,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO;IAMhE,WAAW,IAAI,IAAI;IAInB,SAAS,IAAI,IAAI;IAIhB,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC;IAIhD,eAAe,CAAC,MAAM,EAAE,YAAY;IAIpC,OAAO,IAAI,IAAI;IAIf,SAAS,IAAI,YAAY;IAIxB,IAAI,CAAC,MAAM,EAAE,MAAM;CAGrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.js","names":["#input","#predicate","#output"],"sources":["../../../../../zql/src/ivm/filter.ts"],"sourcesContent":["import type {Row} from '../../../zero-protocol/src/data.ts';\nimport type {Change} from './change.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport {filterPush} from './filter-push.ts';\nimport
|
|
1
|
+
{"version":3,"file":"filter.js","names":["#input","#predicate","#output"],"sources":["../../../../../zql/src/ivm/filter.ts"],"sourcesContent":["import type {Row} from '../../../zero-protocol/src/data.ts';\nimport type {Change} from './change.ts';\nimport {type Node} from './data.ts';\nimport {\n throwFilterOutput,\n type FilterInput,\n type FilterOperator,\n type FilterOutput,\n} from './filter-operators.ts';\nimport {filterPush} from './filter-push.ts';\nimport type {SourceSchema} from './schema.ts';\n\n/**\n * The Filter operator filters data through a predicate. It is stateless.\n *\n * The predicate must be pure.\n */\nexport class Filter implements FilterOperator {\n readonly #input: FilterInput;\n readonly #predicate: (row: Row) => boolean;\n\n #output: FilterOutput = throwFilterOutput;\n\n constructor(input: FilterInput, predicate: (row: Row) => boolean) {\n this.#input = input;\n this.#predicate = predicate;\n input.setFilterOutput(this);\n }\n\n beginFilter(): void {\n this.#output.beginFilter();\n }\n\n endFilter(): void {\n this.#output.endFilter();\n }\n\n *filter(node: Node): Generator<'yield', boolean> {\n return this.#predicate(node.row) && (yield* this.#output.filter(node));\n }\n\n setFilterOutput(output: FilterOutput) {\n this.#output = output;\n }\n\n destroy(): void {\n this.#input.destroy();\n }\n\n getSchema(): SourceSchema {\n return this.#input.getSchema();\n }\n\n *push(change: Change) {\n yield* filterPush(change, this.#output, this, this.#predicate);\n }\n}\n"],"mappings":";;;;;;;;;AAiBA,IAAa,SAAb,MAA8C;CAC5C;CACA;CAEA,UAAwB;CAExB,YAAY,OAAoB,WAAkC;AAChE,QAAA,QAAc;AACd,QAAA,YAAkB;AAClB,QAAM,gBAAgB,KAAK;;CAG7B,cAAoB;AAClB,QAAA,OAAa,aAAa;;CAG5B,YAAkB;AAChB,QAAA,OAAa,WAAW;;CAG1B,CAAC,OAAO,MAAyC;AAC/C,SAAO,MAAA,UAAgB,KAAK,IAAI,KAAK,OAAO,MAAA,OAAa,OAAO,KAAK;;CAGvE,gBAAgB,QAAsB;AACpC,QAAA,SAAe;;CAGjB,UAAgB;AACd,QAAA,MAAY,SAAS;;CAGvB,YAA0B;AACxB,SAAO,MAAA,MAAY,WAAW;;CAGhC,CAAC,KAAK,QAAgB;AACpB,SAAO,WAAW,QAAQ,MAAA,QAAc,MAAM,MAAA,UAAgB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flipped-join.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/flipped-join.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,WAAW,EAAE,MAAM,EAAC,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"flipped-join.d.ts","sourceRoot":"","sources":["../../../../../zql/src/ivm/flipped-join.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,WAAW,EAAE,MAAM,EAAC,MAAM,mCAAmC,CAAC;AAY3E,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAOpC,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,KAAK,EACV,KAAK,MAAM,EACZ,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAC,KAAK,MAAM,EAAC,MAAM,aAAa,CAAC;AAExC,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,KAAK,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IAEb,SAAS,EAAE,WAAW,CAAC;IACvB,QAAQ,EAAE,WAAW,CAAC;IAEtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;;;;;;GAOG;AACH,qBAAa,WAAY,YAAW,KAAK;;gBAa3B,EACV,MAAM,EACN,KAAK,EACL,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,MAAM,EACN,MAAM,GACP,EAAE,IAAI;IAkCP,OAAO,IAAI,IAAI;IAKf,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,SAAS,IAAI,YAAY;IAQxB,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC;CA6XlD"}
|
|
@@ -2,6 +2,7 @@ import { assert, unreachable } from "../../../shared/src/asserts.js";
|
|
|
2
2
|
import { binarySearch } from "../../../shared/src/binary-search.js";
|
|
3
3
|
import { emptyArray } from "../../../shared/src/sentinels.js";
|
|
4
4
|
import { throwOutput } from "./operator.js";
|
|
5
|
+
import { makeAddChange, makeChildChange, makeEditChange, makeRemoveChange } from "./change.js";
|
|
5
6
|
import { constraintsAreCompatible } from "./constraint.js";
|
|
6
7
|
import { buildJoinConstraint, generateWithOverlayNoYield, isJoinMatch, rowEqualsForCompoundKey } from "./join-utils.js";
|
|
7
8
|
//#region ../zql/src/ivm/flipped-join.ts
|
|
@@ -22,6 +23,7 @@ var FlippedJoin = class {
|
|
|
22
23
|
#schema;
|
|
23
24
|
#output = throwOutput;
|
|
24
25
|
#inprogressChildChange;
|
|
26
|
+
#inprogressChildChangePosition;
|
|
25
27
|
constructor({ parent, child, parentKey, childKey, relationshipName, hidden, system }) {
|
|
26
28
|
assert(parent !== child, "Parent and child must be different operators");
|
|
27
29
|
assert(parentKey.length === childKey.length, "The parentKey and childKey keys must have same length");
|
|
@@ -74,8 +76,8 @@ var FlippedJoin = class {
|
|
|
74
76
|
}
|
|
75
77
|
childNodes.push(node);
|
|
76
78
|
}
|
|
77
|
-
if (this.#inprogressChildChange?.
|
|
78
|
-
const removedNode = this.#inprogressChildChange
|
|
79
|
+
if (this.#inprogressChildChange?.[0] === 1) {
|
|
80
|
+
const removedNode = this.#inprogressChildChange[1];
|
|
79
81
|
const compare = this.#child.getSchema().compareRows;
|
|
80
82
|
const insertPos = binarySearch(childNodes.length, (i) => compare(removedNode.row, childNodes[i].row));
|
|
81
83
|
childNodes.splice(insertPos, 0, removedNode);
|
|
@@ -138,11 +140,11 @@ var FlippedJoin = class {
|
|
|
138
140
|
nextParentNodes[minParentNodeChildIndex] = result.done ? null : result.value;
|
|
139
141
|
}
|
|
140
142
|
let overlaidRelatedChildNodes = relatedChildNodes;
|
|
141
|
-
if (this.#inprogressChildChange && this.#
|
|
142
|
-
const hasInprogressChildChangeBeenPushedForMinParentNode = this.#parent.getSchema().compareRows(minParentNode.row, this.#
|
|
143
|
-
if (this.#inprogressChildChange
|
|
144
|
-
if (hasInprogressChildChangeBeenPushedForMinParentNode) overlaidRelatedChildNodes = relatedChildNodes.filter((n) => n !== this.#inprogressChildChange?.
|
|
145
|
-
} else if (!hasInprogressChildChangeBeenPushedForMinParentNode) overlaidRelatedChildNodes = [...generateWithOverlayNoYield(relatedChildNodes, this.#inprogressChildChange
|
|
143
|
+
if (this.#inprogressChildChange && this.#inprogressChildChangePosition && isJoinMatch(this.#inprogressChildChange[1].row, this.#childKey, minParentNode.row, this.#parentKey)) {
|
|
144
|
+
const hasInprogressChildChangeBeenPushedForMinParentNode = this.#parent.getSchema().compareRows(minParentNode.row, this.#inprogressChildChangePosition) <= 0;
|
|
145
|
+
if (this.#inprogressChildChange[0] === 1) {
|
|
146
|
+
if (hasInprogressChildChangeBeenPushedForMinParentNode) overlaidRelatedChildNodes = relatedChildNodes.filter((n) => n !== this.#inprogressChildChange?.[1]);
|
|
147
|
+
} else if (!hasInprogressChildChangeBeenPushedForMinParentNode) overlaidRelatedChildNodes = [...generateWithOverlayNoYield(relatedChildNodes, this.#inprogressChildChange, this.#child.getSchema())];
|
|
146
148
|
}
|
|
147
149
|
if (overlaidRelatedChildNodes.length > 0) yield {
|
|
148
150
|
...minParentNode,
|
|
@@ -165,37 +167,33 @@ var FlippedJoin = class {
|
|
|
165
167
|
}
|
|
166
168
|
}
|
|
167
169
|
*#pushChild(change) {
|
|
168
|
-
switch (change
|
|
169
|
-
case
|
|
170
|
-
case
|
|
170
|
+
switch (change[0]) {
|
|
171
|
+
case 0:
|
|
172
|
+
case 1:
|
|
171
173
|
yield* this.#pushChildChange(change);
|
|
172
174
|
break;
|
|
173
|
-
case
|
|
174
|
-
assert(rowEqualsForCompoundKey(change.
|
|
175
|
+
case 2:
|
|
176
|
+
assert(rowEqualsForCompoundKey(change[2].row, change[1].row, this.#childKey), `Child edit must not change relationship.`);
|
|
175
177
|
yield* this.#pushChildChange(change, true);
|
|
176
178
|
break;
|
|
177
|
-
case
|
|
179
|
+
case 3:
|
|
178
180
|
yield* this.#pushChildChange(change, true);
|
|
179
181
|
break;
|
|
180
182
|
}
|
|
181
183
|
}
|
|
182
184
|
*#pushChildChange(change, exists) {
|
|
183
|
-
this.#inprogressChildChange =
|
|
184
|
-
|
|
185
|
-
position: void 0
|
|
186
|
-
};
|
|
185
|
+
this.#inprogressChildChange = change;
|
|
186
|
+
this.#inprogressChildChangePosition = void 0;
|
|
187
187
|
try {
|
|
188
|
-
const constraint = buildJoinConstraint(change.
|
|
188
|
+
const constraint = buildJoinConstraint(change[1].row, this.#childKey, this.#parentKey);
|
|
189
189
|
const parentNodeStream = constraint ? this.#parent.fetch({ constraint }) : [];
|
|
190
190
|
for (const parentNode of parentNodeStream) {
|
|
191
191
|
if (parentNode === "yield") {
|
|
192
192
|
yield "yield";
|
|
193
193
|
continue;
|
|
194
194
|
}
|
|
195
|
-
this.#inprogressChildChange =
|
|
196
|
-
|
|
197
|
-
position: parentNode.row
|
|
198
|
-
};
|
|
195
|
+
this.#inprogressChildChange = change;
|
|
196
|
+
this.#inprogressChildChangePosition = parentNode.row;
|
|
199
197
|
const childNodeStream = () => {
|
|
200
198
|
const constraint = buildJoinConstraint(parentNode.row, this.#parentKey, this.#childKey);
|
|
201
199
|
return constraint ? this.#child.fetch({ constraint }) : [];
|
|
@@ -205,35 +203,31 @@ var FlippedJoin = class {
|
|
|
205
203
|
yield "yield";
|
|
206
204
|
continue;
|
|
207
205
|
}
|
|
208
|
-
if (this.#child.getSchema().compareRows(childNode.row, change.
|
|
206
|
+
if (this.#child.getSchema().compareRows(childNode.row, change[1].row) !== 0) {
|
|
209
207
|
exists = true;
|
|
210
208
|
break;
|
|
211
209
|
}
|
|
212
210
|
}
|
|
213
|
-
if (exists) yield* this.#output.push({
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
...parentNode,
|
|
217
|
-
|
|
218
|
-
...parentNode.relationships,
|
|
219
|
-
[this.#relationshipName]: childNodeStream
|
|
220
|
-
}
|
|
221
|
-
},
|
|
222
|
-
child: {
|
|
223
|
-
relationshipName: this.#relationshipName,
|
|
224
|
-
change
|
|
211
|
+
if (exists) yield* this.#output.push(makeChildChange({
|
|
212
|
+
...parentNode,
|
|
213
|
+
relationships: {
|
|
214
|
+
...parentNode.relationships,
|
|
215
|
+
[this.#relationshipName]: childNodeStream
|
|
225
216
|
}
|
|
226
|
-
},
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
217
|
+
}, {
|
|
218
|
+
relationshipName: this.#relationshipName,
|
|
219
|
+
change
|
|
220
|
+
}), this);
|
|
221
|
+
else {
|
|
222
|
+
const newNode = {
|
|
230
223
|
...parentNode,
|
|
231
224
|
relationships: {
|
|
232
225
|
...parentNode.relationships,
|
|
233
|
-
[this.#relationshipName]: () => [change
|
|
226
|
+
[this.#relationshipName]: () => [change[1]]
|
|
234
227
|
}
|
|
235
|
-
}
|
|
236
|
-
|
|
228
|
+
};
|
|
229
|
+
yield* this.#output.push(change[0] === 0 ? makeAddChange(newNode) : makeRemoveChange(newNode), this);
|
|
230
|
+
}
|
|
237
231
|
}
|
|
238
232
|
} finally {
|
|
239
233
|
this.#inprogressChildChange = void 0;
|
|
@@ -252,7 +246,7 @@ var FlippedJoin = class {
|
|
|
252
246
|
}
|
|
253
247
|
});
|
|
254
248
|
let hasRelatedChild = false;
|
|
255
|
-
for (const node of childNodeStream(change
|
|
249
|
+
for (const node of childNodeStream(change[1])()) if (node === "yield") {
|
|
256
250
|
yield "yield";
|
|
257
251
|
continue;
|
|
258
252
|
} else {
|
|
@@ -260,22 +254,19 @@ var FlippedJoin = class {
|
|
|
260
254
|
break;
|
|
261
255
|
}
|
|
262
256
|
if (!hasRelatedChild) return;
|
|
263
|
-
switch (change
|
|
264
|
-
case
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
257
|
+
switch (change[0]) {
|
|
258
|
+
case 0:
|
|
259
|
+
yield* this.#output.push(makeAddChange(flip(change[1])), this);
|
|
260
|
+
break;
|
|
261
|
+
case 1:
|
|
262
|
+
yield* this.#output.push(makeRemoveChange(flip(change[1])), this);
|
|
263
|
+
break;
|
|
264
|
+
case 3:
|
|
265
|
+
yield* this.#output.push(makeChildChange(flip(change[1]), change[2]), this);
|
|
271
266
|
break;
|
|
272
|
-
case
|
|
273
|
-
assert(rowEqualsForCompoundKey(change.
|
|
274
|
-
yield* this.#output.push(
|
|
275
|
-
type: "edit",
|
|
276
|
-
oldNode: flip(change.oldNode),
|
|
277
|
-
node: flip(change.node)
|
|
278
|
-
}, this);
|
|
267
|
+
case 2:
|
|
268
|
+
assert(rowEqualsForCompoundKey(change[2].row, change[1].row, this.#parentKey), `Parent edit must not change relationship.`);
|
|
269
|
+
yield* this.#output.push(makeEditChange(flip(change[1]), flip(change[2])), this);
|
|
279
270
|
break;
|
|
280
271
|
default: unreachable(change);
|
|
281
272
|
}
|