@rocicorp/zero 0.25.0-canary.0 → 0.25.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/{chunk-BJ2CGCME.js → chunk-55BOUNXO.js} +3 -3
- package/out/chunk-55BOUNXO.js.map +7 -0
- package/out/{chunk-MXPHMVU7.js → chunk-AIPM77UE.js} +2337 -548
- package/out/chunk-AIPM77UE.js.map +7 -0
- package/out/{chunk-4RB4OYLQ.js → chunk-TJFNGO7E.js} +3 -2
- package/out/{lazy-inspector-2SW772W4.js → lazy-inspector-OXIFYSSQ.js} +2 -2
- package/out/react.js +16 -4
- package/out/react.js.map +4 -4
- package/out/replicache/src/dag/lazy-store.d.ts +1 -1
- package/out/replicache/src/dag/lazy-store.d.ts.map +1 -1
- package/out/replicache/src/log-options.d.ts +1 -1
- package/out/replicache/src/log-options.d.ts.map +1 -1
- package/out/replicache/src/persist/collect-idb-databases.d.ts +3 -3
- package/out/replicache/src/persist/collect-idb-databases.d.ts.map +1 -1
- package/out/replicache/src/replicache-options.d.ts +1 -1
- package/out/replicache/src/replicache-options.d.ts.map +1 -1
- package/out/shared/src/options.d.ts +1 -1
- package/out/shared/src/options.d.ts.map +1 -1
- package/out/shared/src/promise-race.d.ts +17 -0
- package/out/shared/src/promise-race.d.ts.map +1 -0
- package/out/solid.js +19 -6
- package/out/solid.js.map +4 -4
- package/out/z2s/src/compiler.d.ts +1 -1
- package/out/z2s/src/compiler.d.ts.map +1 -1
- package/out/z2s/src/compiler.js +1 -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 -1
- package/out/z2s/src/sql.js.map +1 -1
- package/out/zero/package.json +4 -3
- package/out/zero-cache/src/config/zero-config.d.ts +12 -0
- package/out/zero-cache/src/config/zero-config.d.ts.map +1 -1
- package/out/zero-cache/src/config/zero-config.js +36 -0
- package/out/zero-cache/src/config/zero-config.js.map +1 -1
- package/out/zero-cache/src/custom/fetch.d.ts +3 -1
- package/out/zero-cache/src/custom/fetch.d.ts.map +1 -1
- package/out/zero-cache/src/custom/fetch.js +101 -24
- package/out/zero-cache/src/custom/fetch.js.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.d.ts +2 -6
- package/out/zero-cache/src/custom-queries/transform-query.d.ts.map +1 -1
- package/out/zero-cache/src/custom-queries/transform-query.js +42 -41
- package/out/zero-cache/src/custom-queries/transform-query.js.map +1 -1
- package/out/zero-cache/src/db/create.d.ts +4 -0
- package/out/zero-cache/src/db/create.d.ts.map +1 -1
- package/out/zero-cache/src/db/create.js +7 -9
- package/out/zero-cache/src/db/create.js.map +1 -1
- package/out/zero-cache/src/db/lite-tables.js +2 -2
- package/out/zero-cache/src/db/lite-tables.js.map +1 -1
- package/out/zero-cache/src/db/pg-to-lite.d.ts.map +1 -1
- package/out/zero-cache/src/db/pg-to-lite.js +7 -6
- package/out/zero-cache/src/db/pg-to-lite.js.map +1 -1
- package/out/zero-cache/src/db/specs.d.ts +12 -12
- package/out/zero-cache/src/server/change-streamer.d.ts.map +1 -1
- package/out/zero-cache/src/server/change-streamer.js +1 -1
- package/out/zero-cache/src/server/change-streamer.js.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.d.ts.map +1 -1
- package/out/zero-cache/src/server/inspector-delegate.js +5 -1
- package/out/zero-cache/src/server/inspector-delegate.js.map +1 -1
- package/out/zero-cache/src/server/syncer.d.ts.map +1 -1
- package/out/zero-cache/src/server/syncer.js +1 -1
- package/out/zero-cache/src/server/syncer.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/change-source.js +1 -0
- package/out/zero-cache/src/services/change-source/pg/change-source.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.d.ts +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.d.ts.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js +1 -1
- package/out/zero-cache/src/services/change-source/pg/logical-replication/binary-reader.js.map +1 -1
- package/out/zero-cache/src/services/change-source/pg/schema/ddl.d.ts +25 -25
- package/out/zero-cache/src/services/change-source/pg/schema/published.d.ts +10 -10
- package/out/zero-cache/src/services/change-source/pg/schema/shard.d.ts +5 -5
- package/out/zero-cache/src/services/change-source/protocol/current/data.d.ts +16 -16
- package/out/zero-cache/src/services/change-source/protocol/current/downstream.d.ts +24 -24
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.d.ts +2 -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 +18 -2
- package/out/zero-cache/src/services/change-streamer/change-streamer-http.js.map +1 -1
- package/out/zero-cache/src/services/change-streamer/change-streamer.d.ts +8 -8
- package/out/zero-cache/src/services/mutagen/mutagen.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/mutagen.js +9 -7
- package/out/zero-cache/src/services/mutagen/mutagen.js.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.d.ts +4 -4
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +74 -56
- package/out/zero-cache/src/services/mutagen/pusher.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-handler.d.ts +3 -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 +10 -6
- package/out/zero-cache/src/services/view-syncer/client-handler.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-schema.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/client-schema.js +6 -3
- package/out/zero-cache/src/services/view-syncer/client-schema.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts +4 -4
- package/out/zero-cache/src/services/view-syncer/cvr-store.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr-store.js +15 -6
- package/out/zero-cache/src/services/view-syncer/cvr-store.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/cvr.js +4 -2
- package/out/zero-cache/src/services/view-syncer/cvr.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/key-columns.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/key-columns.js +4 -2
- package/out/zero-cache/src/services/view-syncer/key-columns.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js +19 -2
- package/out/zero-cache/src/services/view-syncer/pipeline-driver.js.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/view-syncer.js +67 -31
- package/out/zero-cache/src/services/view-syncer/view-syncer.js.map +1 -1
- package/out/zero-cache/src/types/error-with-level.d.ts +9 -0
- package/out/zero-cache/src/types/error-with-level.d.ts.map +1 -0
- package/out/zero-cache/src/types/error-with-level.js +24 -0
- package/out/zero-cache/src/types/error-with-level.js.map +1 -0
- package/out/zero-cache/src/types/lite.d.ts +15 -13
- package/out/zero-cache/src/types/lite.d.ts.map +1 -1
- package/out/zero-cache/src/types/lite.js +17 -5
- package/out/zero-cache/src/types/lite.js.map +1 -1
- package/out/zero-cache/src/types/pg-data-type.d.ts +73 -0
- package/out/zero-cache/src/types/pg-data-type.d.ts.map +1 -0
- package/out/zero-cache/src/types/pg-data-type.js +76 -0
- package/out/zero-cache/src/types/pg-data-type.js.map +1 -0
- package/out/zero-cache/src/types/pg.d.ts +1 -73
- package/out/zero-cache/src/types/pg.d.ts.map +1 -1
- package/out/zero-cache/src/types/pg.js +0 -77
- package/out/zero-cache/src/types/pg.js.map +1 -1
- package/out/zero-cache/src/types/processes.d.ts +1 -1
- package/out/zero-cache/src/types/processes.d.ts.map +1 -1
- package/out/zero-cache/src/types/processes.js.map +1 -1
- package/out/zero-cache/src/types/schema-versions.d.ts +7 -3
- package/out/zero-cache/src/types/schema-versions.d.ts.map +1 -1
- package/out/zero-cache/src/types/schema-versions.js +7 -5
- package/out/zero-cache/src/types/schema-versions.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +1 -1
- package/out/zero-cache/src/types/subscription.js +1 -1
- package/out/zero-cache/src/types/websocket-handoff.d.ts +3 -3
- package/out/zero-cache/src/types/websocket-handoff.d.ts.map +1 -1
- package/out/zero-cache/src/types/websocket-handoff.js +6 -4
- package/out/zero-cache/src/types/websocket-handoff.js.map +1 -1
- package/out/zero-cache/src/workers/connection.d.ts +6 -1
- package/out/zero-cache/src/workers/connection.d.ts.map +1 -1
- package/out/zero-cache/src/workers/connection.js +26 -9
- package/out/zero-cache/src/workers/connection.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 +7 -1
- 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 +21 -1
- package/out/zero-cache/src/workers/syncer.js.map +1 -1
- package/out/zero-client/src/client/client-error-kind-enum.d.ts +8 -0
- package/out/zero-client/src/client/client-error-kind-enum.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-manager.d.ts +65 -13
- package/out/zero-client/src/client/connection-manager.d.ts.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.d.ts +45 -0
- package/out/zero-client/src/client/connection.d.ts.map +1 -0
- package/out/zero-client/src/client/error.d.ts +178 -23
- package/out/zero-client/src/client/error.d.ts.map +1 -1
- package/out/zero-client/src/client/ivm-branch.d.ts +2 -2
- package/out/zero-client/src/client/ivm-branch.d.ts.map +1 -1
- package/out/zero-client/src/client/metrics.d.ts +9 -0
- package/out/zero-client/src/client/metrics.d.ts.map +1 -1
- package/out/zero-client/src/client/mutation-tracker.d.ts +5 -4
- package/out/zero-client/src/client/mutation-tracker.d.ts.map +1 -1
- package/out/zero-client/src/client/options.d.ts +6 -2
- package/out/zero-client/src/client/options.d.ts.map +1 -1
- package/out/zero-client/src/client/query-manager.d.ts +5 -4
- package/out/zero-client/src/client/query-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts +1 -1
- package/out/zero-client/src/client/zero-rep.d.ts.map +1 -1
- package/out/zero-client/src/client/zero.d.ts +27 -5
- package/out/zero-client/src/client/zero.d.ts.map +1 -1
- package/out/zero-client/src/mod.d.ts +9 -1
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-protocol/src/custom-queries.d.ts +75 -4
- package/out/zero-protocol/src/custom-queries.d.ts.map +1 -1
- package/out/zero-protocol/src/custom-queries.js +18 -1
- package/out/zero-protocol/src/custom-queries.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +1 -1
- package/out/zero-protocol/src/error-kind-enum.d.ts +65 -0
- package/out/zero-protocol/src/error-kind-enum.d.ts.map +1 -1
- package/out/zero-protocol/src/error-kind-enum.js +2 -0
- package/out/zero-protocol/src/error-kind-enum.js.map +1 -1
- package/out/zero-protocol/src/error-origin-enum.d.ts +7 -0
- package/out/zero-protocol/src/error-origin-enum.d.ts.map +1 -0
- package/out/zero-protocol/src/error-origin-enum.js +4 -0
- package/out/zero-protocol/src/error-origin-enum.js.map +1 -0
- package/out/zero-protocol/src/error-origin.d.ts +5 -0
- package/out/zero-protocol/src/error-origin.d.ts.map +1 -0
- package/out/zero-protocol/src/error-origin.js +3 -0
- package/out/zero-protocol/src/error-origin.js.map +1 -0
- package/out/zero-protocol/src/error-reason-enum.d.ts +15 -0
- package/out/zero-protocol/src/error-reason-enum.d.ts.map +1 -0
- package/out/zero-protocol/src/error-reason-enum.js +8 -0
- package/out/zero-protocol/src/error-reason-enum.js.map +1 -0
- package/out/zero-protocol/src/error-reason.d.ts +5 -0
- package/out/zero-protocol/src/error-reason.d.ts.map +1 -0
- package/out/zero-protocol/src/error-reason.js +3 -0
- package/out/zero-protocol/src/error-reason.js.map +1 -0
- package/out/zero-protocol/src/error.d.ts +139 -1
- package/out/zero-protocol/src/error.d.ts.map +1 -1
- package/out/zero-protocol/src/error.js +64 -2
- package/out/zero-protocol/src/error.js.map +1 -1
- package/out/zero-protocol/src/mutation-id.d.ts +7 -0
- package/out/zero-protocol/src/mutation-id.d.ts.map +1 -0
- package/out/zero-protocol/src/mutation-id.js +6 -0
- package/out/zero-protocol/src/mutation-id.js.map +1 -0
- package/out/zero-protocol/src/mutations-patch.d.ts +3 -3
- package/out/zero-protocol/src/mutations-patch.d.ts.map +1 -1
- package/out/zero-protocol/src/mutations-patch.js +2 -1
- package/out/zero-protocol/src/mutations-patch.js.map +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts +1 -1
- package/out/zero-protocol/src/protocol-version.d.ts.map +1 -1
- package/out/zero-protocol/src/protocol-version.js +2 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +138 -13
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js +34 -13
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero-react/src/mod.d.ts +2 -1
- package/out/zero-react/src/mod.d.ts.map +1 -1
- package/out/zero-react/src/use-zero-connection-state.d.ts +9 -0
- package/out/zero-react/src/use-zero-connection-state.d.ts.map +1 -0
- package/out/zero-react/src/use-zero-online.d.ts +2 -0
- package/out/zero-react/src/use-zero-online.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.d.ts +3 -3
- package/out/zero-server/src/process-mutations.d.ts.map +1 -1
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/schema.js +1 -1
- package/out/zero-server/src/schema.js.map +1 -1
- package/out/zero-server/src/zql-database.d.ts +1 -1
- package/out/zero-server/src/zql-database.d.ts.map +1 -1
- package/out/zero-server/src/zql-database.js.map +1 -1
- package/out/zero-solid/src/mod.d.ts +3 -2
- package/out/zero-solid/src/mod.d.ts.map +1 -1
- package/out/zero-solid/src/use-zero-connection-state.d.ts +10 -0
- package/out/zero-solid/src/use-zero-connection-state.d.ts.map +1 -0
- package/out/zero-solid/src/use-zero-online.d.ts +1 -7
- package/out/zero-solid/src/use-zero-online.d.ts.map +1 -1
- package/out/zero.js +13 -3
- package/out/zql/src/builder/builder.d.ts +2 -1
- package/out/zql/src/builder/builder.d.ts.map +1 -1
- package/out/zql/src/builder/builder.js +5 -1
- package/out/zql/src/builder/builder.js.map +1 -1
- package/out/zql/src/ivm/data.d.ts +1 -1
- package/out/zql/src/ivm/data.d.ts.map +1 -1
- package/out/zql/src/ivm/data.js.map +1 -1
- package/out/zql/src/ivm/filter-push.d.ts +1 -1
- package/out/zql/src/ivm/filter-push.d.ts.map +1 -1
- package/out/zql/src/ivm/filter-push.js.map +1 -1
- package/out/zql/src/ivm/memory-source.d.ts +2 -2
- package/out/zql/src/ivm/memory-source.d.ts.map +1 -1
- package/out/zql/src/ivm/memory-source.js.map +1 -1
- package/out/zql/src/ivm/source.d.ts +1 -1
- package/out/zql/src/ivm/source.d.ts.map +1 -1
- package/out/zql/src/ivm/take.d.ts +1 -1
- package/out/zql/src/ivm/take.d.ts.map +1 -1
- package/out/zql/src/ivm/take.js.map +1 -1
- package/out/zql/src/planner/planner-builder.d.ts +14 -0
- package/out/zql/src/planner/planner-builder.d.ts.map +1 -0
- package/out/zql/src/planner/planner-builder.js +180 -0
- package/out/zql/src/planner/planner-builder.js.map +1 -0
- package/out/zql/src/planner/planner-connection.d.ts +119 -0
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -0
- package/out/zql/src/planner/planner-connection.js +301 -0
- package/out/zql/src/planner/planner-connection.js.map +1 -0
- package/out/zql/src/planner/planner-constraint.d.ts +14 -0
- package/out/zql/src/planner/planner-constraint.d.ts.map +1 -0
- package/out/zql/src/planner/planner-constraint.js +12 -0
- package/out/zql/src/planner/planner-constraint.js.map +1 -0
- package/out/zql/src/planner/planner-debug.d.ts +118 -0
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -0
- package/out/zql/src/planner/planner-debug.js +125 -0
- package/out/zql/src/planner/planner-debug.js.map +1 -0
- package/out/zql/src/planner/planner-fan-in.d.ts +37 -0
- package/out/zql/src/planner/planner-fan-in.d.ts.map +1 -0
- package/out/zql/src/planner/planner-fan-in.js +149 -0
- package/out/zql/src/planner/planner-fan-in.js.map +1 -0
- package/out/zql/src/planner/planner-fan-out.d.ts +21 -0
- package/out/zql/src/planner/planner-fan-out.d.ts.map +1 -0
- package/out/zql/src/planner/planner-fan-out.js +45 -0
- package/out/zql/src/planner/planner-fan-out.js.map +1 -0
- package/out/zql/src/planner/planner-graph.d.ts +103 -0
- package/out/zql/src/planner/planner-graph.d.ts.map +1 -0
- package/out/zql/src/planner/planner-graph.js +411 -0
- package/out/zql/src/planner/planner-graph.js.map +1 -0
- package/out/zql/src/planner/planner-join.d.ts +81 -0
- package/out/zql/src/planner/planner-join.d.ts.map +1 -0
- package/out/zql/src/planner/planner-join.js +246 -0
- package/out/zql/src/planner/planner-join.js.map +1 -0
- package/out/zql/src/planner/planner-node.d.ts +21 -0
- package/out/zql/src/planner/planner-node.d.ts.map +1 -0
- package/out/zql/src/planner/planner-node.js +2 -0
- package/out/zql/src/planner/planner-node.js.map +1 -0
- package/out/zql/src/planner/planner-source.d.ts +11 -0
- package/out/zql/src/planner/planner-source.d.ts.map +1 -0
- package/out/zql/src/planner/planner-source.js +13 -0
- package/out/zql/src/planner/planner-source.js.map +1 -0
- package/out/zql/src/planner/planner-terminus.d.ts +16 -0
- package/out/zql/src/planner/planner-terminus.d.ts.map +1 -0
- package/out/zql/src/planner/planner-terminus.js +28 -0
- package/out/zql/src/planner/planner-terminus.js.map +1 -0
- package/out/zql/src/query/expression.d.ts +2 -2
- package/out/zql/src/query/expression.d.ts.map +1 -1
- package/out/zql/src/query/expression.js.map +1 -1
- package/out/zql/src/query/query-delegate.d.ts +3 -3
- package/out/zql/src/query/query-delegate.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.d.ts +8 -8
- package/out/zql/src/query/query-impl.d.ts.map +1 -1
- package/out/zql/src/query/query-impl.js.map +1 -1
- package/out/zql/src/query/query.d.ts +3 -3
- package/out/zql/src/query/query.d.ts.map +1 -1
- package/out/zql/src/query/static-query.d.ts +1 -1
- package/out/zql/src/query/static-query.d.ts.map +1 -1
- package/out/zql/src/query/static-query.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/query-delegate.d.ts +1 -1
- package/out/zqlite/src/query-delegate.d.ts.map +1 -1
- package/out/zqlite/src/query-delegate.js.map +1 -1
- package/out/zqlite/src/sqlite-cost-model.d.ts +17 -0
- package/out/zqlite/src/sqlite-cost-model.d.ts.map +1 -0
- package/out/zqlite/src/sqlite-cost-model.js +134 -0
- package/out/zqlite/src/sqlite-cost-model.js.map +1 -0
- package/out/zqlite/src/table-source.d.ts +1 -1
- package/out/zqlite/src/table-source.d.ts.map +1 -1
- package/out/zqlite/src/table-source.js.map +1 -1
- package/package.json +4 -3
- package/out/chunk-BJ2CGCME.js.map +0 -7
- package/out/chunk-MXPHMVU7.js.map +0 -7
- package/out/zero-cache/src/types/error-for-client.d.ts +0 -23
- package/out/zero-cache/src/types/error-for-client.d.ts.map +0 -1
- package/out/zero-cache/src/types/error-for-client.js +0 -28
- package/out/zero-cache/src/types/error-for-client.js.map +0 -1
- package/out/zero-client/src/client/ping-result-enum.d.ts +0 -5
- package/out/zero-client/src/client/ping-result-enum.d.ts.map +0 -1
- /package/out/{chunk-4RB4OYLQ.js.map → chunk-TJFNGO7E.js.map} +0 -0
- /package/out/{lazy-inspector-2SW772W4.js.map → lazy-inspector-OXIFYSSQ.js.map} +0 -0
|
@@ -96,6 +96,7 @@ import {
|
|
|
96
96
|
normalizeAST,
|
|
97
97
|
once,
|
|
98
98
|
parse,
|
|
99
|
+
planIdSymbol,
|
|
99
100
|
primaryKeySchema,
|
|
100
101
|
primaryKeyValueRecordSchema,
|
|
101
102
|
readFromDefaultHead,
|
|
@@ -123,7 +124,7 @@ import {
|
|
|
123
124
|
withWrite,
|
|
124
125
|
withWriteNoImplicitCommit,
|
|
125
126
|
wrapIterable
|
|
126
|
-
} from "./chunk-
|
|
127
|
+
} from "./chunk-TJFNGO7E.js";
|
|
127
128
|
import {
|
|
128
129
|
assert,
|
|
129
130
|
assertArray,
|
|
@@ -1511,6 +1512,223 @@ function rejectIfClosed(tx) {
|
|
|
1511
1512
|
return tx.closed ? Promise.reject(new TransactionClosedError()) : void 0;
|
|
1512
1513
|
}
|
|
1513
1514
|
|
|
1515
|
+
// ../zero-protocol/src/error-kind-enum.ts
|
|
1516
|
+
var error_kind_enum_exports = {};
|
|
1517
|
+
__export(error_kind_enum_exports, {
|
|
1518
|
+
AuthInvalidated: () => AuthInvalidated,
|
|
1519
|
+
ClientNotFound: () => ClientNotFound,
|
|
1520
|
+
Internal: () => Internal,
|
|
1521
|
+
InvalidConnectionRequest: () => InvalidConnectionRequest,
|
|
1522
|
+
InvalidConnectionRequestBaseCookie: () => InvalidConnectionRequestBaseCookie,
|
|
1523
|
+
InvalidConnectionRequestClientDeleted: () => InvalidConnectionRequestClientDeleted,
|
|
1524
|
+
InvalidConnectionRequestLastMutationID: () => InvalidConnectionRequestLastMutationID,
|
|
1525
|
+
InvalidMessage: () => InvalidMessage,
|
|
1526
|
+
InvalidPush: () => InvalidPush,
|
|
1527
|
+
MutationFailed: () => MutationFailed,
|
|
1528
|
+
MutationRateLimited: () => MutationRateLimited,
|
|
1529
|
+
PushFailed: () => PushFailed,
|
|
1530
|
+
Rebalance: () => Rebalance,
|
|
1531
|
+
Rehome: () => Rehome,
|
|
1532
|
+
SchemaVersionNotSupported: () => SchemaVersionNotSupported,
|
|
1533
|
+
ServerOverloaded: () => ServerOverloaded,
|
|
1534
|
+
TransformFailed: () => TransformFailed,
|
|
1535
|
+
Unauthorized: () => Unauthorized,
|
|
1536
|
+
VersionNotSupported: () => VersionNotSupported
|
|
1537
|
+
});
|
|
1538
|
+
var AuthInvalidated = "AuthInvalidated";
|
|
1539
|
+
var ClientNotFound = "ClientNotFound";
|
|
1540
|
+
var InvalidConnectionRequest = "InvalidConnectionRequest";
|
|
1541
|
+
var InvalidConnectionRequestBaseCookie = "InvalidConnectionRequestBaseCookie";
|
|
1542
|
+
var InvalidConnectionRequestLastMutationID = "InvalidConnectionRequestLastMutationID";
|
|
1543
|
+
var InvalidConnectionRequestClientDeleted = "InvalidConnectionRequestClientDeleted";
|
|
1544
|
+
var InvalidMessage = "InvalidMessage";
|
|
1545
|
+
var InvalidPush = "InvalidPush";
|
|
1546
|
+
var PushFailed = "PushFailed";
|
|
1547
|
+
var MutationFailed = "MutationFailed";
|
|
1548
|
+
var MutationRateLimited = "MutationRateLimited";
|
|
1549
|
+
var Rebalance = "Rebalance";
|
|
1550
|
+
var Rehome = "Rehome";
|
|
1551
|
+
var TransformFailed = "TransformFailed";
|
|
1552
|
+
var Unauthorized = "Unauthorized";
|
|
1553
|
+
var VersionNotSupported = "VersionNotSupported";
|
|
1554
|
+
var SchemaVersionNotSupported = "SchemaVersionNotSupported";
|
|
1555
|
+
var ServerOverloaded = "ServerOverloaded";
|
|
1556
|
+
var Internal = "Internal";
|
|
1557
|
+
|
|
1558
|
+
// ../zero-protocol/src/error-origin-enum.ts
|
|
1559
|
+
var error_origin_enum_exports = {};
|
|
1560
|
+
__export(error_origin_enum_exports, {
|
|
1561
|
+
Client: () => Client,
|
|
1562
|
+
Server: () => Server,
|
|
1563
|
+
ZeroCache: () => ZeroCache
|
|
1564
|
+
});
|
|
1565
|
+
var Client = "client";
|
|
1566
|
+
var Server = "server";
|
|
1567
|
+
var ZeroCache = "zeroCache";
|
|
1568
|
+
|
|
1569
|
+
// ../zero-protocol/src/error-reason-enum.ts
|
|
1570
|
+
var error_reason_enum_exports = {};
|
|
1571
|
+
__export(error_reason_enum_exports, {
|
|
1572
|
+
Database: () => Database,
|
|
1573
|
+
HTTP: () => HTTP,
|
|
1574
|
+
Internal: () => Internal2,
|
|
1575
|
+
OutOfOrderMutation: () => OutOfOrderMutation,
|
|
1576
|
+
Parse: () => Parse,
|
|
1577
|
+
Timeout: () => Timeout,
|
|
1578
|
+
UnsupportedPushVersion: () => UnsupportedPushVersion
|
|
1579
|
+
});
|
|
1580
|
+
var Database = "database";
|
|
1581
|
+
var Parse = "parse";
|
|
1582
|
+
var OutOfOrderMutation = "oooMutation";
|
|
1583
|
+
var UnsupportedPushVersion = "unsupportedPushVersion";
|
|
1584
|
+
var Internal2 = "internal";
|
|
1585
|
+
var HTTP = "http";
|
|
1586
|
+
var Timeout = "timeout";
|
|
1587
|
+
|
|
1588
|
+
// ../zero-protocol/src/mutation-id.ts
|
|
1589
|
+
var mutationIDSchema = valita_exports.object({
|
|
1590
|
+
id: valita_exports.number(),
|
|
1591
|
+
clientID: valita_exports.string()
|
|
1592
|
+
});
|
|
1593
|
+
|
|
1594
|
+
// ../zero-protocol/src/error.ts
|
|
1595
|
+
var basicErrorKindSchema = literalUnion(
|
|
1596
|
+
error_kind_enum_exports.AuthInvalidated,
|
|
1597
|
+
error_kind_enum_exports.ClientNotFound,
|
|
1598
|
+
error_kind_enum_exports.InvalidConnectionRequest,
|
|
1599
|
+
error_kind_enum_exports.InvalidConnectionRequestBaseCookie,
|
|
1600
|
+
error_kind_enum_exports.InvalidConnectionRequestLastMutationID,
|
|
1601
|
+
error_kind_enum_exports.InvalidConnectionRequestClientDeleted,
|
|
1602
|
+
error_kind_enum_exports.InvalidMessage,
|
|
1603
|
+
error_kind_enum_exports.InvalidPush,
|
|
1604
|
+
error_kind_enum_exports.MutationRateLimited,
|
|
1605
|
+
error_kind_enum_exports.MutationFailed,
|
|
1606
|
+
error_kind_enum_exports.Unauthorized,
|
|
1607
|
+
error_kind_enum_exports.VersionNotSupported,
|
|
1608
|
+
error_kind_enum_exports.SchemaVersionNotSupported,
|
|
1609
|
+
error_kind_enum_exports.Internal
|
|
1610
|
+
);
|
|
1611
|
+
var basicErrorBodySchema = valita_exports.object({
|
|
1612
|
+
kind: basicErrorKindSchema,
|
|
1613
|
+
message: valita_exports.string(),
|
|
1614
|
+
// this is optional for backwards compatibility
|
|
1615
|
+
origin: literalUnion(error_origin_enum_exports.Server, error_origin_enum_exports.ZeroCache).optional()
|
|
1616
|
+
});
|
|
1617
|
+
var backoffErrorKindSchema = literalUnion(
|
|
1618
|
+
error_kind_enum_exports.Rebalance,
|
|
1619
|
+
error_kind_enum_exports.Rehome,
|
|
1620
|
+
error_kind_enum_exports.ServerOverloaded
|
|
1621
|
+
);
|
|
1622
|
+
var backoffBodySchema = valita_exports.object({
|
|
1623
|
+
kind: backoffErrorKindSchema,
|
|
1624
|
+
message: valita_exports.string(),
|
|
1625
|
+
minBackoffMs: valita_exports.number().optional(),
|
|
1626
|
+
maxBackoffMs: valita_exports.number().optional(),
|
|
1627
|
+
// Query parameters to send in the next reconnect. In the event of
|
|
1628
|
+
// a conflict, these will be overridden by the parameters used by
|
|
1629
|
+
// the client; it is the responsibility of the server to avoid
|
|
1630
|
+
// parameter name conflicts.
|
|
1631
|
+
//
|
|
1632
|
+
// The parameters will only be added to the immediately following
|
|
1633
|
+
// reconnect, and not after that.
|
|
1634
|
+
reconnectParams: valita_exports.record(valita_exports.string()).optional(),
|
|
1635
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache).optional()
|
|
1636
|
+
});
|
|
1637
|
+
var pushFailedErrorKindSchema = valita_exports.literal(error_kind_enum_exports.PushFailed);
|
|
1638
|
+
var transformFailedErrorKindSchema = valita_exports.literal(error_kind_enum_exports.TransformFailed);
|
|
1639
|
+
var errorKindSchema = valita_exports.union(
|
|
1640
|
+
basicErrorKindSchema,
|
|
1641
|
+
backoffErrorKindSchema,
|
|
1642
|
+
pushFailedErrorKindSchema,
|
|
1643
|
+
transformFailedErrorKindSchema
|
|
1644
|
+
);
|
|
1645
|
+
var pushFailedBaseSchema = valita_exports.object({
|
|
1646
|
+
kind: pushFailedErrorKindSchema,
|
|
1647
|
+
details: jsonSchema.optional(),
|
|
1648
|
+
mutationIDs: valita_exports.array(mutationIDSchema),
|
|
1649
|
+
message: valita_exports.string()
|
|
1650
|
+
});
|
|
1651
|
+
var pushFailedBodySchema = valita_exports.union(
|
|
1652
|
+
pushFailedBaseSchema.extend({
|
|
1653
|
+
origin: valita_exports.literal(error_origin_enum_exports.Server),
|
|
1654
|
+
reason: literalUnion(
|
|
1655
|
+
error_reason_enum_exports.Database,
|
|
1656
|
+
error_reason_enum_exports.Parse,
|
|
1657
|
+
error_reason_enum_exports.OutOfOrderMutation,
|
|
1658
|
+
error_reason_enum_exports.UnsupportedPushVersion,
|
|
1659
|
+
error_reason_enum_exports.Internal
|
|
1660
|
+
)
|
|
1661
|
+
}),
|
|
1662
|
+
pushFailedBaseSchema.extend({
|
|
1663
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
|
|
1664
|
+
reason: valita_exports.literal(error_reason_enum_exports.HTTP),
|
|
1665
|
+
status: valita_exports.number(),
|
|
1666
|
+
bodyPreview: valita_exports.string().optional()
|
|
1667
|
+
}),
|
|
1668
|
+
pushFailedBaseSchema.extend({
|
|
1669
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
|
|
1670
|
+
reason: literalUnion(
|
|
1671
|
+
error_reason_enum_exports.Timeout,
|
|
1672
|
+
error_reason_enum_exports.Parse,
|
|
1673
|
+
error_reason_enum_exports.Internal
|
|
1674
|
+
)
|
|
1675
|
+
})
|
|
1676
|
+
);
|
|
1677
|
+
var transformFailedBaseSchema = valita_exports.object({
|
|
1678
|
+
kind: transformFailedErrorKindSchema,
|
|
1679
|
+
details: jsonSchema.optional(),
|
|
1680
|
+
queryIDs: valita_exports.array(valita_exports.string()),
|
|
1681
|
+
message: valita_exports.string()
|
|
1682
|
+
});
|
|
1683
|
+
var transformFailedBodySchema = valita_exports.union(
|
|
1684
|
+
transformFailedBaseSchema.extend({
|
|
1685
|
+
origin: valita_exports.literal(error_origin_enum_exports.Server),
|
|
1686
|
+
reason: literalUnion(
|
|
1687
|
+
error_reason_enum_exports.Database,
|
|
1688
|
+
error_reason_enum_exports.Parse,
|
|
1689
|
+
error_reason_enum_exports.Internal
|
|
1690
|
+
)
|
|
1691
|
+
}),
|
|
1692
|
+
transformFailedBaseSchema.extend({
|
|
1693
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
|
|
1694
|
+
reason: valita_exports.literal(error_reason_enum_exports.HTTP),
|
|
1695
|
+
status: valita_exports.number(),
|
|
1696
|
+
bodyPreview: valita_exports.string().optional()
|
|
1697
|
+
}),
|
|
1698
|
+
transformFailedBaseSchema.extend({
|
|
1699
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
|
|
1700
|
+
reason: literalUnion(
|
|
1701
|
+
error_reason_enum_exports.Timeout,
|
|
1702
|
+
error_reason_enum_exports.Parse,
|
|
1703
|
+
error_reason_enum_exports.Internal
|
|
1704
|
+
)
|
|
1705
|
+
})
|
|
1706
|
+
);
|
|
1707
|
+
var errorBodySchema = valita_exports.union(
|
|
1708
|
+
basicErrorBodySchema,
|
|
1709
|
+
backoffBodySchema,
|
|
1710
|
+
pushFailedBodySchema,
|
|
1711
|
+
transformFailedBodySchema
|
|
1712
|
+
);
|
|
1713
|
+
var errorMessageSchema = valita_exports.tuple([
|
|
1714
|
+
valita_exports.literal("error"),
|
|
1715
|
+
errorBodySchema
|
|
1716
|
+
]);
|
|
1717
|
+
var ProtocolError = class extends Error {
|
|
1718
|
+
errorBody;
|
|
1719
|
+
constructor(errorBody, options) {
|
|
1720
|
+
super(errorBody.message, options);
|
|
1721
|
+
this.name = "ProtocolError";
|
|
1722
|
+
this.errorBody = errorBody;
|
|
1723
|
+
}
|
|
1724
|
+
get kind() {
|
|
1725
|
+
return this.errorBody.kind;
|
|
1726
|
+
}
|
|
1727
|
+
};
|
|
1728
|
+
function isProtocolError(error) {
|
|
1729
|
+
return error instanceof ProtocolError;
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1514
1732
|
// ../zero-protocol/src/custom-queries.ts
|
|
1515
1733
|
var transformRequestBodySchema = valita_exports.array(
|
|
1516
1734
|
valita_exports.object({
|
|
@@ -1531,16 +1749,25 @@ var appQueryErrorSchema = valita_exports.object({
|
|
|
1531
1749
|
details: jsonSchema
|
|
1532
1750
|
});
|
|
1533
1751
|
var zeroErrorSchema = valita_exports.object({
|
|
1752
|
+
/** @deprecated */
|
|
1534
1753
|
error: valita_exports.literal("zero"),
|
|
1754
|
+
/** @deprecated */
|
|
1535
1755
|
id: valita_exports.string(),
|
|
1756
|
+
/** @deprecated */
|
|
1536
1757
|
name: valita_exports.string(),
|
|
1758
|
+
/** @deprecated */
|
|
1537
1759
|
details: jsonSchema
|
|
1538
1760
|
});
|
|
1539
1761
|
var httpQueryErrorSchema = valita_exports.object({
|
|
1762
|
+
/** @deprecated */
|
|
1540
1763
|
error: valita_exports.literal("http"),
|
|
1764
|
+
/** @deprecated */
|
|
1541
1765
|
id: valita_exports.string(),
|
|
1766
|
+
/** @deprecated */
|
|
1542
1767
|
name: valita_exports.string(),
|
|
1768
|
+
/** @deprecated */
|
|
1543
1769
|
status: valita_exports.number(),
|
|
1770
|
+
/** @deprecated */
|
|
1544
1771
|
details: jsonSchema
|
|
1545
1772
|
});
|
|
1546
1773
|
var erroredQuerySchema = valita_exports.union(
|
|
@@ -1559,49 +1786,18 @@ var transformErrorMessageSchema = valita_exports.tuple([
|
|
|
1559
1786
|
valita_exports.literal("transformError"),
|
|
1560
1787
|
valita_exports.array(erroredQuerySchema)
|
|
1561
1788
|
]);
|
|
1562
|
-
var
|
|
1789
|
+
var transformFailedMessageSchema = valita_exports.tuple([
|
|
1790
|
+
valita_exports.literal("transformFailed"),
|
|
1791
|
+
transformFailedBodySchema
|
|
1792
|
+
]);
|
|
1793
|
+
var transformOkMessageSchema = valita_exports.tuple([
|
|
1563
1794
|
valita_exports.literal("transformed"),
|
|
1564
1795
|
transformResponseBodySchema
|
|
1565
1796
|
]);
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
AuthInvalidated: () => AuthInvalidated,
|
|
1571
|
-
ClientNotFound: () => ClientNotFound,
|
|
1572
|
-
Internal: () => Internal,
|
|
1573
|
-
InvalidConnectionRequest: () => InvalidConnectionRequest,
|
|
1574
|
-
InvalidConnectionRequestBaseCookie: () => InvalidConnectionRequestBaseCookie,
|
|
1575
|
-
InvalidConnectionRequestClientDeleted: () => InvalidConnectionRequestClientDeleted,
|
|
1576
|
-
InvalidConnectionRequestLastMutationID: () => InvalidConnectionRequestLastMutationID,
|
|
1577
|
-
InvalidMessage: () => InvalidMessage,
|
|
1578
|
-
InvalidPush: () => InvalidPush,
|
|
1579
|
-
MutationFailed: () => MutationFailed,
|
|
1580
|
-
MutationRateLimited: () => MutationRateLimited,
|
|
1581
|
-
Rebalance: () => Rebalance,
|
|
1582
|
-
Rehome: () => Rehome,
|
|
1583
|
-
SchemaVersionNotSupported: () => SchemaVersionNotSupported,
|
|
1584
|
-
ServerOverloaded: () => ServerOverloaded,
|
|
1585
|
-
Unauthorized: () => Unauthorized,
|
|
1586
|
-
VersionNotSupported: () => VersionNotSupported
|
|
1587
|
-
});
|
|
1588
|
-
var AuthInvalidated = "AuthInvalidated";
|
|
1589
|
-
var ClientNotFound = "ClientNotFound";
|
|
1590
|
-
var InvalidConnectionRequest = "InvalidConnectionRequest";
|
|
1591
|
-
var InvalidConnectionRequestBaseCookie = "InvalidConnectionRequestBaseCookie";
|
|
1592
|
-
var InvalidConnectionRequestLastMutationID = "InvalidConnectionRequestLastMutationID";
|
|
1593
|
-
var InvalidConnectionRequestClientDeleted = "InvalidConnectionRequestClientDeleted";
|
|
1594
|
-
var InvalidMessage = "InvalidMessage";
|
|
1595
|
-
var InvalidPush = "InvalidPush";
|
|
1596
|
-
var MutationFailed = "MutationFailed";
|
|
1597
|
-
var MutationRateLimited = "MutationRateLimited";
|
|
1598
|
-
var Rebalance = "Rebalance";
|
|
1599
|
-
var Rehome = "Rehome";
|
|
1600
|
-
var Unauthorized = "Unauthorized";
|
|
1601
|
-
var VersionNotSupported = "VersionNotSupported";
|
|
1602
|
-
var SchemaVersionNotSupported = "SchemaVersionNotSupported";
|
|
1603
|
-
var ServerOverloaded = "ServerOverloaded";
|
|
1604
|
-
var Internal = "Internal";
|
|
1797
|
+
var transformResponseMessageSchema = valita_exports.union(
|
|
1798
|
+
transformOkMessageSchema,
|
|
1799
|
+
transformFailedMessageSchema
|
|
1800
|
+
);
|
|
1605
1801
|
|
|
1606
1802
|
// ../zero-schema/src/builder/table-builder.ts
|
|
1607
1803
|
function table(name) {
|
|
@@ -1611,14 +1807,14 @@ function table(name) {
|
|
|
1611
1807
|
primaryKey: []
|
|
1612
1808
|
});
|
|
1613
1809
|
}
|
|
1614
|
-
function
|
|
1810
|
+
function string4() {
|
|
1615
1811
|
return new ColumnBuilder({
|
|
1616
1812
|
type: "string",
|
|
1617
1813
|
optional: false,
|
|
1618
1814
|
customType: null
|
|
1619
1815
|
});
|
|
1620
1816
|
}
|
|
1621
|
-
function
|
|
1817
|
+
function number4() {
|
|
1622
1818
|
return new ColumnBuilder({
|
|
1623
1819
|
type: "number",
|
|
1624
1820
|
optional: false,
|
|
@@ -2172,6 +2368,170 @@ function makeID(row, schema) {
|
|
|
2172
2368
|
return JSON.stringify(schema.primaryKey.map((k) => row[k]));
|
|
2173
2369
|
}
|
|
2174
2370
|
|
|
2371
|
+
// ../zero-client/src/client/client-error-kind-enum.ts
|
|
2372
|
+
var client_error_kind_enum_exports = {};
|
|
2373
|
+
__export(client_error_kind_enum_exports, {
|
|
2374
|
+
AbruptClose: () => AbruptClose,
|
|
2375
|
+
CleanClose: () => CleanClose,
|
|
2376
|
+
ClientClosed: () => ClientClosed,
|
|
2377
|
+
ConnectTimeout: () => ConnectTimeout,
|
|
2378
|
+
DisconnectTimeout: () => DisconnectTimeout,
|
|
2379
|
+
Hidden: () => Hidden,
|
|
2380
|
+
Internal: () => Internal3,
|
|
2381
|
+
InvalidMessage: () => InvalidMessage2,
|
|
2382
|
+
NoSocketOrigin: () => NoSocketOrigin,
|
|
2383
|
+
PingTimeout: () => PingTimeout,
|
|
2384
|
+
PullTimeout: () => PullTimeout,
|
|
2385
|
+
UnexpectedBaseCookie: () => UnexpectedBaseCookie,
|
|
2386
|
+
UserDisconnect: () => UserDisconnect
|
|
2387
|
+
});
|
|
2388
|
+
var AbruptClose = "AbruptClose";
|
|
2389
|
+
var CleanClose = "CleanClose";
|
|
2390
|
+
var ClientClosed = "ClientClosed";
|
|
2391
|
+
var ConnectTimeout = "ConnectTimeout";
|
|
2392
|
+
var DisconnectTimeout = "DisconnectTimeout";
|
|
2393
|
+
var UnexpectedBaseCookie = "UnexpectedBaseCookie";
|
|
2394
|
+
var PingTimeout = "PingTimeout";
|
|
2395
|
+
var PullTimeout = "PullTimeout";
|
|
2396
|
+
var Hidden = "Hidden";
|
|
2397
|
+
var NoSocketOrigin = "NoSocketOrigin";
|
|
2398
|
+
var InvalidMessage2 = "InvalidMessage";
|
|
2399
|
+
var UserDisconnect = "UserDisconnect";
|
|
2400
|
+
var Internal3 = "Internal";
|
|
2401
|
+
|
|
2402
|
+
// ../zero-client/src/client/connection-status-enum.ts
|
|
2403
|
+
var connection_status_enum_exports = {};
|
|
2404
|
+
__export(connection_status_enum_exports, {
|
|
2405
|
+
Closed: () => Closed,
|
|
2406
|
+
Connected: () => Connected,
|
|
2407
|
+
Connecting: () => Connecting,
|
|
2408
|
+
Disconnected: () => Disconnected,
|
|
2409
|
+
Error: () => Error2
|
|
2410
|
+
});
|
|
2411
|
+
var Disconnected = "disconnected";
|
|
2412
|
+
var Connecting = "connecting";
|
|
2413
|
+
var Connected = "connected";
|
|
2414
|
+
var Error2 = "error";
|
|
2415
|
+
var Closed = "closed";
|
|
2416
|
+
|
|
2417
|
+
// ../zero-client/src/client/error.ts
|
|
2418
|
+
var ClientError = class extends Error {
|
|
2419
|
+
errorBody;
|
|
2420
|
+
constructor(errorBody, options) {
|
|
2421
|
+
super(errorBody.message, options);
|
|
2422
|
+
this.name = "ClientError";
|
|
2423
|
+
this.errorBody = { ...errorBody, origin: error_origin_enum_exports.Client };
|
|
2424
|
+
}
|
|
2425
|
+
get kind() {
|
|
2426
|
+
return this.errorBody.kind;
|
|
2427
|
+
}
|
|
2428
|
+
};
|
|
2429
|
+
function isServerError(ex) {
|
|
2430
|
+
return isProtocolError(ex) && (ex.errorBody.origin === error_origin_enum_exports.Server || ex.errorBody.origin === error_origin_enum_exports.ZeroCache);
|
|
2431
|
+
}
|
|
2432
|
+
function isAuthError(ex) {
|
|
2433
|
+
if (isServerError(ex)) {
|
|
2434
|
+
if (isAuthErrorKind(ex.errorBody.kind)) {
|
|
2435
|
+
return true;
|
|
2436
|
+
}
|
|
2437
|
+
if ((ex.errorBody.kind === error_kind_enum_exports.PushFailed || ex.errorBody.kind === error_kind_enum_exports.TransformFailed) && ex.errorBody.reason === error_reason_enum_exports.HTTP && (ex.errorBody.status === 401 || ex.errorBody.status === 403)) {
|
|
2438
|
+
return true;
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
return false;
|
|
2442
|
+
}
|
|
2443
|
+
function isAuthErrorKind(kind) {
|
|
2444
|
+
return kind === error_kind_enum_exports.AuthInvalidated || kind === error_kind_enum_exports.Unauthorized;
|
|
2445
|
+
}
|
|
2446
|
+
function getBackoffParams(error) {
|
|
2447
|
+
if (isServerError(error)) {
|
|
2448
|
+
switch (error.errorBody.kind) {
|
|
2449
|
+
case error_kind_enum_exports.Rebalance:
|
|
2450
|
+
case error_kind_enum_exports.Rehome:
|
|
2451
|
+
case error_kind_enum_exports.ServerOverloaded:
|
|
2452
|
+
return error.errorBody;
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
return void 0;
|
|
2456
|
+
}
|
|
2457
|
+
function isClientError(ex) {
|
|
2458
|
+
return ex instanceof ClientError && ex.errorBody.origin === error_origin_enum_exports.Client;
|
|
2459
|
+
}
|
|
2460
|
+
var NO_STATUS_TRANSITION = "NO_STATUS_TRANSITION";
|
|
2461
|
+
function getErrorConnectionTransition(ex) {
|
|
2462
|
+
if (isClientError(ex)) {
|
|
2463
|
+
switch (ex.kind) {
|
|
2464
|
+
// Connecting errors that should continue in the current state
|
|
2465
|
+
case client_error_kind_enum_exports.AbruptClose:
|
|
2466
|
+
case client_error_kind_enum_exports.CleanClose:
|
|
2467
|
+
case client_error_kind_enum_exports.ConnectTimeout:
|
|
2468
|
+
case client_error_kind_enum_exports.PingTimeout:
|
|
2469
|
+
case client_error_kind_enum_exports.PullTimeout:
|
|
2470
|
+
case client_error_kind_enum_exports.Hidden:
|
|
2471
|
+
case client_error_kind_enum_exports.NoSocketOrigin:
|
|
2472
|
+
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
2473
|
+
// Fatal errors that should transition to error state
|
|
2474
|
+
case client_error_kind_enum_exports.UnexpectedBaseCookie:
|
|
2475
|
+
case client_error_kind_enum_exports.Internal:
|
|
2476
|
+
case client_error_kind_enum_exports.InvalidMessage:
|
|
2477
|
+
case client_error_kind_enum_exports.UserDisconnect:
|
|
2478
|
+
return { status: connection_status_enum_exports.Error, reason: ex };
|
|
2479
|
+
// Disconnected error (this should already result in a disconnected state)
|
|
2480
|
+
case client_error_kind_enum_exports.DisconnectTimeout:
|
|
2481
|
+
return { status: connection_status_enum_exports.Disconnected, reason: ex };
|
|
2482
|
+
// Closed error (this should already result in a closed state)
|
|
2483
|
+
case client_error_kind_enum_exports.ClientClosed:
|
|
2484
|
+
return { status: connection_status_enum_exports.Closed, reason: ex };
|
|
2485
|
+
default:
|
|
2486
|
+
unreachable(ex.kind);
|
|
2487
|
+
}
|
|
2488
|
+
}
|
|
2489
|
+
if (isAuthError(ex)) {
|
|
2490
|
+
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
2491
|
+
}
|
|
2492
|
+
if (isServerError(ex)) {
|
|
2493
|
+
switch (ex.kind) {
|
|
2494
|
+
// Errors that should transition to error state
|
|
2495
|
+
case error_kind_enum_exports.ClientNotFound:
|
|
2496
|
+
case error_kind_enum_exports.InvalidConnectionRequest:
|
|
2497
|
+
case error_kind_enum_exports.InvalidConnectionRequestBaseCookie:
|
|
2498
|
+
case error_kind_enum_exports.InvalidConnectionRequestLastMutationID:
|
|
2499
|
+
case error_kind_enum_exports.InvalidConnectionRequestClientDeleted:
|
|
2500
|
+
case error_kind_enum_exports.InvalidMessage:
|
|
2501
|
+
case error_kind_enum_exports.InvalidPush:
|
|
2502
|
+
case error_kind_enum_exports.VersionNotSupported:
|
|
2503
|
+
case error_kind_enum_exports.SchemaVersionNotSupported:
|
|
2504
|
+
case error_kind_enum_exports.Internal:
|
|
2505
|
+
case error_kind_enum_exports.PushFailed:
|
|
2506
|
+
case error_kind_enum_exports.TransformFailed:
|
|
2507
|
+
return { status: connection_status_enum_exports.Error, reason: ex };
|
|
2508
|
+
// Errors that should continue with backoff/retry
|
|
2509
|
+
case error_kind_enum_exports.Rebalance:
|
|
2510
|
+
case error_kind_enum_exports.Rehome:
|
|
2511
|
+
case error_kind_enum_exports.ServerOverloaded:
|
|
2512
|
+
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
2513
|
+
// Auth errors will eventually transition to needs-auth state
|
|
2514
|
+
// For now, treat them as non-fatal so we can retry
|
|
2515
|
+
case error_kind_enum_exports.AuthInvalidated:
|
|
2516
|
+
case error_kind_enum_exports.Unauthorized:
|
|
2517
|
+
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
2518
|
+
// Mutation-specific errors don't affect connection state
|
|
2519
|
+
case error_kind_enum_exports.MutationRateLimited:
|
|
2520
|
+
case error_kind_enum_exports.MutationFailed:
|
|
2521
|
+
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
2522
|
+
default:
|
|
2523
|
+
unreachable(ex.kind);
|
|
2524
|
+
}
|
|
2525
|
+
}
|
|
2526
|
+
return {
|
|
2527
|
+
status: connection_status_enum_exports.Error,
|
|
2528
|
+
reason: new ClientError({
|
|
2529
|
+
kind: client_error_kind_enum_exports.Internal,
|
|
2530
|
+
message: "Unexpected internal error: " + (ex instanceof Error ? ex.message : typeof ex === "string" ? ex : String(ex ?? "Unknown error"))
|
|
2531
|
+
})
|
|
2532
|
+
};
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2175
2535
|
// ../zero-client/src/client/update-needed-reason-type-enum.ts
|
|
2176
2536
|
var update_needed_reason_type_enum_exports = {};
|
|
2177
2537
|
__export(update_needed_reason_type_enum_exports, {
|
|
@@ -6283,6 +6643,24 @@ function validateOptions(options) {
|
|
|
6283
6643
|
}
|
|
6284
6644
|
}
|
|
6285
6645
|
|
|
6646
|
+
// ../shared/src/promise-race.ts
|
|
6647
|
+
var NO_PROMISES_MESSAGE = "No promises to race";
|
|
6648
|
+
var wrapPromise = (key, promise) => Promise.resolve(promise).then((result) => ({
|
|
6649
|
+
key,
|
|
6650
|
+
status: "fulfilled",
|
|
6651
|
+
result
|
|
6652
|
+
}));
|
|
6653
|
+
async function promiseRace(promises) {
|
|
6654
|
+
const keys = Object.keys(promises);
|
|
6655
|
+
if (keys.length === 0) {
|
|
6656
|
+
throw new Error(NO_PROMISES_MESSAGE);
|
|
6657
|
+
}
|
|
6658
|
+
const wrapped = keys.map(
|
|
6659
|
+
(key) => wrapPromise(key, promises[key])
|
|
6660
|
+
);
|
|
6661
|
+
return await Promise.race(wrapped);
|
|
6662
|
+
}
|
|
6663
|
+
|
|
6286
6664
|
// ../shared/src/sentinels.ts
|
|
6287
6665
|
function emptyFunction() {
|
|
6288
6666
|
}
|
|
@@ -6292,38 +6670,6 @@ function identity(x) {
|
|
|
6292
6670
|
return x;
|
|
6293
6671
|
}
|
|
6294
6672
|
|
|
6295
|
-
// ../shared/src/subscribable.ts
|
|
6296
|
-
var Subscribable = class {
|
|
6297
|
-
_listeners = /* @__PURE__ */ new Set();
|
|
6298
|
-
/**
|
|
6299
|
-
* Subscribe to the subscribable.
|
|
6300
|
-
*
|
|
6301
|
-
* @param listener - The listener to subscribe to.
|
|
6302
|
-
* @returns A function to unsubscribe from the subscribable.
|
|
6303
|
-
*/
|
|
6304
|
-
subscribe = (listener) => {
|
|
6305
|
-
this._listeners.add(listener);
|
|
6306
|
-
return () => {
|
|
6307
|
-
this._listeners.delete(listener);
|
|
6308
|
-
};
|
|
6309
|
-
};
|
|
6310
|
-
/**
|
|
6311
|
-
* Notify all listeners.
|
|
6312
|
-
*
|
|
6313
|
-
* @param update - The update to notify listeners with.
|
|
6314
|
-
*/
|
|
6315
|
-
notify = (update) => {
|
|
6316
|
-
this._listeners.forEach((listener) => listener(update));
|
|
6317
|
-
};
|
|
6318
|
-
hasListeners = () => this._listeners.size > 0;
|
|
6319
|
-
/**
|
|
6320
|
-
* Unsubscribe all listeners.
|
|
6321
|
-
*/
|
|
6322
|
-
cleanup = () => {
|
|
6323
|
-
this._listeners.clear();
|
|
6324
|
-
};
|
|
6325
|
-
};
|
|
6326
|
-
|
|
6327
6673
|
// ../zero-protocol/src/delete-clients.ts
|
|
6328
6674
|
var deleteClientsBodySchema = valita_exports.union(
|
|
6329
6675
|
readonlyObject({
|
|
@@ -6401,56 +6747,6 @@ function encodeSecProtocols(initConnectionMessage, authToken) {
|
|
|
6401
6747
|
return encodeURIComponent(btoa(s));
|
|
6402
6748
|
}
|
|
6403
6749
|
|
|
6404
|
-
// ../zero-protocol/src/error.ts
|
|
6405
|
-
var basicErrorKindSchema = literalUnion(
|
|
6406
|
-
error_kind_enum_exports.AuthInvalidated,
|
|
6407
|
-
error_kind_enum_exports.ClientNotFound,
|
|
6408
|
-
error_kind_enum_exports.InvalidConnectionRequest,
|
|
6409
|
-
error_kind_enum_exports.InvalidConnectionRequestBaseCookie,
|
|
6410
|
-
error_kind_enum_exports.InvalidConnectionRequestLastMutationID,
|
|
6411
|
-
error_kind_enum_exports.InvalidConnectionRequestClientDeleted,
|
|
6412
|
-
error_kind_enum_exports.InvalidMessage,
|
|
6413
|
-
error_kind_enum_exports.InvalidPush,
|
|
6414
|
-
error_kind_enum_exports.MutationRateLimited,
|
|
6415
|
-
error_kind_enum_exports.MutationFailed,
|
|
6416
|
-
error_kind_enum_exports.Unauthorized,
|
|
6417
|
-
error_kind_enum_exports.VersionNotSupported,
|
|
6418
|
-
error_kind_enum_exports.SchemaVersionNotSupported,
|
|
6419
|
-
error_kind_enum_exports.Internal
|
|
6420
|
-
);
|
|
6421
|
-
var basicErrorBodySchema = valita_exports.object({
|
|
6422
|
-
kind: basicErrorKindSchema,
|
|
6423
|
-
message: valita_exports.string()
|
|
6424
|
-
});
|
|
6425
|
-
var backoffErrorKindSchema = literalUnion(
|
|
6426
|
-
error_kind_enum_exports.Rebalance,
|
|
6427
|
-
error_kind_enum_exports.Rehome,
|
|
6428
|
-
error_kind_enum_exports.ServerOverloaded
|
|
6429
|
-
);
|
|
6430
|
-
var backoffBodySchema = valita_exports.object({
|
|
6431
|
-
kind: backoffErrorKindSchema,
|
|
6432
|
-
message: valita_exports.string(),
|
|
6433
|
-
minBackoffMs: valita_exports.number().optional(),
|
|
6434
|
-
maxBackoffMs: valita_exports.number().optional(),
|
|
6435
|
-
// Query parameters to send in the next reconnect. In the event of
|
|
6436
|
-
// a conflict, these will be overridden by the parameters used by
|
|
6437
|
-
// the client; it is the responsibility of the server to avoid
|
|
6438
|
-
// parameter name conflicts.
|
|
6439
|
-
//
|
|
6440
|
-
// The parameters will only be added to the immediately following
|
|
6441
|
-
// reconnect, and not after that.
|
|
6442
|
-
reconnectParams: valita_exports.record(valita_exports.string()).optional()
|
|
6443
|
-
});
|
|
6444
|
-
var errorKindSchema = valita_exports.union(
|
|
6445
|
-
basicErrorKindSchema,
|
|
6446
|
-
backoffErrorKindSchema
|
|
6447
|
-
);
|
|
6448
|
-
var errorBodySchema = valita_exports.union(basicErrorBodySchema, backoffBodySchema);
|
|
6449
|
-
var errorMessageSchema = valita_exports.tuple([
|
|
6450
|
-
valita_exports.literal("error"),
|
|
6451
|
-
errorBodySchema
|
|
6452
|
-
]);
|
|
6453
|
-
|
|
6454
6750
|
// ../zero-protocol/src/mutation-type-enum.ts
|
|
6455
6751
|
var CRUD = "crud";
|
|
6456
6752
|
var Custom = "custom";
|
|
@@ -6522,17 +6818,17 @@ var pushBodySchema = valita_exports.object({
|
|
|
6522
6818
|
requestID: valita_exports.string()
|
|
6523
6819
|
});
|
|
6524
6820
|
var pushMessageSchema = valita_exports.tuple([valita_exports.literal("push"), pushBodySchema]);
|
|
6525
|
-
var mutationIDSchema = valita_exports.object({
|
|
6526
|
-
id: valita_exports.number(),
|
|
6527
|
-
clientID: valita_exports.string()
|
|
6528
|
-
});
|
|
6529
6821
|
var appErrorSchema = valita_exports.object({
|
|
6530
6822
|
error: valita_exports.literal("app"),
|
|
6531
6823
|
// The user can return any additional data here
|
|
6532
6824
|
details: jsonSchema.optional()
|
|
6533
6825
|
});
|
|
6534
6826
|
var zeroErrorSchema2 = valita_exports.object({
|
|
6535
|
-
error:
|
|
6827
|
+
error: valita_exports.union(
|
|
6828
|
+
/** @deprecated push oooMutation errors are now represented as ['error', { ... }] messages */
|
|
6829
|
+
valita_exports.literal("oooMutation"),
|
|
6830
|
+
valita_exports.literal("alreadyProcessed")
|
|
6831
|
+
),
|
|
6536
6832
|
details: jsonSchema.optional()
|
|
6537
6833
|
});
|
|
6538
6834
|
var mutationOkSchema = valita_exports.object({
|
|
@@ -6552,28 +6848,33 @@ var pushOkSchema = valita_exports.object({
|
|
|
6552
6848
|
mutations: valita_exports.array(mutationResponseSchema)
|
|
6553
6849
|
});
|
|
6554
6850
|
var unsupportedPushVersionSchema = valita_exports.object({
|
|
6851
|
+
/** @deprecated */
|
|
6555
6852
|
error: valita_exports.literal("unsupportedPushVersion"),
|
|
6556
|
-
|
|
6557
|
-
// This field is included so the client knows which mutations
|
|
6558
|
-
// were not processed by the server.
|
|
6853
|
+
/** @deprecated */
|
|
6559
6854
|
mutationIDs: valita_exports.array(mutationIDSchema).optional()
|
|
6560
6855
|
});
|
|
6561
6856
|
var unsupportedSchemaVersionSchema = valita_exports.object({
|
|
6857
|
+
/** @deprecated */
|
|
6562
6858
|
error: valita_exports.literal("unsupportedSchemaVersion"),
|
|
6563
|
-
|
|
6564
|
-
// This field is included so the client knows which mutations
|
|
6565
|
-
// were not processed by the server.
|
|
6859
|
+
/** @deprecated */
|
|
6566
6860
|
mutationIDs: valita_exports.array(mutationIDSchema).optional()
|
|
6567
6861
|
});
|
|
6568
6862
|
var httpErrorSchema = valita_exports.object({
|
|
6863
|
+
/** @deprecated */
|
|
6569
6864
|
error: valita_exports.literal("http"),
|
|
6865
|
+
/** @deprecated */
|
|
6570
6866
|
status: valita_exports.number(),
|
|
6867
|
+
/** @deprecated */
|
|
6571
6868
|
details: valita_exports.string(),
|
|
6869
|
+
/** @deprecated */
|
|
6572
6870
|
mutationIDs: valita_exports.array(mutationIDSchema).optional()
|
|
6573
6871
|
});
|
|
6574
6872
|
var zeroPusherErrorSchema = valita_exports.object({
|
|
6873
|
+
/** @deprecated */
|
|
6575
6874
|
error: valita_exports.literal("zeroPusher"),
|
|
6875
|
+
/** @deprecated */
|
|
6576
6876
|
details: valita_exports.string(),
|
|
6877
|
+
/** @deprecated */
|
|
6577
6878
|
mutationIDs: valita_exports.array(mutationIDSchema).optional()
|
|
6578
6879
|
});
|
|
6579
6880
|
var pushErrorSchema = valita_exports.union(
|
|
@@ -6582,10 +6883,14 @@ var pushErrorSchema = valita_exports.union(
|
|
|
6582
6883
|
httpErrorSchema,
|
|
6583
6884
|
zeroPusherErrorSchema
|
|
6584
6885
|
);
|
|
6585
|
-
var
|
|
6886
|
+
var pushResponseBodySchema = valita_exports.union(pushOkSchema, pushErrorSchema);
|
|
6887
|
+
var pushResponseSchema = valita_exports.union(
|
|
6888
|
+
pushResponseBodySchema,
|
|
6889
|
+
pushFailedBodySchema
|
|
6890
|
+
);
|
|
6586
6891
|
var pushResponseMessageSchema = valita_exports.tuple([
|
|
6587
6892
|
valita_exports.literal("pushResponse"),
|
|
6588
|
-
|
|
6893
|
+
pushResponseBodySchema
|
|
6589
6894
|
]);
|
|
6590
6895
|
var ackMutationResponsesMessageSchema = valita_exports.tuple([
|
|
6591
6896
|
valita_exports.literal("ackMutationResponses"),
|
|
@@ -6750,7 +7055,7 @@ var downstreamSchema = valita_exports.union(
|
|
|
6750
7055
|
);
|
|
6751
7056
|
|
|
6752
7057
|
// ../zero-protocol/src/protocol-version.ts
|
|
6753
|
-
var PROTOCOL_VERSION =
|
|
7058
|
+
var PROTOCOL_VERSION = 38;
|
|
6754
7059
|
var MIN_SERVER_SUPPORTED_SYNC_PROTOCOL = 18;
|
|
6755
7060
|
assert(MIN_SERVER_SUPPORTED_SYNC_PROTOCOL < PROTOCOL_VERSION);
|
|
6756
7061
|
|
|
@@ -9302,176 +9607,1426 @@ var UnionFanOut = class {
|
|
|
9302
9607
|
}
|
|
9303
9608
|
};
|
|
9304
9609
|
|
|
9305
|
-
// ../zql/src/
|
|
9306
|
-
var
|
|
9307
|
-
|
|
9308
|
-
|
|
9309
|
-
|
|
9310
|
-
|
|
9610
|
+
// ../zql/src/planner/planner-fan-in.ts
|
|
9611
|
+
var PlannerFanIn = class {
|
|
9612
|
+
kind = "fan-in";
|
|
9613
|
+
#type;
|
|
9614
|
+
#output;
|
|
9615
|
+
#inputs;
|
|
9616
|
+
constructor(inputs) {
|
|
9617
|
+
this.#type = "FI";
|
|
9618
|
+
this.#inputs = inputs;
|
|
9311
9619
|
}
|
|
9312
|
-
get
|
|
9313
|
-
return this;
|
|
9620
|
+
get type() {
|
|
9621
|
+
return this.#type;
|
|
9314
9622
|
}
|
|
9315
|
-
|
|
9316
|
-
return
|
|
9623
|
+
closestJoinOrSource() {
|
|
9624
|
+
return "join";
|
|
9317
9625
|
}
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
type: "simple",
|
|
9321
|
-
left: isParameterReference(left) ? left[toStaticParam]() : { type: "literal", value: left },
|
|
9322
|
-
right: isParameterReference(right) ? right[toStaticParam]() : { type: "literal", value: right },
|
|
9323
|
-
op
|
|
9324
|
-
};
|
|
9626
|
+
setOutput(node) {
|
|
9627
|
+
this.#output = node;
|
|
9325
9628
|
}
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
exists = (relationship, cb, options) => this.#exists(relationship, cb, options);
|
|
9330
|
-
};
|
|
9331
|
-
function and(...conditions) {
|
|
9332
|
-
const expressions = filterTrue(filterUndefined(conditions));
|
|
9333
|
-
if (expressions.length === 1) {
|
|
9334
|
-
return expressions[0];
|
|
9629
|
+
get output() {
|
|
9630
|
+
assert(this.#output !== void 0, "Output not set");
|
|
9631
|
+
return this.#output;
|
|
9335
9632
|
}
|
|
9336
|
-
|
|
9337
|
-
|
|
9633
|
+
reset() {
|
|
9634
|
+
this.#type = "FI";
|
|
9338
9635
|
}
|
|
9339
|
-
|
|
9340
|
-
|
|
9341
|
-
function or(...conditions) {
|
|
9342
|
-
const expressions = filterFalse(filterUndefined(conditions));
|
|
9343
|
-
if (expressions.length === 1) {
|
|
9344
|
-
return expressions[0];
|
|
9636
|
+
convertToUFI() {
|
|
9637
|
+
this.#type = "UFI";
|
|
9345
9638
|
}
|
|
9346
|
-
|
|
9347
|
-
|
|
9639
|
+
/**
|
|
9640
|
+
* Propagate unlimiting when a parent join is flipped.
|
|
9641
|
+
* Fan-in propagates to all of its inputs.
|
|
9642
|
+
*/
|
|
9643
|
+
propagateUnlimitFromFlippedJoin() {
|
|
9644
|
+
for (const input of this.#inputs) {
|
|
9645
|
+
if ("propagateUnlimitFromFlippedJoin" in input && typeof input.propagateUnlimitFromFlippedJoin === "function") {
|
|
9646
|
+
input.propagateUnlimitFromFlippedJoin();
|
|
9647
|
+
}
|
|
9648
|
+
}
|
|
9348
9649
|
}
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
|
|
9353
|
-
|
|
9354
|
-
|
|
9355
|
-
|
|
9356
|
-
|
|
9357
|
-
|
|
9358
|
-
|
|
9359
|
-
|
|
9360
|
-
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
|
|
9369
|
-
|
|
9370
|
-
|
|
9371
|
-
|
|
9372
|
-
|
|
9373
|
-
|
|
9374
|
-
|
|
9375
|
-
|
|
9650
|
+
estimateCost(branchPattern) {
|
|
9651
|
+
let totalCost = {
|
|
9652
|
+
rows: 0,
|
|
9653
|
+
runningCost: 0,
|
|
9654
|
+
startupCost: 0,
|
|
9655
|
+
selectivity: 0,
|
|
9656
|
+
limit: void 0
|
|
9657
|
+
};
|
|
9658
|
+
branchPattern = branchPattern ?? [];
|
|
9659
|
+
if (this.#type === "FI") {
|
|
9660
|
+
const updatedPattern = [0, ...branchPattern];
|
|
9661
|
+
let maxrows = 0;
|
|
9662
|
+
let maxRunningCost = 0;
|
|
9663
|
+
let maxStartupCost = 0;
|
|
9664
|
+
let noMatchProb = 1;
|
|
9665
|
+
for (const input of this.#inputs) {
|
|
9666
|
+
const cost = input.estimateCost(updatedPattern);
|
|
9667
|
+
if (cost.rows > maxrows) {
|
|
9668
|
+
maxrows = cost.rows;
|
|
9669
|
+
}
|
|
9670
|
+
if (cost.runningCost > maxRunningCost) {
|
|
9671
|
+
maxRunningCost = cost.runningCost;
|
|
9672
|
+
}
|
|
9673
|
+
if (cost.startupCost > maxStartupCost) {
|
|
9674
|
+
maxStartupCost = cost.startupCost;
|
|
9675
|
+
}
|
|
9676
|
+
noMatchProb *= 1 - cost.selectivity;
|
|
9677
|
+
assert(
|
|
9678
|
+
totalCost.limit === void 0 || cost.limit === totalCost.limit,
|
|
9679
|
+
"All FanIn inputs should have the same limit"
|
|
9680
|
+
);
|
|
9681
|
+
totalCost.limit = cost.limit;
|
|
9682
|
+
}
|
|
9683
|
+
totalCost.rows = maxrows;
|
|
9684
|
+
totalCost.runningCost = maxRunningCost;
|
|
9685
|
+
totalCost.startupCost = maxStartupCost;
|
|
9686
|
+
totalCost.selectivity = 1 - noMatchProb;
|
|
9687
|
+
} else {
|
|
9688
|
+
let i = 0;
|
|
9689
|
+
let noMatchProb = 1;
|
|
9690
|
+
for (const input of this.#inputs) {
|
|
9691
|
+
const updatedPattern = [i, ...branchPattern];
|
|
9692
|
+
const cost = input.estimateCost(updatedPattern);
|
|
9693
|
+
totalCost.rows += cost.rows;
|
|
9694
|
+
totalCost.runningCost += cost.runningCost;
|
|
9695
|
+
totalCost.startupCost += cost.startupCost;
|
|
9696
|
+
noMatchProb *= 1 - cost.selectivity;
|
|
9697
|
+
assert(
|
|
9698
|
+
totalCost.limit === void 0 || cost.limit === totalCost.limit,
|
|
9699
|
+
"All FanIn inputs should have the same limit"
|
|
9700
|
+
);
|
|
9701
|
+
totalCost.limit = cost.limit;
|
|
9702
|
+
i++;
|
|
9703
|
+
}
|
|
9704
|
+
totalCost.selectivity = 1 - noMatchProb;
|
|
9705
|
+
}
|
|
9706
|
+
return totalCost;
|
|
9376
9707
|
}
|
|
9377
|
-
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9708
|
+
propagateConstraints(branchPattern, constraint, from) {
|
|
9709
|
+
if (this.#type === "FI") {
|
|
9710
|
+
const updatedPattern = [0, ...branchPattern];
|
|
9711
|
+
for (const input of this.#inputs) {
|
|
9712
|
+
input.propagateConstraints(updatedPattern, constraint, from);
|
|
9713
|
+
}
|
|
9714
|
+
return;
|
|
9715
|
+
}
|
|
9716
|
+
let i = 0;
|
|
9717
|
+
for (const input of this.#inputs) {
|
|
9718
|
+
input.propagateConstraints([i, ...branchPattern], constraint, from);
|
|
9719
|
+
i++;
|
|
9720
|
+
}
|
|
9385
9721
|
}
|
|
9386
|
-
return {
|
|
9387
|
-
type: "simple",
|
|
9388
|
-
left: { type: "column", name: field },
|
|
9389
|
-
right: isParameterReference(value) ? value[toStaticParam]() : { type: "literal", value },
|
|
9390
|
-
op
|
|
9391
|
-
};
|
|
9392
|
-
}
|
|
9393
|
-
function isParameterReference(value) {
|
|
9394
|
-
return value !== null && typeof value === "object" && value[toStaticParam];
|
|
9395
|
-
}
|
|
9396
|
-
var TRUE = {
|
|
9397
|
-
type: "and",
|
|
9398
|
-
conditions: []
|
|
9399
|
-
};
|
|
9400
|
-
var FALSE = {
|
|
9401
|
-
type: "or",
|
|
9402
|
-
conditions: []
|
|
9403
9722
|
};
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9723
|
+
|
|
9724
|
+
// ../zql/src/planner/planner-fan-out.ts
|
|
9725
|
+
var PlannerFanOut = class {
|
|
9726
|
+
kind = "fan-out";
|
|
9727
|
+
#type;
|
|
9728
|
+
#outputs = [];
|
|
9729
|
+
#input;
|
|
9730
|
+
constructor(input) {
|
|
9731
|
+
this.#type = "FO";
|
|
9732
|
+
this.#input = input;
|
|
9413
9733
|
}
|
|
9414
|
-
|
|
9415
|
-
return
|
|
9734
|
+
get type() {
|
|
9735
|
+
return this.#type;
|
|
9416
9736
|
}
|
|
9417
|
-
|
|
9418
|
-
|
|
9419
|
-
return FALSE;
|
|
9737
|
+
addOutput(node) {
|
|
9738
|
+
this.#outputs.push(node);
|
|
9420
9739
|
}
|
|
9421
|
-
|
|
9422
|
-
return
|
|
9740
|
+
get outputs() {
|
|
9741
|
+
return this.#outputs;
|
|
9423
9742
|
}
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
|
|
9430
|
-
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
|
|
9435
|
-
|
|
9743
|
+
closestJoinOrSource() {
|
|
9744
|
+
return this.#input.closestJoinOrSource();
|
|
9745
|
+
}
|
|
9746
|
+
propagateConstraints(branchPattern, constraint, _from) {
|
|
9747
|
+
this.#input.propagateConstraints(branchPattern, constraint, this);
|
|
9748
|
+
}
|
|
9749
|
+
estimateCost(branchPattern) {
|
|
9750
|
+
return this.#input.estimateCost(branchPattern);
|
|
9751
|
+
}
|
|
9752
|
+
convertToUFO() {
|
|
9753
|
+
this.#type = "UFO";
|
|
9754
|
+
}
|
|
9755
|
+
reset() {
|
|
9756
|
+
this.#type = "FO";
|
|
9757
|
+
}
|
|
9758
|
+
/**
|
|
9759
|
+
* Propagate unlimiting when a parent join is flipped.
|
|
9760
|
+
* Fan-out propagates to its input.
|
|
9761
|
+
*/
|
|
9762
|
+
propagateUnlimitFromFlippedJoin() {
|
|
9763
|
+
if ("propagateUnlimitFromFlippedJoin" in this.#input && typeof this.#input.propagateUnlimitFromFlippedJoin === "function") {
|
|
9764
|
+
this.#input.propagateUnlimitFromFlippedJoin();
|
|
9436
9765
|
}
|
|
9437
9766
|
}
|
|
9438
|
-
return flattened;
|
|
9439
|
-
}
|
|
9440
|
-
var negateSimpleOperatorMap = {
|
|
9441
|
-
["="]: "!=",
|
|
9442
|
-
["!="]: "=",
|
|
9443
|
-
["<"]: ">=",
|
|
9444
|
-
[">"]: "<=",
|
|
9445
|
-
[">="]: "<",
|
|
9446
|
-
["<="]: ">",
|
|
9447
|
-
["IN"]: "NOT IN",
|
|
9448
|
-
["NOT IN"]: "IN",
|
|
9449
|
-
["LIKE"]: "NOT LIKE",
|
|
9450
|
-
["NOT LIKE"]: "LIKE",
|
|
9451
|
-
["ILIKE"]: "NOT ILIKE",
|
|
9452
|
-
["NOT ILIKE"]: "ILIKE",
|
|
9453
|
-
["IS"]: "IS NOT",
|
|
9454
|
-
["IS NOT"]: "IS"
|
|
9455
9767
|
};
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
return must(negateOperatorMap[op]);
|
|
9463
|
-
}
|
|
9464
|
-
function filterUndefined(array9) {
|
|
9465
|
-
return array9.filter((e) => e !== void 0);
|
|
9466
|
-
}
|
|
9467
|
-
function filterTrue(conditions) {
|
|
9468
|
-
return conditions.filter((c) => !isAlwaysTrue(c));
|
|
9469
|
-
}
|
|
9470
|
-
function filterFalse(conditions) {
|
|
9471
|
-
return conditions.filter((c) => !isAlwaysFalse(c));
|
|
9768
|
+
|
|
9769
|
+
// ../zql/src/planner/planner-constraint.ts
|
|
9770
|
+
function mergeConstraints(a, b) {
|
|
9771
|
+
if (!a) return b;
|
|
9772
|
+
if (!b) return a;
|
|
9773
|
+
return { ...a, ...b };
|
|
9472
9774
|
}
|
|
9473
9775
|
|
|
9474
|
-
// ../zql/src/
|
|
9776
|
+
// ../zql/src/planner/planner-connection.ts
|
|
9777
|
+
var PlannerConnection = class {
|
|
9778
|
+
kind = "connection";
|
|
9779
|
+
// ========================================================================
|
|
9780
|
+
// IMMUTABLE STRUCTURE (set during construction, never changes)
|
|
9781
|
+
// ========================================================================
|
|
9782
|
+
#sort;
|
|
9783
|
+
#filters;
|
|
9784
|
+
#model;
|
|
9785
|
+
table;
|
|
9786
|
+
name;
|
|
9787
|
+
// Human-readable name for debugging (defaults to table name)
|
|
9788
|
+
#baseConstraints;
|
|
9789
|
+
// Constraints from parent correlation
|
|
9790
|
+
#baseLimit;
|
|
9791
|
+
// Original limit from query structure (never modified)
|
|
9792
|
+
selectivity;
|
|
9793
|
+
// Fraction of rows passing filters (1.0 = no filtering)
|
|
9794
|
+
#output;
|
|
9795
|
+
// Set once during graph construction
|
|
9796
|
+
// ========================================================================
|
|
9797
|
+
// MUTABLE PLANNING STATE (changes during plan search)
|
|
9798
|
+
// ========================================================================
|
|
9799
|
+
/**
|
|
9800
|
+
* Current limit during planning. Can be cleared (set to undefined) when a
|
|
9801
|
+
* parent join is flipped, indicating this connection is now in an outer loop
|
|
9802
|
+
* and should not be limited by EXISTS semantics.
|
|
9803
|
+
*/
|
|
9804
|
+
limit;
|
|
9805
|
+
/**
|
|
9806
|
+
* Constraints accumulated from parent joins during planning.
|
|
9807
|
+
* Key is a path through the graph (e.g., "0,1" for branch pattern [0,1]).
|
|
9808
|
+
*
|
|
9809
|
+
* Undefined constraints are possible when a FO converts to UFO and only
|
|
9810
|
+
* a single join in the UFO is flipped - other branches report undefined.
|
|
9811
|
+
*/
|
|
9812
|
+
#constraints;
|
|
9813
|
+
/**
|
|
9814
|
+
* Cached total cost (sum of all branches) to avoid redundant calculations.
|
|
9815
|
+
* Invalidated when constraints change.
|
|
9816
|
+
*/
|
|
9817
|
+
#cachedTotalCost = void 0;
|
|
9818
|
+
/**
|
|
9819
|
+
* Cached per-constraint costs to avoid redundant cost model calls.
|
|
9820
|
+
* Maps constraint key (branch pattern string) to computed cost.
|
|
9821
|
+
* Invalidated when constraints change.
|
|
9822
|
+
*/
|
|
9823
|
+
#cachedConstraintCosts = /* @__PURE__ */ new Map();
|
|
9824
|
+
#costDirty = true;
|
|
9825
|
+
constructor(table2, model, sort, filters, baseConstraints, limit, name) {
|
|
9826
|
+
this.table = table2;
|
|
9827
|
+
this.name = name ?? table2;
|
|
9828
|
+
this.#sort = sort;
|
|
9829
|
+
this.#filters = filters;
|
|
9830
|
+
this.#model = model;
|
|
9831
|
+
this.#baseConstraints = baseConstraints;
|
|
9832
|
+
this.#baseLimit = limit;
|
|
9833
|
+
this.limit = limit;
|
|
9834
|
+
this.#constraints = /* @__PURE__ */ new Map();
|
|
9835
|
+
if (limit !== void 0 && filters) {
|
|
9836
|
+
const costWithFilters = model(table2, sort, filters, void 0);
|
|
9837
|
+
const costWithoutFilters = model(table2, sort, void 0, void 0);
|
|
9838
|
+
this.selectivity = costWithoutFilters.rows > 0 ? costWithFilters.rows / costWithoutFilters.rows : 1;
|
|
9839
|
+
} else {
|
|
9840
|
+
this.selectivity = 1;
|
|
9841
|
+
}
|
|
9842
|
+
}
|
|
9843
|
+
setOutput(node) {
|
|
9844
|
+
this.#output = node;
|
|
9845
|
+
}
|
|
9846
|
+
get output() {
|
|
9847
|
+
assert(this.#output !== void 0, "Output not set");
|
|
9848
|
+
return this.#output;
|
|
9849
|
+
}
|
|
9850
|
+
closestJoinOrSource() {
|
|
9851
|
+
return "connection";
|
|
9852
|
+
}
|
|
9853
|
+
/**
|
|
9854
|
+
* Constraints are uniquely identified by their path through the
|
|
9855
|
+
* graph.
|
|
9856
|
+
*
|
|
9857
|
+
* FO represents all sub-joins as a single path.
|
|
9858
|
+
* UFO represents each sub-join as a separate path.
|
|
9859
|
+
* The first branch in a UFO will match the path of FO so no re-set needs to happen
|
|
9860
|
+
* when swapping from FO to UFO.
|
|
9861
|
+
*
|
|
9862
|
+
* FO swaps to UFO when a join inside FO-FI gets flipped.
|
|
9863
|
+
*
|
|
9864
|
+
* The max of the last element of the paths is the number of
|
|
9865
|
+
* root branches.
|
|
9866
|
+
*/
|
|
9867
|
+
propagateConstraints(path, c) {
|
|
9868
|
+
const key = path.join(",");
|
|
9869
|
+
this.#constraints.set(key, c);
|
|
9870
|
+
this.#cachedTotalCost = void 0;
|
|
9871
|
+
this.#cachedConstraintCosts.clear();
|
|
9872
|
+
this.#costDirty = true;
|
|
9873
|
+
}
|
|
9874
|
+
estimateCost(branchPattern) {
|
|
9875
|
+
if (branchPattern === void 0) {
|
|
9876
|
+
if (!this.#costDirty && this.#cachedTotalCost !== void 0) {
|
|
9877
|
+
return this.#cachedTotalCost;
|
|
9878
|
+
}
|
|
9879
|
+
let totalRows = 0;
|
|
9880
|
+
let maxStartupCost = 0;
|
|
9881
|
+
if (this.#constraints.size === 0) {
|
|
9882
|
+
const key2 = "";
|
|
9883
|
+
let cost2 = this.#cachedConstraintCosts.get(key2);
|
|
9884
|
+
if (cost2 === void 0) {
|
|
9885
|
+
const { startupCost: startupCost2, rows: rows2 } = this.#model(
|
|
9886
|
+
this.table,
|
|
9887
|
+
this.#sort,
|
|
9888
|
+
this.#filters,
|
|
9889
|
+
this.#baseConstraints
|
|
9890
|
+
);
|
|
9891
|
+
cost2 = {
|
|
9892
|
+
rows: rows2,
|
|
9893
|
+
runningCost: rows2,
|
|
9894
|
+
startupCost: startupCost2,
|
|
9895
|
+
selectivity: this.selectivity,
|
|
9896
|
+
limit: this.limit
|
|
9897
|
+
};
|
|
9898
|
+
this.#cachedConstraintCosts.set(key2, cost2);
|
|
9899
|
+
}
|
|
9900
|
+
totalRows = cost2.rows;
|
|
9901
|
+
maxStartupCost = cost2.startupCost;
|
|
9902
|
+
} else {
|
|
9903
|
+
for (const [key2, constraint2] of this.#constraints.entries()) {
|
|
9904
|
+
let cost2 = this.#cachedConstraintCosts.get(key2);
|
|
9905
|
+
if (cost2 === void 0) {
|
|
9906
|
+
const mergedConstraint2 = mergeConstraints(
|
|
9907
|
+
this.#baseConstraints,
|
|
9908
|
+
constraint2
|
|
9909
|
+
);
|
|
9910
|
+
const { startupCost: startupCost2, rows: rows2 } = this.#model(
|
|
9911
|
+
this.table,
|
|
9912
|
+
this.#sort,
|
|
9913
|
+
this.#filters,
|
|
9914
|
+
mergedConstraint2
|
|
9915
|
+
);
|
|
9916
|
+
cost2 = {
|
|
9917
|
+
rows: rows2,
|
|
9918
|
+
runningCost: rows2,
|
|
9919
|
+
startupCost: startupCost2,
|
|
9920
|
+
selectivity: this.selectivity,
|
|
9921
|
+
limit: this.limit
|
|
9922
|
+
};
|
|
9923
|
+
this.#cachedConstraintCosts.set(key2, cost2);
|
|
9924
|
+
}
|
|
9925
|
+
totalRows += cost2.rows;
|
|
9926
|
+
maxStartupCost = Math.max(maxStartupCost, cost2.startupCost);
|
|
9927
|
+
}
|
|
9928
|
+
}
|
|
9929
|
+
const ret = {
|
|
9930
|
+
rows: totalRows,
|
|
9931
|
+
runningCost: totalRows,
|
|
9932
|
+
startupCost: maxStartupCost,
|
|
9933
|
+
selectivity: this.selectivity,
|
|
9934
|
+
limit: this.limit
|
|
9935
|
+
};
|
|
9936
|
+
this.#cachedTotalCost = ret;
|
|
9937
|
+
this.#costDirty = false;
|
|
9938
|
+
return ret;
|
|
9939
|
+
}
|
|
9940
|
+
const key = branchPattern.join(",");
|
|
9941
|
+
let cost = this.#cachedConstraintCosts.get(key);
|
|
9942
|
+
if (cost !== void 0) {
|
|
9943
|
+
return cost;
|
|
9944
|
+
}
|
|
9945
|
+
const constraint = this.#constraints.get(key);
|
|
9946
|
+
const mergedConstraint = mergeConstraints(
|
|
9947
|
+
this.#baseConstraints,
|
|
9948
|
+
constraint
|
|
9949
|
+
);
|
|
9950
|
+
const { startupCost, rows } = this.#model(
|
|
9951
|
+
this.table,
|
|
9952
|
+
this.#sort,
|
|
9953
|
+
this.#filters,
|
|
9954
|
+
mergedConstraint
|
|
9955
|
+
);
|
|
9956
|
+
cost = {
|
|
9957
|
+
rows,
|
|
9958
|
+
runningCost: rows,
|
|
9959
|
+
startupCost,
|
|
9960
|
+
selectivity: this.selectivity,
|
|
9961
|
+
limit: this.limit
|
|
9962
|
+
};
|
|
9963
|
+
this.#cachedConstraintCosts.set(key, cost);
|
|
9964
|
+
return cost;
|
|
9965
|
+
}
|
|
9966
|
+
/**
|
|
9967
|
+
* Remove the limit from this connection.
|
|
9968
|
+
* Called when a parent join is flipped, making this connection part of an
|
|
9969
|
+
* outer loop that should produce all rows rather than stopping at the limit.
|
|
9970
|
+
*/
|
|
9971
|
+
unlimit() {
|
|
9972
|
+
if (this.limit !== void 0) {
|
|
9973
|
+
this.limit = void 0;
|
|
9974
|
+
}
|
|
9975
|
+
}
|
|
9976
|
+
/**
|
|
9977
|
+
* Propagate unlimiting when a parent join is flipped.
|
|
9978
|
+
* For connections, we simply remove the limit.
|
|
9979
|
+
*/
|
|
9980
|
+
propagateUnlimitFromFlippedJoin() {
|
|
9981
|
+
this.unlimit();
|
|
9982
|
+
}
|
|
9983
|
+
reset() {
|
|
9984
|
+
this.#constraints.clear();
|
|
9985
|
+
this.limit = this.#baseLimit;
|
|
9986
|
+
this.#cachedTotalCost = void 0;
|
|
9987
|
+
this.#cachedConstraintCosts.clear();
|
|
9988
|
+
this.#costDirty = true;
|
|
9989
|
+
}
|
|
9990
|
+
/**
|
|
9991
|
+
* Capture constraint state for snapshotting.
|
|
9992
|
+
* Used by PlannerGraph to save/restore planning state.
|
|
9993
|
+
*/
|
|
9994
|
+
captureConstraints() {
|
|
9995
|
+
return new Map(this.#constraints);
|
|
9996
|
+
}
|
|
9997
|
+
/**
|
|
9998
|
+
* Restore constraint state from a snapshot.
|
|
9999
|
+
* Used by PlannerGraph to restore planning state.
|
|
10000
|
+
*/
|
|
10001
|
+
restoreConstraints(constraints) {
|
|
10002
|
+
this.#constraints.clear();
|
|
10003
|
+
for (const [key, value] of constraints) {
|
|
10004
|
+
this.#constraints.set(key, value);
|
|
10005
|
+
}
|
|
10006
|
+
this.#cachedTotalCost = void 0;
|
|
10007
|
+
this.#cachedConstraintCosts.clear();
|
|
10008
|
+
this.#costDirty = true;
|
|
10009
|
+
}
|
|
10010
|
+
/**
|
|
10011
|
+
* Get current constraints for debugging.
|
|
10012
|
+
* Returns a copy of the constraints map.
|
|
10013
|
+
*/
|
|
10014
|
+
getConstraintsForDebug() {
|
|
10015
|
+
return new Map(this.#constraints);
|
|
10016
|
+
}
|
|
10017
|
+
/**
|
|
10018
|
+
* Get estimated cost for each constraint branch.
|
|
10019
|
+
* Returns a map of constraint key to cost estimate.
|
|
10020
|
+
* Forces cost calculation if not already cached.
|
|
10021
|
+
*/
|
|
10022
|
+
getConstraintCostsForDebug() {
|
|
10023
|
+
this.estimateCost(void 0);
|
|
10024
|
+
return new Map(this.#cachedConstraintCosts);
|
|
10025
|
+
}
|
|
10026
|
+
};
|
|
10027
|
+
|
|
10028
|
+
// ../zql/src/planner/planner-source.ts
|
|
10029
|
+
var PlannerSource = class {
|
|
10030
|
+
name;
|
|
10031
|
+
#model;
|
|
10032
|
+
constructor(name, model) {
|
|
10033
|
+
this.name = name;
|
|
10034
|
+
this.#model = model;
|
|
10035
|
+
}
|
|
10036
|
+
connect(sort, filters, baseConstraints, limit) {
|
|
10037
|
+
return new PlannerConnection(
|
|
10038
|
+
this.name,
|
|
10039
|
+
this.#model,
|
|
10040
|
+
sort,
|
|
10041
|
+
filters,
|
|
10042
|
+
baseConstraints,
|
|
10043
|
+
limit
|
|
10044
|
+
);
|
|
10045
|
+
}
|
|
10046
|
+
};
|
|
10047
|
+
|
|
10048
|
+
// ../zql/src/planner/planner-graph.ts
|
|
10049
|
+
var MAX_FLIPPABLE_JOINS = 13;
|
|
10050
|
+
var PlannerGraph = class {
|
|
10051
|
+
// Sources indexed by table name
|
|
10052
|
+
#sources = /* @__PURE__ */ new Map();
|
|
10053
|
+
// The final output node where constraint propagation starts
|
|
10054
|
+
#terminus = void 0;
|
|
10055
|
+
// Collections of nodes with mutable planning state
|
|
10056
|
+
joins = [];
|
|
10057
|
+
fanOuts = [];
|
|
10058
|
+
fanIns = [];
|
|
10059
|
+
connections = [];
|
|
10060
|
+
/**
|
|
10061
|
+
* Reset all planning state back to initial values for another planning pass.
|
|
10062
|
+
* Resets only mutable planning state - graph structure is unchanged.
|
|
10063
|
+
*
|
|
10064
|
+
* This allows replanning the same query graph with different strategies.
|
|
10065
|
+
*/
|
|
10066
|
+
resetPlanningState() {
|
|
10067
|
+
for (const j of this.joins) j.reset();
|
|
10068
|
+
for (const fo of this.fanOuts) fo.reset();
|
|
10069
|
+
for (const fi of this.fanIns) fi.reset();
|
|
10070
|
+
for (const c of this.connections) c.reset();
|
|
10071
|
+
}
|
|
10072
|
+
/**
|
|
10073
|
+
* Create and register a source (table) in the graph.
|
|
10074
|
+
*/
|
|
10075
|
+
addSource(name, model) {
|
|
10076
|
+
assert(
|
|
10077
|
+
!this.#sources.has(name),
|
|
10078
|
+
`Source ${name} already exists in the graph`
|
|
10079
|
+
);
|
|
10080
|
+
const source = new PlannerSource(name, model);
|
|
10081
|
+
this.#sources.set(name, source);
|
|
10082
|
+
return source;
|
|
10083
|
+
}
|
|
10084
|
+
/**
|
|
10085
|
+
* Get a source by table name.
|
|
10086
|
+
*/
|
|
10087
|
+
getSource(name) {
|
|
10088
|
+
const source = this.#sources.get(name);
|
|
10089
|
+
assert(source !== void 0, `Source ${name} not found in the graph`);
|
|
10090
|
+
return source;
|
|
10091
|
+
}
|
|
10092
|
+
/**
|
|
10093
|
+
* Check if a source exists by table name.
|
|
10094
|
+
*/
|
|
10095
|
+
hasSource(name) {
|
|
10096
|
+
return this.#sources.has(name);
|
|
10097
|
+
}
|
|
10098
|
+
/**
|
|
10099
|
+
* Set the terminus (final output) node of the graph.
|
|
10100
|
+
* Constraint propagation starts from this node.
|
|
10101
|
+
*/
|
|
10102
|
+
setTerminus(terminus) {
|
|
10103
|
+
this.#terminus = terminus;
|
|
10104
|
+
}
|
|
10105
|
+
/**
|
|
10106
|
+
* Initiate constraint propagation from the terminus node.
|
|
10107
|
+
* This sends constraints up through the graph to update
|
|
10108
|
+
* connection cost estimates.
|
|
10109
|
+
*/
|
|
10110
|
+
propagateConstraints() {
|
|
10111
|
+
assert(
|
|
10112
|
+
this.#terminus !== void 0,
|
|
10113
|
+
"Cannot propagate constraints without a terminus node"
|
|
10114
|
+
);
|
|
10115
|
+
this.#terminus.propagateConstraints();
|
|
10116
|
+
}
|
|
10117
|
+
/**
|
|
10118
|
+
* Calculate total cost of the current plan.
|
|
10119
|
+
* Total cost includes both startup cost (one-time, e.g., sorting) and running cost.
|
|
10120
|
+
*/
|
|
10121
|
+
getTotalCost() {
|
|
10122
|
+
const estimate = must(this.#terminus).estimateCost();
|
|
10123
|
+
return estimate.startupCost + estimate.runningCost;
|
|
10124
|
+
}
|
|
10125
|
+
/**
|
|
10126
|
+
* Capture a lightweight snapshot of the current planning state.
|
|
10127
|
+
* Used for backtracking during multi-start greedy search.
|
|
10128
|
+
*
|
|
10129
|
+
* Captures mutable state including pinned flags, join types, and
|
|
10130
|
+
* constraint maps to avoid needing repropagation on restore.
|
|
10131
|
+
*
|
|
10132
|
+
* @returns A snapshot that can be restored via restorePlanningSnapshot()
|
|
10133
|
+
*/
|
|
10134
|
+
capturePlanningSnapshot() {
|
|
10135
|
+
return {
|
|
10136
|
+
connections: this.connections.map((c) => ({
|
|
10137
|
+
limit: c.limit
|
|
10138
|
+
})),
|
|
10139
|
+
joins: this.joins.map((j) => ({ type: j.type })),
|
|
10140
|
+
fanOuts: this.fanOuts.map((fo) => ({ type: fo.type })),
|
|
10141
|
+
fanIns: this.fanIns.map((fi) => ({ type: fi.type })),
|
|
10142
|
+
connectionConstraints: this.connections.map((c) => c.captureConstraints())
|
|
10143
|
+
};
|
|
10144
|
+
}
|
|
10145
|
+
/**
|
|
10146
|
+
* Restore planning state from a previously captured snapshot.
|
|
10147
|
+
* Used for backtracking when a planning attempt fails.
|
|
10148
|
+
*
|
|
10149
|
+
* Restores pinned flags, join types, and constraint maps, eliminating
|
|
10150
|
+
* the need for repropagation.
|
|
10151
|
+
*
|
|
10152
|
+
* @param state - Snapshot created by capturePlanningSnapshot()
|
|
10153
|
+
*/
|
|
10154
|
+
restorePlanningSnapshot(state) {
|
|
10155
|
+
this.#validateSnapshotShape(state);
|
|
10156
|
+
this.#restoreConnections(state);
|
|
10157
|
+
this.#restoreJoins(state);
|
|
10158
|
+
this.#restoreFanNodes(state);
|
|
10159
|
+
}
|
|
10160
|
+
/**
|
|
10161
|
+
* Collect cost estimates from all nodes in the graph for debugging.
|
|
10162
|
+
*/
|
|
10163
|
+
#collectNodeCosts() {
|
|
10164
|
+
const costs = [];
|
|
10165
|
+
for (const c of this.connections) {
|
|
10166
|
+
costs.push({
|
|
10167
|
+
node: c.name,
|
|
10168
|
+
nodeType: "connection",
|
|
10169
|
+
costEstimate: c.estimateCost(void 0)
|
|
10170
|
+
});
|
|
10171
|
+
}
|
|
10172
|
+
for (const j of this.joins) {
|
|
10173
|
+
costs.push({
|
|
10174
|
+
node: j.getName(),
|
|
10175
|
+
nodeType: "join",
|
|
10176
|
+
costEstimate: j.estimateCost(void 0)
|
|
10177
|
+
});
|
|
10178
|
+
}
|
|
10179
|
+
for (const fo of this.fanOuts) {
|
|
10180
|
+
costs.push({
|
|
10181
|
+
node: "FO",
|
|
10182
|
+
nodeType: "fan-out",
|
|
10183
|
+
costEstimate: fo.estimateCost(void 0)
|
|
10184
|
+
});
|
|
10185
|
+
}
|
|
10186
|
+
for (const fi of this.fanIns) {
|
|
10187
|
+
costs.push({
|
|
10188
|
+
node: "FI",
|
|
10189
|
+
nodeType: "fan-in",
|
|
10190
|
+
costEstimate: fi.estimateCost(void 0)
|
|
10191
|
+
});
|
|
10192
|
+
}
|
|
10193
|
+
return costs;
|
|
10194
|
+
}
|
|
10195
|
+
/**
|
|
10196
|
+
* Validate that snapshot shape matches current graph structure.
|
|
10197
|
+
*/
|
|
10198
|
+
#validateSnapshotShape(state) {
|
|
10199
|
+
assert(
|
|
10200
|
+
this.connections.length === state.connections.length,
|
|
10201
|
+
"Plan state mismatch: connections"
|
|
10202
|
+
);
|
|
10203
|
+
assert(
|
|
10204
|
+
this.joins.length === state.joins.length,
|
|
10205
|
+
"Plan state mismatch: joins"
|
|
10206
|
+
);
|
|
10207
|
+
assert(
|
|
10208
|
+
this.fanOuts.length === state.fanOuts.length,
|
|
10209
|
+
"Plan state mismatch: fanOuts"
|
|
10210
|
+
);
|
|
10211
|
+
assert(
|
|
10212
|
+
this.fanIns.length === state.fanIns.length,
|
|
10213
|
+
"Plan state mismatch: fanIns"
|
|
10214
|
+
);
|
|
10215
|
+
assert(
|
|
10216
|
+
this.connections.length === state.connectionConstraints.length,
|
|
10217
|
+
"Plan state mismatch: connectionConstraints"
|
|
10218
|
+
);
|
|
10219
|
+
}
|
|
10220
|
+
/**
|
|
10221
|
+
* Restore connection pinned flags, limits, and constraint maps.
|
|
10222
|
+
*/
|
|
10223
|
+
#restoreConnections(state) {
|
|
10224
|
+
for (let i = 0; i < this.connections.length; i++) {
|
|
10225
|
+
this.connections[i].limit = state.connections[i].limit;
|
|
10226
|
+
this.connections[i].restoreConstraints(state.connectionConstraints[i]);
|
|
10227
|
+
}
|
|
10228
|
+
}
|
|
10229
|
+
/**
|
|
10230
|
+
* Restore join types and pinned flags.
|
|
10231
|
+
*/
|
|
10232
|
+
#restoreJoins(state) {
|
|
10233
|
+
for (let i = 0; i < this.joins.length; i++) {
|
|
10234
|
+
const join = this.joins[i];
|
|
10235
|
+
const targetState = state.joins[i];
|
|
10236
|
+
join.reset();
|
|
10237
|
+
if (targetState.type === "flipped") {
|
|
10238
|
+
join.flip();
|
|
10239
|
+
}
|
|
10240
|
+
}
|
|
10241
|
+
}
|
|
10242
|
+
/**
|
|
10243
|
+
* Restore FanOut and FanIn types.
|
|
10244
|
+
*/
|
|
10245
|
+
#restoreFanNodes(state) {
|
|
10246
|
+
for (let i = 0; i < this.fanOuts.length; i++) {
|
|
10247
|
+
const fo = this.fanOuts[i];
|
|
10248
|
+
const targetType = state.fanOuts[i].type;
|
|
10249
|
+
if (targetType === "UFO" && fo.type === "FO") {
|
|
10250
|
+
fo.convertToUFO();
|
|
10251
|
+
}
|
|
10252
|
+
}
|
|
10253
|
+
for (let i = 0; i < this.fanIns.length; i++) {
|
|
10254
|
+
const fi = this.fanIns[i];
|
|
10255
|
+
const targetType = state.fanIns[i].type;
|
|
10256
|
+
if (targetType === "UFI" && fi.type === "FI") {
|
|
10257
|
+
fi.convertToUFI();
|
|
10258
|
+
}
|
|
10259
|
+
}
|
|
10260
|
+
}
|
|
10261
|
+
/**
|
|
10262
|
+
* Main planning algorithm using exhaustive join flip enumeration.
|
|
10263
|
+
*
|
|
10264
|
+
* Enumerates all possible flip patterns for flippable joins (2^n for n flippable joins).
|
|
10265
|
+
* Each pattern represents a different query execution plan. We evaluate the cost of each
|
|
10266
|
+
* plan and select the one with the lowest cost.
|
|
10267
|
+
*
|
|
10268
|
+
* Connections are used only for cost estimation - the flip patterns determine the plan.
|
|
10269
|
+
* FanOut/FanIn states (FO/UFO and FI/UFI) are automatically derived from join flip states.
|
|
10270
|
+
*
|
|
10271
|
+
* @param planDebugger - Optional debugger to receive structured events during planning
|
|
10272
|
+
*/
|
|
10273
|
+
plan(planDebugger) {
|
|
10274
|
+
const flippableJoins = this.joins.filter((j) => j.isFlippable());
|
|
10275
|
+
if (flippableJoins.length > MAX_FLIPPABLE_JOINS) {
|
|
10276
|
+
throw new Error(
|
|
10277
|
+
`Query has ${flippableJoins.length} EXISTS checks in a single RELATED call (or in the top level query), which would require ${2 ** flippableJoins.length} plan evaluations. This may be very slow. Consider simplifying the query or increasing MAX_FLIPPABLE_JOINS (currently set to ${MAX_FLIPPABLE_JOINS}).`
|
|
10278
|
+
);
|
|
10279
|
+
}
|
|
10280
|
+
const fofiCache = buildFOFICache(this);
|
|
10281
|
+
const numPatterns = 2 ** flippableJoins.length;
|
|
10282
|
+
let bestCost = Infinity;
|
|
10283
|
+
let bestPlan = void 0;
|
|
10284
|
+
let bestAttemptNumber = -1;
|
|
10285
|
+
for (let pattern = 0; pattern < numPatterns; pattern++) {
|
|
10286
|
+
this.resetPlanningState();
|
|
10287
|
+
if (planDebugger) {
|
|
10288
|
+
planDebugger.log({
|
|
10289
|
+
type: "attempt-start",
|
|
10290
|
+
attemptNumber: pattern,
|
|
10291
|
+
totalAttempts: numPatterns
|
|
10292
|
+
});
|
|
10293
|
+
}
|
|
10294
|
+
try {
|
|
10295
|
+
for (let i = 0; i < flippableJoins.length; i++) {
|
|
10296
|
+
if (pattern & 1 << i) {
|
|
10297
|
+
flippableJoins[i].flip();
|
|
10298
|
+
}
|
|
10299
|
+
}
|
|
10300
|
+
checkAndConvertFOFI(fofiCache);
|
|
10301
|
+
propagateUnlimitForFlippedJoins(this);
|
|
10302
|
+
this.propagateConstraints();
|
|
10303
|
+
if (planDebugger) {
|
|
10304
|
+
planDebugger.log({
|
|
10305
|
+
type: "constraints-propagated",
|
|
10306
|
+
attemptNumber: pattern,
|
|
10307
|
+
connectionConstraints: this.connections.map((c) => ({
|
|
10308
|
+
connection: c.name,
|
|
10309
|
+
constraints: c.getConstraintsForDebug(),
|
|
10310
|
+
constraintCosts: c.getConstraintCostsForDebug()
|
|
10311
|
+
}))
|
|
10312
|
+
});
|
|
10313
|
+
}
|
|
10314
|
+
const totalCost = this.getTotalCost();
|
|
10315
|
+
if (planDebugger) {
|
|
10316
|
+
planDebugger.log({
|
|
10317
|
+
type: "plan-complete",
|
|
10318
|
+
attemptNumber: pattern,
|
|
10319
|
+
totalCost,
|
|
10320
|
+
nodeCosts: this.#collectNodeCosts(),
|
|
10321
|
+
joinStates: this.joins.map((j) => {
|
|
10322
|
+
const info = j.getDebugInfo();
|
|
10323
|
+
return {
|
|
10324
|
+
join: info.name,
|
|
10325
|
+
type: info.type
|
|
10326
|
+
};
|
|
10327
|
+
})
|
|
10328
|
+
});
|
|
10329
|
+
}
|
|
10330
|
+
if (totalCost < bestCost) {
|
|
10331
|
+
bestCost = totalCost;
|
|
10332
|
+
bestPlan = this.capturePlanningSnapshot();
|
|
10333
|
+
bestAttemptNumber = pattern;
|
|
10334
|
+
}
|
|
10335
|
+
} catch (e) {
|
|
10336
|
+
if (planDebugger) {
|
|
10337
|
+
planDebugger.log({
|
|
10338
|
+
type: "plan-failed",
|
|
10339
|
+
attemptNumber: pattern,
|
|
10340
|
+
reason: `Flip pattern ${pattern.toString(2)} failed: ${e instanceof Error ? e.message : String(e)}`
|
|
10341
|
+
});
|
|
10342
|
+
}
|
|
10343
|
+
continue;
|
|
10344
|
+
}
|
|
10345
|
+
}
|
|
10346
|
+
if (bestPlan) {
|
|
10347
|
+
this.restorePlanningSnapshot(bestPlan);
|
|
10348
|
+
this.propagateConstraints();
|
|
10349
|
+
if (planDebugger) {
|
|
10350
|
+
planDebugger.log({
|
|
10351
|
+
type: "best-plan-selected",
|
|
10352
|
+
bestAttemptNumber,
|
|
10353
|
+
totalCost: bestCost,
|
|
10354
|
+
joinStates: this.joins.map((j) => ({
|
|
10355
|
+
join: j.getName(),
|
|
10356
|
+
type: j.type
|
|
10357
|
+
}))
|
|
10358
|
+
});
|
|
10359
|
+
}
|
|
10360
|
+
} else {
|
|
10361
|
+
throw new Error(
|
|
10362
|
+
"No valid query plan found. This should not happen - check query structure."
|
|
10363
|
+
);
|
|
10364
|
+
}
|
|
10365
|
+
}
|
|
10366
|
+
};
|
|
10367
|
+
function buildFOFICache(graph) {
|
|
10368
|
+
const cache = /* @__PURE__ */ new Map();
|
|
10369
|
+
for (const fo of graph.fanOuts) {
|
|
10370
|
+
const info = findFIAndJoins(fo);
|
|
10371
|
+
cache.set(fo, info);
|
|
10372
|
+
}
|
|
10373
|
+
return cache;
|
|
10374
|
+
}
|
|
10375
|
+
function checkAndConvertFOFI(fofiCache) {
|
|
10376
|
+
for (const [fo, info] of fofiCache) {
|
|
10377
|
+
const hasFlippedJoin = info.joinsBetween.some((j) => j.type === "flipped");
|
|
10378
|
+
if (info.fi && hasFlippedJoin) {
|
|
10379
|
+
fo.convertToUFO();
|
|
10380
|
+
info.fi.convertToUFI();
|
|
10381
|
+
}
|
|
10382
|
+
}
|
|
10383
|
+
}
|
|
10384
|
+
function findFIAndJoins(fo) {
|
|
10385
|
+
const joinsBetween = [];
|
|
10386
|
+
let fi = void 0;
|
|
10387
|
+
const queue = [...fo.outputs];
|
|
10388
|
+
const visited = /* @__PURE__ */ new Set();
|
|
10389
|
+
while (queue.length > 0) {
|
|
10390
|
+
const node = must(queue.shift());
|
|
10391
|
+
if (visited.has(node)) continue;
|
|
10392
|
+
visited.add(node);
|
|
10393
|
+
switch (node.kind) {
|
|
10394
|
+
case "join":
|
|
10395
|
+
joinsBetween.push(node);
|
|
10396
|
+
queue.push(node.output);
|
|
10397
|
+
break;
|
|
10398
|
+
case "fan-out":
|
|
10399
|
+
queue.push(...node.outputs);
|
|
10400
|
+
break;
|
|
10401
|
+
case "fan-in":
|
|
10402
|
+
fi = node;
|
|
10403
|
+
break;
|
|
10404
|
+
case "connection":
|
|
10405
|
+
break;
|
|
10406
|
+
case "terminus":
|
|
10407
|
+
break;
|
|
10408
|
+
}
|
|
10409
|
+
}
|
|
10410
|
+
return { fi, joinsBetween };
|
|
10411
|
+
}
|
|
10412
|
+
function propagateUnlimitForFlippedJoins(graph) {
|
|
10413
|
+
for (const join of graph.joins) {
|
|
10414
|
+
if (join.type === "flipped") {
|
|
10415
|
+
join.propagateUnlimit();
|
|
10416
|
+
}
|
|
10417
|
+
}
|
|
10418
|
+
}
|
|
10419
|
+
|
|
10420
|
+
// ../zql/src/planner/planner-join.ts
|
|
10421
|
+
var SEMI_JOIN_OVERHEAD_MULTIPLIER = 1.5;
|
|
10422
|
+
var PlannerJoin = class {
|
|
10423
|
+
kind = "join";
|
|
10424
|
+
#parent;
|
|
10425
|
+
#child;
|
|
10426
|
+
#parentConstraint;
|
|
10427
|
+
#childConstraint;
|
|
10428
|
+
#flippable;
|
|
10429
|
+
planId;
|
|
10430
|
+
#output;
|
|
10431
|
+
// Set once during graph construction
|
|
10432
|
+
// Reset between planning attempts
|
|
10433
|
+
#type;
|
|
10434
|
+
constructor(parent, child, parentConstraint, childConstraint, flippable, planId) {
|
|
10435
|
+
this.#type = "semi";
|
|
10436
|
+
this.#parent = parent;
|
|
10437
|
+
this.#child = child;
|
|
10438
|
+
this.#childConstraint = childConstraint;
|
|
10439
|
+
this.#parentConstraint = parentConstraint;
|
|
10440
|
+
this.#flippable = flippable;
|
|
10441
|
+
this.planId = planId;
|
|
10442
|
+
}
|
|
10443
|
+
setOutput(node) {
|
|
10444
|
+
this.#output = node;
|
|
10445
|
+
}
|
|
10446
|
+
get output() {
|
|
10447
|
+
assert(this.#output !== void 0, "Output not set");
|
|
10448
|
+
return this.#output;
|
|
10449
|
+
}
|
|
10450
|
+
closestJoinOrSource() {
|
|
10451
|
+
return "join";
|
|
10452
|
+
}
|
|
10453
|
+
flipIfNeeded(input) {
|
|
10454
|
+
if (input === this.#child) {
|
|
10455
|
+
this.flip();
|
|
10456
|
+
} else {
|
|
10457
|
+
assert(
|
|
10458
|
+
input === this.#parent,
|
|
10459
|
+
"Can only flip a join from one of its inputs"
|
|
10460
|
+
);
|
|
10461
|
+
}
|
|
10462
|
+
}
|
|
10463
|
+
flip() {
|
|
10464
|
+
assert(this.#type === "semi", "Can only flip a semi-join");
|
|
10465
|
+
if (!this.#flippable) {
|
|
10466
|
+
throw new UnflippableJoinError(
|
|
10467
|
+
"Cannot flip a non-flippable join (e.g., NOT EXISTS)"
|
|
10468
|
+
);
|
|
10469
|
+
}
|
|
10470
|
+
this.#type = "flipped";
|
|
10471
|
+
}
|
|
10472
|
+
get type() {
|
|
10473
|
+
return this.#type;
|
|
10474
|
+
}
|
|
10475
|
+
isFlippable() {
|
|
10476
|
+
return this.#flippable;
|
|
10477
|
+
}
|
|
10478
|
+
/**
|
|
10479
|
+
* Propagate unlimiting through the child subgraph when this join is flipped.
|
|
10480
|
+
* When a join is flipped, the child becomes the outer loop and should produce
|
|
10481
|
+
* all rows rather than stopping at an EXISTS limit.
|
|
10482
|
+
*
|
|
10483
|
+
* Propagation rules:
|
|
10484
|
+
* - Connection: call unlimit()
|
|
10485
|
+
* - Semi-join: continue to parent (outer loop)
|
|
10486
|
+
* - Flipped join: stop (already unlimited when it was flipped)
|
|
10487
|
+
* - Fan-out/Fan-in: propagate to all inputs
|
|
10488
|
+
*/
|
|
10489
|
+
propagateUnlimit() {
|
|
10490
|
+
assert(this.#type === "flipped", "Can only unlimit a flipped join");
|
|
10491
|
+
propagateUnlimitToNode(this.#child);
|
|
10492
|
+
}
|
|
10493
|
+
/**
|
|
10494
|
+
* Called when a parent join is flipped and this join is part of its child subgraph.
|
|
10495
|
+
* - Semi-join: continue propagation to parent (the outer loop)
|
|
10496
|
+
* - Flipped join: stop propagation (already unlimited when it was flipped)
|
|
10497
|
+
*/
|
|
10498
|
+
propagateUnlimitFromFlippedJoin() {
|
|
10499
|
+
if (this.#type === "semi") {
|
|
10500
|
+
propagateUnlimitToNode(this.#parent);
|
|
10501
|
+
}
|
|
10502
|
+
}
|
|
10503
|
+
propagateConstraints(branchPattern, constraint) {
|
|
10504
|
+
if (this.#type === "semi") {
|
|
10505
|
+
this.#child.propagateConstraints(
|
|
10506
|
+
branchPattern,
|
|
10507
|
+
this.#childConstraint,
|
|
10508
|
+
this
|
|
10509
|
+
);
|
|
10510
|
+
this.#parent.propagateConstraints(branchPattern, constraint, this);
|
|
10511
|
+
} else if (this.#type === "flipped") {
|
|
10512
|
+
this.#child.propagateConstraints(branchPattern, void 0, this);
|
|
10513
|
+
this.#parent.propagateConstraints(
|
|
10514
|
+
branchPattern,
|
|
10515
|
+
mergeConstraints(constraint, this.#parentConstraint),
|
|
10516
|
+
this
|
|
10517
|
+
);
|
|
10518
|
+
}
|
|
10519
|
+
}
|
|
10520
|
+
reset() {
|
|
10521
|
+
this.#type = "semi";
|
|
10522
|
+
}
|
|
10523
|
+
estimateCost(branchPattern) {
|
|
10524
|
+
const parentCost = this.#parent.estimateCost(branchPattern);
|
|
10525
|
+
const childCost = this.#child.estimateCost(branchPattern);
|
|
10526
|
+
let scanEst = parentCost.rows;
|
|
10527
|
+
if (this.#type === "semi" && parentCost.limit !== void 0) {
|
|
10528
|
+
if (childCost.selectivity !== 0) {
|
|
10529
|
+
scanEst = Math.min(scanEst, parentCost.limit / childCost.selectivity);
|
|
10530
|
+
}
|
|
10531
|
+
}
|
|
10532
|
+
if (this.#parent.closestJoinOrSource() === "join") {
|
|
10533
|
+
const pipelineCost = this.#type === "flipped" ? childCost.startupCost + childCost.runningCost * (parentCost.startupCost + parentCost.runningCost) : parentCost.runningCost + SEMI_JOIN_OVERHEAD_MULTIPLIER * scanEst * (childCost.startupCost + childCost.runningCost);
|
|
10534
|
+
return {
|
|
10535
|
+
rows: parentCost.rows,
|
|
10536
|
+
runningCost: pipelineCost,
|
|
10537
|
+
startupCost: parentCost.startupCost,
|
|
10538
|
+
selectivity: parentCost.selectivity,
|
|
10539
|
+
limit: parentCost.limit
|
|
10540
|
+
};
|
|
10541
|
+
}
|
|
10542
|
+
const nestedLoopCost = this.#type === "flipped" ? childCost.runningCost * (parentCost.startupCost + parentCost.runningCost) : SEMI_JOIN_OVERHEAD_MULTIPLIER * scanEst * (childCost.startupCost + childCost.runningCost);
|
|
10543
|
+
return {
|
|
10544
|
+
rows: parentCost.rows,
|
|
10545
|
+
runningCost: nestedLoopCost,
|
|
10546
|
+
startupCost: parentCost.startupCost,
|
|
10547
|
+
selectivity: parentCost.selectivity,
|
|
10548
|
+
limit: parentCost.limit
|
|
10549
|
+
};
|
|
10550
|
+
}
|
|
10551
|
+
/**
|
|
10552
|
+
* Get a human-readable name for this join for debugging.
|
|
10553
|
+
* Format: "parentName ⋈ childName"
|
|
10554
|
+
*/
|
|
10555
|
+
getName() {
|
|
10556
|
+
const parentName = getNodeName(this.#parent);
|
|
10557
|
+
const childName = getNodeName(this.#child);
|
|
10558
|
+
return `${parentName} \u22C8 ${childName}`;
|
|
10559
|
+
}
|
|
10560
|
+
/**
|
|
10561
|
+
* Get debug information about this join's state.
|
|
10562
|
+
*/
|
|
10563
|
+
getDebugInfo() {
|
|
10564
|
+
return {
|
|
10565
|
+
name: this.getName(),
|
|
10566
|
+
type: this.#type,
|
|
10567
|
+
planId: this.planId
|
|
10568
|
+
};
|
|
10569
|
+
}
|
|
10570
|
+
};
|
|
10571
|
+
var UnflippableJoinError = class extends Error {
|
|
10572
|
+
constructor(message) {
|
|
10573
|
+
super(message);
|
|
10574
|
+
this.name = "UnflippableJoinError";
|
|
10575
|
+
}
|
|
10576
|
+
};
|
|
10577
|
+
function getNodeName(node) {
|
|
10578
|
+
switch (node.kind) {
|
|
10579
|
+
case "connection":
|
|
10580
|
+
return node.name;
|
|
10581
|
+
case "join":
|
|
10582
|
+
return node.getName();
|
|
10583
|
+
case "fan-out":
|
|
10584
|
+
return "FO";
|
|
10585
|
+
case "fan-in":
|
|
10586
|
+
return "FI";
|
|
10587
|
+
case "terminus":
|
|
10588
|
+
return "terminus";
|
|
10589
|
+
}
|
|
10590
|
+
}
|
|
10591
|
+
function propagateUnlimitToNode(node) {
|
|
10592
|
+
if ("propagateUnlimitFromFlippedJoin" in node && typeof node.propagateUnlimitFromFlippedJoin === "function") {
|
|
10593
|
+
node.propagateUnlimitFromFlippedJoin();
|
|
10594
|
+
}
|
|
10595
|
+
}
|
|
10596
|
+
|
|
10597
|
+
// ../zql/src/planner/planner-terminus.ts
|
|
10598
|
+
var PlannerTerminus = class {
|
|
10599
|
+
kind = "terminus";
|
|
10600
|
+
#input;
|
|
10601
|
+
constructor(input) {
|
|
10602
|
+
this.#input = input;
|
|
10603
|
+
}
|
|
10604
|
+
get pinned() {
|
|
10605
|
+
return true;
|
|
10606
|
+
}
|
|
10607
|
+
closestJoinOrSource() {
|
|
10608
|
+
return this.#input.closestJoinOrSource();
|
|
10609
|
+
}
|
|
10610
|
+
propagateConstraints() {
|
|
10611
|
+
this.#input.propagateConstraints([], void 0, this);
|
|
10612
|
+
}
|
|
10613
|
+
estimateCost() {
|
|
10614
|
+
return this.#input.estimateCost([]);
|
|
10615
|
+
}
|
|
10616
|
+
/**
|
|
10617
|
+
* Propagate unlimiting when a parent join is flipped.
|
|
10618
|
+
* Terminus doesn't participate in unlimiting.
|
|
10619
|
+
*/
|
|
10620
|
+
propagateUnlimitFromFlippedJoin() {
|
|
10621
|
+
}
|
|
10622
|
+
};
|
|
10623
|
+
|
|
10624
|
+
// ../zql/src/planner/planner-builder.ts
|
|
10625
|
+
function wireOutput(from, to) {
|
|
10626
|
+
switch (from.kind) {
|
|
10627
|
+
case "connection":
|
|
10628
|
+
case "join":
|
|
10629
|
+
case "fan-in":
|
|
10630
|
+
from.setOutput(to);
|
|
10631
|
+
break;
|
|
10632
|
+
case "fan-out":
|
|
10633
|
+
from.addOutput(to);
|
|
10634
|
+
break;
|
|
10635
|
+
case "terminus":
|
|
10636
|
+
assert(false, "Terminus nodes cannot have outputs");
|
|
10637
|
+
}
|
|
10638
|
+
}
|
|
10639
|
+
function buildPlanGraph(ast, model, baseConstraints) {
|
|
10640
|
+
const graph = new PlannerGraph();
|
|
10641
|
+
let nextPlanId = 0;
|
|
10642
|
+
const source = graph.addSource(ast.table, model);
|
|
10643
|
+
const connection = source.connect(
|
|
10644
|
+
ast.orderBy ?? [],
|
|
10645
|
+
ast.where,
|
|
10646
|
+
baseConstraints,
|
|
10647
|
+
ast.limit
|
|
10648
|
+
);
|
|
10649
|
+
graph.connections.push(connection);
|
|
10650
|
+
let end = connection;
|
|
10651
|
+
if (ast.where) {
|
|
10652
|
+
end = processCondition(
|
|
10653
|
+
ast.where,
|
|
10654
|
+
end,
|
|
10655
|
+
graph,
|
|
10656
|
+
model,
|
|
10657
|
+
ast.table,
|
|
10658
|
+
() => nextPlanId++
|
|
10659
|
+
);
|
|
10660
|
+
}
|
|
10661
|
+
const terminus = new PlannerTerminus(end);
|
|
10662
|
+
wireOutput(end, terminus);
|
|
10663
|
+
graph.setTerminus(terminus);
|
|
10664
|
+
const subPlans = {};
|
|
10665
|
+
if (ast.related) {
|
|
10666
|
+
for (const csq of ast.related) {
|
|
10667
|
+
const alias = must(
|
|
10668
|
+
csq.subquery.alias,
|
|
10669
|
+
"Related subquery must have alias"
|
|
10670
|
+
);
|
|
10671
|
+
const childConstraints = extractConstraint(
|
|
10672
|
+
csq.correlation.childField,
|
|
10673
|
+
csq.subquery.table
|
|
10674
|
+
);
|
|
10675
|
+
subPlans[alias] = buildPlanGraph(csq.subquery, model, childConstraints);
|
|
10676
|
+
}
|
|
10677
|
+
}
|
|
10678
|
+
return { plan: graph, subPlans };
|
|
10679
|
+
}
|
|
10680
|
+
function processCondition(condition, input, graph, model, parentTable, getPlanId) {
|
|
10681
|
+
switch (condition.type) {
|
|
10682
|
+
case "simple":
|
|
10683
|
+
return input;
|
|
10684
|
+
case "and":
|
|
10685
|
+
return processAnd(condition, input, graph, model, parentTable, getPlanId);
|
|
10686
|
+
case "or":
|
|
10687
|
+
return processOr(condition, input, graph, model, parentTable, getPlanId);
|
|
10688
|
+
case "correlatedSubquery":
|
|
10689
|
+
return processCorrelatedSubquery(
|
|
10690
|
+
condition,
|
|
10691
|
+
input,
|
|
10692
|
+
graph,
|
|
10693
|
+
model,
|
|
10694
|
+
parentTable,
|
|
10695
|
+
getPlanId
|
|
10696
|
+
);
|
|
10697
|
+
}
|
|
10698
|
+
}
|
|
10699
|
+
function processAnd(condition, input, graph, model, parentTable, getPlanId) {
|
|
10700
|
+
let end = input;
|
|
10701
|
+
for (const subCondition of condition.conditions) {
|
|
10702
|
+
end = processCondition(
|
|
10703
|
+
subCondition,
|
|
10704
|
+
end,
|
|
10705
|
+
graph,
|
|
10706
|
+
model,
|
|
10707
|
+
parentTable,
|
|
10708
|
+
getPlanId
|
|
10709
|
+
);
|
|
10710
|
+
}
|
|
10711
|
+
return end;
|
|
10712
|
+
}
|
|
10713
|
+
function processOr(condition, input, graph, model, parentTable, getPlanId) {
|
|
10714
|
+
const subqueryConditions = condition.conditions.filter(
|
|
10715
|
+
(c) => c.type === "correlatedSubquery" || hasCorrelatedSubquery(c)
|
|
10716
|
+
);
|
|
10717
|
+
if (subqueryConditions.length === 0) {
|
|
10718
|
+
return input;
|
|
10719
|
+
}
|
|
10720
|
+
const fanOut = new PlannerFanOut(input);
|
|
10721
|
+
graph.fanOuts.push(fanOut);
|
|
10722
|
+
wireOutput(input, fanOut);
|
|
10723
|
+
const branches = [];
|
|
10724
|
+
for (const subCondition of subqueryConditions) {
|
|
10725
|
+
const branch = processCondition(
|
|
10726
|
+
subCondition,
|
|
10727
|
+
fanOut,
|
|
10728
|
+
graph,
|
|
10729
|
+
model,
|
|
10730
|
+
parentTable,
|
|
10731
|
+
getPlanId
|
|
10732
|
+
);
|
|
10733
|
+
branches.push(branch);
|
|
10734
|
+
fanOut.addOutput(branch);
|
|
10735
|
+
}
|
|
10736
|
+
const fanIn = new PlannerFanIn(branches);
|
|
10737
|
+
graph.fanIns.push(fanIn);
|
|
10738
|
+
for (const branch of branches) {
|
|
10739
|
+
wireOutput(branch, fanIn);
|
|
10740
|
+
}
|
|
10741
|
+
return fanIn;
|
|
10742
|
+
}
|
|
10743
|
+
function processCorrelatedSubquery(condition, input, graph, model, parentTable, getPlanId) {
|
|
10744
|
+
const { related } = condition;
|
|
10745
|
+
const childTable = related.subquery.table;
|
|
10746
|
+
const childSource = graph.hasSource(childTable) ? graph.getSource(childTable) : graph.addSource(childTable, model);
|
|
10747
|
+
const childConnection = childSource.connect(
|
|
10748
|
+
related.subquery.orderBy ?? [],
|
|
10749
|
+
related.subquery.where,
|
|
10750
|
+
void 0,
|
|
10751
|
+
// no base constraints for EXISTS/NOT EXISTS
|
|
10752
|
+
condition.op === "EXISTS" ? 1 : void 0
|
|
10753
|
+
);
|
|
10754
|
+
graph.connections.push(childConnection);
|
|
10755
|
+
let childEnd = childConnection;
|
|
10756
|
+
if (related.subquery.where) {
|
|
10757
|
+
childEnd = processCondition(
|
|
10758
|
+
related.subquery.where,
|
|
10759
|
+
childEnd,
|
|
10760
|
+
graph,
|
|
10761
|
+
model,
|
|
10762
|
+
childTable,
|
|
10763
|
+
getPlanId
|
|
10764
|
+
);
|
|
10765
|
+
}
|
|
10766
|
+
const parentConstraint = extractConstraint(
|
|
10767
|
+
related.correlation.parentField,
|
|
10768
|
+
parentTable
|
|
10769
|
+
);
|
|
10770
|
+
const childConstraint = extractConstraint(
|
|
10771
|
+
related.correlation.childField,
|
|
10772
|
+
childTable
|
|
10773
|
+
);
|
|
10774
|
+
const planId = getPlanId();
|
|
10775
|
+
condition[planIdSymbol] = planId;
|
|
10776
|
+
const join = new PlannerJoin(
|
|
10777
|
+
input,
|
|
10778
|
+
childEnd,
|
|
10779
|
+
parentConstraint,
|
|
10780
|
+
childConstraint,
|
|
10781
|
+
condition.op !== "NOT EXISTS",
|
|
10782
|
+
planId
|
|
10783
|
+
);
|
|
10784
|
+
graph.joins.push(join);
|
|
10785
|
+
wireOutput(input, join);
|
|
10786
|
+
wireOutput(childEnd, join);
|
|
10787
|
+
return join;
|
|
10788
|
+
}
|
|
10789
|
+
function hasCorrelatedSubquery(condition) {
|
|
10790
|
+
if (condition.type === "correlatedSubquery") {
|
|
10791
|
+
return true;
|
|
10792
|
+
}
|
|
10793
|
+
if (condition.type === "and" || condition.type === "or") {
|
|
10794
|
+
return condition.conditions.some(hasCorrelatedSubquery);
|
|
10795
|
+
}
|
|
10796
|
+
return false;
|
|
10797
|
+
}
|
|
10798
|
+
function extractConstraint(fields, _tableName) {
|
|
10799
|
+
return Object.fromEntries(fields.map((field) => [field, void 0]));
|
|
10800
|
+
}
|
|
10801
|
+
function planRecursively(plans, planDebugger) {
|
|
10802
|
+
for (const subPlan of Object.values(plans.subPlans)) {
|
|
10803
|
+
planRecursively(subPlan, planDebugger);
|
|
10804
|
+
}
|
|
10805
|
+
plans.plan.plan(planDebugger);
|
|
10806
|
+
}
|
|
10807
|
+
function planQuery(ast, model, planDebugger) {
|
|
10808
|
+
const plans = buildPlanGraph(ast, model);
|
|
10809
|
+
planRecursively(plans, planDebugger);
|
|
10810
|
+
return applyPlansToAST(ast, plans);
|
|
10811
|
+
}
|
|
10812
|
+
function applyToCondition(condition, flippedIds) {
|
|
10813
|
+
if (condition.type === "simple") {
|
|
10814
|
+
return condition;
|
|
10815
|
+
}
|
|
10816
|
+
if (condition.type === "correlatedSubquery") {
|
|
10817
|
+
const planId = condition[planIdSymbol];
|
|
10818
|
+
const shouldFlip = planId !== void 0 && flippedIds.has(planId);
|
|
10819
|
+
return {
|
|
10820
|
+
...condition,
|
|
10821
|
+
flip: shouldFlip ? true : condition.flip,
|
|
10822
|
+
related: {
|
|
10823
|
+
...condition.related,
|
|
10824
|
+
subquery: {
|
|
10825
|
+
...condition.related.subquery,
|
|
10826
|
+
where: condition.related.subquery.where ? applyToCondition(condition.related.subquery.where, flippedIds) : void 0
|
|
10827
|
+
}
|
|
10828
|
+
}
|
|
10829
|
+
};
|
|
10830
|
+
}
|
|
10831
|
+
return {
|
|
10832
|
+
...condition,
|
|
10833
|
+
conditions: condition.conditions.map((c) => applyToCondition(c, flippedIds))
|
|
10834
|
+
};
|
|
10835
|
+
}
|
|
10836
|
+
function applyPlansToAST(ast, plans) {
|
|
10837
|
+
const flippedIds = /* @__PURE__ */ new Set();
|
|
10838
|
+
for (const join of plans.plan.joins) {
|
|
10839
|
+
if (join.type === "flipped" && join.planId !== void 0) {
|
|
10840
|
+
flippedIds.add(join.planId);
|
|
10841
|
+
}
|
|
10842
|
+
}
|
|
10843
|
+
return {
|
|
10844
|
+
...ast,
|
|
10845
|
+
where: ast.where ? applyToCondition(ast.where, flippedIds) : void 0,
|
|
10846
|
+
related: ast.related?.map((csq) => {
|
|
10847
|
+
const alias = must(
|
|
10848
|
+
csq.subquery.alias,
|
|
10849
|
+
"Related subquery must have alias"
|
|
10850
|
+
);
|
|
10851
|
+
const subPlan = plans.subPlans[alias];
|
|
10852
|
+
return {
|
|
10853
|
+
...csq,
|
|
10854
|
+
subquery: subPlan ? applyPlansToAST(csq.subquery, subPlan) : csq.subquery
|
|
10855
|
+
};
|
|
10856
|
+
})
|
|
10857
|
+
};
|
|
10858
|
+
}
|
|
10859
|
+
|
|
10860
|
+
// ../zql/src/query/expression.ts
|
|
10861
|
+
var ExpressionBuilder = class {
|
|
10862
|
+
#exists;
|
|
10863
|
+
constructor(exists) {
|
|
10864
|
+
this.#exists = exists;
|
|
10865
|
+
this.exists = this.exists.bind(this);
|
|
10866
|
+
}
|
|
10867
|
+
get eb() {
|
|
10868
|
+
return this;
|
|
10869
|
+
}
|
|
10870
|
+
cmp(field, opOrValue, value) {
|
|
10871
|
+
return cmp(field, opOrValue, value);
|
|
10872
|
+
}
|
|
10873
|
+
cmpLit(left, op, right) {
|
|
10874
|
+
return {
|
|
10875
|
+
type: "simple",
|
|
10876
|
+
left: isParameterReference(left) ? left[toStaticParam]() : { type: "literal", value: left },
|
|
10877
|
+
right: isParameterReference(right) ? right[toStaticParam]() : { type: "literal", value: right },
|
|
10878
|
+
op
|
|
10879
|
+
};
|
|
10880
|
+
}
|
|
10881
|
+
and = and;
|
|
10882
|
+
or = or;
|
|
10883
|
+
not = not;
|
|
10884
|
+
exists = (relationship, cb, options) => this.#exists(relationship, cb, options);
|
|
10885
|
+
};
|
|
10886
|
+
function and(...conditions) {
|
|
10887
|
+
const expressions = filterTrue(filterUndefined(conditions));
|
|
10888
|
+
if (expressions.length === 1) {
|
|
10889
|
+
return expressions[0];
|
|
10890
|
+
}
|
|
10891
|
+
if (expressions.some(isAlwaysFalse)) {
|
|
10892
|
+
return FALSE;
|
|
10893
|
+
}
|
|
10894
|
+
return { type: "and", conditions: expressions };
|
|
10895
|
+
}
|
|
10896
|
+
function or(...conditions) {
|
|
10897
|
+
const expressions = filterFalse(filterUndefined(conditions));
|
|
10898
|
+
if (expressions.length === 1) {
|
|
10899
|
+
return expressions[0];
|
|
10900
|
+
}
|
|
10901
|
+
if (expressions.some(isAlwaysTrue)) {
|
|
10902
|
+
return TRUE;
|
|
10903
|
+
}
|
|
10904
|
+
return { type: "or", conditions: expressions };
|
|
10905
|
+
}
|
|
10906
|
+
function not(expression) {
|
|
10907
|
+
switch (expression.type) {
|
|
10908
|
+
case "and":
|
|
10909
|
+
return {
|
|
10910
|
+
type: "or",
|
|
10911
|
+
conditions: expression.conditions.map(not)
|
|
10912
|
+
};
|
|
10913
|
+
case "or":
|
|
10914
|
+
return {
|
|
10915
|
+
type: "and",
|
|
10916
|
+
conditions: expression.conditions.map(not)
|
|
10917
|
+
};
|
|
10918
|
+
case "correlatedSubquery":
|
|
10919
|
+
return {
|
|
10920
|
+
type: "correlatedSubquery",
|
|
10921
|
+
related: expression.related,
|
|
10922
|
+
op: negateOperator(expression.op)
|
|
10923
|
+
};
|
|
10924
|
+
case "simple":
|
|
10925
|
+
return {
|
|
10926
|
+
type: "simple",
|
|
10927
|
+
op: negateOperator(expression.op),
|
|
10928
|
+
left: expression.left,
|
|
10929
|
+
right: expression.right
|
|
10930
|
+
};
|
|
10931
|
+
}
|
|
10932
|
+
}
|
|
10933
|
+
function cmp(field, opOrValue, value) {
|
|
10934
|
+
let op;
|
|
10935
|
+
if (value === void 0) {
|
|
10936
|
+
value = opOrValue;
|
|
10937
|
+
op = "=";
|
|
10938
|
+
} else {
|
|
10939
|
+
op = opOrValue;
|
|
10940
|
+
}
|
|
10941
|
+
return {
|
|
10942
|
+
type: "simple",
|
|
10943
|
+
left: { type: "column", name: field },
|
|
10944
|
+
right: isParameterReference(value) ? value[toStaticParam]() : { type: "literal", value },
|
|
10945
|
+
op
|
|
10946
|
+
};
|
|
10947
|
+
}
|
|
10948
|
+
function isParameterReference(value) {
|
|
10949
|
+
return value !== null && typeof value === "object" && value[toStaticParam];
|
|
10950
|
+
}
|
|
10951
|
+
var TRUE = {
|
|
10952
|
+
type: "and",
|
|
10953
|
+
conditions: []
|
|
10954
|
+
};
|
|
10955
|
+
var FALSE = {
|
|
10956
|
+
type: "or",
|
|
10957
|
+
conditions: []
|
|
10958
|
+
};
|
|
10959
|
+
function isAlwaysTrue(condition) {
|
|
10960
|
+
return condition.type === "and" && condition.conditions.length === 0;
|
|
10961
|
+
}
|
|
10962
|
+
function isAlwaysFalse(condition) {
|
|
10963
|
+
return condition.type === "or" && condition.conditions.length === 0;
|
|
10964
|
+
}
|
|
10965
|
+
function simplifyCondition(c) {
|
|
10966
|
+
if (c.type === "simple" || c.type === "correlatedSubquery") {
|
|
10967
|
+
return c;
|
|
10968
|
+
}
|
|
10969
|
+
if (c.conditions.length === 1) {
|
|
10970
|
+
return simplifyCondition(c.conditions[0]);
|
|
10971
|
+
}
|
|
10972
|
+
const conditions = flatten(c.type, c.conditions.map(simplifyCondition));
|
|
10973
|
+
if (c.type === "and" && conditions.some(isAlwaysFalse)) {
|
|
10974
|
+
return FALSE;
|
|
10975
|
+
}
|
|
10976
|
+
if (c.type === "or" && conditions.some(isAlwaysTrue)) {
|
|
10977
|
+
return TRUE;
|
|
10978
|
+
}
|
|
10979
|
+
return {
|
|
10980
|
+
type: c.type,
|
|
10981
|
+
conditions
|
|
10982
|
+
};
|
|
10983
|
+
}
|
|
10984
|
+
function flatten(type, conditions) {
|
|
10985
|
+
const flattened = [];
|
|
10986
|
+
for (const c of conditions) {
|
|
10987
|
+
if (c.type === type) {
|
|
10988
|
+
flattened.push(...c.conditions);
|
|
10989
|
+
} else {
|
|
10990
|
+
flattened.push(c);
|
|
10991
|
+
}
|
|
10992
|
+
}
|
|
10993
|
+
return flattened;
|
|
10994
|
+
}
|
|
10995
|
+
var negateSimpleOperatorMap = {
|
|
10996
|
+
["="]: "!=",
|
|
10997
|
+
["!="]: "=",
|
|
10998
|
+
["<"]: ">=",
|
|
10999
|
+
[">"]: "<=",
|
|
11000
|
+
[">="]: "<",
|
|
11001
|
+
["<="]: ">",
|
|
11002
|
+
["IN"]: "NOT IN",
|
|
11003
|
+
["NOT IN"]: "IN",
|
|
11004
|
+
["LIKE"]: "NOT LIKE",
|
|
11005
|
+
["NOT LIKE"]: "LIKE",
|
|
11006
|
+
["ILIKE"]: "NOT ILIKE",
|
|
11007
|
+
["NOT ILIKE"]: "ILIKE",
|
|
11008
|
+
["IS"]: "IS NOT",
|
|
11009
|
+
["IS NOT"]: "IS"
|
|
11010
|
+
};
|
|
11011
|
+
var negateOperatorMap = {
|
|
11012
|
+
...negateSimpleOperatorMap,
|
|
11013
|
+
["EXISTS"]: "NOT EXISTS",
|
|
11014
|
+
["NOT EXISTS"]: "EXISTS"
|
|
11015
|
+
};
|
|
11016
|
+
function negateOperator(op) {
|
|
11017
|
+
return must(negateOperatorMap[op]);
|
|
11018
|
+
}
|
|
11019
|
+
function filterUndefined(array10) {
|
|
11020
|
+
return array10.filter((e) => e !== void 0);
|
|
11021
|
+
}
|
|
11022
|
+
function filterTrue(conditions) {
|
|
11023
|
+
return conditions.filter((c) => !isAlwaysTrue(c));
|
|
11024
|
+
}
|
|
11025
|
+
function filterFalse(conditions) {
|
|
11026
|
+
return conditions.filter((c) => !isAlwaysFalse(c));
|
|
11027
|
+
}
|
|
11028
|
+
|
|
11029
|
+
// ../zql/src/builder/like.ts
|
|
9475
11030
|
function getLikePredicate(pattern, flags) {
|
|
9476
11031
|
const op = getLikeOp(String(pattern), flags);
|
|
9477
11032
|
return (lhs) => {
|
|
@@ -9666,8 +11221,11 @@ function transformFilters(filters) {
|
|
|
9666
11221
|
}
|
|
9667
11222
|
|
|
9668
11223
|
// ../zql/src/builder/builder.ts
|
|
9669
|
-
function buildPipeline(ast, delegate, queryID) {
|
|
11224
|
+
function buildPipeline(ast, delegate, queryID, costModel) {
|
|
9670
11225
|
ast = delegate.mapAst ? delegate.mapAst(ast) : ast;
|
|
11226
|
+
if (costModel) {
|
|
11227
|
+
ast = planQuery(ast, costModel);
|
|
11228
|
+
}
|
|
9671
11229
|
return buildPipelineInternal(ast, delegate, queryID, "");
|
|
9672
11230
|
}
|
|
9673
11231
|
var EXISTS_LIMIT = 3;
|
|
@@ -11094,25 +12652,47 @@ var MockClientLockManager = class {
|
|
|
11094
12652
|
}
|
|
11095
12653
|
};
|
|
11096
12654
|
|
|
11097
|
-
// ../zero-client/src/client/connection-manager.ts
|
|
11098
|
-
import { resolver as resolver9 } from "@rocicorp/resolver";
|
|
11099
|
-
|
|
11100
|
-
// ../
|
|
11101
|
-
var
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
11112
|
-
|
|
12655
|
+
// ../zero-client/src/client/connection-manager.ts
|
|
12656
|
+
import { resolver as resolver9 } from "@rocicorp/resolver";
|
|
12657
|
+
|
|
12658
|
+
// ../shared/src/subscribable.ts
|
|
12659
|
+
var Subscribable = class {
|
|
12660
|
+
_listeners = /* @__PURE__ */ new Set();
|
|
12661
|
+
/**
|
|
12662
|
+
* Subscribe to the subscribable.
|
|
12663
|
+
*
|
|
12664
|
+
* @param listener - The listener to subscribe to.
|
|
12665
|
+
* @returns A function to unsubscribe from the subscribable.
|
|
12666
|
+
*/
|
|
12667
|
+
subscribe = (listener) => {
|
|
12668
|
+
this._listeners.add(listener);
|
|
12669
|
+
return () => {
|
|
12670
|
+
this._listeners.delete(listener);
|
|
12671
|
+
};
|
|
12672
|
+
};
|
|
12673
|
+
/**
|
|
12674
|
+
* Notify all listeners.
|
|
12675
|
+
*
|
|
12676
|
+
* @param update - The update to notify listeners with.
|
|
12677
|
+
*/
|
|
12678
|
+
notify = (update) => {
|
|
12679
|
+
this._listeners.forEach((listener) => listener(update));
|
|
12680
|
+
};
|
|
12681
|
+
hasListeners = () => this._listeners.size > 0;
|
|
12682
|
+
/**
|
|
12683
|
+
* Unsubscribe all listeners.
|
|
12684
|
+
*/
|
|
12685
|
+
cleanup = () => {
|
|
12686
|
+
this._listeners.clear();
|
|
12687
|
+
};
|
|
12688
|
+
};
|
|
12689
|
+
|
|
11113
12690
|
// ../zero-client/src/client/connection-manager.ts
|
|
11114
12691
|
var DEFAULT_TIMEOUT_CHECK_INTERVAL_MS = 1e3;
|
|
11115
|
-
var
|
|
12692
|
+
var TERMINAL_STATES = [
|
|
12693
|
+
connection_status_enum_exports.Error
|
|
12694
|
+
];
|
|
12695
|
+
var ConnectionManager = class _ConnectionManager extends Subscribable {
|
|
11116
12696
|
#state;
|
|
11117
12697
|
/**
|
|
11118
12698
|
* The timestamp when we first started trying to connect.
|
|
@@ -11160,14 +12740,34 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11160
12740
|
is(status) {
|
|
11161
12741
|
return this.#state.name === status;
|
|
11162
12742
|
}
|
|
12743
|
+
/**
|
|
12744
|
+
* Returns true if the current state is a terminal state
|
|
12745
|
+
* that can be recovered from by calling connect().
|
|
12746
|
+
*/
|
|
12747
|
+
isInTerminalState() {
|
|
12748
|
+
return _ConnectionManager.isTerminalState(this.#state);
|
|
12749
|
+
}
|
|
12750
|
+
/**
|
|
12751
|
+
* Returns true if the given status is a terminal state
|
|
12752
|
+
* that can be recovered from by calling connect().
|
|
12753
|
+
*/
|
|
12754
|
+
static isTerminalState(state) {
|
|
12755
|
+
return TERMINAL_STATES.includes(
|
|
12756
|
+
state.name
|
|
12757
|
+
);
|
|
12758
|
+
}
|
|
11163
12759
|
/**
|
|
11164
12760
|
* Returns true if the run loop should continue.
|
|
11165
|
-
* The run loop continues in disconnected, connecting, and
|
|
12761
|
+
* The run loop continues in disconnected, connecting, connected, and error states.
|
|
11166
12762
|
* It stops in closed state.
|
|
11167
12763
|
*/
|
|
11168
12764
|
shouldContinueRunLoop() {
|
|
11169
12765
|
return this.#state.name !== connection_status_enum_exports.Closed;
|
|
11170
12766
|
}
|
|
12767
|
+
/**
|
|
12768
|
+
* Waits for the next state change.
|
|
12769
|
+
* @returns A promise that resolves when the next state change occurs.
|
|
12770
|
+
*/
|
|
11171
12771
|
waitForStateChange() {
|
|
11172
12772
|
return this.#nextStatePromise();
|
|
11173
12773
|
}
|
|
@@ -11259,29 +12859,55 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11259
12859
|
return { nextStatePromise };
|
|
11260
12860
|
}
|
|
11261
12861
|
/**
|
|
11262
|
-
* Transition to
|
|
11263
|
-
* This
|
|
12862
|
+
* Transition to error state.
|
|
12863
|
+
* This pauses the run loop until connect() is called.
|
|
12864
|
+
* Resets the 5-minute retry window and attempt counter.
|
|
11264
12865
|
*
|
|
11265
12866
|
* @returns An object containing a promise that resolves on the next state change.
|
|
11266
12867
|
*/
|
|
11267
|
-
|
|
12868
|
+
error(reason) {
|
|
11268
12869
|
if (this.#state.name === connection_status_enum_exports.Closed) {
|
|
11269
12870
|
return { nextStatePromise: this.#nextStatePromise() };
|
|
11270
12871
|
}
|
|
12872
|
+
if (this.#state.name === connection_status_enum_exports.Error) {
|
|
12873
|
+
return { nextStatePromise: this.#nextStatePromise() };
|
|
12874
|
+
}
|
|
11271
12875
|
this.#connectingStartedAt = void 0;
|
|
11272
12876
|
this.#maybeStopTimeoutInterval();
|
|
11273
12877
|
this.#state = {
|
|
11274
|
-
name: connection_status_enum_exports.
|
|
12878
|
+
name: connection_status_enum_exports.Error,
|
|
12879
|
+
reason
|
|
11275
12880
|
};
|
|
11276
12881
|
const nextStatePromise = this.#publishStateAndGetPromise();
|
|
11277
12882
|
return { nextStatePromise };
|
|
11278
12883
|
}
|
|
12884
|
+
/**
|
|
12885
|
+
* Transition to closed state.
|
|
12886
|
+
* This is terminal - no further transitions are allowed.
|
|
12887
|
+
*/
|
|
12888
|
+
closed() {
|
|
12889
|
+
if (this.#state.name === connection_status_enum_exports.Closed) {
|
|
12890
|
+
return;
|
|
12891
|
+
}
|
|
12892
|
+
this.#connectingStartedAt = void 0;
|
|
12893
|
+
this.#maybeStopTimeoutInterval();
|
|
12894
|
+
this.#state = {
|
|
12895
|
+
name: connection_status_enum_exports.Closed,
|
|
12896
|
+
reason: new ClientError({
|
|
12897
|
+
kind: client_error_kind_enum_exports.ClientClosed,
|
|
12898
|
+
message: "Zero was explicitly closed by calling zero.close()"
|
|
12899
|
+
})
|
|
12900
|
+
};
|
|
12901
|
+
this.#publishState();
|
|
12902
|
+
this.cleanup();
|
|
12903
|
+
return;
|
|
12904
|
+
}
|
|
11279
12905
|
cleanup = () => {
|
|
11280
12906
|
this._listeners.clear();
|
|
11281
12907
|
this.#resolveNextStateWaiters();
|
|
11282
12908
|
};
|
|
11283
12909
|
#resolveNextStateWaiters() {
|
|
11284
|
-
this.#stateChangeResolver.resolve();
|
|
12910
|
+
this.#stateChangeResolver.resolve(this.#state);
|
|
11285
12911
|
this.#stateChangeResolver = resolver9();
|
|
11286
12912
|
}
|
|
11287
12913
|
#publishState() {
|
|
@@ -11305,7 +12931,12 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11305
12931
|
}
|
|
11306
12932
|
const now = Date.now();
|
|
11307
12933
|
if (now >= this.#state.disconnectAt) {
|
|
11308
|
-
this.disconnected(
|
|
12934
|
+
this.disconnected(
|
|
12935
|
+
new ClientError({
|
|
12936
|
+
kind: client_error_kind_enum_exports.DisconnectTimeout,
|
|
12937
|
+
message: `Zero was unable to connect for ${Math.floor(this.#disconnectTimeoutMs / 1e3)} seconds and was disconnected`
|
|
12938
|
+
})
|
|
12939
|
+
);
|
|
11309
12940
|
return true;
|
|
11310
12941
|
}
|
|
11311
12942
|
return false;
|
|
@@ -11326,6 +12957,56 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11326
12957
|
this.#timeoutInterval = void 0;
|
|
11327
12958
|
}
|
|
11328
12959
|
};
|
|
12960
|
+
var throwIfConnectionError = (state) => {
|
|
12961
|
+
if (ConnectionManager.isTerminalState(state) || state.name === connection_status_enum_exports.Closed || (state.name === connection_status_enum_exports.Connecting || state.name === connection_status_enum_exports.Disconnected) && state.reason) {
|
|
12962
|
+
if (isClientError(state.reason) && (state.reason.kind === client_error_kind_enum_exports.ConnectTimeout || state.reason.kind === client_error_kind_enum_exports.AbruptClose || state.reason.kind === client_error_kind_enum_exports.CleanClose)) {
|
|
12963
|
+
return;
|
|
12964
|
+
}
|
|
12965
|
+
throw state.reason;
|
|
12966
|
+
}
|
|
12967
|
+
};
|
|
12968
|
+
|
|
12969
|
+
// ../zero-client/src/client/connection.ts
|
|
12970
|
+
var ConnectionImpl = class {
|
|
12971
|
+
#connectionManager;
|
|
12972
|
+
#lc;
|
|
12973
|
+
#source;
|
|
12974
|
+
constructor(connectionManager, lc) {
|
|
12975
|
+
this.#connectionManager = connectionManager;
|
|
12976
|
+
this.#lc = lc;
|
|
12977
|
+
this.#source = new ConnectionSource(connectionManager);
|
|
12978
|
+
}
|
|
12979
|
+
get state() {
|
|
12980
|
+
return this.#source;
|
|
12981
|
+
}
|
|
12982
|
+
async connect() {
|
|
12983
|
+
const lc = this.#lc.withContext("connect");
|
|
12984
|
+
if (!this.#connectionManager.isInTerminalState()) {
|
|
12985
|
+
lc.debug?.(
|
|
12986
|
+
"connect() called but not in a terminal state. Current state:",
|
|
12987
|
+
this.#connectionManager.state.name
|
|
12988
|
+
);
|
|
12989
|
+
return;
|
|
12990
|
+
}
|
|
12991
|
+
lc.info?.(
|
|
12992
|
+
`Resuming connection from state: ${this.#connectionManager.state.name}`
|
|
12993
|
+
);
|
|
12994
|
+
const { nextStatePromise } = this.#connectionManager.connecting();
|
|
12995
|
+
await nextStatePromise;
|
|
12996
|
+
}
|
|
12997
|
+
};
|
|
12998
|
+
var ConnectionSource = class {
|
|
12999
|
+
#connectionManager;
|
|
13000
|
+
constructor(connectionManager) {
|
|
13001
|
+
this.#connectionManager = connectionManager;
|
|
13002
|
+
}
|
|
13003
|
+
get current() {
|
|
13004
|
+
return this.#connectionManager.state;
|
|
13005
|
+
}
|
|
13006
|
+
get subscribe() {
|
|
13007
|
+
return this.#connectionManager.subscribe;
|
|
13008
|
+
}
|
|
13009
|
+
};
|
|
11329
13010
|
|
|
11330
13011
|
// ../zql/src/ivm/memory-storage.ts
|
|
11331
13012
|
import { compareUTF8 as compareUTF83 } from "compare-utf8";
|
|
@@ -13267,7 +14948,7 @@ function makeMessage(message, context, logLevel) {
|
|
|
13267
14948
|
}
|
|
13268
14949
|
|
|
13269
14950
|
// ../zero-client/src/client/version.ts
|
|
13270
|
-
var version2 = "0.25.0-canary.
|
|
14951
|
+
var version2 = "0.25.0-canary.1";
|
|
13271
14952
|
|
|
13272
14953
|
// ../zero-client/src/client/log-options.ts
|
|
13273
14954
|
var LevelFilterLogSink = class {
|
|
@@ -13323,74 +15004,6 @@ function createLogOptions(options, createDatadogLogSink = (options2) => new Data
|
|
|
13323
15004
|
};
|
|
13324
15005
|
}
|
|
13325
15006
|
|
|
13326
|
-
// ../zero-client/src/client/client-error-kind-enum.ts
|
|
13327
|
-
var client_error_kind_enum_exports = {};
|
|
13328
|
-
__export(client_error_kind_enum_exports, {
|
|
13329
|
-
AbruptClose: () => AbruptClose,
|
|
13330
|
-
CleanClose: () => CleanClose,
|
|
13331
|
-
ClientClosed: () => ClientClosed,
|
|
13332
|
-
ConnectTimeout: () => ConnectTimeout,
|
|
13333
|
-
DisconnectTimeout: () => DisconnectTimeout,
|
|
13334
|
-
Hidden: () => Hidden,
|
|
13335
|
-
NoSocketOrigin: () => NoSocketOrigin,
|
|
13336
|
-
PingTimeout: () => PingTimeout,
|
|
13337
|
-
UnexpectedBaseCookie: () => UnexpectedBaseCookie
|
|
13338
|
-
});
|
|
13339
|
-
var AbruptClose = "AbruptClose";
|
|
13340
|
-
var CleanClose = "CleanClose";
|
|
13341
|
-
var ClientClosed = "ClientClosed";
|
|
13342
|
-
var ConnectTimeout = "ConnectTimeout";
|
|
13343
|
-
var DisconnectTimeout = "DisconnectTimeout";
|
|
13344
|
-
var UnexpectedBaseCookie = "UnexpectedBaseCookie";
|
|
13345
|
-
var PingTimeout = "PingTimeout";
|
|
13346
|
-
var Hidden = "Hidden";
|
|
13347
|
-
var NoSocketOrigin = "NoSocketOrigin";
|
|
13348
|
-
|
|
13349
|
-
// ../zero-client/src/client/error.ts
|
|
13350
|
-
var BaseError = class extends Error {
|
|
13351
|
-
errorBody;
|
|
13352
|
-
constructor(errorBody, options) {
|
|
13353
|
-
super(errorBody.kind + ": " + errorBody.message, options);
|
|
13354
|
-
this.errorBody = errorBody;
|
|
13355
|
-
}
|
|
13356
|
-
get kind() {
|
|
13357
|
-
return this.errorBody.kind;
|
|
13358
|
-
}
|
|
13359
|
-
};
|
|
13360
|
-
var ServerError = class extends BaseError {
|
|
13361
|
-
get name() {
|
|
13362
|
-
return "ServerError";
|
|
13363
|
-
}
|
|
13364
|
-
};
|
|
13365
|
-
var ClientError = class extends BaseError {
|
|
13366
|
-
get name() {
|
|
13367
|
-
return "ClientError";
|
|
13368
|
-
}
|
|
13369
|
-
};
|
|
13370
|
-
function isServerError(ex) {
|
|
13371
|
-
return ex instanceof ServerError;
|
|
13372
|
-
}
|
|
13373
|
-
function isAuthError(ex) {
|
|
13374
|
-
return isServerError(ex) && isAuthErrorKind(ex.kind);
|
|
13375
|
-
}
|
|
13376
|
-
function isAuthErrorKind(kind) {
|
|
13377
|
-
return kind === error_kind_enum_exports.AuthInvalidated || kind === error_kind_enum_exports.Unauthorized;
|
|
13378
|
-
}
|
|
13379
|
-
function isBackoffError(ex) {
|
|
13380
|
-
if (isServerError(ex)) {
|
|
13381
|
-
switch (ex.errorBody.kind) {
|
|
13382
|
-
case error_kind_enum_exports.Rebalance:
|
|
13383
|
-
case error_kind_enum_exports.Rehome:
|
|
13384
|
-
case error_kind_enum_exports.ServerOverloaded:
|
|
13385
|
-
return ex.errorBody;
|
|
13386
|
-
}
|
|
13387
|
-
}
|
|
13388
|
-
return void 0;
|
|
13389
|
-
}
|
|
13390
|
-
function isClientError(ex) {
|
|
13391
|
-
return ex instanceof ClientError;
|
|
13392
|
-
}
|
|
13393
|
-
|
|
13394
15007
|
// ../zero-client/src/client/metric-name-enum.ts
|
|
13395
15008
|
var metric_name_enum_exports = {};
|
|
13396
15009
|
__export(metric_name_enum_exports, {
|
|
@@ -13417,6 +15030,21 @@ function getLastConnectErrorValue(reason) {
|
|
|
13417
15030
|
function camelToSnake(kind) {
|
|
13418
15031
|
return kind.split(/\.?(?=[A-Z])/).join("_").toLowerCase();
|
|
13419
15032
|
}
|
|
15033
|
+
function shouldReportConnectError(reason) {
|
|
15034
|
+
if (!isClientError(reason)) {
|
|
15035
|
+
return true;
|
|
15036
|
+
}
|
|
15037
|
+
switch (reason.kind) {
|
|
15038
|
+
case client_error_kind_enum_exports.Hidden:
|
|
15039
|
+
case client_error_kind_enum_exports.ClientClosed:
|
|
15040
|
+
case client_error_kind_enum_exports.UserDisconnect:
|
|
15041
|
+
case client_error_kind_enum_exports.CleanClose:
|
|
15042
|
+
case client_error_kind_enum_exports.AbruptClose:
|
|
15043
|
+
return false;
|
|
15044
|
+
default:
|
|
15045
|
+
return true;
|
|
15046
|
+
}
|
|
15047
|
+
}
|
|
13420
15048
|
var MetricManager = class {
|
|
13421
15049
|
#reportIntervalMs;
|
|
13422
15050
|
#host;
|
|
@@ -13647,10 +15275,11 @@ var MutationTracker = class {
|
|
|
13647
15275
|
#allMutationsAppliedListeners;
|
|
13648
15276
|
#lc;
|
|
13649
15277
|
#ackMutations;
|
|
15278
|
+
#onFatalError;
|
|
13650
15279
|
#clientID;
|
|
13651
15280
|
#largestOutstandingMutationID;
|
|
13652
15281
|
#currentMutationID;
|
|
13653
|
-
constructor(lc, ackMutations) {
|
|
15282
|
+
constructor(lc, ackMutations, onFatalError) {
|
|
13654
15283
|
this.#lc = lc.withContext("MutationTracker");
|
|
13655
15284
|
this.#outstandingMutations = /* @__PURE__ */ new Map();
|
|
13656
15285
|
this.#ephemeralIDsByMutationID = /* @__PURE__ */ new Map();
|
|
@@ -13658,6 +15287,7 @@ var MutationTracker = class {
|
|
|
13658
15287
|
this.#largestOutstandingMutationID = 0;
|
|
13659
15288
|
this.#currentMutationID = 0;
|
|
13660
15289
|
this.#ackMutations = ackMutations;
|
|
15290
|
+
this.#onFatalError = onFatalError;
|
|
13661
15291
|
}
|
|
13662
15292
|
setClientIDAndWatch(clientID, experimentalWatch) {
|
|
13663
15293
|
assert(this.#clientID === void 0, "clientID already set");
|
|
@@ -13745,10 +15375,53 @@ var MutationTracker = class {
|
|
|
13745
15375
|
"Received an error response when pushing mutations",
|
|
13746
15376
|
response
|
|
13747
15377
|
);
|
|
15378
|
+
const fatalError = this.#fatalErrorFromPushError(response);
|
|
15379
|
+
if (fatalError) {
|
|
15380
|
+
this.#onFatalError(fatalError);
|
|
15381
|
+
}
|
|
13748
15382
|
} else {
|
|
13749
15383
|
this.#processPushOk(response);
|
|
13750
15384
|
}
|
|
13751
15385
|
}
|
|
15386
|
+
#fatalErrorFromPushError(error) {
|
|
15387
|
+
switch (error.error) {
|
|
15388
|
+
case "unsupportedPushVersion":
|
|
15389
|
+
return new ProtocolError({
|
|
15390
|
+
kind: error_kind_enum_exports.PushFailed,
|
|
15391
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15392
|
+
reason: error_reason_enum_exports.Internal,
|
|
15393
|
+
message: `Unsupported push version`,
|
|
15394
|
+
mutationIDs: []
|
|
15395
|
+
});
|
|
15396
|
+
case "unsupportedSchemaVersion":
|
|
15397
|
+
return new ProtocolError({
|
|
15398
|
+
kind: error_kind_enum_exports.PushFailed,
|
|
15399
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15400
|
+
reason: error_reason_enum_exports.Internal,
|
|
15401
|
+
message: `Unsupported schema version`,
|
|
15402
|
+
mutationIDs: []
|
|
15403
|
+
});
|
|
15404
|
+
case "http":
|
|
15405
|
+
return new ProtocolError({
|
|
15406
|
+
kind: error_kind_enum_exports.PushFailed,
|
|
15407
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15408
|
+
reason: error_reason_enum_exports.HTTP,
|
|
15409
|
+
status: error.status,
|
|
15410
|
+
message: `Fetch from API server returned non-OK status ${error.status}: ${error.details ?? "unknown"}`,
|
|
15411
|
+
mutationIDs: []
|
|
15412
|
+
});
|
|
15413
|
+
case "zeroPusher":
|
|
15414
|
+
return new ProtocolError({
|
|
15415
|
+
kind: error_kind_enum_exports.PushFailed,
|
|
15416
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15417
|
+
reason: error_reason_enum_exports.Internal,
|
|
15418
|
+
message: `ZeroPusher error: ${error.details ?? "unknown"}`,
|
|
15419
|
+
mutationIDs: []
|
|
15420
|
+
});
|
|
15421
|
+
default:
|
|
15422
|
+
unreachable(error);
|
|
15423
|
+
}
|
|
15424
|
+
}
|
|
13752
15425
|
/**
|
|
13753
15426
|
* DEPRECATED: to be removed when we switch to fully driving
|
|
13754
15427
|
* mutation resolution via poke.
|
|
@@ -13842,6 +15515,17 @@ var MutationTracker = class {
|
|
|
13842
15515
|
const entry = this.#outstandingMutations.get(ephemeralID);
|
|
13843
15516
|
assert(entry && entry.mutationID === mid);
|
|
13844
15517
|
this.#settleMutation(ephemeralID, entry, "reject", error);
|
|
15518
|
+
if (error.error === "oooMutation") {
|
|
15519
|
+
this.#onFatalError(
|
|
15520
|
+
new ProtocolError({
|
|
15521
|
+
kind: error_kind_enum_exports.InvalidPush,
|
|
15522
|
+
origin: error_origin_enum_exports.Server,
|
|
15523
|
+
reason: error_reason_enum_exports.Internal,
|
|
15524
|
+
message: "Server reported an out-of-order mutation",
|
|
15525
|
+
details: error.details
|
|
15526
|
+
})
|
|
15527
|
+
);
|
|
15528
|
+
}
|
|
13845
15529
|
}
|
|
13846
15530
|
#processMutationOk(clientID, mid, result) {
|
|
13847
15531
|
assert(
|
|
@@ -13891,16 +15575,13 @@ var MutationTracker = class {
|
|
|
13891
15575
|
}
|
|
13892
15576
|
};
|
|
13893
15577
|
|
|
13894
|
-
// ../zero-client/src/client/ping-result-enum.ts
|
|
13895
|
-
var TimedOut = 0;
|
|
13896
|
-
var Success = 1;
|
|
13897
|
-
|
|
13898
15578
|
// ../zero-client/src/client/query-manager.ts
|
|
13899
15579
|
var QueryManager = class {
|
|
13900
15580
|
#clientID;
|
|
13901
15581
|
#clientToServer;
|
|
13902
15582
|
#serverToClient;
|
|
13903
15583
|
#send;
|
|
15584
|
+
#onFatalError;
|
|
13904
15585
|
#queries = /* @__PURE__ */ new Map();
|
|
13905
15586
|
#recentQueriesMaxSize;
|
|
13906
15587
|
#recentQueries = /* @__PURE__ */ new Set();
|
|
@@ -13914,7 +15595,7 @@ var QueryManager = class {
|
|
|
13914
15595
|
#metrics = newMetrics();
|
|
13915
15596
|
#queryMetrics = /* @__PURE__ */ new Map();
|
|
13916
15597
|
#slowMaterializeThreshold;
|
|
13917
|
-
constructor(lc, mutationTracker, clientID, tables, send2, experimentalWatch, recentQueriesMaxSize, queryChangeThrottleMs, slowMaterializeThreshold) {
|
|
15598
|
+
constructor(lc, mutationTracker, clientID, tables, send2, experimentalWatch, recentQueriesMaxSize, queryChangeThrottleMs, slowMaterializeThreshold, onFatalError) {
|
|
13918
15599
|
this.#lc = lc.withContext("QueryManager");
|
|
13919
15600
|
this.#clientID = clientID;
|
|
13920
15601
|
this.#clientToServer = clientToServer(tables);
|
|
@@ -13924,6 +15605,7 @@ var QueryManager = class {
|
|
|
13924
15605
|
this.#mutationTracker = mutationTracker;
|
|
13925
15606
|
this.#queryChangeThrottleMs = queryChangeThrottleMs;
|
|
13926
15607
|
this.#slowMaterializeThreshold = slowMaterializeThreshold;
|
|
15608
|
+
this.#onFatalError = onFatalError;
|
|
13927
15609
|
this.#mutationTracker.onAllMutationsApplied(() => {
|
|
13928
15610
|
if (this.#pendingRemovals.length === 0) {
|
|
13929
15611
|
return;
|
|
@@ -14030,6 +15712,26 @@ var QueryManager = class {
|
|
|
14030
15712
|
if (entry) {
|
|
14031
15713
|
entry.gotCallbacks.forEach((callback) => callback(false, error));
|
|
14032
15714
|
}
|
|
15715
|
+
if (error.error !== "app") {
|
|
15716
|
+
this.#onFatalError(
|
|
15717
|
+
new ProtocolError(
|
|
15718
|
+
error.error === "http" ? {
|
|
15719
|
+
kind: error_kind_enum_exports.TransformFailed,
|
|
15720
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15721
|
+
reason: error_reason_enum_exports.HTTP,
|
|
15722
|
+
message: `HTTP ${error.status} transforming queries`,
|
|
15723
|
+
status: error.status,
|
|
15724
|
+
queryIDs: []
|
|
15725
|
+
} : {
|
|
15726
|
+
kind: error_kind_enum_exports.TransformFailed,
|
|
15727
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15728
|
+
reason: error_reason_enum_exports.Internal,
|
|
15729
|
+
message: `Unknown error transforming queries`,
|
|
15730
|
+
queryIDs: []
|
|
15731
|
+
}
|
|
15732
|
+
)
|
|
15733
|
+
);
|
|
15734
|
+
}
|
|
14033
15735
|
}
|
|
14034
15736
|
}
|
|
14035
15737
|
addCustom(ast, { name, args }, ttl, gotCallback) {
|
|
@@ -14845,20 +16547,20 @@ var Zero = class _Zero {
|
|
|
14845
16547
|
};
|
|
14846
16548
|
#zeroContext;
|
|
14847
16549
|
queryDelegate;
|
|
14848
|
-
#connectResolver = resolver11();
|
|
14849
16550
|
#pendingPullsByRequestID = /* @__PURE__ */ new Map();
|
|
14850
16551
|
#lastMutationIDReceived = 0;
|
|
14851
16552
|
#socket = void 0;
|
|
14852
16553
|
#socketResolver = resolver11();
|
|
14853
16554
|
/**
|
|
14854
|
-
*
|
|
14855
|
-
*
|
|
14856
|
-
*
|
|
16555
|
+
* Utility promise that resolves when the socket transitions to connected.
|
|
16556
|
+
* It rejects if we hit an error or timeout before the connected message.
|
|
16557
|
+
* Used by push/pull helpers to queue work until the connection is usable.
|
|
14857
16558
|
*/
|
|
14858
|
-
#
|
|
16559
|
+
#connectResolver = resolver11();
|
|
14859
16560
|
#closeAbortController = new AbortController();
|
|
14860
16561
|
#visibilityWatcher;
|
|
14861
16562
|
#connectionManager;
|
|
16563
|
+
#connection;
|
|
14862
16564
|
#activeClientsManager;
|
|
14863
16565
|
#inspector;
|
|
14864
16566
|
#connectStart = void 0;
|
|
@@ -14894,7 +16596,10 @@ var Zero = class _Zero {
|
|
|
14894
16596
|
slowMaterializeThreshold = 5e3
|
|
14895
16597
|
} = options;
|
|
14896
16598
|
if (!userID) {
|
|
14897
|
-
throw new
|
|
16599
|
+
throw new ClientError({
|
|
16600
|
+
kind: client_error_kind_enum_exports.Internal,
|
|
16601
|
+
message: "ZeroOptions.userID must not be empty."
|
|
16602
|
+
});
|
|
14898
16603
|
}
|
|
14899
16604
|
const server = getServer(options.server);
|
|
14900
16605
|
this.#enableAnalytics = shouldEnableAnalytics(
|
|
@@ -14912,9 +16617,10 @@ var Zero = class _Zero {
|
|
|
14912
16617
|
}
|
|
14913
16618
|
}
|
|
14914
16619
|
if (hiddenTabDisconnectDelay < 0) {
|
|
14915
|
-
throw new
|
|
14916
|
-
|
|
14917
|
-
|
|
16620
|
+
throw new ClientError({
|
|
16621
|
+
kind: client_error_kind_enum_exports.Internal,
|
|
16622
|
+
message: "ZeroOptions.hiddenTabDisconnectDelay must not be negative."
|
|
16623
|
+
});
|
|
14918
16624
|
}
|
|
14919
16625
|
this.#onlineManager = new OnlineManager();
|
|
14920
16626
|
if (onOnlineChange) {
|
|
@@ -14933,7 +16639,12 @@ var Zero = class _Zero {
|
|
|
14933
16639
|
});
|
|
14934
16640
|
const { enableLegacyMutators = true, enableLegacyQueries = true } = schema;
|
|
14935
16641
|
const replicacheMutators = {
|
|
14936
|
-
[CRUD_MUTATION_NAME]: enableLegacyMutators ? makeCRUDMutator(schema) : () => Promise.reject(
|
|
16642
|
+
[CRUD_MUTATION_NAME]: enableLegacyMutators ? makeCRUDMutator(schema) : () => Promise.reject(
|
|
16643
|
+
new ClientError({
|
|
16644
|
+
kind: client_error_kind_enum_exports.Internal,
|
|
16645
|
+
message: "Zero CRUD mutators are not enabled."
|
|
16646
|
+
})
|
|
16647
|
+
)
|
|
14937
16648
|
};
|
|
14938
16649
|
this.#ivmMain = new IVMSourceBranch(schema.tables);
|
|
14939
16650
|
function assertUnique(key) {
|
|
@@ -14959,7 +16670,10 @@ var Zero = class _Zero {
|
|
|
14959
16670
|
const lc = new ZeroLogContext(logOptions.logLevel, {}, logSink);
|
|
14960
16671
|
this.#mutationTracker = new MutationTracker(
|
|
14961
16672
|
lc,
|
|
14962
|
-
(upTo) => this.#send(["ackMutationResponses", upTo])
|
|
16673
|
+
(upTo) => this.#send(["ackMutationResponses", upTo]),
|
|
16674
|
+
(error) => {
|
|
16675
|
+
this.#disconnect(lc, error);
|
|
16676
|
+
}
|
|
14963
16677
|
);
|
|
14964
16678
|
if (options.mutators) {
|
|
14965
16679
|
for (const [namespaceOrKey, mutatorOrMutators] of Object.entries(
|
|
@@ -15065,6 +16779,7 @@ var Zero = class _Zero {
|
|
|
15065
16779
|
this.#server = server;
|
|
15066
16780
|
this.userID = userID;
|
|
15067
16781
|
this.#lc = lc.withContext("clientID", rep.clientID);
|
|
16782
|
+
this.#connection = new ConnectionImpl(this.#connectionManager, this.#lc);
|
|
15068
16783
|
this.#mutationTracker.setClientIDAndWatch(
|
|
15069
16784
|
rep.clientID,
|
|
15070
16785
|
rep.experimentalWatch.bind(rep)
|
|
@@ -15135,7 +16850,10 @@ var Zero = class _Zero {
|
|
|
15135
16850
|
rep.experimentalWatch.bind(rep),
|
|
15136
16851
|
maxRecentQueries,
|
|
15137
16852
|
options.queryChangeThrottleMs ?? DEFAULT_QUERY_CHANGE_THROTTLE_MS,
|
|
15138
|
-
slowMaterializeThreshold
|
|
16853
|
+
slowMaterializeThreshold,
|
|
16854
|
+
(error) => {
|
|
16855
|
+
this.#disconnect(lc, error);
|
|
16856
|
+
}
|
|
15139
16857
|
);
|
|
15140
16858
|
this.#clientToServer = clientToServer(schema.tables);
|
|
15141
16859
|
this.#deleteClientsManager = new DeleteClientsManager(
|
|
@@ -15326,6 +17044,25 @@ var Zero = class _Zero {
|
|
|
15326
17044
|
* will throw an error.
|
|
15327
17045
|
*/
|
|
15328
17046
|
mutateBatch;
|
|
17047
|
+
/**
|
|
17048
|
+
* The connection API for managing Zero's connection lifecycle.
|
|
17049
|
+
*
|
|
17050
|
+
* Use this to monitor connection state and manually control connections.
|
|
17051
|
+
*
|
|
17052
|
+
* @example
|
|
17053
|
+
* ```ts
|
|
17054
|
+
* // Subscribe to connection state changes
|
|
17055
|
+
* z.connection.state.subscribe(state => {
|
|
17056
|
+
* console.log('Connection state:', state.name);
|
|
17057
|
+
* });
|
|
17058
|
+
*
|
|
17059
|
+
* // Manually resume connection from error state
|
|
17060
|
+
* await z.connection.connect();
|
|
17061
|
+
* ```
|
|
17062
|
+
*/
|
|
17063
|
+
get connection() {
|
|
17064
|
+
return this.#connection;
|
|
17065
|
+
}
|
|
15329
17066
|
/**
|
|
15330
17067
|
* Whether this Zero instance has been closed.
|
|
15331
17068
|
*
|
|
@@ -15371,7 +17108,6 @@ var Zero = class _Zero {
|
|
|
15371
17108
|
throw e;
|
|
15372
17109
|
} finally {
|
|
15373
17110
|
this.#connectionManager.closed();
|
|
15374
|
-
this.#connectionManager.cleanup();
|
|
15375
17111
|
}
|
|
15376
17112
|
}
|
|
15377
17113
|
#onMessage = (e) => {
|
|
@@ -15381,11 +17117,6 @@ var Zero = class _Zero {
|
|
|
15381
17117
|
lc.debug?.("ignoring message because already closed");
|
|
15382
17118
|
return;
|
|
15383
17119
|
}
|
|
15384
|
-
const rejectInvalidMessage = (e2) => this.#rejectMessageError?.reject(
|
|
15385
|
-
new Error(
|
|
15386
|
-
`Invalid message received from server: ${e2 instanceof Error ? e2.message + ". " : ""}${data}`
|
|
15387
|
-
)
|
|
15388
|
-
);
|
|
15389
17120
|
let downMessage;
|
|
15390
17121
|
const { data } = e;
|
|
15391
17122
|
try {
|
|
@@ -15395,7 +17126,11 @@ var Zero = class _Zero {
|
|
|
15395
17126
|
"passthrough"
|
|
15396
17127
|
);
|
|
15397
17128
|
} catch (e2) {
|
|
15398
|
-
|
|
17129
|
+
const invalidMessageError = new ClientError({
|
|
17130
|
+
kind: client_error_kind_enum_exports.InvalidMessage,
|
|
17131
|
+
message: `Invalid message received from server: ${e2 instanceof Error ? e2.message + ". " : ""}${data}`
|
|
17132
|
+
});
|
|
17133
|
+
this.#disconnect(lc, invalidMessageError);
|
|
15399
17134
|
return;
|
|
15400
17135
|
}
|
|
15401
17136
|
this.#messageCount++;
|
|
@@ -15430,9 +17165,14 @@ var Zero = class _Zero {
|
|
|
15430
17165
|
break;
|
|
15431
17166
|
case "inspect":
|
|
15432
17167
|
break;
|
|
15433
|
-
default:
|
|
15434
|
-
|
|
15435
|
-
|
|
17168
|
+
default: {
|
|
17169
|
+
const invalidMessageError = new ClientError({
|
|
17170
|
+
kind: client_error_kind_enum_exports.InvalidMessage,
|
|
17171
|
+
message: `Invalid message received from server: ${data}`
|
|
17172
|
+
});
|
|
17173
|
+
this.#disconnect(lc, invalidMessageError);
|
|
17174
|
+
return;
|
|
17175
|
+
}
|
|
15436
17176
|
}
|
|
15437
17177
|
};
|
|
15438
17178
|
#onOpen = () => {
|
|
@@ -15481,11 +17221,10 @@ var Zero = class _Zero {
|
|
|
15481
17221
|
return;
|
|
15482
17222
|
}
|
|
15483
17223
|
lc.info?.(`${kind}: ${message}}`);
|
|
15484
|
-
const error = new
|
|
17224
|
+
const error = new ProtocolError(downMessage[1]);
|
|
15485
17225
|
lc.error?.(`${error.kind}:
|
|
15486
17226
|
|
|
15487
17227
|
${error.errorBody.message}`, error);
|
|
15488
|
-
this.#rejectMessageError?.reject(error);
|
|
15489
17228
|
lc.debug?.("Rejecting connect resolver due to error", error);
|
|
15490
17229
|
this.#connectResolver.reject(error);
|
|
15491
17230
|
this.#disconnect(lc, error);
|
|
@@ -15691,8 +17430,14 @@ ${error.errorBody.message}`, error);
|
|
|
15691
17430
|
}
|
|
15692
17431
|
}
|
|
15693
17432
|
#disconnect(lc, reason, closeCode) {
|
|
15694
|
-
if (
|
|
17433
|
+
if (shouldReportConnectError(reason)) {
|
|
15695
17434
|
this.#connectErrorCount++;
|
|
17435
|
+
this.#metrics.lastConnectError.set(getLastConnectErrorValue(reason));
|
|
17436
|
+
this.#metrics.timeToConnectMs.set(DID_NOT_CONNECT_VALUE);
|
|
17437
|
+
this.#metrics.setConnectError(reason);
|
|
17438
|
+
if (this.#connectErrorCount % CHECK_CONNECTIVITY_ON_ERROR_FREQUENCY === 1) {
|
|
17439
|
+
this.#checkConnectivity(`connectErrorCount=${this.#connectErrorCount}`);
|
|
17440
|
+
}
|
|
15696
17441
|
}
|
|
15697
17442
|
lc.info?.("disconnecting", {
|
|
15698
17443
|
navigatorOnline: localNavigator?.onLine,
|
|
@@ -15705,8 +17450,8 @@ ${error.errorBody.message}`, error);
|
|
|
15705
17450
|
connectionState: this.#connectionManager.state,
|
|
15706
17451
|
connectErrorCount: this.#connectErrorCount
|
|
15707
17452
|
});
|
|
15708
|
-
const
|
|
15709
|
-
switch (
|
|
17453
|
+
const connectionStatus = this.#connectionManager.state.name;
|
|
17454
|
+
switch (connectionStatus) {
|
|
15710
17455
|
case connection_status_enum_exports.Connected: {
|
|
15711
17456
|
if (this.#connectStart !== void 0) {
|
|
15712
17457
|
lc.error?.(
|
|
@@ -15715,26 +17460,15 @@ ${error.errorBody.message}`, error);
|
|
|
15715
17460
|
}
|
|
15716
17461
|
break;
|
|
15717
17462
|
}
|
|
15718
|
-
case connection_status_enum_exports.Disconnected:
|
|
15719
|
-
case connection_status_enum_exports.Connecting: {
|
|
15720
|
-
this.#metrics.lastConnectError.set(getLastConnectErrorValue(reason));
|
|
15721
|
-
this.#metrics.timeToConnectMs.set(DID_NOT_CONNECT_VALUE);
|
|
15722
|
-
this.#metrics.setConnectError(reason);
|
|
15723
|
-
if (this.#connectErrorCount % CHECK_CONNECTIVITY_ON_ERROR_FREQUENCY === 1) {
|
|
15724
|
-
this.#checkConnectivity(
|
|
15725
|
-
`connectErrorCount=${this.#connectErrorCount}`
|
|
15726
|
-
);
|
|
15727
|
-
}
|
|
15728
|
-
if (this.#connectStart === void 0) {
|
|
15729
|
-
lc.error?.(
|
|
15730
|
-
"disconnect() called while connecting but connect start time is undefined."
|
|
15731
|
-
);
|
|
15732
|
-
}
|
|
15733
|
-
break;
|
|
15734
|
-
}
|
|
15735
17463
|
case connection_status_enum_exports.Closed:
|
|
15736
|
-
lc.
|
|
17464
|
+
lc.debug?.("disconnect() called while closed");
|
|
15737
17465
|
return;
|
|
17466
|
+
case connection_status_enum_exports.Disconnected:
|
|
17467
|
+
case connection_status_enum_exports.Connecting:
|
|
17468
|
+
case connection_status_enum_exports.Error:
|
|
17469
|
+
break;
|
|
17470
|
+
default:
|
|
17471
|
+
unreachable(connectionStatus);
|
|
15738
17472
|
}
|
|
15739
17473
|
this.#socketResolver = resolver11();
|
|
15740
17474
|
lc.debug?.("Creating new connect resolver");
|
|
@@ -15749,11 +17483,22 @@ ${error.errorBody.message}`, error);
|
|
|
15749
17483
|
this.#socket = void 0;
|
|
15750
17484
|
this.#lastMutationIDSent = NULL_LAST_MUTATION_ID_SENT;
|
|
15751
17485
|
this.#pokeHandler.handleDisconnect();
|
|
15752
|
-
const
|
|
15753
|
-
|
|
15754
|
-
|
|
15755
|
-
|
|
15756
|
-
|
|
17486
|
+
const transition = getErrorConnectionTransition(reason);
|
|
17487
|
+
switch (transition.status) {
|
|
17488
|
+
case connection_status_enum_exports.Error:
|
|
17489
|
+
this.#connectionManager.error(transition.reason);
|
|
17490
|
+
break;
|
|
17491
|
+
case connection_status_enum_exports.Disconnected:
|
|
17492
|
+
this.#connectionManager.disconnected(transition.reason);
|
|
17493
|
+
break;
|
|
17494
|
+
case connection_status_enum_exports.Closed:
|
|
17495
|
+
this.#connectionManager.closed();
|
|
17496
|
+
break;
|
|
17497
|
+
case NO_STATUS_TRANSITION:
|
|
17498
|
+
this.#connectionManager.connecting(transition.reason);
|
|
17499
|
+
break;
|
|
17500
|
+
default:
|
|
17501
|
+
unreachable(transition);
|
|
15757
17502
|
}
|
|
15758
17503
|
}
|
|
15759
17504
|
#handlePokeStart(_lc, pokeMessage) {
|
|
@@ -15872,7 +17617,7 @@ ${error.errorBody.message}`, error);
|
|
|
15872
17617
|
this.#lc.info?.(`Starting Zero version: ${this.version}`);
|
|
15873
17618
|
if (this.#server === null) {
|
|
15874
17619
|
this.#lc.info?.("No socket origin provided, not starting connect loop.");
|
|
15875
|
-
this.#connectionManager.
|
|
17620
|
+
this.#connectionManager.error(
|
|
15876
17621
|
new ClientError({
|
|
15877
17622
|
kind: client_error_kind_enum_exports.NoSocketOrigin,
|
|
15878
17623
|
message: "No server socket origin provided"
|
|
@@ -15892,22 +17637,29 @@ ${error.errorBody.message}`, error);
|
|
|
15892
17637
|
await this.#updateAuthToken(bareLogContext);
|
|
15893
17638
|
let needsReauth = false;
|
|
15894
17639
|
let lastReauthAttemptAt;
|
|
15895
|
-
let
|
|
15896
|
-
let backoffMs = RUN_LOOP_INTERVAL_MS;
|
|
17640
|
+
let backoffMs;
|
|
15897
17641
|
let additionalConnectParams;
|
|
15898
17642
|
while (this.#connectionManager.shouldContinueRunLoop()) {
|
|
15899
17643
|
runLoopCounter++;
|
|
15900
17644
|
let lc = getLogContext();
|
|
15901
17645
|
backoffMs = RUN_LOOP_INTERVAL_MS;
|
|
15902
17646
|
try {
|
|
15903
|
-
|
|
17647
|
+
const currentState = this.#connectionManager.state;
|
|
17648
|
+
switch (currentState.name) {
|
|
15904
17649
|
case connection_status_enum_exports.Connecting:
|
|
15905
17650
|
case connection_status_enum_exports.Disconnected: {
|
|
15906
17651
|
if (this.#visibilityWatcher.visibilityState === "hidden") {
|
|
15907
17652
|
this.#metrics.setDisconnectedWaitingForVisible();
|
|
15908
17653
|
this.#totalToConnectStart = void 0;
|
|
15909
17654
|
}
|
|
15910
|
-
await
|
|
17655
|
+
const visibilityResult = await promiseRace({
|
|
17656
|
+
visible: this.#visibilityWatcher.waitForVisible(),
|
|
17657
|
+
stateChange: this.#connectionManager.waitForStateChange()
|
|
17658
|
+
});
|
|
17659
|
+
if (visibilityResult.key === "stateChange") {
|
|
17660
|
+
throwIfConnectionError(visibilityResult.result);
|
|
17661
|
+
break;
|
|
17662
|
+
}
|
|
15911
17663
|
if (needsReauth) {
|
|
15912
17664
|
lastReauthAttemptAt = Date.now();
|
|
15913
17665
|
await this.#updateAuthToken(lc, "invalid-token");
|
|
@@ -15917,13 +17669,10 @@ ${error.errorBody.message}`, error);
|
|
|
15917
17669
|
}
|
|
15918
17670
|
await this.#connect(lc, additionalConnectParams);
|
|
15919
17671
|
additionalConnectParams = void 0;
|
|
15920
|
-
|
|
15921
|
-
break;
|
|
15922
|
-
}
|
|
17672
|
+
throwIfConnectionError(this.#connectionManager.state);
|
|
15923
17673
|
assert(this.#socket);
|
|
15924
17674
|
lc = getLogContext();
|
|
15925
17675
|
lc.debug?.("Connected successfully");
|
|
15926
|
-
gotError = false;
|
|
15927
17676
|
needsReauth = false;
|
|
15928
17677
|
this.#setOnline(true);
|
|
15929
17678
|
break;
|
|
@@ -15935,51 +17684,52 @@ ${error.errorBody.message}`, error);
|
|
|
15935
17684
|
PING_INTERVAL_MS,
|
|
15936
17685
|
controller.signal
|
|
15937
17686
|
);
|
|
15938
|
-
|
|
15939
|
-
|
|
15940
|
-
|
|
15941
|
-
|
|
15942
|
-
|
|
15943
|
-
|
|
15944
|
-
|
|
15945
|
-
|
|
15946
|
-
|
|
15947
|
-
]);
|
|
15948
|
-
if (this.closed) {
|
|
15949
|
-
this.#rejectMessageError = void 0;
|
|
15950
|
-
break;
|
|
15951
|
-
}
|
|
15952
|
-
switch (raceResult) {
|
|
15953
|
-
case PING: {
|
|
15954
|
-
const pingResult = await this.#ping(
|
|
15955
|
-
lc,
|
|
15956
|
-
this.#rejectMessageError.promise
|
|
15957
|
-
);
|
|
15958
|
-
if (pingResult === TimedOut) {
|
|
15959
|
-
gotError = true;
|
|
15960
|
-
}
|
|
17687
|
+
const raceResult = await promiseRace({
|
|
17688
|
+
waitForPing: pingTimeoutPromise,
|
|
17689
|
+
waitForPingAborted: pingTimeoutAborted,
|
|
17690
|
+
tabHidden: this.#visibilityWatcher.waitForHidden(),
|
|
17691
|
+
stateChange: this.#connectionManager.waitForStateChange()
|
|
17692
|
+
});
|
|
17693
|
+
switch (raceResult.key) {
|
|
17694
|
+
case "waitForPing": {
|
|
17695
|
+
await this.#ping(lc);
|
|
15961
17696
|
break;
|
|
15962
17697
|
}
|
|
15963
|
-
case
|
|
15964
|
-
|
|
15965
|
-
|
|
15966
|
-
|
|
15967
|
-
|
|
15968
|
-
|
|
15969
|
-
|
|
15970
|
-
);
|
|
17698
|
+
case "waitForPingAborted":
|
|
17699
|
+
break;
|
|
17700
|
+
case "tabHidden": {
|
|
17701
|
+
const hiddenError = new ClientError({
|
|
17702
|
+
kind: client_error_kind_enum_exports.Hidden,
|
|
17703
|
+
message: "Connection closed because tab was hidden"
|
|
17704
|
+
});
|
|
17705
|
+
this.#disconnect(lc, hiddenError);
|
|
15971
17706
|
this.#setOnline(false);
|
|
15972
17707
|
break;
|
|
17708
|
+
}
|
|
17709
|
+
case "stateChange":
|
|
17710
|
+
throwIfConnectionError(raceResult.result);
|
|
17711
|
+
break;
|
|
17712
|
+
default:
|
|
17713
|
+
unreachable(raceResult);
|
|
15973
17714
|
}
|
|
15974
|
-
|
|
17715
|
+
break;
|
|
17716
|
+
}
|
|
17717
|
+
case connection_status_enum_exports.Error: {
|
|
17718
|
+
lc.info?.(
|
|
17719
|
+
`Run loop paused in error state. Call zero.connection.connect() to resume.`,
|
|
17720
|
+
currentState.reason
|
|
17721
|
+
);
|
|
17722
|
+
await this.#connectionManager.waitForStateChange();
|
|
15975
17723
|
break;
|
|
15976
17724
|
}
|
|
15977
17725
|
case connection_status_enum_exports.Closed:
|
|
15978
|
-
this.#rejectMessageError = void 0;
|
|
15979
17726
|
break;
|
|
17727
|
+
default:
|
|
17728
|
+
unreachable(currentState);
|
|
15980
17729
|
}
|
|
15981
17730
|
} catch (ex) {
|
|
15982
|
-
|
|
17731
|
+
const isClientClosedError = isClientError(ex) && ex.kind === client_error_kind_enum_exports.ClientClosed;
|
|
17732
|
+
if (!this.#connectionManager.is(connection_status_enum_exports.Connected) && !isClientClosedError) {
|
|
15983
17733
|
const level = isAuthError(ex) ? "warn" : "error";
|
|
15984
17734
|
const kind = isServerError(ex) ? ex.kind : "Unknown Error";
|
|
15985
17735
|
lc[level]?.("Failed to connect", ex, kind, {
|
|
@@ -15994,38 +17744,56 @@ ${error.errorBody.message}`, error);
|
|
|
15994
17744
|
"exception:",
|
|
15995
17745
|
ex
|
|
15996
17746
|
);
|
|
15997
|
-
|
|
15998
|
-
|
|
15999
|
-
|
|
16000
|
-
|
|
16001
|
-
|
|
16002
|
-
|
|
17747
|
+
const transition = getErrorConnectionTransition(ex);
|
|
17748
|
+
switch (transition.status) {
|
|
17749
|
+
case NO_STATUS_TRANSITION: {
|
|
17750
|
+
const backoffParams = getBackoffParams(transition.reason);
|
|
17751
|
+
if (backoffParams) {
|
|
17752
|
+
if (backoffParams.minBackoffMs !== void 0) {
|
|
17753
|
+
backoffMs = Math.max(backoffMs, backoffParams.minBackoffMs);
|
|
17754
|
+
}
|
|
17755
|
+
if (backoffParams.maxBackoffMs !== void 0) {
|
|
17756
|
+
backoffMs = Math.min(backoffMs, backoffParams.maxBackoffMs);
|
|
17757
|
+
}
|
|
17758
|
+
additionalConnectParams = backoffParams.reconnectParams;
|
|
17759
|
+
}
|
|
17760
|
+
if (isAuthError(transition.reason)) {
|
|
17761
|
+
const now = Date.now();
|
|
17762
|
+
const msSinceLastReauthAttempt = lastReauthAttemptAt === void 0 ? Number.POSITIVE_INFINITY : now - lastReauthAttemptAt;
|
|
17763
|
+
needsReauth = true;
|
|
17764
|
+
if (msSinceLastReauthAttempt > RUN_LOOP_INTERVAL_MS) {
|
|
17765
|
+
continue;
|
|
17766
|
+
}
|
|
17767
|
+
}
|
|
17768
|
+
this.#setOnline(false);
|
|
17769
|
+
lc.debug?.(
|
|
17770
|
+
"Sleeping",
|
|
17771
|
+
backoffMs,
|
|
17772
|
+
"ms before reconnecting due to error, state:",
|
|
17773
|
+
this.#connectionManager.state
|
|
17774
|
+
);
|
|
17775
|
+
await sleep(backoffMs);
|
|
17776
|
+
break;
|
|
16003
17777
|
}
|
|
16004
|
-
|
|
16005
|
-
|
|
16006
|
-
|
|
16007
|
-
|
|
16008
|
-
|
|
16009
|
-
|
|
16010
|
-
|
|
16011
|
-
|
|
17778
|
+
case connection_status_enum_exports.Error: {
|
|
17779
|
+
lc.debug?.("Fatal error encountered, transitioning to error state");
|
|
17780
|
+
this.#setOnline(false);
|
|
17781
|
+
this.#connectionManager.error(transition.reason);
|
|
17782
|
+
break;
|
|
17783
|
+
}
|
|
17784
|
+
case connection_status_enum_exports.Disconnected: {
|
|
17785
|
+
this.#setOnline(false);
|
|
17786
|
+
this.#connectionManager.disconnected(transition.reason);
|
|
17787
|
+
break;
|
|
16012
17788
|
}
|
|
16013
|
-
|
|
16014
|
-
|
|
17789
|
+
case connection_status_enum_exports.Closed: {
|
|
17790
|
+
this.#setOnline(false);
|
|
17791
|
+
break;
|
|
16015
17792
|
}
|
|
16016
|
-
|
|
17793
|
+
default:
|
|
17794
|
+
unreachable(transition);
|
|
16017
17795
|
}
|
|
16018
17796
|
}
|
|
16019
|
-
if (gotError) {
|
|
16020
|
-
this.#setOnline(false);
|
|
16021
|
-
lc.debug?.(
|
|
16022
|
-
"Sleeping",
|
|
16023
|
-
backoffMs,
|
|
16024
|
-
"ms before reconnecting due to error, state:",
|
|
16025
|
-
this.#connectionManager.state
|
|
16026
|
-
);
|
|
16027
|
-
await sleep(backoffMs);
|
|
16028
|
-
}
|
|
16029
17797
|
}
|
|
16030
17798
|
}
|
|
16031
17799
|
async #puller(req, requestID) {
|
|
@@ -16061,17 +17829,18 @@ ${error.errorBody.message}`, error);
|
|
|
16061
17829
|
const pullResponseResolver = resolver11();
|
|
16062
17830
|
this.#pendingPullsByRequestID.set(requestID, pullResponseResolver);
|
|
16063
17831
|
try {
|
|
16064
|
-
const
|
|
16065
|
-
|
|
16066
|
-
|
|
16067
|
-
|
|
16068
|
-
|
|
16069
|
-
|
|
16070
|
-
switch (raceResult) {
|
|
16071
|
-
case TIMEOUT:
|
|
17832
|
+
const raceResult = await promiseRace({
|
|
17833
|
+
timeout: sleep(PULL_TIMEOUT_MS),
|
|
17834
|
+
success: pullResponseResolver.promise
|
|
17835
|
+
});
|
|
17836
|
+
switch (raceResult.key) {
|
|
17837
|
+
case "timeout":
|
|
16072
17838
|
lc.debug?.("Mutation recovery pull timed out");
|
|
16073
|
-
throw new
|
|
16074
|
-
|
|
17839
|
+
throw new ClientError({
|
|
17840
|
+
kind: client_error_kind_enum_exports.PullTimeout,
|
|
17841
|
+
message: "Pull timed out"
|
|
17842
|
+
});
|
|
17843
|
+
case "success": {
|
|
16075
17844
|
lc.debug?.("Returning mutation recovery pull response");
|
|
16076
17845
|
const response = await pullResponseResolver.promise;
|
|
16077
17846
|
return {
|
|
@@ -16087,10 +17856,15 @@ ${error.errorBody.message}`, error);
|
|
|
16087
17856
|
};
|
|
16088
17857
|
}
|
|
16089
17858
|
default:
|
|
16090
|
-
unreachable();
|
|
17859
|
+
unreachable(raceResult);
|
|
16091
17860
|
}
|
|
16092
17861
|
} finally {
|
|
16093
|
-
pullResponseResolver.reject(
|
|
17862
|
+
pullResponseResolver.reject(
|
|
17863
|
+
new ClientError({
|
|
17864
|
+
kind: client_error_kind_enum_exports.PullTimeout,
|
|
17865
|
+
message: "Pull timed out"
|
|
17866
|
+
})
|
|
17867
|
+
);
|
|
16094
17868
|
this.#pendingPullsByRequestID.delete(requestID);
|
|
16095
17869
|
}
|
|
16096
17870
|
}
|
|
@@ -16100,6 +17874,8 @@ ${error.errorBody.message}`, error);
|
|
|
16100
17874
|
/**
|
|
16101
17875
|
* A rough heuristic for whether the client is currently online and
|
|
16102
17876
|
* authenticated.
|
|
17877
|
+
*
|
|
17878
|
+
* @deprecated Use `connection` instead, which provides more detailed connection state.
|
|
16103
17879
|
*/
|
|
16104
17880
|
get online() {
|
|
16105
17881
|
return this.#onlineManager.online;
|
|
@@ -16111,15 +17887,14 @@ ${error.errorBody.message}`, error);
|
|
|
16111
17887
|
*
|
|
16112
17888
|
* @param listener - The listener to subscribe to.
|
|
16113
17889
|
* @returns A function to unsubscribe the listener.
|
|
17890
|
+
*
|
|
17891
|
+
* @deprecated Use `connection` instead, which provides more detailed connection state.
|
|
16114
17892
|
*/
|
|
16115
17893
|
onOnline = (listener) => this.#onlineManager.subscribe(listener);
|
|
16116
17894
|
/**
|
|
16117
17895
|
* Starts a ping and waits for a pong.
|
|
16118
|
-
*
|
|
16119
|
-
* If it takes too long to get a pong we disconnect and this returns
|
|
16120
|
-
* {@linkcode PingResult.TimedOut}.
|
|
16121
17896
|
*/
|
|
16122
|
-
async #ping(lc
|
|
17897
|
+
async #ping(lc) {
|
|
16123
17898
|
lc.debug?.("pinging");
|
|
16124
17899
|
const { promise, resolve } = resolver11();
|
|
16125
17900
|
this.#onPong = resolve;
|
|
@@ -16127,25 +17902,37 @@ ${error.errorBody.message}`, error);
|
|
|
16127
17902
|
const t0 = performance.now();
|
|
16128
17903
|
assert(this.#socket);
|
|
16129
17904
|
send(this.#socket, pingMessage);
|
|
16130
|
-
const
|
|
16131
|
-
promise,
|
|
16132
|
-
sleep(PING_TIMEOUT_MS),
|
|
16133
|
-
|
|
16134
|
-
|
|
17905
|
+
const raceResult = await promiseRace({
|
|
17906
|
+
waitForPong: promise,
|
|
17907
|
+
pingTimeout: sleep(PING_TIMEOUT_MS),
|
|
17908
|
+
stateChange: this.#connectionManager.waitForStateChange()
|
|
17909
|
+
});
|
|
16135
17910
|
const delta = performance.now() - t0;
|
|
16136
|
-
|
|
16137
|
-
|
|
16138
|
-
|
|
16139
|
-
|
|
16140
|
-
|
|
17911
|
+
switch (raceResult.key) {
|
|
17912
|
+
case "waitForPong": {
|
|
17913
|
+
lc.debug?.("ping succeeded in", delta, "ms");
|
|
17914
|
+
return;
|
|
17915
|
+
}
|
|
17916
|
+
case "pingTimeout": {
|
|
17917
|
+
lc.info?.("ping failed in", delta, "ms - disconnecting");
|
|
17918
|
+
const pingTimeoutError = new ClientError({
|
|
16141
17919
|
kind: client_error_kind_enum_exports.PingTimeout,
|
|
16142
|
-
message: "Server ping request
|
|
16143
|
-
})
|
|
16144
|
-
|
|
16145
|
-
|
|
17920
|
+
message: "Server ping request failed"
|
|
17921
|
+
});
|
|
17922
|
+
this.#disconnect(lc, pingTimeoutError);
|
|
17923
|
+
throw pingTimeoutError;
|
|
17924
|
+
}
|
|
17925
|
+
case "stateChange": {
|
|
17926
|
+
lc.debug?.(
|
|
17927
|
+
"ping aborted due to connection state change",
|
|
17928
|
+
raceResult.result
|
|
17929
|
+
);
|
|
17930
|
+
throwIfConnectionError(raceResult.result);
|
|
17931
|
+
break;
|
|
17932
|
+
}
|
|
17933
|
+
default:
|
|
17934
|
+
unreachable(raceResult);
|
|
16146
17935
|
}
|
|
16147
|
-
lc.debug?.("ping succeeded in", delta, "ms");
|
|
16148
|
-
return Success;
|
|
16149
17936
|
}
|
|
16150
17937
|
// Sends a set of metrics to the server. Throws unless the server
|
|
16151
17938
|
// returns 200.
|
|
@@ -16304,9 +18091,6 @@ function addWebSocketIDFromSocketToLogContext({ url }, lc) {
|
|
|
16304
18091
|
function addWebSocketIDToLogContext(wsid, lc) {
|
|
16305
18092
|
return lc.withContext("wsid", wsid);
|
|
16306
18093
|
}
|
|
16307
|
-
function promiseRace(ps) {
|
|
16308
|
-
return Promise.race(ps.map((p, i) => p.then(() => i)));
|
|
16309
|
-
}
|
|
16310
18094
|
function assertValidRunOptions2(_options) {
|
|
16311
18095
|
}
|
|
16312
18096
|
async function makeActiveClientsManager(clientGroupID, clientID, signal, onDelete) {
|
|
@@ -16326,12 +18110,14 @@ export {
|
|
|
16326
18110
|
dropDatabase,
|
|
16327
18111
|
dropAllDatabases,
|
|
16328
18112
|
TransactionClosedError,
|
|
18113
|
+
error_kind_enum_exports,
|
|
18114
|
+
error_origin_enum_exports,
|
|
18115
|
+
error_reason_enum_exports,
|
|
16329
18116
|
transformRequestMessageSchema,
|
|
16330
18117
|
transformResponseMessageSchema,
|
|
16331
|
-
error_kind_enum_exports,
|
|
16332
18118
|
table,
|
|
16333
|
-
|
|
16334
|
-
|
|
18119
|
+
string4 as string,
|
|
18120
|
+
number4 as number,
|
|
16335
18121
|
boolean,
|
|
16336
18122
|
json,
|
|
16337
18123
|
enumeration,
|
|
@@ -16344,7 +18130,10 @@ export {
|
|
|
16344
18130
|
newQuerySymbol,
|
|
16345
18131
|
AbstractQuery,
|
|
16346
18132
|
clientToServer,
|
|
18133
|
+
client_error_kind_enum_exports,
|
|
18134
|
+
connection_status_enum_exports,
|
|
18135
|
+
ClientError,
|
|
16347
18136
|
update_needed_reason_type_enum_exports,
|
|
16348
18137
|
Zero
|
|
16349
18138
|
};
|
|
16350
|
-
//# sourceMappingURL=chunk-
|
|
18139
|
+
//# sourceMappingURL=chunk-AIPM77UE.js.map
|