@rocicorp/zero 0.25.0-canary.0 → 0.25.0-canary.2
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-MXPHMVU7.js → chunk-COKJ5W7V.js} +2527 -540
- package/out/chunk-COKJ5W7V.js.map +7 -0
- package/out/{chunk-4RB4OYLQ.js → chunk-TJFNGO7E.js} +3 -2
- package/out/{chunk-BJ2CGCME.js → chunk-YWU2DZ23.js} +20 -4
- package/out/chunk-YWU2DZ23.js.map +7 -0
- package/out/{lazy-inspector-2SW772W4.js → lazy-inspector-OXIFYSSQ.js} +2 -2
- package/out/react.js +59 -28
- 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/error.d.ts +4 -0
- package/out/shared/src/error.d.ts.map +1 -0
- package/out/shared/src/error.js +70 -0
- package/out/shared/src/error.js.map +1 -0
- 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 +61 -22
- 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 +6 -4
- package/out/zero/src/zero-out.d.ts +3 -0
- package/out/zero/src/zero-out.d.ts.map +1 -0
- package/out/zero/src/zero-out.js +13 -0
- package/out/zero/src/zero-out.js.map +1 -0
- 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 +104 -27
- 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/scripts/decommission.d.ts +50 -0
- package/out/zero-cache/src/scripts/decommission.d.ts.map +1 -0
- package/out/zero-cache/src/scripts/decommission.js +51 -0
- package/out/zero-cache/src/scripts/decommission.js.map +1 -0
- 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 +6 -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 +21 -25
- package/out/zero-cache/src/services/mutagen/pusher.d.ts.map +1 -1
- package/out/zero-cache/src/services/mutagen/pusher.js +78 -60
- 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/drain-coordinator.d.ts +1 -0
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.d.ts.map +1 -1
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.js +5 -0
- package/out/zero-cache/src/services/view-syncer/drain-coordinator.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 +7 -0
- 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 +91 -32
- 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/streams.d.ts +1 -1
- package/out/zero-cache/src/types/streams.d.ts.map +1 -1
- package/out/zero-cache/src/types/streams.js +19 -9
- package/out/zero-cache/src/types/streams.js.map +1 -1
- package/out/zero-cache/src/types/subscription.d.ts +17 -2
- package/out/zero-cache/src/types/subscription.d.ts.map +1 -1
- package/out/zero-cache/src/types/subscription.js +42 -6
- package/out/zero-cache/src/types/subscription.js.map +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 +22 -4
- 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 +82 -14
- package/out/zero-client/src/client/connection-manager.d.ts.map +1 -1
- package/out/zero-client/src/client/connection-status-enum.d.ts +4 -0
- package/out/zero-client/src/client/connection-status-enum.d.ts.map +1 -1
- package/out/zero-client/src/client/connection.d.ts +53 -0
- package/out/zero-client/src/client/connection.d.ts.map +1 -0
- package/out/zero-client/src/client/error.d.ts +51 -24
- 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 +15 -18
- 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 +3 -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 +12 -1
- package/out/zero-client/src/mod.d.ts.map +1 -1
- package/out/zero-client/src/types/query-result.d.ts +23 -0
- package/out/zero-client/src/types/query-result.d.ts.map +1 -0
- package/out/zero-protocol/src/application-error.d.ts +33 -0
- package/out/zero-protocol/src/application-error.d.ts.map +1 -0
- package/out/zero-protocol/src/application-error.js +37 -0
- package/out/zero-protocol/src/application-error.js.map +1 -0
- package/out/zero-protocol/src/custom-queries.d.ts +56 -53
- package/out/zero-protocol/src/custom-queries.d.ts.map +1 -1
- package/out/zero-protocol/src/custom-queries.js +16 -14
- package/out/zero-protocol/src/custom-queries.js.map +1 -1
- package/out/zero-protocol/src/down.d.ts +8 -10
- package/out/zero-protocol/src/down.d.ts.map +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 +181 -1
- package/out/zero-protocol/src/error.d.ts.map +1 -1
- package/out/zero-protocol/src/error.js +71 -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 +6 -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/poke.d.ts +2 -0
- package/out/zero-protocol/src/poke.d.ts.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 +3 -1
- package/out/zero-protocol/src/protocol-version.js.map +1 -1
- package/out/zero-protocol/src/push.d.ts +145 -13
- package/out/zero-protocol/src/push.d.ts.map +1 -1
- package/out/zero-protocol/src/push.js +35 -13
- package/out/zero-protocol/src/push.js.map +1 -1
- package/out/zero-react/src/mod.d.ts +7 -2
- package/out/zero-react/src/mod.d.ts.map +1 -1
- package/out/zero-react/src/use-query.d.ts +1 -21
- package/out/zero-react/src/use-query.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-react/src/zero-provider.d.ts.map +1 -1
- package/out/zero-server/src/mod.d.ts +5 -4
- package/out/zero-server/src/mod.d.ts.map +1 -1
- package/out/zero-server/src/mod.js +5 -4
- package/out/zero-server/src/mod.js.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 +181 -68
- package/out/zero-server/src/process-mutations.js.map +1 -1
- package/out/zero-server/src/queries/process-queries.d.ts +4 -3
- package/out/zero-server/src/queries/process-queries.d.ts.map +1 -1
- package/out/zero-server/src/queries/process-queries.js +85 -19
- package/out/zero-server/src/queries/process-queries.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 +11 -2
- package/out/zero-solid/src/mod.d.ts.map +1 -1
- package/out/zero-solid/src/solid-view.d.ts +3 -23
- package/out/zero-solid/src/solid-view.d.ts.map +1 -1
- package/out/zero-solid/src/use-query.d.ts +1 -1
- package/out/zero-solid/src/use-query.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-solid/src/use-zero.d.ts +1 -0
- package/out/zero-solid/src/use-zero.d.ts.map +1 -1
- package/out/zero.js +15 -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 +15 -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 +125 -0
- package/out/zql/src/planner/planner-connection.d.ts.map +1 -0
- package/out/zql/src/planner/planner-connection.js +257 -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 +148 -0
- package/out/zql/src/planner/planner-debug.d.ts.map +1 -0
- package/out/zql/src/planner/planner-debug.js +176 -0
- package/out/zql/src/planner/planner-debug.js.map +1 -0
- package/out/zql/src/planner/planner-fan-in.d.ts +39 -0
- package/out/zql/src/planner/planner-fan-in.d.ts.map +1 -0
- package/out/zql/src/planner/planner-fan-in.js +167 -0
- package/out/zql/src/planner/planner-fan-in.js.map +1 -0
- package/out/zql/src/planner/planner-fan-out.d.ts +23 -0
- package/out/zql/src/planner/planner-fan-out.d.ts.map +1 -0
- package/out/zql/src/planner/planner-fan-out.js +62 -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 +380 -0
- package/out/zql/src/planner/planner-graph.js.map +1 -0
- package/out/zql/src/planner/planner-join.d.ts +136 -0
- package/out/zql/src/planner/planner-join.d.ts.map +1 -0
- package/out/zql/src/planner/planner-join.js +329 -0
- package/out/zql/src/planner/planner-join.js.map +1 -0
- package/out/zql/src/planner/planner-node.d.ts +48 -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 +17 -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/error.d.ts +4 -0
- package/out/zql/src/query/error.d.ts.map +1 -0
- package/out/zql/src/query/error.js +9 -0
- package/out/zql/src/query/error.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/named.d.ts.map +1 -1
- package/out/zql/src/query/named.js +9 -1
- package/out/zql/src/query/named.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 +6 -4
- 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,58 +1512,102 @@ function rejectIfClosed(tx) {
|
|
|
1511
1512
|
return tx.closed ? Promise.reject(new TransactionClosedError()) : void 0;
|
|
1512
1513
|
}
|
|
1513
1514
|
|
|
1514
|
-
// ../
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
error
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
}
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
)
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1515
|
+
// ../shared/src/error.ts
|
|
1516
|
+
function getErrorMessage(error) {
|
|
1517
|
+
return getErrorMessageInternal(error, /* @__PURE__ */ new Set());
|
|
1518
|
+
}
|
|
1519
|
+
function getErrorMessageInternal(error, seen) {
|
|
1520
|
+
if (typeof error === "string") {
|
|
1521
|
+
return error;
|
|
1522
|
+
}
|
|
1523
|
+
if (typeof error === "object" && error !== null) {
|
|
1524
|
+
if (seen.has(error)) {
|
|
1525
|
+
return "Circular error reference detected while extracting the error message.";
|
|
1526
|
+
}
|
|
1527
|
+
seen.add(error);
|
|
1528
|
+
}
|
|
1529
|
+
if (error instanceof Error) {
|
|
1530
|
+
if (error.message) {
|
|
1531
|
+
return error.message;
|
|
1532
|
+
}
|
|
1533
|
+
if ("cause" in error) {
|
|
1534
|
+
const cause = error.cause;
|
|
1535
|
+
if (cause !== void 0) {
|
|
1536
|
+
const causeMessage = getErrorMessageInternal(cause, seen);
|
|
1537
|
+
if (causeMessage) {
|
|
1538
|
+
return causeMessage;
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") {
|
|
1544
|
+
const message = error.message;
|
|
1545
|
+
if (message) {
|
|
1546
|
+
return message;
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
try {
|
|
1550
|
+
const json2 = jsonSchema.parse(error);
|
|
1551
|
+
return `Parsed message: ${JSON.stringify(json2)}`;
|
|
1552
|
+
} catch (_e) {
|
|
1553
|
+
}
|
|
1554
|
+
return `Unknown error of type ${typeof error} was thrown and the message could not be determined. See cause for details.`;
|
|
1555
|
+
}
|
|
1556
|
+
function getErrorDetails(error) {
|
|
1557
|
+
if (error instanceof Error) {
|
|
1558
|
+
if ("details" in error) {
|
|
1559
|
+
try {
|
|
1560
|
+
return jsonSchema.parse(error?.details);
|
|
1561
|
+
} catch (_e) {
|
|
1562
|
+
}
|
|
1563
|
+
}
|
|
1564
|
+
if (error.name && error.name !== "Error") {
|
|
1565
|
+
return { name: error.name };
|
|
1566
|
+
}
|
|
1567
|
+
return void 0;
|
|
1568
|
+
}
|
|
1569
|
+
if (typeof error === "object" && error !== null && "details" in error) {
|
|
1570
|
+
try {
|
|
1571
|
+
return jsonSchema.parse(error?.details);
|
|
1572
|
+
} catch (_e) {
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
try {
|
|
1576
|
+
return jsonSchema.parse(error);
|
|
1577
|
+
} catch (_e) {
|
|
1578
|
+
}
|
|
1579
|
+
return void 0;
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
// ../zero-protocol/src/application-error.ts
|
|
1583
|
+
var ApplicationError = class extends Error {
|
|
1584
|
+
/**
|
|
1585
|
+
* This maps onto errors for transform and push app-level failures.
|
|
1586
|
+
*/
|
|
1587
|
+
#details;
|
|
1588
|
+
constructor(message, options) {
|
|
1589
|
+
super(message, { cause: options?.cause });
|
|
1590
|
+
this.name = "ApplicationError";
|
|
1591
|
+
this.#details = options?.details ?? void 0;
|
|
1592
|
+
}
|
|
1593
|
+
get details() {
|
|
1594
|
+
return this.#details;
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1597
|
+
function isApplicationError(error) {
|
|
1598
|
+
return error instanceof ApplicationError;
|
|
1599
|
+
}
|
|
1600
|
+
function wrapWithApplicationError(error) {
|
|
1601
|
+
if (isApplicationError(error)) {
|
|
1602
|
+
return error;
|
|
1603
|
+
}
|
|
1604
|
+
const message = getErrorMessage(error);
|
|
1605
|
+
const details = getErrorDetails(error);
|
|
1606
|
+
return new ApplicationError(message, {
|
|
1607
|
+
cause: error,
|
|
1608
|
+
details
|
|
1609
|
+
});
|
|
1610
|
+
}
|
|
1566
1611
|
|
|
1567
1612
|
// ../zero-protocol/src/error-kind-enum.ts
|
|
1568
1613
|
var error_kind_enum_exports = {};
|
|
@@ -1578,10 +1623,12 @@ __export(error_kind_enum_exports, {
|
|
|
1578
1623
|
InvalidPush: () => InvalidPush,
|
|
1579
1624
|
MutationFailed: () => MutationFailed,
|
|
1580
1625
|
MutationRateLimited: () => MutationRateLimited,
|
|
1626
|
+
PushFailed: () => PushFailed,
|
|
1581
1627
|
Rebalance: () => Rebalance,
|
|
1582
1628
|
Rehome: () => Rehome,
|
|
1583
1629
|
SchemaVersionNotSupported: () => SchemaVersionNotSupported,
|
|
1584
1630
|
ServerOverloaded: () => ServerOverloaded,
|
|
1631
|
+
TransformFailed: () => TransformFailed,
|
|
1585
1632
|
Unauthorized: () => Unauthorized,
|
|
1586
1633
|
VersionNotSupported: () => VersionNotSupported
|
|
1587
1634
|
});
|
|
@@ -1593,16 +1640,255 @@ var InvalidConnectionRequestLastMutationID = "InvalidConnectionRequestLastMutati
|
|
|
1593
1640
|
var InvalidConnectionRequestClientDeleted = "InvalidConnectionRequestClientDeleted";
|
|
1594
1641
|
var InvalidMessage = "InvalidMessage";
|
|
1595
1642
|
var InvalidPush = "InvalidPush";
|
|
1643
|
+
var PushFailed = "PushFailed";
|
|
1596
1644
|
var MutationFailed = "MutationFailed";
|
|
1597
1645
|
var MutationRateLimited = "MutationRateLimited";
|
|
1598
1646
|
var Rebalance = "Rebalance";
|
|
1599
1647
|
var Rehome = "Rehome";
|
|
1648
|
+
var TransformFailed = "TransformFailed";
|
|
1600
1649
|
var Unauthorized = "Unauthorized";
|
|
1601
1650
|
var VersionNotSupported = "VersionNotSupported";
|
|
1602
1651
|
var SchemaVersionNotSupported = "SchemaVersionNotSupported";
|
|
1603
1652
|
var ServerOverloaded = "ServerOverloaded";
|
|
1604
1653
|
var Internal = "Internal";
|
|
1605
1654
|
|
|
1655
|
+
// ../zero-protocol/src/error-origin-enum.ts
|
|
1656
|
+
var error_origin_enum_exports = {};
|
|
1657
|
+
__export(error_origin_enum_exports, {
|
|
1658
|
+
Client: () => Client,
|
|
1659
|
+
Server: () => Server,
|
|
1660
|
+
ZeroCache: () => ZeroCache
|
|
1661
|
+
});
|
|
1662
|
+
var Client = "client";
|
|
1663
|
+
var Server = "server";
|
|
1664
|
+
var ZeroCache = "zeroCache";
|
|
1665
|
+
|
|
1666
|
+
// ../zero-protocol/src/error-reason-enum.ts
|
|
1667
|
+
var error_reason_enum_exports = {};
|
|
1668
|
+
__export(error_reason_enum_exports, {
|
|
1669
|
+
Database: () => Database,
|
|
1670
|
+
HTTP: () => HTTP,
|
|
1671
|
+
Internal: () => Internal2,
|
|
1672
|
+
OutOfOrderMutation: () => OutOfOrderMutation,
|
|
1673
|
+
Parse: () => Parse,
|
|
1674
|
+
Timeout: () => Timeout,
|
|
1675
|
+
UnsupportedPushVersion: () => UnsupportedPushVersion
|
|
1676
|
+
});
|
|
1677
|
+
var Database = "database";
|
|
1678
|
+
var Parse = "parse";
|
|
1679
|
+
var OutOfOrderMutation = "oooMutation";
|
|
1680
|
+
var UnsupportedPushVersion = "unsupportedPushVersion";
|
|
1681
|
+
var Internal2 = "internal";
|
|
1682
|
+
var HTTP = "http";
|
|
1683
|
+
var Timeout = "timeout";
|
|
1684
|
+
|
|
1685
|
+
// ../zero-protocol/src/mutation-id.ts
|
|
1686
|
+
var mutationIDSchema = valita_exports.object({
|
|
1687
|
+
id: valita_exports.number(),
|
|
1688
|
+
clientID: valita_exports.string()
|
|
1689
|
+
});
|
|
1690
|
+
|
|
1691
|
+
// ../zero-protocol/src/error.ts
|
|
1692
|
+
var basicErrorKindSchema = literalUnion(
|
|
1693
|
+
error_kind_enum_exports.AuthInvalidated,
|
|
1694
|
+
error_kind_enum_exports.ClientNotFound,
|
|
1695
|
+
error_kind_enum_exports.InvalidConnectionRequest,
|
|
1696
|
+
error_kind_enum_exports.InvalidConnectionRequestBaseCookie,
|
|
1697
|
+
error_kind_enum_exports.InvalidConnectionRequestLastMutationID,
|
|
1698
|
+
error_kind_enum_exports.InvalidConnectionRequestClientDeleted,
|
|
1699
|
+
error_kind_enum_exports.InvalidMessage,
|
|
1700
|
+
error_kind_enum_exports.InvalidPush,
|
|
1701
|
+
error_kind_enum_exports.MutationRateLimited,
|
|
1702
|
+
error_kind_enum_exports.MutationFailed,
|
|
1703
|
+
error_kind_enum_exports.Unauthorized,
|
|
1704
|
+
error_kind_enum_exports.VersionNotSupported,
|
|
1705
|
+
error_kind_enum_exports.SchemaVersionNotSupported,
|
|
1706
|
+
error_kind_enum_exports.Internal
|
|
1707
|
+
);
|
|
1708
|
+
var basicErrorBodySchema = valita_exports.object({
|
|
1709
|
+
kind: basicErrorKindSchema,
|
|
1710
|
+
message: valita_exports.string(),
|
|
1711
|
+
// this is optional for backwards compatibility
|
|
1712
|
+
origin: literalUnion(error_origin_enum_exports.Server, error_origin_enum_exports.ZeroCache).optional()
|
|
1713
|
+
});
|
|
1714
|
+
var backoffErrorKindSchema = literalUnion(
|
|
1715
|
+
error_kind_enum_exports.Rebalance,
|
|
1716
|
+
error_kind_enum_exports.Rehome,
|
|
1717
|
+
error_kind_enum_exports.ServerOverloaded
|
|
1718
|
+
);
|
|
1719
|
+
var backoffBodySchema = valita_exports.object({
|
|
1720
|
+
kind: backoffErrorKindSchema,
|
|
1721
|
+
message: valita_exports.string(),
|
|
1722
|
+
minBackoffMs: valita_exports.number().optional(),
|
|
1723
|
+
maxBackoffMs: valita_exports.number().optional(),
|
|
1724
|
+
// Query parameters to send in the next reconnect. In the event of
|
|
1725
|
+
// a conflict, these will be overridden by the parameters used by
|
|
1726
|
+
// the client; it is the responsibility of the server to avoid
|
|
1727
|
+
// parameter name conflicts.
|
|
1728
|
+
//
|
|
1729
|
+
// The parameters will only be added to the immediately following
|
|
1730
|
+
// reconnect, and not after that.
|
|
1731
|
+
reconnectParams: valita_exports.record(valita_exports.string()).optional(),
|
|
1732
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache).optional()
|
|
1733
|
+
});
|
|
1734
|
+
var pushFailedErrorKindSchema = valita_exports.literal(error_kind_enum_exports.PushFailed);
|
|
1735
|
+
var transformFailedErrorKindSchema = valita_exports.literal(error_kind_enum_exports.TransformFailed);
|
|
1736
|
+
var errorKindSchema = valita_exports.union(
|
|
1737
|
+
basicErrorKindSchema,
|
|
1738
|
+
backoffErrorKindSchema,
|
|
1739
|
+
pushFailedErrorKindSchema,
|
|
1740
|
+
transformFailedErrorKindSchema
|
|
1741
|
+
);
|
|
1742
|
+
var pushFailedBaseSchema = valita_exports.object({
|
|
1743
|
+
kind: pushFailedErrorKindSchema,
|
|
1744
|
+
details: jsonSchema.optional(),
|
|
1745
|
+
/**
|
|
1746
|
+
* The mutationIDs of the mutations that failed to process.
|
|
1747
|
+
* This can be a subset of the mutationIDs in the request.
|
|
1748
|
+
*/
|
|
1749
|
+
mutationIDs: valita_exports.array(mutationIDSchema),
|
|
1750
|
+
message: valita_exports.string()
|
|
1751
|
+
});
|
|
1752
|
+
var pushFailedBodySchema = valita_exports.union(
|
|
1753
|
+
pushFailedBaseSchema.extend({
|
|
1754
|
+
origin: valita_exports.literal(error_origin_enum_exports.Server),
|
|
1755
|
+
reason: literalUnion(
|
|
1756
|
+
error_reason_enum_exports.Database,
|
|
1757
|
+
error_reason_enum_exports.Parse,
|
|
1758
|
+
error_reason_enum_exports.OutOfOrderMutation,
|
|
1759
|
+
error_reason_enum_exports.UnsupportedPushVersion,
|
|
1760
|
+
error_reason_enum_exports.Internal
|
|
1761
|
+
)
|
|
1762
|
+
}),
|
|
1763
|
+
pushFailedBaseSchema.extend({
|
|
1764
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
|
|
1765
|
+
reason: valita_exports.literal(error_reason_enum_exports.HTTP),
|
|
1766
|
+
status: valita_exports.number(),
|
|
1767
|
+
bodyPreview: valita_exports.string().optional()
|
|
1768
|
+
}),
|
|
1769
|
+
pushFailedBaseSchema.extend({
|
|
1770
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
|
|
1771
|
+
reason: literalUnion(
|
|
1772
|
+
error_reason_enum_exports.Timeout,
|
|
1773
|
+
error_reason_enum_exports.Parse,
|
|
1774
|
+
error_reason_enum_exports.Internal
|
|
1775
|
+
)
|
|
1776
|
+
})
|
|
1777
|
+
);
|
|
1778
|
+
var transformFailedBaseSchema = valita_exports.object({
|
|
1779
|
+
kind: transformFailedErrorKindSchema,
|
|
1780
|
+
details: jsonSchema.optional(),
|
|
1781
|
+
/**
|
|
1782
|
+
* The queryIDs of the queries that failed to transform.
|
|
1783
|
+
*/
|
|
1784
|
+
queryIDs: valita_exports.array(valita_exports.string()),
|
|
1785
|
+
message: valita_exports.string()
|
|
1786
|
+
});
|
|
1787
|
+
var transformFailedBodySchema = valita_exports.union(
|
|
1788
|
+
transformFailedBaseSchema.extend({
|
|
1789
|
+
origin: valita_exports.literal(error_origin_enum_exports.Server),
|
|
1790
|
+
reason: literalUnion(
|
|
1791
|
+
error_reason_enum_exports.Database,
|
|
1792
|
+
error_reason_enum_exports.Parse,
|
|
1793
|
+
error_reason_enum_exports.Internal
|
|
1794
|
+
)
|
|
1795
|
+
}),
|
|
1796
|
+
transformFailedBaseSchema.extend({
|
|
1797
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
|
|
1798
|
+
reason: valita_exports.literal(error_reason_enum_exports.HTTP),
|
|
1799
|
+
status: valita_exports.number(),
|
|
1800
|
+
bodyPreview: valita_exports.string().optional()
|
|
1801
|
+
}),
|
|
1802
|
+
transformFailedBaseSchema.extend({
|
|
1803
|
+
origin: valita_exports.literal(error_origin_enum_exports.ZeroCache),
|
|
1804
|
+
reason: literalUnion(
|
|
1805
|
+
error_reason_enum_exports.Timeout,
|
|
1806
|
+
error_reason_enum_exports.Parse,
|
|
1807
|
+
error_reason_enum_exports.Internal
|
|
1808
|
+
)
|
|
1809
|
+
})
|
|
1810
|
+
);
|
|
1811
|
+
var errorBodySchema = valita_exports.union(
|
|
1812
|
+
basicErrorBodySchema,
|
|
1813
|
+
backoffBodySchema,
|
|
1814
|
+
pushFailedBodySchema,
|
|
1815
|
+
transformFailedBodySchema
|
|
1816
|
+
);
|
|
1817
|
+
var errorMessageSchema = valita_exports.tuple([
|
|
1818
|
+
valita_exports.literal("error"),
|
|
1819
|
+
errorBodySchema
|
|
1820
|
+
]);
|
|
1821
|
+
var ProtocolError = class extends Error {
|
|
1822
|
+
errorBody;
|
|
1823
|
+
constructor(errorBody, options) {
|
|
1824
|
+
super(errorBody.message, options);
|
|
1825
|
+
this.name = "ProtocolError";
|
|
1826
|
+
this.errorBody = errorBody;
|
|
1827
|
+
}
|
|
1828
|
+
get kind() {
|
|
1829
|
+
return this.errorBody.kind;
|
|
1830
|
+
}
|
|
1831
|
+
};
|
|
1832
|
+
function isProtocolError(error) {
|
|
1833
|
+
return error instanceof ProtocolError;
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
// ../zero-protocol/src/custom-queries.ts
|
|
1837
|
+
var transformRequestBodySchema = valita_exports.array(
|
|
1838
|
+
valita_exports.object({
|
|
1839
|
+
id: valita_exports.string(),
|
|
1840
|
+
name: valita_exports.string(),
|
|
1841
|
+
args: readonly(valita_exports.array(jsonSchema))
|
|
1842
|
+
})
|
|
1843
|
+
);
|
|
1844
|
+
var transformedQuerySchema = valita_exports.object({
|
|
1845
|
+
id: valita_exports.string(),
|
|
1846
|
+
name: valita_exports.string(),
|
|
1847
|
+
ast: astSchema
|
|
1848
|
+
});
|
|
1849
|
+
var appErroredQuerySchema = valita_exports.object({
|
|
1850
|
+
error: valita_exports.literal("app"),
|
|
1851
|
+
id: valita_exports.string(),
|
|
1852
|
+
name: valita_exports.string(),
|
|
1853
|
+
// optional for backwards compatibility
|
|
1854
|
+
message: valita_exports.string().optional(),
|
|
1855
|
+
details: jsonSchema.optional()
|
|
1856
|
+
});
|
|
1857
|
+
var parseErroredQuerySchema = valita_exports.object({
|
|
1858
|
+
error: valita_exports.literal("parse"),
|
|
1859
|
+
id: valita_exports.string(),
|
|
1860
|
+
name: valita_exports.string(),
|
|
1861
|
+
message: valita_exports.string(),
|
|
1862
|
+
details: jsonSchema.optional()
|
|
1863
|
+
});
|
|
1864
|
+
var erroredQuerySchema = valita_exports.union(
|
|
1865
|
+
appErroredQuerySchema,
|
|
1866
|
+
parseErroredQuerySchema
|
|
1867
|
+
);
|
|
1868
|
+
var transformResponseBodySchema = valita_exports.array(
|
|
1869
|
+
valita_exports.union(transformedQuerySchema, erroredQuerySchema)
|
|
1870
|
+
);
|
|
1871
|
+
var transformRequestMessageSchema = valita_exports.tuple([
|
|
1872
|
+
valita_exports.literal("transform"),
|
|
1873
|
+
transformRequestBodySchema
|
|
1874
|
+
]);
|
|
1875
|
+
var transformErrorMessageSchema = valita_exports.tuple([
|
|
1876
|
+
valita_exports.literal("transformError"),
|
|
1877
|
+
valita_exports.array(erroredQuerySchema)
|
|
1878
|
+
]);
|
|
1879
|
+
var transformFailedMessageSchema = valita_exports.tuple([
|
|
1880
|
+
valita_exports.literal("transformFailed"),
|
|
1881
|
+
transformFailedBodySchema
|
|
1882
|
+
]);
|
|
1883
|
+
var transformOkMessageSchema = valita_exports.tuple([
|
|
1884
|
+
valita_exports.literal("transformed"),
|
|
1885
|
+
transformResponseBodySchema
|
|
1886
|
+
]);
|
|
1887
|
+
var transformResponseMessageSchema = valita_exports.union(
|
|
1888
|
+
transformOkMessageSchema,
|
|
1889
|
+
transformFailedMessageSchema
|
|
1890
|
+
);
|
|
1891
|
+
|
|
1606
1892
|
// ../zero-schema/src/builder/table-builder.ts
|
|
1607
1893
|
function table(name) {
|
|
1608
1894
|
return new TableBuilder({
|
|
@@ -1611,14 +1897,14 @@ function table(name) {
|
|
|
1611
1897
|
primaryKey: []
|
|
1612
1898
|
});
|
|
1613
1899
|
}
|
|
1614
|
-
function
|
|
1900
|
+
function string4() {
|
|
1615
1901
|
return new ColumnBuilder({
|
|
1616
1902
|
type: "string",
|
|
1617
1903
|
optional: false,
|
|
1618
1904
|
customType: null
|
|
1619
1905
|
});
|
|
1620
1906
|
}
|
|
1621
|
-
function
|
|
1907
|
+
function number3() {
|
|
1622
1908
|
return new ColumnBuilder({
|
|
1623
1909
|
type: "number",
|
|
1624
1910
|
optional: false,
|
|
@@ -2172,37 +2458,207 @@ function makeID(row, schema) {
|
|
|
2172
2458
|
return JSON.stringify(schema.primaryKey.map((k) => row[k]));
|
|
2173
2459
|
}
|
|
2174
2460
|
|
|
2175
|
-
// ../zero-client/src/client/
|
|
2176
|
-
var
|
|
2177
|
-
__export(
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2461
|
+
// ../zero-client/src/client/client-error-kind-enum.ts
|
|
2462
|
+
var client_error_kind_enum_exports = {};
|
|
2463
|
+
__export(client_error_kind_enum_exports, {
|
|
2464
|
+
AbruptClose: () => AbruptClose,
|
|
2465
|
+
CleanClose: () => CleanClose,
|
|
2466
|
+
ClientClosed: () => ClientClosed,
|
|
2467
|
+
ConnectTimeout: () => ConnectTimeout,
|
|
2468
|
+
DisconnectTimeout: () => DisconnectTimeout,
|
|
2469
|
+
Hidden: () => Hidden,
|
|
2470
|
+
Internal: () => Internal3,
|
|
2471
|
+
InvalidMessage: () => InvalidMessage2,
|
|
2472
|
+
NoSocketOrigin: () => NoSocketOrigin,
|
|
2473
|
+
PingTimeout: () => PingTimeout,
|
|
2474
|
+
PullTimeout: () => PullTimeout,
|
|
2475
|
+
UnexpectedBaseCookie: () => UnexpectedBaseCookie,
|
|
2476
|
+
UserDisconnect: () => UserDisconnect
|
|
2181
2477
|
});
|
|
2182
|
-
var
|
|
2183
|
-
var
|
|
2184
|
-
var
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2478
|
+
var AbruptClose = "AbruptClose";
|
|
2479
|
+
var CleanClose = "CleanClose";
|
|
2480
|
+
var ClientClosed = "ClientClosed";
|
|
2481
|
+
var ConnectTimeout = "ConnectTimeout";
|
|
2482
|
+
var DisconnectTimeout = "DisconnectTimeout";
|
|
2483
|
+
var UnexpectedBaseCookie = "UnexpectedBaseCookie";
|
|
2484
|
+
var PingTimeout = "PingTimeout";
|
|
2485
|
+
var PullTimeout = "PullTimeout";
|
|
2486
|
+
var Hidden = "Hidden";
|
|
2487
|
+
var NoSocketOrigin = "NoSocketOrigin";
|
|
2488
|
+
var InvalidMessage2 = "InvalidMessage";
|
|
2489
|
+
var UserDisconnect = "UserDisconnect";
|
|
2490
|
+
var Internal3 = "Internal";
|
|
2189
2491
|
|
|
2190
|
-
// ../
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2492
|
+
// ../zero-client/src/client/connection-status-enum.ts
|
|
2493
|
+
var connection_status_enum_exports = {};
|
|
2494
|
+
__export(connection_status_enum_exports, {
|
|
2495
|
+
Closed: () => Closed,
|
|
2496
|
+
Connected: () => Connected,
|
|
2497
|
+
Connecting: () => Connecting,
|
|
2498
|
+
Disconnected: () => Disconnected,
|
|
2499
|
+
Error: () => Error2,
|
|
2500
|
+
NeedsAuth: () => NeedsAuth
|
|
2501
|
+
});
|
|
2502
|
+
var Disconnected = "disconnected";
|
|
2503
|
+
var Connecting = "connecting";
|
|
2504
|
+
var Connected = "connected";
|
|
2505
|
+
var NeedsAuth = "needs-auth";
|
|
2506
|
+
var Error2 = "error";
|
|
2507
|
+
var Closed = "closed";
|
|
2194
2508
|
|
|
2195
|
-
// ../
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2509
|
+
// ../zero-client/src/client/error.ts
|
|
2510
|
+
var ClientError = class extends Error {
|
|
2511
|
+
errorBody;
|
|
2512
|
+
constructor(errorBody, options) {
|
|
2513
|
+
super(errorBody.message, options);
|
|
2514
|
+
this.name = "ClientError";
|
|
2515
|
+
this.errorBody = { ...errorBody, origin: error_origin_enum_exports.Client };
|
|
2516
|
+
}
|
|
2517
|
+
get kind() {
|
|
2518
|
+
return this.errorBody.kind;
|
|
2519
|
+
}
|
|
2520
|
+
};
|
|
2521
|
+
function isServerError(ex) {
|
|
2522
|
+
return isProtocolError(ex) && (ex.errorBody.origin === error_origin_enum_exports.Server || ex.errorBody.origin === error_origin_enum_exports.ZeroCache);
|
|
2523
|
+
}
|
|
2524
|
+
function isAuthError(ex) {
|
|
2525
|
+
if (isServerError(ex)) {
|
|
2526
|
+
if (ex.kind === error_kind_enum_exports.AuthInvalidated || ex.kind === error_kind_enum_exports.Unauthorized) {
|
|
2527
|
+
return true;
|
|
2528
|
+
}
|
|
2529
|
+
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)) {
|
|
2530
|
+
return true;
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
return false;
|
|
2534
|
+
}
|
|
2535
|
+
function getBackoffParams(error) {
|
|
2536
|
+
if (isServerError(error)) {
|
|
2537
|
+
switch (error.errorBody.kind) {
|
|
2538
|
+
case error_kind_enum_exports.Rebalance:
|
|
2539
|
+
case error_kind_enum_exports.Rehome:
|
|
2540
|
+
case error_kind_enum_exports.ServerOverloaded:
|
|
2541
|
+
return error.errorBody;
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
return void 0;
|
|
2545
|
+
}
|
|
2546
|
+
function isClientError(ex) {
|
|
2547
|
+
return ex instanceof ClientError && ex.errorBody.origin === error_origin_enum_exports.Client;
|
|
2548
|
+
}
|
|
2549
|
+
var NO_STATUS_TRANSITION = "NO_STATUS_TRANSITION";
|
|
2550
|
+
function getErrorConnectionTransition(ex) {
|
|
2551
|
+
if (isAuthError(ex)) {
|
|
2552
|
+
return {
|
|
2553
|
+
status: connection_status_enum_exports.NeedsAuth,
|
|
2554
|
+
reason: ex
|
|
2555
|
+
};
|
|
2556
|
+
}
|
|
2557
|
+
if (isClientError(ex)) {
|
|
2558
|
+
switch (ex.kind) {
|
|
2559
|
+
// Connecting errors that should continue in the current state
|
|
2560
|
+
case client_error_kind_enum_exports.AbruptClose:
|
|
2561
|
+
case client_error_kind_enum_exports.CleanClose:
|
|
2562
|
+
case client_error_kind_enum_exports.ConnectTimeout:
|
|
2563
|
+
case client_error_kind_enum_exports.PingTimeout:
|
|
2564
|
+
case client_error_kind_enum_exports.PullTimeout:
|
|
2565
|
+
case client_error_kind_enum_exports.Hidden:
|
|
2566
|
+
case client_error_kind_enum_exports.NoSocketOrigin:
|
|
2567
|
+
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
2568
|
+
// Fatal errors that should transition to error state
|
|
2569
|
+
case client_error_kind_enum_exports.UnexpectedBaseCookie:
|
|
2570
|
+
case client_error_kind_enum_exports.Internal:
|
|
2571
|
+
case client_error_kind_enum_exports.InvalidMessage:
|
|
2572
|
+
case client_error_kind_enum_exports.UserDisconnect:
|
|
2573
|
+
return { status: connection_status_enum_exports.Error, reason: ex };
|
|
2574
|
+
// Disconnected error (this should already result in a disconnected state)
|
|
2575
|
+
case client_error_kind_enum_exports.DisconnectTimeout:
|
|
2576
|
+
return { status: connection_status_enum_exports.Disconnected, reason: ex };
|
|
2577
|
+
// Closed error (this should already result in a closed state)
|
|
2578
|
+
case client_error_kind_enum_exports.ClientClosed:
|
|
2579
|
+
return { status: connection_status_enum_exports.Closed, reason: ex };
|
|
2580
|
+
default:
|
|
2581
|
+
unreachable(ex.kind);
|
|
2582
|
+
}
|
|
2583
|
+
}
|
|
2584
|
+
if (isServerError(ex)) {
|
|
2585
|
+
switch (ex.kind) {
|
|
2586
|
+
// Errors that should transition to error state
|
|
2587
|
+
case error_kind_enum_exports.ClientNotFound:
|
|
2588
|
+
case error_kind_enum_exports.InvalidConnectionRequest:
|
|
2589
|
+
case error_kind_enum_exports.InvalidConnectionRequestBaseCookie:
|
|
2590
|
+
case error_kind_enum_exports.InvalidConnectionRequestLastMutationID:
|
|
2591
|
+
case error_kind_enum_exports.InvalidConnectionRequestClientDeleted:
|
|
2592
|
+
case error_kind_enum_exports.InvalidMessage:
|
|
2593
|
+
case error_kind_enum_exports.InvalidPush:
|
|
2594
|
+
case error_kind_enum_exports.VersionNotSupported:
|
|
2595
|
+
case error_kind_enum_exports.SchemaVersionNotSupported:
|
|
2596
|
+
case error_kind_enum_exports.Internal:
|
|
2597
|
+
// PushFailed and TransformFailed can be auth errors (401/403)
|
|
2598
|
+
// or other errors - handle non-auth cases here
|
|
2599
|
+
case error_kind_enum_exports.PushFailed:
|
|
2600
|
+
case error_kind_enum_exports.TransformFailed:
|
|
2601
|
+
return { status: connection_status_enum_exports.Error, reason: ex };
|
|
2602
|
+
// Errors that should continue with backoff/retry
|
|
2603
|
+
case error_kind_enum_exports.Rebalance:
|
|
2604
|
+
case error_kind_enum_exports.Rehome:
|
|
2605
|
+
case error_kind_enum_exports.ServerOverloaded:
|
|
2606
|
+
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
2607
|
+
// Auth errors are handled above by isAuthError check
|
|
2608
|
+
case error_kind_enum_exports.AuthInvalidated:
|
|
2609
|
+
case error_kind_enum_exports.Unauthorized:
|
|
2610
|
+
return {
|
|
2611
|
+
status: connection_status_enum_exports.NeedsAuth,
|
|
2612
|
+
reason: ex
|
|
2613
|
+
};
|
|
2614
|
+
// Mutation-specific errors don't affect connection state
|
|
2615
|
+
case error_kind_enum_exports.MutationRateLimited:
|
|
2616
|
+
case error_kind_enum_exports.MutationFailed:
|
|
2617
|
+
return { status: NO_STATUS_TRANSITION, reason: ex };
|
|
2618
|
+
default:
|
|
2619
|
+
unreachable(ex.kind);
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2622
|
+
return {
|
|
2623
|
+
status: connection_status_enum_exports.Error,
|
|
2624
|
+
reason: new ClientError({
|
|
2625
|
+
kind: client_error_kind_enum_exports.Internal,
|
|
2626
|
+
message: "Unexpected internal error: " + (ex instanceof Error ? ex.message : typeof ex === "string" ? ex : String(ex ?? "Unknown error"))
|
|
2627
|
+
})
|
|
2628
|
+
};
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
// ../zero-client/src/client/update-needed-reason-type-enum.ts
|
|
2632
|
+
var update_needed_reason_type_enum_exports = {};
|
|
2633
|
+
__export(update_needed_reason_type_enum_exports, {
|
|
2634
|
+
NewClientGroup: () => NewClientGroup,
|
|
2635
|
+
SchemaVersionNotSupported: () => SchemaVersionNotSupported2,
|
|
2636
|
+
VersionNotSupported: () => VersionNotSupported2
|
|
2637
|
+
});
|
|
2638
|
+
var NewClientGroup = "NewClientGroup";
|
|
2639
|
+
var VersionNotSupported2 = "VersionNotSupported";
|
|
2640
|
+
var SchemaVersionNotSupported2 = "SchemaVersionNotSupported";
|
|
2641
|
+
|
|
2642
|
+
// ../zero-client/src/client/zero.ts
|
|
2643
|
+
import "@rocicorp/logger";
|
|
2644
|
+
import { resolver as resolver11 } from "@rocicorp/resolver";
|
|
2645
|
+
|
|
2646
|
+
// ../replicache/src/replicache-impl.ts
|
|
2647
|
+
import { Lock } from "@rocicorp/lock";
|
|
2648
|
+
import { consoleLogSink as consoleLogSink2 } from "@rocicorp/logger";
|
|
2649
|
+
import { resolver as resolver6 } from "@rocicorp/resolver";
|
|
2650
|
+
|
|
2651
|
+
// ../shared/src/document-visible.ts
|
|
2652
|
+
import { resolver as resolver3 } from "@rocicorp/resolver";
|
|
2653
|
+
function getDocumentVisibilityWatcher(doc, hiddenIntervalMS, signal) {
|
|
2654
|
+
return doc ? new DocumentVisibilityWatcherImpl(doc, hiddenIntervalMS, signal) : new DocumentVisibilityWatcherNoDoc();
|
|
2655
|
+
}
|
|
2656
|
+
var DocumentVisibilityWatcherImpl = class {
|
|
2657
|
+
#doc;
|
|
2658
|
+
#hiddenIntervalMS;
|
|
2659
|
+
#timeoutID = 0;
|
|
2660
|
+
// This trails doc.visibilityState by hiddenIntervalMS when being hidden. This
|
|
2661
|
+
// is because we want to wait for the tab to be hidden for a while before
|
|
2206
2662
|
// considering as hidden.
|
|
2207
2663
|
visibilityState;
|
|
2208
2664
|
#promises = /* @__PURE__ */ new Set();
|
|
@@ -6283,6 +6739,24 @@ function validateOptions(options) {
|
|
|
6283
6739
|
}
|
|
6284
6740
|
}
|
|
6285
6741
|
|
|
6742
|
+
// ../shared/src/promise-race.ts
|
|
6743
|
+
var NO_PROMISES_MESSAGE = "No promises to race";
|
|
6744
|
+
var wrapPromise = (key, promise) => Promise.resolve(promise).then((result) => ({
|
|
6745
|
+
key,
|
|
6746
|
+
status: "fulfilled",
|
|
6747
|
+
result
|
|
6748
|
+
}));
|
|
6749
|
+
async function promiseRace(promises) {
|
|
6750
|
+
const keys = Object.keys(promises);
|
|
6751
|
+
if (keys.length === 0) {
|
|
6752
|
+
throw new Error(NO_PROMISES_MESSAGE);
|
|
6753
|
+
}
|
|
6754
|
+
const wrapped = keys.map(
|
|
6755
|
+
(key) => wrapPromise(key, promises[key])
|
|
6756
|
+
);
|
|
6757
|
+
return await Promise.race(wrapped);
|
|
6758
|
+
}
|
|
6759
|
+
|
|
6286
6760
|
// ../shared/src/sentinels.ts
|
|
6287
6761
|
function emptyFunction() {
|
|
6288
6762
|
}
|
|
@@ -6292,38 +6766,6 @@ function identity(x) {
|
|
|
6292
6766
|
return x;
|
|
6293
6767
|
}
|
|
6294
6768
|
|
|
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
6769
|
// ../zero-protocol/src/delete-clients.ts
|
|
6328
6770
|
var deleteClientsBodySchema = valita_exports.union(
|
|
6329
6771
|
readonlyObject({
|
|
@@ -6401,56 +6843,6 @@ function encodeSecProtocols(initConnectionMessage, authToken) {
|
|
|
6401
6843
|
return encodeURIComponent(btoa(s));
|
|
6402
6844
|
}
|
|
6403
6845
|
|
|
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
6846
|
// ../zero-protocol/src/mutation-type-enum.ts
|
|
6455
6847
|
var CRUD = "crud";
|
|
6456
6848
|
var Custom = "custom";
|
|
@@ -6522,24 +6914,25 @@ var pushBodySchema = valita_exports.object({
|
|
|
6522
6914
|
requestID: valita_exports.string()
|
|
6523
6915
|
});
|
|
6524
6916
|
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
6917
|
var appErrorSchema = valita_exports.object({
|
|
6530
6918
|
error: valita_exports.literal("app"),
|
|
6531
6919
|
// The user can return any additional data here
|
|
6920
|
+
message: valita_exports.string().optional(),
|
|
6532
6921
|
details: jsonSchema.optional()
|
|
6533
6922
|
});
|
|
6534
|
-
var
|
|
6535
|
-
error:
|
|
6923
|
+
var zeroErrorSchema = valita_exports.object({
|
|
6924
|
+
error: valita_exports.union(
|
|
6925
|
+
/** @deprecated push oooMutation errors are now represented as ['error', { ... }] messages */
|
|
6926
|
+
valita_exports.literal("oooMutation"),
|
|
6927
|
+
valita_exports.literal("alreadyProcessed")
|
|
6928
|
+
),
|
|
6536
6929
|
details: jsonSchema.optional()
|
|
6537
6930
|
});
|
|
6538
6931
|
var mutationOkSchema = valita_exports.object({
|
|
6539
6932
|
// The user can return any additional data here
|
|
6540
6933
|
data: jsonSchema.optional()
|
|
6541
6934
|
});
|
|
6542
|
-
var mutationErrorSchema = valita_exports.union(appErrorSchema,
|
|
6935
|
+
var mutationErrorSchema = valita_exports.union(appErrorSchema, zeroErrorSchema);
|
|
6543
6936
|
var mutationResultSchema = valita_exports.union(
|
|
6544
6937
|
mutationOkSchema,
|
|
6545
6938
|
mutationErrorSchema
|
|
@@ -6552,28 +6945,33 @@ var pushOkSchema = valita_exports.object({
|
|
|
6552
6945
|
mutations: valita_exports.array(mutationResponseSchema)
|
|
6553
6946
|
});
|
|
6554
6947
|
var unsupportedPushVersionSchema = valita_exports.object({
|
|
6948
|
+
/** @deprecated */
|
|
6555
6949
|
error: valita_exports.literal("unsupportedPushVersion"),
|
|
6556
|
-
|
|
6557
|
-
// This field is included so the client knows which mutations
|
|
6558
|
-
// were not processed by the server.
|
|
6950
|
+
/** @deprecated */
|
|
6559
6951
|
mutationIDs: valita_exports.array(mutationIDSchema).optional()
|
|
6560
6952
|
});
|
|
6561
6953
|
var unsupportedSchemaVersionSchema = valita_exports.object({
|
|
6954
|
+
/** @deprecated */
|
|
6562
6955
|
error: valita_exports.literal("unsupportedSchemaVersion"),
|
|
6563
|
-
|
|
6564
|
-
// This field is included so the client knows which mutations
|
|
6565
|
-
// were not processed by the server.
|
|
6956
|
+
/** @deprecated */
|
|
6566
6957
|
mutationIDs: valita_exports.array(mutationIDSchema).optional()
|
|
6567
6958
|
});
|
|
6568
6959
|
var httpErrorSchema = valita_exports.object({
|
|
6960
|
+
/** @deprecated */
|
|
6569
6961
|
error: valita_exports.literal("http"),
|
|
6962
|
+
/** @deprecated */
|
|
6570
6963
|
status: valita_exports.number(),
|
|
6964
|
+
/** @deprecated */
|
|
6571
6965
|
details: valita_exports.string(),
|
|
6966
|
+
/** @deprecated */
|
|
6572
6967
|
mutationIDs: valita_exports.array(mutationIDSchema).optional()
|
|
6573
6968
|
});
|
|
6574
6969
|
var zeroPusherErrorSchema = valita_exports.object({
|
|
6970
|
+
/** @deprecated */
|
|
6575
6971
|
error: valita_exports.literal("zeroPusher"),
|
|
6972
|
+
/** @deprecated */
|
|
6576
6973
|
details: valita_exports.string(),
|
|
6974
|
+
/** @deprecated */
|
|
6577
6975
|
mutationIDs: valita_exports.array(mutationIDSchema).optional()
|
|
6578
6976
|
});
|
|
6579
6977
|
var pushErrorSchema = valita_exports.union(
|
|
@@ -6582,10 +6980,14 @@ var pushErrorSchema = valita_exports.union(
|
|
|
6582
6980
|
httpErrorSchema,
|
|
6583
6981
|
zeroPusherErrorSchema
|
|
6584
6982
|
);
|
|
6585
|
-
var
|
|
6983
|
+
var pushResponseBodySchema = valita_exports.union(pushOkSchema, pushErrorSchema);
|
|
6984
|
+
var pushResponseSchema = valita_exports.union(
|
|
6985
|
+
pushResponseBodySchema,
|
|
6986
|
+
pushFailedBodySchema
|
|
6987
|
+
);
|
|
6586
6988
|
var pushResponseMessageSchema = valita_exports.tuple([
|
|
6587
6989
|
valita_exports.literal("pushResponse"),
|
|
6588
|
-
|
|
6990
|
+
pushResponseBodySchema
|
|
6589
6991
|
]);
|
|
6590
6992
|
var ackMutationResponsesMessageSchema = valita_exports.tuple([
|
|
6591
6993
|
valita_exports.literal("ackMutationResponses"),
|
|
@@ -6750,7 +7152,7 @@ var downstreamSchema = valita_exports.union(
|
|
|
6750
7152
|
);
|
|
6751
7153
|
|
|
6752
7154
|
// ../zero-protocol/src/protocol-version.ts
|
|
6753
|
-
var PROTOCOL_VERSION =
|
|
7155
|
+
var PROTOCOL_VERSION = 39;
|
|
6754
7156
|
var MIN_SERVER_SUPPORTED_SYNC_PROTOCOL = 18;
|
|
6755
7157
|
assert(MIN_SERVER_SUPPORTED_SYNC_PROTOCOL < PROTOCOL_VERSION);
|
|
6756
7158
|
|
|
@@ -9227,80 +9629,1385 @@ var UnionFanIn = class {
|
|
|
9227
9629
|
return;
|
|
9228
9630
|
}
|
|
9229
9631
|
}
|
|
9230
|
-
assert(hadMatch, "Pusher was not one of the inputs to union-fan-in!");
|
|
9231
|
-
this.#output.push(change, this);
|
|
9632
|
+
assert(hadMatch, "Pusher was not one of the inputs to union-fan-in!");
|
|
9633
|
+
this.#output.push(change, this);
|
|
9634
|
+
}
|
|
9635
|
+
fanOutStartedPushing() {
|
|
9636
|
+
assert(this.#fanOutPushStarted === false);
|
|
9637
|
+
this.#fanOutPushStarted = true;
|
|
9638
|
+
}
|
|
9639
|
+
fanOutDonePushing(fanOutChangeType) {
|
|
9640
|
+
assert(this.#fanOutPushStarted);
|
|
9641
|
+
this.#fanOutPushStarted = false;
|
|
9642
|
+
if (this.#inputs.length === 0) {
|
|
9643
|
+
return;
|
|
9644
|
+
}
|
|
9645
|
+
if (this.#accumulatedPushes.length === 0) {
|
|
9646
|
+
return;
|
|
9647
|
+
}
|
|
9648
|
+
pushAccumulatedChanges(
|
|
9649
|
+
this.#accumulatedPushes,
|
|
9650
|
+
this.#output,
|
|
9651
|
+
this,
|
|
9652
|
+
fanOutChangeType,
|
|
9653
|
+
mergeRelationships,
|
|
9654
|
+
makeAddEmptyRelationships(this.#schema)
|
|
9655
|
+
);
|
|
9656
|
+
}
|
|
9657
|
+
setOutput(output) {
|
|
9658
|
+
this.#output = output;
|
|
9659
|
+
}
|
|
9660
|
+
};
|
|
9661
|
+
|
|
9662
|
+
// ../zql/src/ivm/union-fan-out.ts
|
|
9663
|
+
var UnionFanOut = class {
|
|
9664
|
+
#destroyCount = 0;
|
|
9665
|
+
#unionFanIn;
|
|
9666
|
+
#input;
|
|
9667
|
+
#outputs = [];
|
|
9668
|
+
constructor(input) {
|
|
9669
|
+
this.#input = input;
|
|
9670
|
+
input.setOutput(this);
|
|
9671
|
+
}
|
|
9672
|
+
setFanIn(fanIn) {
|
|
9673
|
+
assert(!this.#unionFanIn, "FanIn already set for this FanOut");
|
|
9674
|
+
this.#unionFanIn = fanIn;
|
|
9675
|
+
}
|
|
9676
|
+
push(change) {
|
|
9677
|
+
must(this.#unionFanIn).fanOutStartedPushing();
|
|
9678
|
+
for (const output of this.#outputs) {
|
|
9679
|
+
output.push(change, this);
|
|
9680
|
+
}
|
|
9681
|
+
must(this.#unionFanIn).fanOutDonePushing(change.type);
|
|
9682
|
+
}
|
|
9683
|
+
setOutput(output) {
|
|
9684
|
+
this.#outputs.push(output);
|
|
9685
|
+
}
|
|
9686
|
+
getSchema() {
|
|
9687
|
+
return this.#input.getSchema();
|
|
9688
|
+
}
|
|
9689
|
+
fetch(req) {
|
|
9690
|
+
return this.#input.fetch(req);
|
|
9691
|
+
}
|
|
9692
|
+
cleanup(_req) {
|
|
9693
|
+
return [];
|
|
9694
|
+
}
|
|
9695
|
+
destroy() {
|
|
9696
|
+
if (this.#destroyCount < this.#outputs.length) {
|
|
9697
|
+
++this.#destroyCount;
|
|
9698
|
+
if (this.#destroyCount === this.#outputs.length) {
|
|
9699
|
+
this.#input.destroy();
|
|
9700
|
+
}
|
|
9701
|
+
} else {
|
|
9702
|
+
throw new Error("FanOut already destroyed once for each output");
|
|
9703
|
+
}
|
|
9704
|
+
}
|
|
9705
|
+
};
|
|
9706
|
+
|
|
9707
|
+
// ../zql/src/planner/planner-fan-in.ts
|
|
9708
|
+
var PlannerFanIn = class {
|
|
9709
|
+
kind = "fan-in";
|
|
9710
|
+
#type;
|
|
9711
|
+
#output;
|
|
9712
|
+
#inputs;
|
|
9713
|
+
constructor(inputs) {
|
|
9714
|
+
this.#type = "FI";
|
|
9715
|
+
this.#inputs = inputs;
|
|
9716
|
+
}
|
|
9717
|
+
get type() {
|
|
9718
|
+
return this.#type;
|
|
9719
|
+
}
|
|
9720
|
+
closestJoinOrSource() {
|
|
9721
|
+
return "join";
|
|
9722
|
+
}
|
|
9723
|
+
setOutput(node) {
|
|
9724
|
+
this.#output = node;
|
|
9725
|
+
}
|
|
9726
|
+
get output() {
|
|
9727
|
+
assert(this.#output !== void 0, "Output not set");
|
|
9728
|
+
return this.#output;
|
|
9729
|
+
}
|
|
9730
|
+
reset() {
|
|
9731
|
+
this.#type = "FI";
|
|
9732
|
+
}
|
|
9733
|
+
convertToUFI() {
|
|
9734
|
+
this.#type = "UFI";
|
|
9735
|
+
}
|
|
9736
|
+
/**
|
|
9737
|
+
* Propagate unlimiting when a parent join is flipped.
|
|
9738
|
+
* Fan-in propagates to all of its inputs.
|
|
9739
|
+
*/
|
|
9740
|
+
propagateUnlimitFromFlippedJoin() {
|
|
9741
|
+
for (const input of this.#inputs) {
|
|
9742
|
+
if ("propagateUnlimitFromFlippedJoin" in input && typeof input.propagateUnlimitFromFlippedJoin === "function") {
|
|
9743
|
+
input.propagateUnlimitFromFlippedJoin();
|
|
9744
|
+
}
|
|
9745
|
+
}
|
|
9746
|
+
}
|
|
9747
|
+
estimateCost(downstreamChildSelectivity, branchPattern, planDebugger) {
|
|
9748
|
+
let totalCost = {
|
|
9749
|
+
returnedRows: 0,
|
|
9750
|
+
cost: 0,
|
|
9751
|
+
scanEst: 0,
|
|
9752
|
+
startupCost: 0,
|
|
9753
|
+
selectivity: 0,
|
|
9754
|
+
limit: void 0
|
|
9755
|
+
};
|
|
9756
|
+
if (this.#type === "FI") {
|
|
9757
|
+
const updatedPattern = [0, ...branchPattern];
|
|
9758
|
+
let maxrows = 0;
|
|
9759
|
+
let maxRunningCost = 0;
|
|
9760
|
+
let maxStartupCost = 0;
|
|
9761
|
+
let maxScanEst = 0;
|
|
9762
|
+
let noMatchProb = 1;
|
|
9763
|
+
for (const input of this.#inputs) {
|
|
9764
|
+
const cost = input.estimateCost(
|
|
9765
|
+
downstreamChildSelectivity,
|
|
9766
|
+
updatedPattern,
|
|
9767
|
+
planDebugger
|
|
9768
|
+
);
|
|
9769
|
+
if (cost.returnedRows > maxrows) {
|
|
9770
|
+
maxrows = cost.returnedRows;
|
|
9771
|
+
}
|
|
9772
|
+
if (cost.cost > maxRunningCost) {
|
|
9773
|
+
maxRunningCost = cost.cost;
|
|
9774
|
+
}
|
|
9775
|
+
if (cost.startupCost > maxStartupCost) {
|
|
9776
|
+
maxStartupCost = cost.startupCost;
|
|
9777
|
+
}
|
|
9778
|
+
if (cost.scanEst > maxScanEst) {
|
|
9779
|
+
maxScanEst = cost.scanEst;
|
|
9780
|
+
}
|
|
9781
|
+
noMatchProb *= 1 - cost.selectivity;
|
|
9782
|
+
assert(
|
|
9783
|
+
totalCost.limit === void 0 || cost.limit === totalCost.limit,
|
|
9784
|
+
"All FanIn inputs should have the same limit"
|
|
9785
|
+
);
|
|
9786
|
+
totalCost.limit = cost.limit;
|
|
9787
|
+
}
|
|
9788
|
+
totalCost.returnedRows = maxrows;
|
|
9789
|
+
totalCost.cost = maxRunningCost;
|
|
9790
|
+
totalCost.selectivity = 1 - noMatchProb;
|
|
9791
|
+
totalCost.startupCost = maxStartupCost;
|
|
9792
|
+
totalCost.scanEst = maxScanEst;
|
|
9793
|
+
} else {
|
|
9794
|
+
let i = 0;
|
|
9795
|
+
let noMatchProb = 1;
|
|
9796
|
+
for (const input of this.#inputs) {
|
|
9797
|
+
const updatedPattern = [i, ...branchPattern];
|
|
9798
|
+
const cost = input.estimateCost(
|
|
9799
|
+
downstreamChildSelectivity,
|
|
9800
|
+
updatedPattern,
|
|
9801
|
+
planDebugger
|
|
9802
|
+
);
|
|
9803
|
+
totalCost.returnedRows += cost.returnedRows;
|
|
9804
|
+
totalCost.cost += cost.cost;
|
|
9805
|
+
totalCost.scanEst += cost.scanEst;
|
|
9806
|
+
totalCost.startupCost = totalCost.startupCost + cost.startupCost;
|
|
9807
|
+
noMatchProb *= 1 - cost.selectivity;
|
|
9808
|
+
assert(
|
|
9809
|
+
totalCost.limit === void 0 || cost.limit === totalCost.limit,
|
|
9810
|
+
"All FanIn inputs should have the same limit"
|
|
9811
|
+
);
|
|
9812
|
+
totalCost.limit = cost.limit;
|
|
9813
|
+
i++;
|
|
9814
|
+
}
|
|
9815
|
+
totalCost.selectivity = 1 - noMatchProb;
|
|
9816
|
+
}
|
|
9817
|
+
planDebugger?.log({
|
|
9818
|
+
type: "node-cost",
|
|
9819
|
+
nodeType: "fan-in",
|
|
9820
|
+
node: this.#type,
|
|
9821
|
+
branchPattern,
|
|
9822
|
+
downstreamChildSelectivity,
|
|
9823
|
+
costEstimate: totalCost
|
|
9824
|
+
});
|
|
9825
|
+
return totalCost;
|
|
9826
|
+
}
|
|
9827
|
+
propagateConstraints(branchPattern, constraint, from, planDebugger) {
|
|
9828
|
+
planDebugger?.log({
|
|
9829
|
+
type: "node-constraint",
|
|
9830
|
+
nodeType: "fan-in",
|
|
9831
|
+
node: this.#type,
|
|
9832
|
+
branchPattern,
|
|
9833
|
+
constraint,
|
|
9834
|
+
from: from?.kind ?? "unknown"
|
|
9835
|
+
});
|
|
9836
|
+
if (this.#type === "FI") {
|
|
9837
|
+
const updatedPattern = [0, ...branchPattern];
|
|
9838
|
+
for (const input of this.#inputs) {
|
|
9839
|
+
input.propagateConstraints(
|
|
9840
|
+
updatedPattern,
|
|
9841
|
+
constraint,
|
|
9842
|
+
this,
|
|
9843
|
+
planDebugger
|
|
9844
|
+
);
|
|
9845
|
+
}
|
|
9846
|
+
return;
|
|
9847
|
+
}
|
|
9848
|
+
let i = 0;
|
|
9849
|
+
for (const input of this.#inputs) {
|
|
9850
|
+
input.propagateConstraints(
|
|
9851
|
+
[i, ...branchPattern],
|
|
9852
|
+
constraint,
|
|
9853
|
+
this,
|
|
9854
|
+
planDebugger
|
|
9855
|
+
);
|
|
9856
|
+
i++;
|
|
9857
|
+
}
|
|
9858
|
+
}
|
|
9859
|
+
};
|
|
9860
|
+
|
|
9861
|
+
// ../zql/src/planner/planner-fan-out.ts
|
|
9862
|
+
var PlannerFanOut = class {
|
|
9863
|
+
kind = "fan-out";
|
|
9864
|
+
#type;
|
|
9865
|
+
#outputs = [];
|
|
9866
|
+
#input;
|
|
9867
|
+
constructor(input) {
|
|
9868
|
+
this.#type = "FO";
|
|
9869
|
+
this.#input = input;
|
|
9870
|
+
}
|
|
9871
|
+
get type() {
|
|
9872
|
+
return this.#type;
|
|
9873
|
+
}
|
|
9874
|
+
addOutput(node) {
|
|
9875
|
+
this.#outputs.push(node);
|
|
9876
|
+
}
|
|
9877
|
+
get outputs() {
|
|
9878
|
+
return this.#outputs;
|
|
9879
|
+
}
|
|
9880
|
+
closestJoinOrSource() {
|
|
9881
|
+
return this.#input.closestJoinOrSource();
|
|
9882
|
+
}
|
|
9883
|
+
propagateConstraints(branchPattern, constraint, from, planDebugger) {
|
|
9884
|
+
planDebugger?.log({
|
|
9885
|
+
type: "node-constraint",
|
|
9886
|
+
nodeType: "fan-out",
|
|
9887
|
+
node: "FO",
|
|
9888
|
+
branchPattern,
|
|
9889
|
+
constraint,
|
|
9890
|
+
from: from?.kind ?? "unknown"
|
|
9891
|
+
});
|
|
9892
|
+
this.#input.propagateConstraints(
|
|
9893
|
+
branchPattern,
|
|
9894
|
+
constraint,
|
|
9895
|
+
this,
|
|
9896
|
+
planDebugger
|
|
9897
|
+
);
|
|
9898
|
+
}
|
|
9899
|
+
estimateCost(downstreamChildSelectivity, branchPattern, planDebugger) {
|
|
9900
|
+
const ret = this.#input.estimateCost(
|
|
9901
|
+
downstreamChildSelectivity,
|
|
9902
|
+
branchPattern,
|
|
9903
|
+
planDebugger
|
|
9904
|
+
);
|
|
9905
|
+
planDebugger?.log({
|
|
9906
|
+
type: "node-cost",
|
|
9907
|
+
nodeType: "fan-out",
|
|
9908
|
+
node: "FO",
|
|
9909
|
+
branchPattern,
|
|
9910
|
+
downstreamChildSelectivity,
|
|
9911
|
+
costEstimate: ret
|
|
9912
|
+
});
|
|
9913
|
+
return ret;
|
|
9914
|
+
}
|
|
9915
|
+
convertToUFO() {
|
|
9916
|
+
this.#type = "UFO";
|
|
9917
|
+
}
|
|
9918
|
+
reset() {
|
|
9919
|
+
this.#type = "FO";
|
|
9920
|
+
}
|
|
9921
|
+
/**
|
|
9922
|
+
* Propagate unlimiting when a parent join is flipped.
|
|
9923
|
+
* Fan-out propagates to its input.
|
|
9924
|
+
*/
|
|
9925
|
+
propagateUnlimitFromFlippedJoin() {
|
|
9926
|
+
if ("propagateUnlimitFromFlippedJoin" in this.#input && typeof this.#input.propagateUnlimitFromFlippedJoin === "function") {
|
|
9927
|
+
this.#input.propagateUnlimitFromFlippedJoin();
|
|
9928
|
+
}
|
|
9929
|
+
}
|
|
9930
|
+
};
|
|
9931
|
+
|
|
9932
|
+
// ../zql/src/planner/planner-constraint.ts
|
|
9933
|
+
function mergeConstraints(a, b) {
|
|
9934
|
+
if (!a) return b;
|
|
9935
|
+
if (!b) return a;
|
|
9936
|
+
return { ...a, ...b };
|
|
9937
|
+
}
|
|
9938
|
+
|
|
9939
|
+
// ../zql/src/planner/planner-connection.ts
|
|
9940
|
+
var PlannerConnection = class {
|
|
9941
|
+
kind = "connection";
|
|
9942
|
+
// ========================================================================
|
|
9943
|
+
// IMMUTABLE STRUCTURE (set during construction, never changes)
|
|
9944
|
+
// ========================================================================
|
|
9945
|
+
#sort;
|
|
9946
|
+
#filters;
|
|
9947
|
+
#model;
|
|
9948
|
+
table;
|
|
9949
|
+
name;
|
|
9950
|
+
// Human-readable name for debugging (defaults to table name)
|
|
9951
|
+
#baseConstraints;
|
|
9952
|
+
// Constraints from parent correlation
|
|
9953
|
+
#baseLimit;
|
|
9954
|
+
// Original limit from query structure (never modified)
|
|
9955
|
+
selectivity;
|
|
9956
|
+
// Fraction of rows passing filters (1.0 = no filtering)
|
|
9957
|
+
#output;
|
|
9958
|
+
// Set once during graph construction
|
|
9959
|
+
// ========================================================================
|
|
9960
|
+
// MUTABLE PLANNING STATE (changes during plan search)
|
|
9961
|
+
// ========================================================================
|
|
9962
|
+
/**
|
|
9963
|
+
* Current limit during planning. Can be cleared (set to undefined) when a
|
|
9964
|
+
* parent join is flipped, indicating this connection is now in an outer loop
|
|
9965
|
+
* and should not be limited by EXISTS semantics.
|
|
9966
|
+
*/
|
|
9967
|
+
limit;
|
|
9968
|
+
/**
|
|
9969
|
+
* Constraints accumulated from parent joins during planning.
|
|
9970
|
+
* Key is a path through the graph (e.g., "0,1" for branch pattern [0,1]).
|
|
9971
|
+
*
|
|
9972
|
+
* Undefined constraints are possible when a FO converts to UFO and only
|
|
9973
|
+
* a single join in the UFO is flipped - other branches report undefined.
|
|
9974
|
+
*/
|
|
9975
|
+
#constraints;
|
|
9976
|
+
#isRoot;
|
|
9977
|
+
/**
|
|
9978
|
+
* Cached per-constraint costs to avoid redundant cost model calls.
|
|
9979
|
+
* Maps constraint key (branch pattern string) to computed cost.
|
|
9980
|
+
* Invalidated when constraints change.
|
|
9981
|
+
*/
|
|
9982
|
+
#cachedConstraintCosts = /* @__PURE__ */ new Map();
|
|
9983
|
+
constructor(table2, model, sort, filters, isRoot, baseConstraints, limit, name) {
|
|
9984
|
+
this.table = table2;
|
|
9985
|
+
this.name = name ?? table2;
|
|
9986
|
+
this.#sort = sort;
|
|
9987
|
+
this.#filters = filters;
|
|
9988
|
+
this.#model = model;
|
|
9989
|
+
this.#baseConstraints = baseConstraints;
|
|
9990
|
+
this.#baseLimit = limit;
|
|
9991
|
+
this.limit = limit;
|
|
9992
|
+
this.#constraints = /* @__PURE__ */ new Map();
|
|
9993
|
+
this.#isRoot = isRoot;
|
|
9994
|
+
if (limit !== void 0 && filters) {
|
|
9995
|
+
const costWithFilters = model(table2, sort, filters, void 0);
|
|
9996
|
+
const costWithoutFilters = model(table2, sort, void 0, void 0);
|
|
9997
|
+
this.selectivity = costWithoutFilters.rows > 0 ? costWithFilters.rows / costWithoutFilters.rows : 1;
|
|
9998
|
+
} else {
|
|
9999
|
+
this.selectivity = 1;
|
|
10000
|
+
}
|
|
10001
|
+
}
|
|
10002
|
+
setOutput(node) {
|
|
10003
|
+
this.#output = node;
|
|
10004
|
+
}
|
|
10005
|
+
get output() {
|
|
10006
|
+
assert(this.#output !== void 0, "Output not set");
|
|
10007
|
+
return this.#output;
|
|
10008
|
+
}
|
|
10009
|
+
closestJoinOrSource() {
|
|
10010
|
+
return "connection";
|
|
10011
|
+
}
|
|
10012
|
+
/**
|
|
10013
|
+
* Constraints are uniquely identified by their path through the
|
|
10014
|
+
* graph.
|
|
10015
|
+
*
|
|
10016
|
+
* FO represents all sub-joins as a single path.
|
|
10017
|
+
* UFO represents each sub-join as a separate path.
|
|
10018
|
+
* The first branch in a UFO will match the path of FO so no re-set needs to happen
|
|
10019
|
+
* when swapping from FO to UFO.
|
|
10020
|
+
*
|
|
10021
|
+
* FO swaps to UFO when a join inside FO-FI gets flipped.
|
|
10022
|
+
*
|
|
10023
|
+
* The max of the last element of the paths is the number of
|
|
10024
|
+
* root branches.
|
|
10025
|
+
*/
|
|
10026
|
+
propagateConstraints(path, c, from, planDebugger) {
|
|
10027
|
+
const key = path.join(",");
|
|
10028
|
+
this.#constraints.set(key, c);
|
|
10029
|
+
this.#cachedConstraintCosts.clear();
|
|
10030
|
+
planDebugger?.log({
|
|
10031
|
+
type: "node-constraint",
|
|
10032
|
+
nodeType: "connection",
|
|
10033
|
+
node: this.name,
|
|
10034
|
+
branchPattern: path,
|
|
10035
|
+
constraint: c,
|
|
10036
|
+
from: from?.kind ?? "unknown"
|
|
10037
|
+
});
|
|
10038
|
+
}
|
|
10039
|
+
estimateCost(downstreamChildSelectivity, branchPattern, planDebugger) {
|
|
10040
|
+
const key = branchPattern.join(",");
|
|
10041
|
+
let cost = this.#cachedConstraintCosts.get(key);
|
|
10042
|
+
if (cost !== void 0) {
|
|
10043
|
+
return cost;
|
|
10044
|
+
}
|
|
10045
|
+
const constraint = this.#constraints.get(key);
|
|
10046
|
+
const mergedConstraint = mergeConstraints(
|
|
10047
|
+
this.#baseConstraints,
|
|
10048
|
+
constraint
|
|
10049
|
+
);
|
|
10050
|
+
const { startupCost, rows } = this.#model(
|
|
10051
|
+
this.table,
|
|
10052
|
+
this.#sort,
|
|
10053
|
+
this.#filters,
|
|
10054
|
+
mergedConstraint
|
|
10055
|
+
);
|
|
10056
|
+
cost = {
|
|
10057
|
+
startupCost,
|
|
10058
|
+
scanEst: this.limit === void 0 ? rows : Math.min(rows, this.limit / downstreamChildSelectivity),
|
|
10059
|
+
cost: 0,
|
|
10060
|
+
returnedRows: rows,
|
|
10061
|
+
selectivity: this.selectivity,
|
|
10062
|
+
limit: this.limit
|
|
10063
|
+
};
|
|
10064
|
+
this.#cachedConstraintCosts.set(key, cost);
|
|
10065
|
+
planDebugger?.log({
|
|
10066
|
+
type: "node-cost",
|
|
10067
|
+
nodeType: "connection",
|
|
10068
|
+
node: this.name,
|
|
10069
|
+
branchPattern,
|
|
10070
|
+
downstreamChildSelectivity,
|
|
10071
|
+
costEstimate: cost,
|
|
10072
|
+
filters: this.#filters
|
|
10073
|
+
});
|
|
10074
|
+
return cost;
|
|
10075
|
+
}
|
|
10076
|
+
/**
|
|
10077
|
+
* Remove the limit from this connection.
|
|
10078
|
+
* Called when a parent join is flipped, making this connection part of an
|
|
10079
|
+
* outer loop that should produce all rows rather than stopping at the limit.
|
|
10080
|
+
*/
|
|
10081
|
+
unlimit() {
|
|
10082
|
+
if (this.#isRoot) {
|
|
10083
|
+
return;
|
|
10084
|
+
}
|
|
10085
|
+
if (this.limit !== void 0) {
|
|
10086
|
+
this.limit = void 0;
|
|
10087
|
+
}
|
|
10088
|
+
}
|
|
10089
|
+
/**
|
|
10090
|
+
* Propagate unlimiting when a parent join is flipped.
|
|
10091
|
+
* For connections, we simply remove the limit.
|
|
10092
|
+
*/
|
|
10093
|
+
propagateUnlimitFromFlippedJoin() {
|
|
10094
|
+
this.unlimit();
|
|
10095
|
+
}
|
|
10096
|
+
reset() {
|
|
10097
|
+
this.#constraints.clear();
|
|
10098
|
+
this.limit = this.#baseLimit;
|
|
10099
|
+
this.#cachedConstraintCosts.clear();
|
|
10100
|
+
}
|
|
10101
|
+
/**
|
|
10102
|
+
* Capture constraint state for snapshotting.
|
|
10103
|
+
* Used by PlannerGraph to save/restore planning state.
|
|
10104
|
+
*/
|
|
10105
|
+
captureConstraints() {
|
|
10106
|
+
return new Map(this.#constraints);
|
|
10107
|
+
}
|
|
10108
|
+
/**
|
|
10109
|
+
* Restore constraint state from a snapshot.
|
|
10110
|
+
* Used by PlannerGraph to restore planning state.
|
|
10111
|
+
*/
|
|
10112
|
+
restoreConstraints(constraints) {
|
|
10113
|
+
this.#constraints.clear();
|
|
10114
|
+
for (const [key, value] of constraints) {
|
|
10115
|
+
this.#constraints.set(key, value);
|
|
10116
|
+
}
|
|
10117
|
+
this.#cachedConstraintCosts.clear();
|
|
10118
|
+
}
|
|
10119
|
+
/**
|
|
10120
|
+
* Get current constraints for debugging.
|
|
10121
|
+
* Returns a copy of the constraints map.
|
|
10122
|
+
*/
|
|
10123
|
+
getConstraintsForDebug() {
|
|
10124
|
+
return new Map(this.#constraints);
|
|
10125
|
+
}
|
|
10126
|
+
/**
|
|
10127
|
+
* Get filters for debugging.
|
|
10128
|
+
* Returns the filters applied to this connection.
|
|
10129
|
+
*/
|
|
10130
|
+
getFiltersForDebug() {
|
|
10131
|
+
return this.#filters;
|
|
10132
|
+
}
|
|
10133
|
+
/**
|
|
10134
|
+
* Get estimated cost for each constraint branch.
|
|
10135
|
+
* Returns a map of constraint key to cost estimate.
|
|
10136
|
+
* Forces cost calculation if not already cached.
|
|
10137
|
+
*/
|
|
10138
|
+
getConstraintCostsForDebug() {
|
|
10139
|
+
return new Map(this.#cachedConstraintCosts);
|
|
10140
|
+
}
|
|
10141
|
+
};
|
|
10142
|
+
|
|
10143
|
+
// ../zql/src/planner/planner-source.ts
|
|
10144
|
+
var PlannerSource = class {
|
|
10145
|
+
name;
|
|
10146
|
+
#model;
|
|
10147
|
+
constructor(name, model) {
|
|
10148
|
+
this.name = name;
|
|
10149
|
+
this.#model = model;
|
|
10150
|
+
}
|
|
10151
|
+
connect(sort, filters, isRoot, baseConstraints, limit) {
|
|
10152
|
+
return new PlannerConnection(
|
|
10153
|
+
this.name,
|
|
10154
|
+
this.#model,
|
|
10155
|
+
sort,
|
|
10156
|
+
filters,
|
|
10157
|
+
isRoot,
|
|
10158
|
+
baseConstraints,
|
|
10159
|
+
limit
|
|
10160
|
+
);
|
|
10161
|
+
}
|
|
10162
|
+
};
|
|
10163
|
+
|
|
10164
|
+
// ../zql/src/planner/planner-graph.ts
|
|
10165
|
+
var MAX_FLIPPABLE_JOINS = 13;
|
|
10166
|
+
var PlannerGraph = class {
|
|
10167
|
+
// Sources indexed by table name
|
|
10168
|
+
#sources = /* @__PURE__ */ new Map();
|
|
10169
|
+
// The final output node where constraint propagation starts
|
|
10170
|
+
#terminus = void 0;
|
|
10171
|
+
// Collections of nodes with mutable planning state
|
|
10172
|
+
joins = [];
|
|
10173
|
+
fanOuts = [];
|
|
10174
|
+
fanIns = [];
|
|
10175
|
+
connections = [];
|
|
10176
|
+
/**
|
|
10177
|
+
* Reset all planning state back to initial values for another planning pass.
|
|
10178
|
+
* Resets only mutable planning state - graph structure is unchanged.
|
|
10179
|
+
*
|
|
10180
|
+
* This allows replanning the same query graph with different strategies.
|
|
10181
|
+
*/
|
|
10182
|
+
resetPlanningState() {
|
|
10183
|
+
for (const j of this.joins) j.reset();
|
|
10184
|
+
for (const fo of this.fanOuts) fo.reset();
|
|
10185
|
+
for (const fi of this.fanIns) fi.reset();
|
|
10186
|
+
for (const c of this.connections) c.reset();
|
|
10187
|
+
}
|
|
10188
|
+
/**
|
|
10189
|
+
* Create and register a source (table) in the graph.
|
|
10190
|
+
*/
|
|
10191
|
+
addSource(name, model) {
|
|
10192
|
+
assert(
|
|
10193
|
+
!this.#sources.has(name),
|
|
10194
|
+
`Source ${name} already exists in the graph`
|
|
10195
|
+
);
|
|
10196
|
+
const source = new PlannerSource(name, model);
|
|
10197
|
+
this.#sources.set(name, source);
|
|
10198
|
+
return source;
|
|
10199
|
+
}
|
|
10200
|
+
/**
|
|
10201
|
+
* Get a source by table name.
|
|
10202
|
+
*/
|
|
10203
|
+
getSource(name) {
|
|
10204
|
+
const source = this.#sources.get(name);
|
|
10205
|
+
assert(source !== void 0, `Source ${name} not found in the graph`);
|
|
10206
|
+
return source;
|
|
10207
|
+
}
|
|
10208
|
+
/**
|
|
10209
|
+
* Check if a source exists by table name.
|
|
10210
|
+
*/
|
|
10211
|
+
hasSource(name) {
|
|
10212
|
+
return this.#sources.has(name);
|
|
10213
|
+
}
|
|
10214
|
+
/**
|
|
10215
|
+
* Set the terminus (final output) node of the graph.
|
|
10216
|
+
* Constraint propagation starts from this node.
|
|
10217
|
+
*/
|
|
10218
|
+
setTerminus(terminus) {
|
|
10219
|
+
this.#terminus = terminus;
|
|
10220
|
+
}
|
|
10221
|
+
/**
|
|
10222
|
+
* Initiate constraint propagation from the terminus node.
|
|
10223
|
+
* This sends constraints up through the graph to update
|
|
10224
|
+
* connection cost estimates.
|
|
10225
|
+
*/
|
|
10226
|
+
propagateConstraints(planDebugger) {
|
|
10227
|
+
assert(
|
|
10228
|
+
this.#terminus !== void 0,
|
|
10229
|
+
"Cannot propagate constraints without a terminus node"
|
|
10230
|
+
);
|
|
10231
|
+
this.#terminus.propagateConstraints(planDebugger);
|
|
10232
|
+
}
|
|
10233
|
+
/**
|
|
10234
|
+
* Calculate total cost of the current plan.
|
|
10235
|
+
* Total cost includes both startup cost (one-time, e.g., sorting) and running cost.
|
|
10236
|
+
*/
|
|
10237
|
+
getTotalCost(planDebugger) {
|
|
10238
|
+
const estimate = must(this.#terminus).estimateCost(planDebugger);
|
|
10239
|
+
return estimate.cost + estimate.startupCost;
|
|
10240
|
+
}
|
|
10241
|
+
/**
|
|
10242
|
+
* Capture a lightweight snapshot of the current planning state.
|
|
10243
|
+
* Used for backtracking during multi-start greedy search.
|
|
10244
|
+
*
|
|
10245
|
+
* Captures mutable state including pinned flags, join types, and
|
|
10246
|
+
* constraint maps to avoid needing repropagation on restore.
|
|
10247
|
+
*
|
|
10248
|
+
* @returns A snapshot that can be restored via restorePlanningSnapshot()
|
|
10249
|
+
*/
|
|
10250
|
+
capturePlanningSnapshot() {
|
|
10251
|
+
return {
|
|
10252
|
+
connections: this.connections.map((c) => ({
|
|
10253
|
+
limit: c.limit
|
|
10254
|
+
})),
|
|
10255
|
+
joins: this.joins.map((j) => ({ type: j.type })),
|
|
10256
|
+
fanOuts: this.fanOuts.map((fo) => ({ type: fo.type })),
|
|
10257
|
+
fanIns: this.fanIns.map((fi) => ({ type: fi.type })),
|
|
10258
|
+
connectionConstraints: this.connections.map((c) => c.captureConstraints())
|
|
10259
|
+
};
|
|
10260
|
+
}
|
|
10261
|
+
/**
|
|
10262
|
+
* Restore planning state from a previously captured snapshot.
|
|
10263
|
+
* Used for backtracking when a planning attempt fails.
|
|
10264
|
+
*
|
|
10265
|
+
* Restores pinned flags, join types, and constraint maps, eliminating
|
|
10266
|
+
* the need for repropagation.
|
|
10267
|
+
*
|
|
10268
|
+
* @param state - Snapshot created by capturePlanningSnapshot()
|
|
10269
|
+
*/
|
|
10270
|
+
restorePlanningSnapshot(state) {
|
|
10271
|
+
this.#validateSnapshotShape(state);
|
|
10272
|
+
this.#restoreConnections(state);
|
|
10273
|
+
this.#restoreJoins(state);
|
|
10274
|
+
this.#restoreFanNodes(state);
|
|
10275
|
+
}
|
|
10276
|
+
/**
|
|
10277
|
+
* Validate that snapshot shape matches current graph structure.
|
|
10278
|
+
*/
|
|
10279
|
+
#validateSnapshotShape(state) {
|
|
10280
|
+
assert(
|
|
10281
|
+
this.connections.length === state.connections.length,
|
|
10282
|
+
"Plan state mismatch: connections"
|
|
10283
|
+
);
|
|
10284
|
+
assert(
|
|
10285
|
+
this.joins.length === state.joins.length,
|
|
10286
|
+
"Plan state mismatch: joins"
|
|
10287
|
+
);
|
|
10288
|
+
assert(
|
|
10289
|
+
this.fanOuts.length === state.fanOuts.length,
|
|
10290
|
+
"Plan state mismatch: fanOuts"
|
|
10291
|
+
);
|
|
10292
|
+
assert(
|
|
10293
|
+
this.fanIns.length === state.fanIns.length,
|
|
10294
|
+
"Plan state mismatch: fanIns"
|
|
10295
|
+
);
|
|
10296
|
+
assert(
|
|
10297
|
+
this.connections.length === state.connectionConstraints.length,
|
|
10298
|
+
"Plan state mismatch: connectionConstraints"
|
|
10299
|
+
);
|
|
10300
|
+
}
|
|
10301
|
+
/**
|
|
10302
|
+
* Restore connection pinned flags, limits, and constraint maps.
|
|
10303
|
+
*/
|
|
10304
|
+
#restoreConnections(state) {
|
|
10305
|
+
for (let i = 0; i < this.connections.length; i++) {
|
|
10306
|
+
this.connections[i].limit = state.connections[i].limit;
|
|
10307
|
+
this.connections[i].restoreConstraints(state.connectionConstraints[i]);
|
|
10308
|
+
}
|
|
10309
|
+
}
|
|
10310
|
+
/**
|
|
10311
|
+
* Restore join types and pinned flags.
|
|
10312
|
+
*/
|
|
10313
|
+
#restoreJoins(state) {
|
|
10314
|
+
for (let i = 0; i < this.joins.length; i++) {
|
|
10315
|
+
const join = this.joins[i];
|
|
10316
|
+
const targetState = state.joins[i];
|
|
10317
|
+
join.reset();
|
|
10318
|
+
if (targetState.type === "flipped") {
|
|
10319
|
+
join.flip();
|
|
10320
|
+
}
|
|
10321
|
+
}
|
|
10322
|
+
}
|
|
10323
|
+
/**
|
|
10324
|
+
* Restore FanOut and FanIn types.
|
|
10325
|
+
*/
|
|
10326
|
+
#restoreFanNodes(state) {
|
|
10327
|
+
for (let i = 0; i < this.fanOuts.length; i++) {
|
|
10328
|
+
const fo = this.fanOuts[i];
|
|
10329
|
+
const targetType = state.fanOuts[i].type;
|
|
10330
|
+
if (targetType === "UFO" && fo.type === "FO") {
|
|
10331
|
+
fo.convertToUFO();
|
|
10332
|
+
}
|
|
10333
|
+
}
|
|
10334
|
+
for (let i = 0; i < this.fanIns.length; i++) {
|
|
10335
|
+
const fi = this.fanIns[i];
|
|
10336
|
+
const targetType = state.fanIns[i].type;
|
|
10337
|
+
if (targetType === "UFI" && fi.type === "FI") {
|
|
10338
|
+
fi.convertToUFI();
|
|
10339
|
+
}
|
|
10340
|
+
}
|
|
10341
|
+
}
|
|
10342
|
+
/**
|
|
10343
|
+
* Main planning algorithm using exhaustive join flip enumeration.
|
|
10344
|
+
*
|
|
10345
|
+
* Enumerates all possible flip patterns for flippable joins (2^n for n flippable joins).
|
|
10346
|
+
* Each pattern represents a different query execution plan. We evaluate the cost of each
|
|
10347
|
+
* plan and select the one with the lowest cost.
|
|
10348
|
+
*
|
|
10349
|
+
* Connections are used only for cost estimation - the flip patterns determine the plan.
|
|
10350
|
+
* FanOut/FanIn states (FO/UFO and FI/UFI) are automatically derived from join flip states.
|
|
10351
|
+
*
|
|
10352
|
+
* @param planDebugger - Optional debugger to receive structured events during planning
|
|
10353
|
+
*/
|
|
10354
|
+
plan(planDebugger) {
|
|
10355
|
+
const flippableJoins = this.joins.filter((j) => j.isFlippable());
|
|
10356
|
+
if (flippableJoins.length > MAX_FLIPPABLE_JOINS) {
|
|
10357
|
+
throw new Error(
|
|
10358
|
+
`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}).`
|
|
10359
|
+
);
|
|
10360
|
+
}
|
|
10361
|
+
const fofiCache = buildFOFICache(this);
|
|
10362
|
+
const numPatterns = 2 ** flippableJoins.length;
|
|
10363
|
+
let bestCost = Infinity;
|
|
10364
|
+
let bestPlan = void 0;
|
|
10365
|
+
let bestAttemptNumber = -1;
|
|
10366
|
+
const forcePattern = void 0;
|
|
10367
|
+
for (let pattern = 0; pattern < numPatterns; pattern++) {
|
|
10368
|
+
if (forcePattern !== void 0 && pattern !== forcePattern) {
|
|
10369
|
+
continue;
|
|
10370
|
+
}
|
|
10371
|
+
this.resetPlanningState();
|
|
10372
|
+
if (planDebugger) {
|
|
10373
|
+
planDebugger.log({
|
|
10374
|
+
type: "attempt-start",
|
|
10375
|
+
attemptNumber: pattern,
|
|
10376
|
+
totalAttempts: numPatterns
|
|
10377
|
+
});
|
|
10378
|
+
}
|
|
10379
|
+
try {
|
|
10380
|
+
for (let i = 0; i < flippableJoins.length; i++) {
|
|
10381
|
+
if (pattern & 1 << i) {
|
|
10382
|
+
flippableJoins[i].flip();
|
|
10383
|
+
}
|
|
10384
|
+
}
|
|
10385
|
+
checkAndConvertFOFI(fofiCache);
|
|
10386
|
+
propagateUnlimitForFlippedJoins(this);
|
|
10387
|
+
this.propagateConstraints(planDebugger);
|
|
10388
|
+
if (planDebugger) {
|
|
10389
|
+
planDebugger.log({
|
|
10390
|
+
type: "constraints-propagated",
|
|
10391
|
+
attemptNumber: pattern,
|
|
10392
|
+
connectionConstraints: this.connections.map((c) => ({
|
|
10393
|
+
connection: c.name,
|
|
10394
|
+
constraints: c.getConstraintsForDebug(),
|
|
10395
|
+
constraintCosts: c.getConstraintCostsForDebug()
|
|
10396
|
+
}))
|
|
10397
|
+
});
|
|
10398
|
+
}
|
|
10399
|
+
const totalCost = this.getTotalCost(planDebugger);
|
|
10400
|
+
if (planDebugger) {
|
|
10401
|
+
planDebugger.log({
|
|
10402
|
+
type: "plan-complete",
|
|
10403
|
+
attemptNumber: pattern,
|
|
10404
|
+
totalCost,
|
|
10405
|
+
flipPattern: pattern,
|
|
10406
|
+
// Bitmask of which joins are flipped
|
|
10407
|
+
// TODO: we'll need a different way to collect these
|
|
10408
|
+
// nodeCosts: this.#collectNodeCosts(),
|
|
10409
|
+
joinStates: this.joins.map((j) => {
|
|
10410
|
+
const info = j.getDebugInfo();
|
|
10411
|
+
return {
|
|
10412
|
+
join: info.name,
|
|
10413
|
+
type: info.type
|
|
10414
|
+
};
|
|
10415
|
+
})
|
|
10416
|
+
});
|
|
10417
|
+
}
|
|
10418
|
+
if (totalCost < bestCost) {
|
|
10419
|
+
bestCost = totalCost;
|
|
10420
|
+
bestPlan = this.capturePlanningSnapshot();
|
|
10421
|
+
bestAttemptNumber = pattern;
|
|
10422
|
+
}
|
|
10423
|
+
} catch (e) {
|
|
10424
|
+
if (planDebugger) {
|
|
10425
|
+
planDebugger.log({
|
|
10426
|
+
type: "plan-failed",
|
|
10427
|
+
attemptNumber: pattern,
|
|
10428
|
+
reason: `Flip pattern ${pattern.toString(2)} failed: ${e instanceof Error ? e.message : String(e)}`
|
|
10429
|
+
});
|
|
10430
|
+
}
|
|
10431
|
+
continue;
|
|
10432
|
+
}
|
|
10433
|
+
}
|
|
10434
|
+
if (bestPlan) {
|
|
10435
|
+
this.restorePlanningSnapshot(bestPlan);
|
|
10436
|
+
this.propagateConstraints(planDebugger);
|
|
10437
|
+
if (planDebugger) {
|
|
10438
|
+
planDebugger.log({
|
|
10439
|
+
type: "best-plan-selected",
|
|
10440
|
+
bestAttemptNumber,
|
|
10441
|
+
totalCost: bestCost,
|
|
10442
|
+
flipPattern: bestAttemptNumber,
|
|
10443
|
+
// The best attempt number is also the flip pattern
|
|
10444
|
+
joinStates: this.joins.map((j) => ({
|
|
10445
|
+
join: j.getName(),
|
|
10446
|
+
type: j.type
|
|
10447
|
+
}))
|
|
10448
|
+
});
|
|
10449
|
+
}
|
|
10450
|
+
} else {
|
|
10451
|
+
throw new Error(
|
|
10452
|
+
"No valid query plan found. This should not happen - check query structure."
|
|
10453
|
+
);
|
|
10454
|
+
}
|
|
10455
|
+
}
|
|
10456
|
+
};
|
|
10457
|
+
function buildFOFICache(graph) {
|
|
10458
|
+
const cache = /* @__PURE__ */ new Map();
|
|
10459
|
+
for (const fo of graph.fanOuts) {
|
|
10460
|
+
const info = findFIAndJoins(fo);
|
|
10461
|
+
cache.set(fo, info);
|
|
10462
|
+
}
|
|
10463
|
+
return cache;
|
|
10464
|
+
}
|
|
10465
|
+
function checkAndConvertFOFI(fofiCache) {
|
|
10466
|
+
for (const [fo, info] of fofiCache) {
|
|
10467
|
+
const hasFlippedJoin = info.joinsBetween.some((j) => j.type === "flipped");
|
|
10468
|
+
if (info.fi && hasFlippedJoin) {
|
|
10469
|
+
fo.convertToUFO();
|
|
10470
|
+
info.fi.convertToUFI();
|
|
10471
|
+
}
|
|
10472
|
+
}
|
|
10473
|
+
}
|
|
10474
|
+
function findFIAndJoins(fo) {
|
|
10475
|
+
const joinsBetween = [];
|
|
10476
|
+
let fi = void 0;
|
|
10477
|
+
const queue = [...fo.outputs];
|
|
10478
|
+
const visited = /* @__PURE__ */ new Set();
|
|
10479
|
+
while (queue.length > 0) {
|
|
10480
|
+
const node = must(queue.shift());
|
|
10481
|
+
if (visited.has(node)) continue;
|
|
10482
|
+
visited.add(node);
|
|
10483
|
+
switch (node.kind) {
|
|
10484
|
+
case "join":
|
|
10485
|
+
joinsBetween.push(node);
|
|
10486
|
+
queue.push(node.output);
|
|
10487
|
+
break;
|
|
10488
|
+
case "fan-out":
|
|
10489
|
+
queue.push(...node.outputs);
|
|
10490
|
+
break;
|
|
10491
|
+
case "fan-in":
|
|
10492
|
+
fi = node;
|
|
10493
|
+
break;
|
|
10494
|
+
case "connection":
|
|
10495
|
+
break;
|
|
10496
|
+
case "terminus":
|
|
10497
|
+
break;
|
|
10498
|
+
}
|
|
10499
|
+
}
|
|
10500
|
+
return { fi, joinsBetween };
|
|
10501
|
+
}
|
|
10502
|
+
function propagateUnlimitForFlippedJoins(graph) {
|
|
10503
|
+
for (const join of graph.joins) {
|
|
10504
|
+
if (join.type === "flipped") {
|
|
10505
|
+
join.propagateUnlimit();
|
|
10506
|
+
}
|
|
10507
|
+
}
|
|
10508
|
+
}
|
|
10509
|
+
|
|
10510
|
+
// ../zql/src/planner/planner-join.ts
|
|
10511
|
+
function translateConstraintsForFlippedJoin(incomingConstraint, parentConstraint, childConstraint) {
|
|
10512
|
+
if (!incomingConstraint) return void 0;
|
|
10513
|
+
const parentKeys = Object.keys(parentConstraint);
|
|
10514
|
+
const childKeys = Object.keys(childConstraint);
|
|
10515
|
+
const translated = {};
|
|
10516
|
+
for (const [key, value] of Object.entries(incomingConstraint)) {
|
|
10517
|
+
const index = parentKeys.indexOf(key);
|
|
10518
|
+
if (index !== -1) {
|
|
10519
|
+
translated[childKeys[index]] = value;
|
|
10520
|
+
}
|
|
10521
|
+
}
|
|
10522
|
+
return Object.keys(translated).length > 0 ? translated : void 0;
|
|
10523
|
+
}
|
|
10524
|
+
var PlannerJoin = class {
|
|
10525
|
+
kind = "join";
|
|
10526
|
+
#parent;
|
|
10527
|
+
#child;
|
|
10528
|
+
#parentConstraint;
|
|
10529
|
+
#childConstraint;
|
|
10530
|
+
#flippable;
|
|
10531
|
+
planId;
|
|
10532
|
+
#output;
|
|
10533
|
+
// Set once during graph construction
|
|
10534
|
+
// Reset between planning attempts
|
|
10535
|
+
#type;
|
|
10536
|
+
constructor(parent, child, parentConstraint, childConstraint, flippable, planId) {
|
|
10537
|
+
this.#type = "semi";
|
|
10538
|
+
this.#parent = parent;
|
|
10539
|
+
this.#child = child;
|
|
10540
|
+
this.#childConstraint = childConstraint;
|
|
10541
|
+
this.#parentConstraint = parentConstraint;
|
|
10542
|
+
this.#flippable = flippable;
|
|
10543
|
+
this.planId = planId;
|
|
10544
|
+
}
|
|
10545
|
+
setOutput(node) {
|
|
10546
|
+
this.#output = node;
|
|
10547
|
+
}
|
|
10548
|
+
get output() {
|
|
10549
|
+
assert(this.#output !== void 0, "Output not set");
|
|
10550
|
+
return this.#output;
|
|
10551
|
+
}
|
|
10552
|
+
closestJoinOrSource() {
|
|
10553
|
+
return "join";
|
|
10554
|
+
}
|
|
10555
|
+
flipIfNeeded(input) {
|
|
10556
|
+
if (input === this.#child) {
|
|
10557
|
+
this.flip();
|
|
10558
|
+
} else {
|
|
10559
|
+
assert(
|
|
10560
|
+
input === this.#parent,
|
|
10561
|
+
"Can only flip a join from one of its inputs"
|
|
10562
|
+
);
|
|
10563
|
+
}
|
|
10564
|
+
}
|
|
10565
|
+
flip() {
|
|
10566
|
+
assert(this.#type === "semi", "Can only flip a semi-join");
|
|
10567
|
+
if (!this.#flippable) {
|
|
10568
|
+
throw new UnflippableJoinError(
|
|
10569
|
+
"Cannot flip a non-flippable join (e.g., NOT EXISTS)"
|
|
10570
|
+
);
|
|
10571
|
+
}
|
|
10572
|
+
this.#type = "flipped";
|
|
10573
|
+
}
|
|
10574
|
+
get type() {
|
|
10575
|
+
return this.#type;
|
|
10576
|
+
}
|
|
10577
|
+
isFlippable() {
|
|
10578
|
+
return this.#flippable;
|
|
10579
|
+
}
|
|
10580
|
+
/**
|
|
10581
|
+
* Propagate unlimiting when this join is flipped.
|
|
10582
|
+
* When a join is flipped:
|
|
10583
|
+
* 1. Child becomes outer loop → produces all rows (unlimited)
|
|
10584
|
+
* 2. Parent is fetched once per child row → effectively unlimited
|
|
10585
|
+
*
|
|
10586
|
+
* Example: If child produces 896 rows, parent is fetched 896 times.
|
|
10587
|
+
* Even if each fetch returns 1 row, parent produces 896 total rows.
|
|
10588
|
+
*
|
|
10589
|
+
* Propagation rules:
|
|
10590
|
+
* - Connection: call unlimit()
|
|
10591
|
+
* - Semi-join: continue to parent (outer loop)
|
|
10592
|
+
* - Flipped join: stop (already unlimited when it was flipped)
|
|
10593
|
+
* - Fan-out/Fan-in: propagate to all inputs
|
|
10594
|
+
*/
|
|
10595
|
+
propagateUnlimit() {
|
|
10596
|
+
assert(this.#type === "flipped", "Can only unlimit a flipped join");
|
|
10597
|
+
this.#parent.propagateUnlimitFromFlippedJoin();
|
|
10598
|
+
this.#child.propagateUnlimitFromFlippedJoin();
|
|
10599
|
+
}
|
|
10600
|
+
/**
|
|
10601
|
+
* Called when a parent join is flipped and this join is part of its child subgraph.
|
|
10602
|
+
* - Semi-join: continue propagation to parent (the outer loop)
|
|
10603
|
+
* - Flipped join: stop propagation (already unlimited when it was flipped)
|
|
10604
|
+
*/
|
|
10605
|
+
propagateUnlimitFromFlippedJoin() {
|
|
10606
|
+
if (this.#type === "semi") {
|
|
10607
|
+
this.#parent.propagateUnlimitFromFlippedJoin();
|
|
10608
|
+
}
|
|
10609
|
+
}
|
|
10610
|
+
propagateConstraints(branchPattern, constraint, from, planDebugger) {
|
|
10611
|
+
planDebugger?.log({
|
|
10612
|
+
type: "node-constraint",
|
|
10613
|
+
nodeType: "join",
|
|
10614
|
+
node: this.getName(),
|
|
10615
|
+
branchPattern,
|
|
10616
|
+
constraint,
|
|
10617
|
+
from: from ? getNodeName(from) : "unknown"
|
|
10618
|
+
});
|
|
10619
|
+
if (this.#type === "semi") {
|
|
10620
|
+
this.#child.propagateConstraints(
|
|
10621
|
+
branchPattern,
|
|
10622
|
+
this.#childConstraint,
|
|
10623
|
+
this,
|
|
10624
|
+
planDebugger
|
|
10625
|
+
);
|
|
10626
|
+
this.#parent.propagateConstraints(
|
|
10627
|
+
branchPattern,
|
|
10628
|
+
constraint,
|
|
10629
|
+
this,
|
|
10630
|
+
planDebugger
|
|
10631
|
+
);
|
|
10632
|
+
} else if (this.#type === "flipped") {
|
|
10633
|
+
const translatedConstraint = translateConstraintsForFlippedJoin(
|
|
10634
|
+
constraint,
|
|
10635
|
+
this.#parentConstraint,
|
|
10636
|
+
this.#childConstraint
|
|
10637
|
+
);
|
|
10638
|
+
this.#child.propagateConstraints(
|
|
10639
|
+
branchPattern,
|
|
10640
|
+
translatedConstraint,
|
|
10641
|
+
this,
|
|
10642
|
+
planDebugger
|
|
10643
|
+
);
|
|
10644
|
+
this.#parent.propagateConstraints(
|
|
10645
|
+
branchPattern,
|
|
10646
|
+
mergeConstraints(constraint, this.#parentConstraint),
|
|
10647
|
+
this,
|
|
10648
|
+
planDebugger
|
|
10649
|
+
);
|
|
10650
|
+
}
|
|
9232
10651
|
}
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
this.#fanOutPushStarted = true;
|
|
10652
|
+
reset() {
|
|
10653
|
+
this.#type = "semi";
|
|
9236
10654
|
}
|
|
9237
|
-
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
}
|
|
9246
|
-
pushAccumulatedChanges(
|
|
9247
|
-
this.#accumulatedPushes,
|
|
9248
|
-
this.#output,
|
|
9249
|
-
this,
|
|
9250
|
-
fanOutChangeType,
|
|
9251
|
-
mergeRelationships,
|
|
9252
|
-
makeAddEmptyRelationships(this.#schema)
|
|
10655
|
+
estimateCost(downstreamChildSelectivity, branchPattern, planDebugger) {
|
|
10656
|
+
const child = this.#child.estimateCost(1, branchPattern, planDebugger);
|
|
10657
|
+
const parent = this.#parent.estimateCost(
|
|
10658
|
+
// Selectivity flows up the graph from child to parent
|
|
10659
|
+
// so we can determine the total selectivity of all ANDed exists checks.
|
|
10660
|
+
child.selectivity * downstreamChildSelectivity,
|
|
10661
|
+
branchPattern,
|
|
10662
|
+
planDebugger
|
|
9253
10663
|
);
|
|
10664
|
+
let costEstimate;
|
|
10665
|
+
if (this.type === "semi") {
|
|
10666
|
+
costEstimate = {
|
|
10667
|
+
startupCost: parent.startupCost,
|
|
10668
|
+
scanEst: parent.limit === void 0 ? parent.returnedRows : Math.min(
|
|
10669
|
+
parent.returnedRows,
|
|
10670
|
+
parent.limit / downstreamChildSelectivity
|
|
10671
|
+
),
|
|
10672
|
+
cost: parent.cost + parent.scanEst * (child.startupCost + child.scanEst),
|
|
10673
|
+
returnedRows: parent.returnedRows * child.selectivity,
|
|
10674
|
+
selectivity: child.selectivity * parent.selectivity,
|
|
10675
|
+
limit: parent.limit
|
|
10676
|
+
};
|
|
10677
|
+
} else {
|
|
10678
|
+
costEstimate = {
|
|
10679
|
+
startupCost: child.startupCost,
|
|
10680
|
+
scanEst: parent.limit === void 0 ? parent.returnedRows : Math.min(
|
|
10681
|
+
parent.returnedRows * child.returnedRows,
|
|
10682
|
+
parent.limit / downstreamChildSelectivity
|
|
10683
|
+
),
|
|
10684
|
+
cost: child.cost + child.scanEst * (parent.startupCost + parent.scanEst),
|
|
10685
|
+
returnedRows: parent.returnedRows * child.returnedRows * child.selectivity,
|
|
10686
|
+
selectivity: parent.selectivity * child.selectivity,
|
|
10687
|
+
limit: parent.limit
|
|
10688
|
+
};
|
|
10689
|
+
}
|
|
10690
|
+
planDebugger?.log({
|
|
10691
|
+
type: "node-cost",
|
|
10692
|
+
nodeType: "join",
|
|
10693
|
+
node: this.getName(),
|
|
10694
|
+
branchPattern,
|
|
10695
|
+
downstreamChildSelectivity,
|
|
10696
|
+
costEstimate,
|
|
10697
|
+
joinType: this.#type
|
|
10698
|
+
});
|
|
10699
|
+
return costEstimate;
|
|
9254
10700
|
}
|
|
9255
|
-
|
|
9256
|
-
|
|
10701
|
+
/**
|
|
10702
|
+
* Get a human-readable name for this join for debugging.
|
|
10703
|
+
* Format: "parentName ⋈ childName"
|
|
10704
|
+
*/
|
|
10705
|
+
getName() {
|
|
10706
|
+
const parentName = getNodeName(this.#parent);
|
|
10707
|
+
const childName = getNodeName(this.#child);
|
|
10708
|
+
return `${parentName} \u22C8 ${childName}`;
|
|
10709
|
+
}
|
|
10710
|
+
/**
|
|
10711
|
+
* Get debug information about this join's state.
|
|
10712
|
+
*/
|
|
10713
|
+
getDebugInfo() {
|
|
10714
|
+
return {
|
|
10715
|
+
name: this.getName(),
|
|
10716
|
+
type: this.#type,
|
|
10717
|
+
planId: this.planId
|
|
10718
|
+
};
|
|
10719
|
+
}
|
|
10720
|
+
};
|
|
10721
|
+
var UnflippableJoinError = class extends Error {
|
|
10722
|
+
constructor(message) {
|
|
10723
|
+
super(message);
|
|
10724
|
+
this.name = "UnflippableJoinError";
|
|
9257
10725
|
}
|
|
9258
10726
|
};
|
|
10727
|
+
function getNodeName(node) {
|
|
10728
|
+
switch (node.kind) {
|
|
10729
|
+
case "connection":
|
|
10730
|
+
return node.name;
|
|
10731
|
+
case "join":
|
|
10732
|
+
return node.getName();
|
|
10733
|
+
case "fan-out":
|
|
10734
|
+
return "FO";
|
|
10735
|
+
case "fan-in":
|
|
10736
|
+
return "FI";
|
|
10737
|
+
case "terminus":
|
|
10738
|
+
return "terminus";
|
|
10739
|
+
}
|
|
10740
|
+
}
|
|
9259
10741
|
|
|
9260
|
-
// ../zql/src/
|
|
9261
|
-
var
|
|
9262
|
-
|
|
9263
|
-
#unionFanIn;
|
|
10742
|
+
// ../zql/src/planner/planner-terminus.ts
|
|
10743
|
+
var PlannerTerminus = class {
|
|
10744
|
+
kind = "terminus";
|
|
9264
10745
|
#input;
|
|
9265
|
-
#outputs = [];
|
|
9266
10746
|
constructor(input) {
|
|
9267
10747
|
this.#input = input;
|
|
9268
|
-
input.setOutput(this);
|
|
9269
10748
|
}
|
|
9270
|
-
|
|
9271
|
-
|
|
9272
|
-
this.#unionFanIn = fanIn;
|
|
10749
|
+
get pinned() {
|
|
10750
|
+
return true;
|
|
9273
10751
|
}
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
|
|
9277
|
-
|
|
10752
|
+
closestJoinOrSource() {
|
|
10753
|
+
return this.#input.closestJoinOrSource();
|
|
10754
|
+
}
|
|
10755
|
+
propagateConstraints(planDebugger) {
|
|
10756
|
+
this.#input.propagateConstraints([], void 0, this, planDebugger);
|
|
10757
|
+
}
|
|
10758
|
+
estimateCost(planDebugger) {
|
|
10759
|
+
return this.#input.estimateCost(1, [], planDebugger);
|
|
10760
|
+
}
|
|
10761
|
+
/**
|
|
10762
|
+
* Propagate unlimiting when a parent join is flipped.
|
|
10763
|
+
* Terminus doesn't participate in unlimiting.
|
|
10764
|
+
*/
|
|
10765
|
+
propagateUnlimitFromFlippedJoin() {
|
|
10766
|
+
}
|
|
10767
|
+
};
|
|
10768
|
+
|
|
10769
|
+
// ../zql/src/planner/planner-builder.ts
|
|
10770
|
+
function wireOutput(from, to) {
|
|
10771
|
+
switch (from.kind) {
|
|
10772
|
+
case "connection":
|
|
10773
|
+
case "join":
|
|
10774
|
+
case "fan-in":
|
|
10775
|
+
from.setOutput(to);
|
|
10776
|
+
break;
|
|
10777
|
+
case "fan-out":
|
|
10778
|
+
from.addOutput(to);
|
|
10779
|
+
break;
|
|
10780
|
+
case "terminus":
|
|
10781
|
+
assert(false, "Terminus nodes cannot have outputs");
|
|
10782
|
+
}
|
|
10783
|
+
}
|
|
10784
|
+
function buildPlanGraph(ast, model, isRoot, baseConstraints) {
|
|
10785
|
+
const graph = new PlannerGraph();
|
|
10786
|
+
let nextPlanId = 0;
|
|
10787
|
+
const source = graph.addSource(ast.table, model);
|
|
10788
|
+
const connection = source.connect(
|
|
10789
|
+
ast.orderBy ?? [],
|
|
10790
|
+
ast.where,
|
|
10791
|
+
isRoot,
|
|
10792
|
+
baseConstraints,
|
|
10793
|
+
ast.limit
|
|
10794
|
+
);
|
|
10795
|
+
graph.connections.push(connection);
|
|
10796
|
+
let end = connection;
|
|
10797
|
+
if (ast.where) {
|
|
10798
|
+
end = processCondition(
|
|
10799
|
+
ast.where,
|
|
10800
|
+
end,
|
|
10801
|
+
graph,
|
|
10802
|
+
model,
|
|
10803
|
+
ast.table,
|
|
10804
|
+
() => nextPlanId++
|
|
10805
|
+
);
|
|
10806
|
+
}
|
|
10807
|
+
const terminus = new PlannerTerminus(end);
|
|
10808
|
+
wireOutput(end, terminus);
|
|
10809
|
+
graph.setTerminus(terminus);
|
|
10810
|
+
const subPlans = {};
|
|
10811
|
+
if (ast.related) {
|
|
10812
|
+
for (const csq of ast.related) {
|
|
10813
|
+
const alias = must(
|
|
10814
|
+
csq.subquery.alias,
|
|
10815
|
+
"Related subquery must have alias"
|
|
10816
|
+
);
|
|
10817
|
+
const childConstraints = extractConstraint(
|
|
10818
|
+
csq.correlation.childField,
|
|
10819
|
+
csq.subquery.table
|
|
10820
|
+
);
|
|
10821
|
+
subPlans[alias] = buildPlanGraph(
|
|
10822
|
+
csq.subquery,
|
|
10823
|
+
model,
|
|
10824
|
+
true,
|
|
10825
|
+
childConstraints
|
|
10826
|
+
);
|
|
9278
10827
|
}
|
|
9279
|
-
must(this.#unionFanIn).fanOutDonePushing(change.type);
|
|
9280
10828
|
}
|
|
9281
|
-
|
|
9282
|
-
|
|
10829
|
+
return { plan: graph, subPlans };
|
|
10830
|
+
}
|
|
10831
|
+
function processCondition(condition, input, graph, model, parentTable, getPlanId) {
|
|
10832
|
+
switch (condition.type) {
|
|
10833
|
+
case "simple":
|
|
10834
|
+
return input;
|
|
10835
|
+
case "and":
|
|
10836
|
+
return processAnd(condition, input, graph, model, parentTable, getPlanId);
|
|
10837
|
+
case "or":
|
|
10838
|
+
return processOr(condition, input, graph, model, parentTable, getPlanId);
|
|
10839
|
+
case "correlatedSubquery":
|
|
10840
|
+
return processCorrelatedSubquery(
|
|
10841
|
+
condition,
|
|
10842
|
+
input,
|
|
10843
|
+
graph,
|
|
10844
|
+
model,
|
|
10845
|
+
parentTable,
|
|
10846
|
+
getPlanId
|
|
10847
|
+
);
|
|
9283
10848
|
}
|
|
9284
|
-
|
|
9285
|
-
|
|
10849
|
+
}
|
|
10850
|
+
function processAnd(condition, input, graph, model, parentTable, getPlanId) {
|
|
10851
|
+
let end = input;
|
|
10852
|
+
for (const subCondition of condition.conditions) {
|
|
10853
|
+
end = processCondition(
|
|
10854
|
+
subCondition,
|
|
10855
|
+
end,
|
|
10856
|
+
graph,
|
|
10857
|
+
model,
|
|
10858
|
+
parentTable,
|
|
10859
|
+
getPlanId
|
|
10860
|
+
);
|
|
9286
10861
|
}
|
|
9287
|
-
|
|
9288
|
-
|
|
10862
|
+
return end;
|
|
10863
|
+
}
|
|
10864
|
+
function processOr(condition, input, graph, model, parentTable, getPlanId) {
|
|
10865
|
+
const subqueryConditions = condition.conditions.filter(
|
|
10866
|
+
(c) => c.type === "correlatedSubquery" || hasCorrelatedSubquery(c)
|
|
10867
|
+
);
|
|
10868
|
+
if (subqueryConditions.length === 0) {
|
|
10869
|
+
return input;
|
|
9289
10870
|
}
|
|
9290
|
-
|
|
9291
|
-
|
|
10871
|
+
const fanOut = new PlannerFanOut(input);
|
|
10872
|
+
graph.fanOuts.push(fanOut);
|
|
10873
|
+
wireOutput(input, fanOut);
|
|
10874
|
+
const branches = [];
|
|
10875
|
+
for (const subCondition of subqueryConditions) {
|
|
10876
|
+
const branch = processCondition(
|
|
10877
|
+
subCondition,
|
|
10878
|
+
fanOut,
|
|
10879
|
+
graph,
|
|
10880
|
+
model,
|
|
10881
|
+
parentTable,
|
|
10882
|
+
getPlanId
|
|
10883
|
+
);
|
|
10884
|
+
branches.push(branch);
|
|
10885
|
+
fanOut.addOutput(branch);
|
|
9292
10886
|
}
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
10887
|
+
const fanIn = new PlannerFanIn(branches);
|
|
10888
|
+
graph.fanIns.push(fanIn);
|
|
10889
|
+
for (const branch of branches) {
|
|
10890
|
+
wireOutput(branch, fanIn);
|
|
10891
|
+
}
|
|
10892
|
+
return fanIn;
|
|
10893
|
+
}
|
|
10894
|
+
function processCorrelatedSubquery(condition, input, graph, model, parentTable, getPlanId) {
|
|
10895
|
+
const { related } = condition;
|
|
10896
|
+
const childTable = related.subquery.table;
|
|
10897
|
+
const childSource = graph.hasSource(childTable) ? graph.getSource(childTable) : graph.addSource(childTable, model);
|
|
10898
|
+
const childConnection = childSource.connect(
|
|
10899
|
+
related.subquery.orderBy ?? [],
|
|
10900
|
+
related.subquery.where,
|
|
10901
|
+
false,
|
|
10902
|
+
void 0,
|
|
10903
|
+
// no base constraints for EXISTS/NOT EXISTS
|
|
10904
|
+
condition.op === "EXISTS" ? 1 : void 0
|
|
10905
|
+
);
|
|
10906
|
+
graph.connections.push(childConnection);
|
|
10907
|
+
let childEnd = childConnection;
|
|
10908
|
+
if (related.subquery.where) {
|
|
10909
|
+
childEnd = processCondition(
|
|
10910
|
+
related.subquery.where,
|
|
10911
|
+
childEnd,
|
|
10912
|
+
graph,
|
|
10913
|
+
model,
|
|
10914
|
+
childTable,
|
|
10915
|
+
getPlanId
|
|
10916
|
+
);
|
|
10917
|
+
}
|
|
10918
|
+
const parentConstraint = extractConstraint(
|
|
10919
|
+
related.correlation.parentField,
|
|
10920
|
+
parentTable
|
|
10921
|
+
);
|
|
10922
|
+
const childConstraint = extractConstraint(
|
|
10923
|
+
related.correlation.childField,
|
|
10924
|
+
childTable
|
|
10925
|
+
);
|
|
10926
|
+
const planId = getPlanId();
|
|
10927
|
+
condition[planIdSymbol] = planId;
|
|
10928
|
+
const join = new PlannerJoin(
|
|
10929
|
+
input,
|
|
10930
|
+
childEnd,
|
|
10931
|
+
parentConstraint,
|
|
10932
|
+
childConstraint,
|
|
10933
|
+
condition.op !== "NOT EXISTS",
|
|
10934
|
+
planId
|
|
10935
|
+
);
|
|
10936
|
+
graph.joins.push(join);
|
|
10937
|
+
wireOutput(input, join);
|
|
10938
|
+
wireOutput(childEnd, join);
|
|
10939
|
+
return join;
|
|
10940
|
+
}
|
|
10941
|
+
function hasCorrelatedSubquery(condition) {
|
|
10942
|
+
if (condition.type === "correlatedSubquery") {
|
|
10943
|
+
return true;
|
|
10944
|
+
}
|
|
10945
|
+
if (condition.type === "and" || condition.type === "or") {
|
|
10946
|
+
return condition.conditions.some(hasCorrelatedSubquery);
|
|
10947
|
+
}
|
|
10948
|
+
return false;
|
|
10949
|
+
}
|
|
10950
|
+
function extractConstraint(fields, _tableName) {
|
|
10951
|
+
return Object.fromEntries(fields.map((field) => [field, void 0]));
|
|
10952
|
+
}
|
|
10953
|
+
function planRecursively(plans, planDebugger) {
|
|
10954
|
+
for (const subPlan of Object.values(plans.subPlans)) {
|
|
10955
|
+
planRecursively(subPlan, planDebugger);
|
|
10956
|
+
}
|
|
10957
|
+
plans.plan.plan(planDebugger);
|
|
10958
|
+
}
|
|
10959
|
+
function planQuery(ast, model, planDebugger) {
|
|
10960
|
+
const plans = buildPlanGraph(ast, model, true);
|
|
10961
|
+
planRecursively(plans, planDebugger);
|
|
10962
|
+
return applyPlansToAST(ast, plans);
|
|
10963
|
+
}
|
|
10964
|
+
function applyToCondition(condition, flippedIds) {
|
|
10965
|
+
if (condition.type === "simple") {
|
|
10966
|
+
return condition;
|
|
10967
|
+
}
|
|
10968
|
+
if (condition.type === "correlatedSubquery") {
|
|
10969
|
+
const planId = condition[planIdSymbol];
|
|
10970
|
+
const shouldFlip = planId !== void 0 && flippedIds.has(planId);
|
|
10971
|
+
return {
|
|
10972
|
+
...condition,
|
|
10973
|
+
flip: shouldFlip ? true : condition.flip,
|
|
10974
|
+
related: {
|
|
10975
|
+
...condition.related,
|
|
10976
|
+
subquery: {
|
|
10977
|
+
...condition.related.subquery,
|
|
10978
|
+
where: condition.related.subquery.where ? applyToCondition(condition.related.subquery.where, flippedIds) : void 0
|
|
10979
|
+
}
|
|
9298
10980
|
}
|
|
9299
|
-
}
|
|
9300
|
-
|
|
10981
|
+
};
|
|
10982
|
+
}
|
|
10983
|
+
return {
|
|
10984
|
+
...condition,
|
|
10985
|
+
conditions: condition.conditions.map((c) => applyToCondition(c, flippedIds))
|
|
10986
|
+
};
|
|
10987
|
+
}
|
|
10988
|
+
function applyPlansToAST(ast, plans) {
|
|
10989
|
+
const flippedIds = /* @__PURE__ */ new Set();
|
|
10990
|
+
for (const join of plans.plan.joins) {
|
|
10991
|
+
if (join.type === "flipped" && join.planId !== void 0) {
|
|
10992
|
+
flippedIds.add(join.planId);
|
|
9301
10993
|
}
|
|
9302
10994
|
}
|
|
9303
|
-
|
|
10995
|
+
return {
|
|
10996
|
+
...ast,
|
|
10997
|
+
where: ast.where ? applyToCondition(ast.where, flippedIds) : void 0,
|
|
10998
|
+
related: ast.related?.map((csq) => {
|
|
10999
|
+
const alias = must(
|
|
11000
|
+
csq.subquery.alias,
|
|
11001
|
+
"Related subquery must have alias"
|
|
11002
|
+
);
|
|
11003
|
+
const subPlan = plans.subPlans[alias];
|
|
11004
|
+
return {
|
|
11005
|
+
...csq,
|
|
11006
|
+
subquery: subPlan ? applyPlansToAST(csq.subquery, subPlan) : csq.subquery
|
|
11007
|
+
};
|
|
11008
|
+
})
|
|
11009
|
+
};
|
|
11010
|
+
}
|
|
9304
11011
|
|
|
9305
11012
|
// ../zql/src/query/expression.ts
|
|
9306
11013
|
var ExpressionBuilder = class {
|
|
@@ -9461,8 +11168,8 @@ var negateOperatorMap = {
|
|
|
9461
11168
|
function negateOperator(op) {
|
|
9462
11169
|
return must(negateOperatorMap[op]);
|
|
9463
11170
|
}
|
|
9464
|
-
function filterUndefined(
|
|
9465
|
-
return
|
|
11171
|
+
function filterUndefined(array10) {
|
|
11172
|
+
return array10.filter((e) => e !== void 0);
|
|
9466
11173
|
}
|
|
9467
11174
|
function filterTrue(conditions) {
|
|
9468
11175
|
return conditions.filter((c) => !isAlwaysTrue(c));
|
|
@@ -9666,8 +11373,11 @@ function transformFilters(filters) {
|
|
|
9666
11373
|
}
|
|
9667
11374
|
|
|
9668
11375
|
// ../zql/src/builder/builder.ts
|
|
9669
|
-
function buildPipeline(ast, delegate, queryID) {
|
|
11376
|
+
function buildPipeline(ast, delegate, queryID, costModel) {
|
|
9670
11377
|
ast = delegate.mapAst ? delegate.mapAst(ast) : ast;
|
|
11378
|
+
if (costModel) {
|
|
11379
|
+
ast = planQuery(ast, costModel);
|
|
11380
|
+
}
|
|
9671
11381
|
return buildPipelineInternal(ast, delegate, queryID, "");
|
|
9672
11382
|
}
|
|
9673
11383
|
var EXISTS_LIMIT = 3;
|
|
@@ -11097,22 +12807,45 @@ var MockClientLockManager = class {
|
|
|
11097
12807
|
// ../zero-client/src/client/connection-manager.ts
|
|
11098
12808
|
import { resolver as resolver9 } from "@rocicorp/resolver";
|
|
11099
12809
|
|
|
11100
|
-
// ../
|
|
11101
|
-
var
|
|
11102
|
-
|
|
11103
|
-
|
|
11104
|
-
|
|
11105
|
-
|
|
11106
|
-
|
|
11107
|
-
|
|
11108
|
-
|
|
11109
|
-
|
|
11110
|
-
|
|
11111
|
-
|
|
12810
|
+
// ../shared/src/subscribable.ts
|
|
12811
|
+
var Subscribable = class {
|
|
12812
|
+
_listeners = /* @__PURE__ */ new Set();
|
|
12813
|
+
/**
|
|
12814
|
+
* Subscribe to the subscribable.
|
|
12815
|
+
*
|
|
12816
|
+
* @param listener - The listener to subscribe to.
|
|
12817
|
+
* @returns A function to unsubscribe from the subscribable.
|
|
12818
|
+
*/
|
|
12819
|
+
subscribe = (listener) => {
|
|
12820
|
+
this._listeners.add(listener);
|
|
12821
|
+
return () => {
|
|
12822
|
+
this._listeners.delete(listener);
|
|
12823
|
+
};
|
|
12824
|
+
};
|
|
12825
|
+
/**
|
|
12826
|
+
* Notify all listeners.
|
|
12827
|
+
*
|
|
12828
|
+
* @param update - The update to notify listeners with.
|
|
12829
|
+
*/
|
|
12830
|
+
notify = (update) => {
|
|
12831
|
+
this._listeners.forEach((listener) => listener(update));
|
|
12832
|
+
};
|
|
12833
|
+
hasListeners = () => this._listeners.size > 0;
|
|
12834
|
+
/**
|
|
12835
|
+
* Unsubscribe all listeners.
|
|
12836
|
+
*/
|
|
12837
|
+
cleanup = () => {
|
|
12838
|
+
this._listeners.clear();
|
|
12839
|
+
};
|
|
12840
|
+
};
|
|
11112
12841
|
|
|
11113
12842
|
// ../zero-client/src/client/connection-manager.ts
|
|
11114
12843
|
var DEFAULT_TIMEOUT_CHECK_INTERVAL_MS = 1e3;
|
|
11115
|
-
var
|
|
12844
|
+
var TERMINAL_STATES = [
|
|
12845
|
+
connection_status_enum_exports.NeedsAuth,
|
|
12846
|
+
connection_status_enum_exports.Error
|
|
12847
|
+
];
|
|
12848
|
+
var ConnectionManager = class _ConnectionManager extends Subscribable {
|
|
11116
12849
|
#state;
|
|
11117
12850
|
/**
|
|
11118
12851
|
* The timestamp when we first started trying to connect.
|
|
@@ -11160,14 +12893,34 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11160
12893
|
is(status) {
|
|
11161
12894
|
return this.#state.name === status;
|
|
11162
12895
|
}
|
|
12896
|
+
/**
|
|
12897
|
+
* Returns true if the current state is a terminal state
|
|
12898
|
+
* that can be recovered from by calling connect().
|
|
12899
|
+
*/
|
|
12900
|
+
isInTerminalState() {
|
|
12901
|
+
return _ConnectionManager.isTerminalState(this.#state);
|
|
12902
|
+
}
|
|
12903
|
+
/**
|
|
12904
|
+
* Returns true if the given status is a terminal state
|
|
12905
|
+
* that can be recovered from by calling connect().
|
|
12906
|
+
*/
|
|
12907
|
+
static isTerminalState(state) {
|
|
12908
|
+
return TERMINAL_STATES.includes(
|
|
12909
|
+
state.name
|
|
12910
|
+
);
|
|
12911
|
+
}
|
|
11163
12912
|
/**
|
|
11164
12913
|
* Returns true if the run loop should continue.
|
|
11165
|
-
* The run loop continues in
|
|
11166
|
-
*
|
|
12914
|
+
* The run loop continues in all states except closed.
|
|
12915
|
+
* In needs-auth and error states, the run loop pauses and waits for connect() to be called.
|
|
11167
12916
|
*/
|
|
11168
12917
|
shouldContinueRunLoop() {
|
|
11169
12918
|
return this.#state.name !== connection_status_enum_exports.Closed;
|
|
11170
12919
|
}
|
|
12920
|
+
/**
|
|
12921
|
+
* Waits for the next state change.
|
|
12922
|
+
* @returns A promise that resolves when the next state change occurs.
|
|
12923
|
+
*/
|
|
11171
12924
|
waitForStateChange() {
|
|
11172
12925
|
return this.#nextStatePromise();
|
|
11173
12926
|
}
|
|
@@ -11217,42 +12970,88 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11217
12970
|
*
|
|
11218
12971
|
* @returns An object containing a promise that resolves on the next state change.
|
|
11219
12972
|
*/
|
|
11220
|
-
connected() {
|
|
12973
|
+
connected() {
|
|
12974
|
+
if (this.#state.name === connection_status_enum_exports.Closed) {
|
|
12975
|
+
return { nextStatePromise: this.#nextStatePromise() };
|
|
12976
|
+
}
|
|
12977
|
+
if (this.#state.name === connection_status_enum_exports.Connected) {
|
|
12978
|
+
return { nextStatePromise: this.#nextStatePromise() };
|
|
12979
|
+
}
|
|
12980
|
+
this.#connectingStartedAt = void 0;
|
|
12981
|
+
this.#maybeStopTimeoutInterval();
|
|
12982
|
+
this.#state = {
|
|
12983
|
+
name: connection_status_enum_exports.Connected
|
|
12984
|
+
};
|
|
12985
|
+
const nextStatePromise = this.#publishStateAndGetPromise();
|
|
12986
|
+
return { nextStatePromise };
|
|
12987
|
+
}
|
|
12988
|
+
/**
|
|
12989
|
+
* Transition to disconnected state.
|
|
12990
|
+
* This is called when the 5-minute timeout expires, or when we're intentionally
|
|
12991
|
+
* disconnecting due to an error (this will eventually be a separate state, error).
|
|
12992
|
+
* The run loop will continue trying to reconnect.
|
|
12993
|
+
*
|
|
12994
|
+
* @returns An object containing a promise that resolves on the next state change.
|
|
12995
|
+
*/
|
|
12996
|
+
disconnected(reason) {
|
|
12997
|
+
if (this.#state.name === connection_status_enum_exports.Closed) {
|
|
12998
|
+
return { nextStatePromise: this.#nextStatePromise() };
|
|
12999
|
+
}
|
|
13000
|
+
if (this.#state.name === connection_status_enum_exports.Disconnected) {
|
|
13001
|
+
return { nextStatePromise: this.#nextStatePromise() };
|
|
13002
|
+
}
|
|
13003
|
+
if (this.#state.name === connection_status_enum_exports.Connected) {
|
|
13004
|
+
this.#connectingStartedAt = void 0;
|
|
13005
|
+
}
|
|
13006
|
+
this.#maybeStopTimeoutInterval();
|
|
13007
|
+
this.#state = {
|
|
13008
|
+
name: connection_status_enum_exports.Disconnected,
|
|
13009
|
+
reason
|
|
13010
|
+
};
|
|
13011
|
+
const nextStatePromise = this.#publishStateAndGetPromise();
|
|
13012
|
+
return { nextStatePromise };
|
|
13013
|
+
}
|
|
13014
|
+
/**
|
|
13015
|
+
* Transition to needs-auth state.
|
|
13016
|
+
* This pauses the run loop until connect() is called with new credentials.
|
|
13017
|
+
* Resets the retry window and attempt counter.
|
|
13018
|
+
*
|
|
13019
|
+
* @returns An object containing a promise that resolves on the next state change.
|
|
13020
|
+
*/
|
|
13021
|
+
needsAuth(reason) {
|
|
11221
13022
|
if (this.#state.name === connection_status_enum_exports.Closed) {
|
|
11222
13023
|
return { nextStatePromise: this.#nextStatePromise() };
|
|
11223
13024
|
}
|
|
11224
|
-
if (this.#state.name === connection_status_enum_exports.
|
|
13025
|
+
if (this.#state.name === connection_status_enum_exports.NeedsAuth) {
|
|
11225
13026
|
return { nextStatePromise: this.#nextStatePromise() };
|
|
11226
13027
|
}
|
|
11227
13028
|
this.#connectingStartedAt = void 0;
|
|
11228
13029
|
this.#maybeStopTimeoutInterval();
|
|
11229
13030
|
this.#state = {
|
|
11230
|
-
name: connection_status_enum_exports.
|
|
13031
|
+
name: connection_status_enum_exports.NeedsAuth,
|
|
13032
|
+
reason
|
|
11231
13033
|
};
|
|
11232
13034
|
const nextStatePromise = this.#publishStateAndGetPromise();
|
|
11233
13035
|
return { nextStatePromise };
|
|
11234
13036
|
}
|
|
11235
13037
|
/**
|
|
11236
|
-
* Transition to
|
|
11237
|
-
* This
|
|
11238
|
-
*
|
|
11239
|
-
* The run loop will continue trying to reconnect.
|
|
13038
|
+
* Transition to error state.
|
|
13039
|
+
* This pauses the run loop until connect() is called.
|
|
13040
|
+
* Resets the retry window and attempt counter.
|
|
11240
13041
|
*
|
|
11241
13042
|
* @returns An object containing a promise that resolves on the next state change.
|
|
11242
13043
|
*/
|
|
11243
|
-
|
|
13044
|
+
error(reason) {
|
|
11244
13045
|
if (this.#state.name === connection_status_enum_exports.Closed) {
|
|
11245
13046
|
return { nextStatePromise: this.#nextStatePromise() };
|
|
11246
13047
|
}
|
|
11247
|
-
if (this.#state.name === connection_status_enum_exports.
|
|
13048
|
+
if (this.#state.name === connection_status_enum_exports.Error) {
|
|
11248
13049
|
return { nextStatePromise: this.#nextStatePromise() };
|
|
11249
13050
|
}
|
|
11250
|
-
|
|
11251
|
-
this.#connectingStartedAt = void 0;
|
|
11252
|
-
}
|
|
13051
|
+
this.#connectingStartedAt = void 0;
|
|
11253
13052
|
this.#maybeStopTimeoutInterval();
|
|
11254
13053
|
this.#state = {
|
|
11255
|
-
name: connection_status_enum_exports.
|
|
13054
|
+
name: connection_status_enum_exports.Error,
|
|
11256
13055
|
reason
|
|
11257
13056
|
};
|
|
11258
13057
|
const nextStatePromise = this.#publishStateAndGetPromise();
|
|
@@ -11261,27 +13060,30 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11261
13060
|
/**
|
|
11262
13061
|
* Transition to closed state.
|
|
11263
13062
|
* This is terminal - no further transitions are allowed.
|
|
11264
|
-
*
|
|
11265
|
-
* @returns An object containing a promise that resolves on the next state change.
|
|
11266
13063
|
*/
|
|
11267
13064
|
closed() {
|
|
11268
13065
|
if (this.#state.name === connection_status_enum_exports.Closed) {
|
|
11269
|
-
return
|
|
13066
|
+
return;
|
|
11270
13067
|
}
|
|
11271
13068
|
this.#connectingStartedAt = void 0;
|
|
11272
13069
|
this.#maybeStopTimeoutInterval();
|
|
11273
13070
|
this.#state = {
|
|
11274
|
-
name: connection_status_enum_exports.Closed
|
|
13071
|
+
name: connection_status_enum_exports.Closed,
|
|
13072
|
+
reason: new ClientError({
|
|
13073
|
+
kind: client_error_kind_enum_exports.ClientClosed,
|
|
13074
|
+
message: "Zero was explicitly closed by calling zero.close()"
|
|
13075
|
+
})
|
|
11275
13076
|
};
|
|
11276
|
-
|
|
11277
|
-
|
|
13077
|
+
this.#publishState();
|
|
13078
|
+
this.cleanup();
|
|
13079
|
+
return;
|
|
11278
13080
|
}
|
|
11279
13081
|
cleanup = () => {
|
|
11280
13082
|
this._listeners.clear();
|
|
11281
13083
|
this.#resolveNextStateWaiters();
|
|
11282
13084
|
};
|
|
11283
13085
|
#resolveNextStateWaiters() {
|
|
11284
|
-
this.#stateChangeResolver.resolve();
|
|
13086
|
+
this.#stateChangeResolver.resolve(this.#state);
|
|
11285
13087
|
this.#stateChangeResolver = resolver9();
|
|
11286
13088
|
}
|
|
11287
13089
|
#publishState() {
|
|
@@ -11305,7 +13107,12 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11305
13107
|
}
|
|
11306
13108
|
const now = Date.now();
|
|
11307
13109
|
if (now >= this.#state.disconnectAt) {
|
|
11308
|
-
this.disconnected(
|
|
13110
|
+
this.disconnected(
|
|
13111
|
+
new ClientError({
|
|
13112
|
+
kind: client_error_kind_enum_exports.DisconnectTimeout,
|
|
13113
|
+
message: `Zero was unable to connect for ${Math.floor(this.#disconnectTimeoutMs / 1e3)} seconds and was disconnected`
|
|
13114
|
+
})
|
|
13115
|
+
);
|
|
11309
13116
|
return true;
|
|
11310
13117
|
}
|
|
11311
13118
|
return false;
|
|
@@ -11326,6 +13133,62 @@ var ConnectionManager = class extends Subscribable {
|
|
|
11326
13133
|
this.#timeoutInterval = void 0;
|
|
11327
13134
|
}
|
|
11328
13135
|
};
|
|
13136
|
+
var throwIfConnectionError = (state) => {
|
|
13137
|
+
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) {
|
|
13138
|
+
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)) {
|
|
13139
|
+
return;
|
|
13140
|
+
}
|
|
13141
|
+
throw state.reason;
|
|
13142
|
+
}
|
|
13143
|
+
};
|
|
13144
|
+
|
|
13145
|
+
// ../zero-client/src/client/connection.ts
|
|
13146
|
+
var ConnectionImpl = class {
|
|
13147
|
+
#connectionManager;
|
|
13148
|
+
#lc;
|
|
13149
|
+
#source;
|
|
13150
|
+
#setAuth;
|
|
13151
|
+
constructor(connectionManager, lc, setAuth) {
|
|
13152
|
+
this.#connectionManager = connectionManager;
|
|
13153
|
+
this.#lc = lc;
|
|
13154
|
+
this.#source = new ConnectionSource(connectionManager);
|
|
13155
|
+
this.#setAuth = setAuth;
|
|
13156
|
+
}
|
|
13157
|
+
get state() {
|
|
13158
|
+
return this.#source;
|
|
13159
|
+
}
|
|
13160
|
+
async connect(opts) {
|
|
13161
|
+
const lc = this.#lc.withContext("connect");
|
|
13162
|
+
if (opts && "auth" in opts) {
|
|
13163
|
+
lc.debug?.("Updating auth credential from connect()");
|
|
13164
|
+
this.#setAuth(opts.auth);
|
|
13165
|
+
}
|
|
13166
|
+
if (!this.#connectionManager.isInTerminalState()) {
|
|
13167
|
+
lc.debug?.(
|
|
13168
|
+
"connect() called but not in a terminal state. Current state:",
|
|
13169
|
+
this.#connectionManager.state.name
|
|
13170
|
+
);
|
|
13171
|
+
return;
|
|
13172
|
+
}
|
|
13173
|
+
lc.info?.(
|
|
13174
|
+
`Resuming connection from state: ${this.#connectionManager.state.name}`
|
|
13175
|
+
);
|
|
13176
|
+
const { nextStatePromise } = this.#connectionManager.connecting();
|
|
13177
|
+
await nextStatePromise;
|
|
13178
|
+
}
|
|
13179
|
+
};
|
|
13180
|
+
var ConnectionSource = class {
|
|
13181
|
+
#connectionManager;
|
|
13182
|
+
constructor(connectionManager) {
|
|
13183
|
+
this.#connectionManager = connectionManager;
|
|
13184
|
+
}
|
|
13185
|
+
get current() {
|
|
13186
|
+
return this.#connectionManager.state;
|
|
13187
|
+
}
|
|
13188
|
+
get subscribe() {
|
|
13189
|
+
return this.#connectionManager.subscribe;
|
|
13190
|
+
}
|
|
13191
|
+
};
|
|
11329
13192
|
|
|
11330
13193
|
// ../zql/src/ivm/memory-storage.ts
|
|
11331
13194
|
import { compareUTF8 as compareUTF83 } from "compare-utf8";
|
|
@@ -13267,7 +15130,7 @@ function makeMessage(message, context, logLevel) {
|
|
|
13267
15130
|
}
|
|
13268
15131
|
|
|
13269
15132
|
// ../zero-client/src/client/version.ts
|
|
13270
|
-
var version2 = "0.25.0-canary.
|
|
15133
|
+
var version2 = "0.25.0-canary.2";
|
|
13271
15134
|
|
|
13272
15135
|
// ../zero-client/src/client/log-options.ts
|
|
13273
15136
|
var LevelFilterLogSink = class {
|
|
@@ -13323,74 +15186,6 @@ function createLogOptions(options, createDatadogLogSink = (options2) => new Data
|
|
|
13323
15186
|
};
|
|
13324
15187
|
}
|
|
13325
15188
|
|
|
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
15189
|
// ../zero-client/src/client/metric-name-enum.ts
|
|
13395
15190
|
var metric_name_enum_exports = {};
|
|
13396
15191
|
__export(metric_name_enum_exports, {
|
|
@@ -13417,6 +15212,21 @@ function getLastConnectErrorValue(reason) {
|
|
|
13417
15212
|
function camelToSnake(kind) {
|
|
13418
15213
|
return kind.split(/\.?(?=[A-Z])/).join("_").toLowerCase();
|
|
13419
15214
|
}
|
|
15215
|
+
function shouldReportConnectError(reason) {
|
|
15216
|
+
if (!isClientError(reason)) {
|
|
15217
|
+
return true;
|
|
15218
|
+
}
|
|
15219
|
+
switch (reason.kind) {
|
|
15220
|
+
case client_error_kind_enum_exports.Hidden:
|
|
15221
|
+
case client_error_kind_enum_exports.ClientClosed:
|
|
15222
|
+
case client_error_kind_enum_exports.UserDisconnect:
|
|
15223
|
+
case client_error_kind_enum_exports.CleanClose:
|
|
15224
|
+
case client_error_kind_enum_exports.AbruptClose:
|
|
15225
|
+
return false;
|
|
15226
|
+
default:
|
|
15227
|
+
return true;
|
|
15228
|
+
}
|
|
15229
|
+
}
|
|
13420
15230
|
var MetricManager = class {
|
|
13421
15231
|
#reportIntervalMs;
|
|
13422
15232
|
#host;
|
|
@@ -13647,10 +15457,11 @@ var MutationTracker = class {
|
|
|
13647
15457
|
#allMutationsAppliedListeners;
|
|
13648
15458
|
#lc;
|
|
13649
15459
|
#ackMutations;
|
|
15460
|
+
#onFatalError;
|
|
13650
15461
|
#clientID;
|
|
13651
15462
|
#largestOutstandingMutationID;
|
|
13652
15463
|
#currentMutationID;
|
|
13653
|
-
constructor(lc, ackMutations) {
|
|
15464
|
+
constructor(lc, ackMutations, onFatalError) {
|
|
13654
15465
|
this.#lc = lc.withContext("MutationTracker");
|
|
13655
15466
|
this.#outstandingMutations = /* @__PURE__ */ new Map();
|
|
13656
15467
|
this.#ephemeralIDsByMutationID = /* @__PURE__ */ new Map();
|
|
@@ -13658,6 +15469,7 @@ var MutationTracker = class {
|
|
|
13658
15469
|
this.#largestOutstandingMutationID = 0;
|
|
13659
15470
|
this.#currentMutationID = 0;
|
|
13660
15471
|
this.#ackMutations = ackMutations;
|
|
15472
|
+
this.#onFatalError = onFatalError;
|
|
13661
15473
|
}
|
|
13662
15474
|
setClientIDAndWatch(clientID, experimentalWatch) {
|
|
13663
15475
|
assert(this.#clientID === void 0, "clientID already set");
|
|
@@ -13698,7 +15510,7 @@ var MutationTracker = class {
|
|
|
13698
15510
|
rejectMutation(id, e) {
|
|
13699
15511
|
const entry = this.#outstandingMutations.get(id);
|
|
13700
15512
|
if (entry) {
|
|
13701
|
-
this.#settleMutation(id, entry, "reject", e);
|
|
15513
|
+
this.#settleMutation(id, entry, "reject", wrapWithApplicationError(e));
|
|
13702
15514
|
}
|
|
13703
15515
|
}
|
|
13704
15516
|
/**
|
|
@@ -13745,10 +15557,53 @@ var MutationTracker = class {
|
|
|
13745
15557
|
"Received an error response when pushing mutations",
|
|
13746
15558
|
response
|
|
13747
15559
|
);
|
|
15560
|
+
const fatalError = this.#fatalErrorFromPushError(response);
|
|
15561
|
+
if (fatalError) {
|
|
15562
|
+
this.#onFatalError(fatalError);
|
|
15563
|
+
}
|
|
13748
15564
|
} else {
|
|
13749
15565
|
this.#processPushOk(response);
|
|
13750
15566
|
}
|
|
13751
15567
|
}
|
|
15568
|
+
#fatalErrorFromPushError(error) {
|
|
15569
|
+
switch (error.error) {
|
|
15570
|
+
case "unsupportedPushVersion":
|
|
15571
|
+
return new ProtocolError({
|
|
15572
|
+
kind: error_kind_enum_exports.PushFailed,
|
|
15573
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15574
|
+
reason: error_reason_enum_exports.Internal,
|
|
15575
|
+
message: `Unsupported push version`,
|
|
15576
|
+
mutationIDs: []
|
|
15577
|
+
});
|
|
15578
|
+
case "unsupportedSchemaVersion":
|
|
15579
|
+
return new ProtocolError({
|
|
15580
|
+
kind: error_kind_enum_exports.PushFailed,
|
|
15581
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15582
|
+
reason: error_reason_enum_exports.Internal,
|
|
15583
|
+
message: `Unsupported schema version`,
|
|
15584
|
+
mutationIDs: []
|
|
15585
|
+
});
|
|
15586
|
+
case "http":
|
|
15587
|
+
return new ProtocolError({
|
|
15588
|
+
kind: error_kind_enum_exports.PushFailed,
|
|
15589
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15590
|
+
reason: error_reason_enum_exports.HTTP,
|
|
15591
|
+
status: error.status,
|
|
15592
|
+
message: `Fetch from API server returned non-OK status ${error.status}: ${error.details ?? "unknown"}`,
|
|
15593
|
+
mutationIDs: []
|
|
15594
|
+
});
|
|
15595
|
+
case "zeroPusher":
|
|
15596
|
+
return new ProtocolError({
|
|
15597
|
+
kind: error_kind_enum_exports.PushFailed,
|
|
15598
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15599
|
+
reason: error_reason_enum_exports.Internal,
|
|
15600
|
+
message: `ZeroPusher error: ${error.details ?? "unknown"}`,
|
|
15601
|
+
mutationIDs: []
|
|
15602
|
+
});
|
|
15603
|
+
default:
|
|
15604
|
+
unreachable(error);
|
|
15605
|
+
}
|
|
15606
|
+
}
|
|
13752
15607
|
/**
|
|
13753
15608
|
* DEPRECATED: to be removed when we switch to fully driving
|
|
13754
15609
|
* mutation resolution via poke.
|
|
@@ -13841,7 +15696,28 @@ var MutationTracker = class {
|
|
|
13841
15696
|
);
|
|
13842
15697
|
const entry = this.#outstandingMutations.get(ephemeralID);
|
|
13843
15698
|
assert(entry && entry.mutationID === mid);
|
|
13844
|
-
this.#settleMutation(
|
|
15699
|
+
this.#settleMutation(
|
|
15700
|
+
ephemeralID,
|
|
15701
|
+
entry,
|
|
15702
|
+
"reject",
|
|
15703
|
+
error.error === "app" ? new ApplicationError(
|
|
15704
|
+
error.message ?? `Unknown application error: ${error.error}`,
|
|
15705
|
+
error.details ? { details: error.details } : void 0
|
|
15706
|
+
) : new Error(
|
|
15707
|
+
error.error === "alreadyProcessed" ? "Mutation already processed" : error.error === "oooMutation" ? "Server reported an out-of-order mutation" : `Unknown fallback error with mutation ID ${mid}: ${error.error}`
|
|
15708
|
+
)
|
|
15709
|
+
);
|
|
15710
|
+
if (error.error === "oooMutation") {
|
|
15711
|
+
this.#onFatalError(
|
|
15712
|
+
new ProtocolError({
|
|
15713
|
+
kind: error_kind_enum_exports.InvalidPush,
|
|
15714
|
+
origin: error_origin_enum_exports.Server,
|
|
15715
|
+
reason: error_reason_enum_exports.Internal,
|
|
15716
|
+
message: "Server reported an out-of-order mutation",
|
|
15717
|
+
details: error.details
|
|
15718
|
+
})
|
|
15719
|
+
);
|
|
15720
|
+
}
|
|
13845
15721
|
}
|
|
13846
15722
|
#processMutationOk(clientID, mid, result) {
|
|
13847
15723
|
assert(
|
|
@@ -13891,16 +15767,13 @@ var MutationTracker = class {
|
|
|
13891
15767
|
}
|
|
13892
15768
|
};
|
|
13893
15769
|
|
|
13894
|
-
// ../zero-client/src/client/ping-result-enum.ts
|
|
13895
|
-
var TimedOut = 0;
|
|
13896
|
-
var Success = 1;
|
|
13897
|
-
|
|
13898
15770
|
// ../zero-client/src/client/query-manager.ts
|
|
13899
15771
|
var QueryManager = class {
|
|
13900
15772
|
#clientID;
|
|
13901
15773
|
#clientToServer;
|
|
13902
15774
|
#serverToClient;
|
|
13903
15775
|
#send;
|
|
15776
|
+
#onFatalError;
|
|
13904
15777
|
#queries = /* @__PURE__ */ new Map();
|
|
13905
15778
|
#recentQueriesMaxSize;
|
|
13906
15779
|
#recentQueries = /* @__PURE__ */ new Set();
|
|
@@ -13914,7 +15787,7 @@ var QueryManager = class {
|
|
|
13914
15787
|
#metrics = newMetrics();
|
|
13915
15788
|
#queryMetrics = /* @__PURE__ */ new Map();
|
|
13916
15789
|
#slowMaterializeThreshold;
|
|
13917
|
-
constructor(lc, mutationTracker, clientID, tables, send2, experimentalWatch, recentQueriesMaxSize, queryChangeThrottleMs, slowMaterializeThreshold) {
|
|
15790
|
+
constructor(lc, mutationTracker, clientID, tables, send2, experimentalWatch, recentQueriesMaxSize, queryChangeThrottleMs, slowMaterializeThreshold, onFatalError) {
|
|
13918
15791
|
this.#lc = lc.withContext("QueryManager");
|
|
13919
15792
|
this.#clientID = clientID;
|
|
13920
15793
|
this.#clientToServer = clientToServer(tables);
|
|
@@ -13924,6 +15797,7 @@ var QueryManager = class {
|
|
|
13924
15797
|
this.#mutationTracker = mutationTracker;
|
|
13925
15798
|
this.#queryChangeThrottleMs = queryChangeThrottleMs;
|
|
13926
15799
|
this.#slowMaterializeThreshold = slowMaterializeThreshold;
|
|
15800
|
+
this.#onFatalError = onFatalError;
|
|
13927
15801
|
this.#mutationTracker.onAllMutationsApplied(() => {
|
|
13928
15802
|
if (this.#pendingRemovals.length === 0) {
|
|
13929
15803
|
return;
|
|
@@ -14027,8 +15901,21 @@ var QueryManager = class {
|
|
|
14027
15901
|
for (const error of errors) {
|
|
14028
15902
|
const queryId = error.id;
|
|
14029
15903
|
const entry = this.#queries.get(queryId);
|
|
14030
|
-
if (entry) {
|
|
15904
|
+
if (!entry) {
|
|
15905
|
+
continue;
|
|
15906
|
+
}
|
|
15907
|
+
if (error.error === "app" || error.error === "parse") {
|
|
14031
15908
|
entry.gotCallbacks.forEach((callback) => callback(false, error));
|
|
15909
|
+
} else {
|
|
15910
|
+
this.#onFatalError(
|
|
15911
|
+
new ProtocolError({
|
|
15912
|
+
kind: error_kind_enum_exports.TransformFailed,
|
|
15913
|
+
origin: error_origin_enum_exports.ZeroCache,
|
|
15914
|
+
reason: error_reason_enum_exports.Internal,
|
|
15915
|
+
message: `Unknown error transforming queries: ${JSON.stringify(error)}`,
|
|
15916
|
+
queryIDs: []
|
|
15917
|
+
})
|
|
15918
|
+
);
|
|
14032
15919
|
}
|
|
14033
15920
|
}
|
|
14034
15921
|
}
|
|
@@ -14689,13 +16576,17 @@ function rafFallback(callback) {
|
|
|
14689
16576
|
}
|
|
14690
16577
|
|
|
14691
16578
|
// ../zero-client/src/client/zero-rep.ts
|
|
16579
|
+
var REPLICACHE_NO_AUTH_TOKEN = "";
|
|
16580
|
+
var toReplicacheAuthToken = (auth) => auth ?? REPLICACHE_NO_AUTH_TOKEN;
|
|
16581
|
+
var fromReplicacheAuthToken = (auth) => !auth ? void 0 : auth;
|
|
14692
16582
|
var ZeroRep = class {
|
|
14693
16583
|
#context;
|
|
14694
16584
|
#ivmMain;
|
|
14695
16585
|
#customMutatorsEnabled;
|
|
14696
16586
|
#mutationTracker;
|
|
14697
16587
|
#store;
|
|
14698
|
-
|
|
16588
|
+
// matches replicache's auth token type
|
|
16589
|
+
#auth = REPLICACHE_NO_AUTH_TOKEN;
|
|
14699
16590
|
constructor(context, ivmMain, customMutatorsEnabled, mutationTracker) {
|
|
14700
16591
|
this.#context = context;
|
|
14701
16592
|
this.#ivmMain = ivmMain;
|
|
@@ -14703,11 +16594,7 @@ var ZeroRep = class {
|
|
|
14703
16594
|
this.#mutationTracker = mutationTracker;
|
|
14704
16595
|
}
|
|
14705
16596
|
set auth(auth) {
|
|
14706
|
-
|
|
14707
|
-
this.#auth = void 0;
|
|
14708
|
-
} else {
|
|
14709
|
-
this.#auth = auth;
|
|
14710
|
-
}
|
|
16597
|
+
this.#auth = auth;
|
|
14711
16598
|
}
|
|
14712
16599
|
async init(hash, store) {
|
|
14713
16600
|
const diffs = [];
|
|
@@ -14733,7 +16620,7 @@ var ZeroRep = class {
|
|
|
14733
16620
|
}
|
|
14734
16621
|
return this.#ivmMain.forkToHead(must(this.#store), desiredHead, readOptions).then((branch) => ({
|
|
14735
16622
|
ivmSources: branch,
|
|
14736
|
-
token: this.#auth
|
|
16623
|
+
token: fromReplicacheAuthToken(this.#auth)
|
|
14737
16624
|
}));
|
|
14738
16625
|
};
|
|
14739
16626
|
advance = (expectedHash, newHash, diffs) => {
|
|
@@ -14845,20 +16732,21 @@ var Zero = class _Zero {
|
|
|
14845
16732
|
};
|
|
14846
16733
|
#zeroContext;
|
|
14847
16734
|
queryDelegate;
|
|
14848
|
-
#connectResolver = resolver11();
|
|
14849
16735
|
#pendingPullsByRequestID = /* @__PURE__ */ new Map();
|
|
14850
16736
|
#lastMutationIDReceived = 0;
|
|
14851
16737
|
#socket = void 0;
|
|
14852
16738
|
#socketResolver = resolver11();
|
|
14853
16739
|
/**
|
|
14854
|
-
*
|
|
14855
|
-
*
|
|
14856
|
-
*
|
|
16740
|
+
* Utility promise that resolves when the socket transitions to connected.
|
|
16741
|
+
* It rejects if we hit an error or timeout before the connected message.
|
|
16742
|
+
* Used by push/pull helpers to queue work until the connection is usable.
|
|
14857
16743
|
*/
|
|
14858
|
-
#
|
|
16744
|
+
#connectResolver = resolver11();
|
|
14859
16745
|
#closeAbortController = new AbortController();
|
|
14860
16746
|
#visibilityWatcher;
|
|
14861
16747
|
#connectionManager;
|
|
16748
|
+
#connection;
|
|
16749
|
+
#unsubscribeConnectionState = void 0;
|
|
14862
16750
|
#activeClientsManager;
|
|
14863
16751
|
#inspector;
|
|
14864
16752
|
#connectStart = void 0;
|
|
@@ -14894,7 +16782,10 @@ var Zero = class _Zero {
|
|
|
14894
16782
|
slowMaterializeThreshold = 5e3
|
|
14895
16783
|
} = options;
|
|
14896
16784
|
if (!userID) {
|
|
14897
|
-
throw new
|
|
16785
|
+
throw new ClientError({
|
|
16786
|
+
kind: client_error_kind_enum_exports.Internal,
|
|
16787
|
+
message: "ZeroOptions.userID must not be empty."
|
|
16788
|
+
});
|
|
14898
16789
|
}
|
|
14899
16790
|
const server = getServer(options.server);
|
|
14900
16791
|
this.#enableAnalytics = shouldEnableAnalytics(
|
|
@@ -14912,9 +16803,10 @@ var Zero = class _Zero {
|
|
|
14912
16803
|
}
|
|
14913
16804
|
}
|
|
14914
16805
|
if (hiddenTabDisconnectDelay < 0) {
|
|
14915
|
-
throw new
|
|
14916
|
-
|
|
14917
|
-
|
|
16806
|
+
throw new ClientError({
|
|
16807
|
+
kind: client_error_kind_enum_exports.Internal,
|
|
16808
|
+
message: "ZeroOptions.hiddenTabDisconnectDelay must not be negative."
|
|
16809
|
+
});
|
|
14918
16810
|
}
|
|
14919
16811
|
this.#onlineManager = new OnlineManager();
|
|
14920
16812
|
if (onOnlineChange) {
|
|
@@ -14931,9 +16823,19 @@ var Zero = class _Zero {
|
|
|
14931
16823
|
this.#connectionManager = new ConnectionManager({
|
|
14932
16824
|
disconnectTimeoutMs: DEFAULT_DISCONNECT_TIMEOUT_MS
|
|
14933
16825
|
});
|
|
16826
|
+
const syncOnlineState = (state) => {
|
|
16827
|
+
this.#onlineManager.setOnline(state.name === connection_status_enum_exports.Connected);
|
|
16828
|
+
};
|
|
16829
|
+
syncOnlineState(this.#connectionManager.state);
|
|
16830
|
+
this.#unsubscribeConnectionState = this.#connectionManager.subscribe(syncOnlineState);
|
|
14934
16831
|
const { enableLegacyMutators = true, enableLegacyQueries = true } = schema;
|
|
14935
16832
|
const replicacheMutators = {
|
|
14936
|
-
[CRUD_MUTATION_NAME]: enableLegacyMutators ? makeCRUDMutator(schema) : () => Promise.reject(
|
|
16833
|
+
[CRUD_MUTATION_NAME]: enableLegacyMutators ? makeCRUDMutator(schema) : () => Promise.reject(
|
|
16834
|
+
new ClientError({
|
|
16835
|
+
kind: client_error_kind_enum_exports.Internal,
|
|
16836
|
+
message: "Zero CRUD mutators are not enabled."
|
|
16837
|
+
})
|
|
16838
|
+
)
|
|
14937
16839
|
};
|
|
14938
16840
|
this.#ivmMain = new IVMSourceBranch(schema.tables);
|
|
14939
16841
|
function assertUnique(key) {
|
|
@@ -14959,7 +16861,10 @@ var Zero = class _Zero {
|
|
|
14959
16861
|
const lc = new ZeroLogContext(logOptions.logLevel, {}, logSink);
|
|
14960
16862
|
this.#mutationTracker = new MutationTracker(
|
|
14961
16863
|
lc,
|
|
14962
|
-
(upTo) => this.#send(["ackMutationResponses", upTo])
|
|
16864
|
+
(upTo) => this.#send(["ackMutationResponses", upTo]),
|
|
16865
|
+
(error) => {
|
|
16866
|
+
this.#disconnect(lc, error);
|
|
16867
|
+
}
|
|
14963
16868
|
);
|
|
14964
16869
|
if (options.mutators) {
|
|
14965
16870
|
for (const [namespaceOrKey, mutatorOrMutators] of Object.entries(
|
|
@@ -15065,6 +16970,11 @@ var Zero = class _Zero {
|
|
|
15065
16970
|
this.#server = server;
|
|
15066
16971
|
this.userID = userID;
|
|
15067
16972
|
this.#lc = lc.withContext("clientID", rep.clientID);
|
|
16973
|
+
this.#connection = new ConnectionImpl(
|
|
16974
|
+
this.#connectionManager,
|
|
16975
|
+
this.#lc,
|
|
16976
|
+
(auth) => this.#setAuth(auth)
|
|
16977
|
+
);
|
|
15068
16978
|
this.#mutationTracker.setClientIDAndWatch(
|
|
15069
16979
|
rep.clientID,
|
|
15070
16980
|
rep.experimentalWatch.bind(rep)
|
|
@@ -15135,7 +17045,10 @@ var Zero = class _Zero {
|
|
|
15135
17045
|
rep.experimentalWatch.bind(rep),
|
|
15136
17046
|
maxRecentQueries,
|
|
15137
17047
|
options.queryChangeThrottleMs ?? DEFAULT_QUERY_CHANGE_THROTTLE_MS,
|
|
15138
|
-
slowMaterializeThreshold
|
|
17048
|
+
slowMaterializeThreshold,
|
|
17049
|
+
(error) => {
|
|
17050
|
+
this.#disconnect(lc, error);
|
|
17051
|
+
}
|
|
15139
17052
|
);
|
|
15140
17053
|
this.#clientToServer = clientToServer(schema.tables);
|
|
15141
17054
|
this.#deleteClientsManager = new DeleteClientsManager(
|
|
@@ -15326,6 +17239,25 @@ var Zero = class _Zero {
|
|
|
15326
17239
|
* will throw an error.
|
|
15327
17240
|
*/
|
|
15328
17241
|
mutateBatch;
|
|
17242
|
+
/**
|
|
17243
|
+
* The connection API for managing Zero's connection lifecycle.
|
|
17244
|
+
*
|
|
17245
|
+
* Use this to monitor connection state and manually control connections.
|
|
17246
|
+
*
|
|
17247
|
+
* @example
|
|
17248
|
+
* ```ts
|
|
17249
|
+
* // Subscribe to connection state changes
|
|
17250
|
+
* z.connection.state.subscribe(state => {
|
|
17251
|
+
* console.log('Connection state:', state.name);
|
|
17252
|
+
* });
|
|
17253
|
+
*
|
|
17254
|
+
* // Manually resume connection from error state
|
|
17255
|
+
* await z.connection.connect();
|
|
17256
|
+
* ```
|
|
17257
|
+
*/
|
|
17258
|
+
get connection() {
|
|
17259
|
+
return this.#connection;
|
|
17260
|
+
}
|
|
15329
17261
|
/**
|
|
15330
17262
|
* Whether this Zero instance has been closed.
|
|
15331
17263
|
*
|
|
@@ -15349,6 +17281,8 @@ var Zero = class _Zero {
|
|
|
15349
17281
|
return;
|
|
15350
17282
|
}
|
|
15351
17283
|
lc.debug?.("Closing Zero instance. Stack:", new Error().stack);
|
|
17284
|
+
this.#unsubscribeConnectionState?.();
|
|
17285
|
+
this.#unsubscribeConnectionState = void 0;
|
|
15352
17286
|
this.#onlineManager.cleanup();
|
|
15353
17287
|
if (!this.#connectionManager.is(connection_status_enum_exports.Disconnected)) {
|
|
15354
17288
|
this.#disconnect(
|
|
@@ -15371,7 +17305,6 @@ var Zero = class _Zero {
|
|
|
15371
17305
|
throw e;
|
|
15372
17306
|
} finally {
|
|
15373
17307
|
this.#connectionManager.closed();
|
|
15374
|
-
this.#connectionManager.cleanup();
|
|
15375
17308
|
}
|
|
15376
17309
|
}
|
|
15377
17310
|
#onMessage = (e) => {
|
|
@@ -15381,11 +17314,6 @@ var Zero = class _Zero {
|
|
|
15381
17314
|
lc.debug?.("ignoring message because already closed");
|
|
15382
17315
|
return;
|
|
15383
17316
|
}
|
|
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
17317
|
let downMessage;
|
|
15390
17318
|
const { data } = e;
|
|
15391
17319
|
try {
|
|
@@ -15395,7 +17323,11 @@ var Zero = class _Zero {
|
|
|
15395
17323
|
"passthrough"
|
|
15396
17324
|
);
|
|
15397
17325
|
} catch (e2) {
|
|
15398
|
-
|
|
17326
|
+
const invalidMessageError = new ClientError({
|
|
17327
|
+
kind: client_error_kind_enum_exports.InvalidMessage,
|
|
17328
|
+
message: `Invalid message received from server: ${e2 instanceof Error ? e2.message + ". " : ""}${data}`
|
|
17329
|
+
});
|
|
17330
|
+
this.#disconnect(lc, invalidMessageError);
|
|
15399
17331
|
return;
|
|
15400
17332
|
}
|
|
15401
17333
|
this.#messageCount++;
|
|
@@ -15430,9 +17362,14 @@ var Zero = class _Zero {
|
|
|
15430
17362
|
break;
|
|
15431
17363
|
case "inspect":
|
|
15432
17364
|
break;
|
|
15433
|
-
default:
|
|
15434
|
-
|
|
15435
|
-
|
|
17365
|
+
default: {
|
|
17366
|
+
const invalidMessageError = new ClientError({
|
|
17367
|
+
kind: client_error_kind_enum_exports.InvalidMessage,
|
|
17368
|
+
message: `Invalid message received from server: ${data}`
|
|
17369
|
+
});
|
|
17370
|
+
this.#disconnect(lc, invalidMessageError);
|
|
17371
|
+
return;
|
|
17372
|
+
}
|
|
15436
17373
|
}
|
|
15437
17374
|
};
|
|
15438
17375
|
#onOpen = () => {
|
|
@@ -15481,11 +17418,10 @@ var Zero = class _Zero {
|
|
|
15481
17418
|
return;
|
|
15482
17419
|
}
|
|
15483
17420
|
lc.info?.(`${kind}: ${message}}`);
|
|
15484
|
-
const error = new
|
|
17421
|
+
const error = new ProtocolError(downMessage[1]);
|
|
15485
17422
|
lc.error?.(`${error.kind}:
|
|
15486
17423
|
|
|
15487
17424
|
${error.errorBody.message}`, error);
|
|
15488
|
-
this.#rejectMessageError?.reject(error);
|
|
15489
17425
|
lc.debug?.("Rejecting connect resolver due to error", error);
|
|
15490
17426
|
this.#connectResolver.reject(error);
|
|
15491
17427
|
this.#disconnect(lc, error);
|
|
@@ -15607,15 +17543,19 @@ ${error.errorBody.message}`, error);
|
|
|
15607
17543
|
* attempt times out.
|
|
15608
17544
|
*/
|
|
15609
17545
|
async #connect(lc, additionalConnectParams) {
|
|
15610
|
-
|
|
17546
|
+
if (this.closed) {
|
|
17547
|
+
return;
|
|
17548
|
+
}
|
|
17549
|
+
assert(this.#server, "No server provided");
|
|
15611
17550
|
assert(
|
|
15612
|
-
this.#connectionManager.is(connection_status_enum_exports.Disconnected) || this.#connectionManager.is(connection_status_enum_exports.Connecting)
|
|
17551
|
+
this.#connectionManager.is(connection_status_enum_exports.Disconnected) || this.#connectionManager.is(connection_status_enum_exports.Connecting),
|
|
17552
|
+
"connect() called from invalid state: " + this.#connectionManager.state.name
|
|
15613
17553
|
);
|
|
15614
17554
|
const wsid = nanoid();
|
|
15615
17555
|
lc = addWebSocketIDToLogContext(wsid, lc);
|
|
15616
17556
|
lc.info?.("Connecting...", { navigatorOnline: localNavigator?.onLine });
|
|
15617
17557
|
this.#connectionManager.connecting();
|
|
15618
|
-
assert(this.#connectStart === void 0);
|
|
17558
|
+
assert(this.#connectStart === void 0, "connect start time is defined");
|
|
15619
17559
|
const now = Date.now();
|
|
15620
17560
|
this.#connectStart = now;
|
|
15621
17561
|
if (this.#totalToConnectStart === void 0) {
|
|
@@ -15655,7 +17595,7 @@ ${error.errorBody.message}`, error);
|
|
|
15655
17595
|
await this.clientGroupID,
|
|
15656
17596
|
this.#clientSchema,
|
|
15657
17597
|
this.userID,
|
|
15658
|
-
this.#rep.auth,
|
|
17598
|
+
fromReplicacheAuthToken(this.#rep.auth),
|
|
15659
17599
|
this.#lastMutationIDReceived,
|
|
15660
17600
|
wsid,
|
|
15661
17601
|
this.#options.logLevel === "debug",
|
|
@@ -15691,8 +17631,14 @@ ${error.errorBody.message}`, error);
|
|
|
15691
17631
|
}
|
|
15692
17632
|
}
|
|
15693
17633
|
#disconnect(lc, reason, closeCode) {
|
|
15694
|
-
if (
|
|
17634
|
+
if (shouldReportConnectError(reason)) {
|
|
15695
17635
|
this.#connectErrorCount++;
|
|
17636
|
+
this.#metrics.lastConnectError.set(getLastConnectErrorValue(reason));
|
|
17637
|
+
this.#metrics.timeToConnectMs.set(DID_NOT_CONNECT_VALUE);
|
|
17638
|
+
this.#metrics.setConnectError(reason);
|
|
17639
|
+
if (this.#connectErrorCount % CHECK_CONNECTIVITY_ON_ERROR_FREQUENCY === 1) {
|
|
17640
|
+
this.#checkConnectivity(`connectErrorCount=${this.#connectErrorCount}`);
|
|
17641
|
+
}
|
|
15696
17642
|
}
|
|
15697
17643
|
lc.info?.("disconnecting", {
|
|
15698
17644
|
navigatorOnline: localNavigator?.onLine,
|
|
@@ -15705,8 +17651,8 @@ ${error.errorBody.message}`, error);
|
|
|
15705
17651
|
connectionState: this.#connectionManager.state,
|
|
15706
17652
|
connectErrorCount: this.#connectErrorCount
|
|
15707
17653
|
});
|
|
15708
|
-
const
|
|
15709
|
-
switch (
|
|
17654
|
+
const connectionStatus = this.#connectionManager.state.name;
|
|
17655
|
+
switch (connectionStatus) {
|
|
15710
17656
|
case connection_status_enum_exports.Connected: {
|
|
15711
17657
|
if (this.#connectStart !== void 0) {
|
|
15712
17658
|
lc.error?.(
|
|
@@ -15715,26 +17661,16 @@ ${error.errorBody.message}`, error);
|
|
|
15715
17661
|
}
|
|
15716
17662
|
break;
|
|
15717
17663
|
}
|
|
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
17664
|
case connection_status_enum_exports.Closed:
|
|
15736
|
-
lc.
|
|
17665
|
+
lc.debug?.("disconnect() called while closed");
|
|
15737
17666
|
return;
|
|
17667
|
+
case connection_status_enum_exports.Disconnected:
|
|
17668
|
+
case connection_status_enum_exports.Connecting:
|
|
17669
|
+
case connection_status_enum_exports.NeedsAuth:
|
|
17670
|
+
case connection_status_enum_exports.Error:
|
|
17671
|
+
break;
|
|
17672
|
+
default:
|
|
17673
|
+
unreachable(connectionStatus);
|
|
15738
17674
|
}
|
|
15739
17675
|
this.#socketResolver = resolver11();
|
|
15740
17676
|
lc.debug?.("Creating new connect resolver");
|
|
@@ -15749,11 +17685,25 @@ ${error.errorBody.message}`, error);
|
|
|
15749
17685
|
this.#socket = void 0;
|
|
15750
17686
|
this.#lastMutationIDSent = NULL_LAST_MUTATION_ID_SENT;
|
|
15751
17687
|
this.#pokeHandler.handleDisconnect();
|
|
15752
|
-
const
|
|
15753
|
-
|
|
15754
|
-
|
|
15755
|
-
|
|
15756
|
-
|
|
17688
|
+
const transition = getErrorConnectionTransition(reason);
|
|
17689
|
+
switch (transition.status) {
|
|
17690
|
+
case connection_status_enum_exports.NeedsAuth:
|
|
17691
|
+
this.#connectionManager.needsAuth(transition.reason);
|
|
17692
|
+
break;
|
|
17693
|
+
case connection_status_enum_exports.Error:
|
|
17694
|
+
this.#connectionManager.error(transition.reason);
|
|
17695
|
+
break;
|
|
17696
|
+
case connection_status_enum_exports.Disconnected:
|
|
17697
|
+
this.#connectionManager.disconnected(transition.reason);
|
|
17698
|
+
break;
|
|
17699
|
+
case connection_status_enum_exports.Closed:
|
|
17700
|
+
this.#connectionManager.closed();
|
|
17701
|
+
break;
|
|
17702
|
+
case NO_STATUS_TRANSITION:
|
|
17703
|
+
this.#connectionManager.connecting(transition.reason);
|
|
17704
|
+
break;
|
|
17705
|
+
default:
|
|
17706
|
+
unreachable(transition);
|
|
15757
17707
|
}
|
|
15758
17708
|
}
|
|
15759
17709
|
#handlePokeStart(_lc, pokeMessage) {
|
|
@@ -15860,19 +17810,11 @@ ${error.errorBody.message}`, error);
|
|
|
15860
17810
|
}
|
|
15861
17811
|
};
|
|
15862
17812
|
}
|
|
15863
|
-
async #updateAuthToken(lc, error) {
|
|
15864
|
-
const { auth: authOption } = this.#options;
|
|
15865
|
-
const auth = await (typeof authOption === "function" ? authOption(error) : authOption);
|
|
15866
|
-
if (auth) {
|
|
15867
|
-
lc.debug?.("Got auth token");
|
|
15868
|
-
this.#rep.auth = auth;
|
|
15869
|
-
}
|
|
15870
|
-
}
|
|
15871
17813
|
async #runLoop() {
|
|
15872
17814
|
this.#lc.info?.(`Starting Zero version: ${this.version}`);
|
|
15873
17815
|
if (this.#server === null) {
|
|
15874
17816
|
this.#lc.info?.("No socket origin provided, not starting connect loop.");
|
|
15875
|
-
this.#connectionManager.
|
|
17817
|
+
this.#connectionManager.error(
|
|
15876
17818
|
new ClientError({
|
|
15877
17819
|
kind: client_error_kind_enum_exports.NoSocketOrigin,
|
|
15878
17820
|
message: "No server socket origin provided"
|
|
@@ -15889,43 +17831,40 @@ ${error.errorBody.message}`, error);
|
|
|
15889
17831
|
}
|
|
15890
17832
|
return lc.withContext("runLoopCounter", runLoopCounter);
|
|
15891
17833
|
};
|
|
15892
|
-
|
|
15893
|
-
|
|
15894
|
-
let
|
|
15895
|
-
let gotError = false;
|
|
15896
|
-
let backoffMs = RUN_LOOP_INTERVAL_MS;
|
|
17834
|
+
const { auth } = this.#options;
|
|
17835
|
+
this.#setAuth(auth);
|
|
17836
|
+
let backoffMs;
|
|
15897
17837
|
let additionalConnectParams;
|
|
15898
17838
|
while (this.#connectionManager.shouldContinueRunLoop()) {
|
|
15899
17839
|
runLoopCounter++;
|
|
15900
17840
|
let lc = getLogContext();
|
|
15901
17841
|
backoffMs = RUN_LOOP_INTERVAL_MS;
|
|
15902
17842
|
try {
|
|
15903
|
-
|
|
17843
|
+
const currentState = this.#connectionManager.state;
|
|
17844
|
+
switch (currentState.name) {
|
|
15904
17845
|
case connection_status_enum_exports.Connecting:
|
|
15905
17846
|
case connection_status_enum_exports.Disconnected: {
|
|
15906
17847
|
if (this.#visibilityWatcher.visibilityState === "hidden") {
|
|
15907
17848
|
this.#metrics.setDisconnectedWaitingForVisible();
|
|
15908
17849
|
this.#totalToConnectStart = void 0;
|
|
15909
17850
|
}
|
|
15910
|
-
await
|
|
15911
|
-
|
|
15912
|
-
|
|
15913
|
-
|
|
17851
|
+
const visibilityResult = await promiseRace({
|
|
17852
|
+
visible: this.#visibilityWatcher.waitForVisible(),
|
|
17853
|
+
stateChange: this.#connectionManager.waitForStateChange()
|
|
17854
|
+
});
|
|
17855
|
+
if (visibilityResult.key === "stateChange") {
|
|
17856
|
+
throwIfConnectionError(visibilityResult.result);
|
|
17857
|
+
break;
|
|
15914
17858
|
}
|
|
15915
17859
|
if (reloadScheduled()) {
|
|
15916
17860
|
break;
|
|
15917
17861
|
}
|
|
15918
17862
|
await this.#connect(lc, additionalConnectParams);
|
|
15919
17863
|
additionalConnectParams = void 0;
|
|
15920
|
-
|
|
15921
|
-
break;
|
|
15922
|
-
}
|
|
17864
|
+
throwIfConnectionError(this.#connectionManager.state);
|
|
15923
17865
|
assert(this.#socket);
|
|
15924
17866
|
lc = getLogContext();
|
|
15925
17867
|
lc.debug?.("Connected successfully");
|
|
15926
|
-
gotError = false;
|
|
15927
|
-
needsReauth = false;
|
|
15928
|
-
this.#setOnline(true);
|
|
15929
17868
|
break;
|
|
15930
17869
|
}
|
|
15931
17870
|
case connection_status_enum_exports.Connected: {
|
|
@@ -15935,51 +17874,59 @@ ${error.errorBody.message}`, error);
|
|
|
15935
17874
|
PING_INTERVAL_MS,
|
|
15936
17875
|
controller.signal
|
|
15937
17876
|
);
|
|
15938
|
-
|
|
15939
|
-
|
|
15940
|
-
|
|
15941
|
-
|
|
15942
|
-
|
|
15943
|
-
|
|
15944
|
-
|
|
15945
|
-
|
|
15946
|
-
|
|
15947
|
-
|
|
15948
|
-
|
|
15949
|
-
|
|
15950
|
-
|
|
15951
|
-
|
|
15952
|
-
|
|
15953
|
-
|
|
15954
|
-
|
|
15955
|
-
|
|
15956
|
-
|
|
15957
|
-
);
|
|
15958
|
-
if (pingResult === TimedOut) {
|
|
15959
|
-
gotError = true;
|
|
15960
|
-
}
|
|
17877
|
+
const raceResult = await promiseRace({
|
|
17878
|
+
waitForPing: pingTimeoutPromise,
|
|
17879
|
+
waitForPingAborted: pingTimeoutAborted,
|
|
17880
|
+
tabHidden: this.#visibilityWatcher.waitForHidden(),
|
|
17881
|
+
stateChange: this.#connectionManager.waitForStateChange()
|
|
17882
|
+
});
|
|
17883
|
+
switch (raceResult.key) {
|
|
17884
|
+
case "waitForPing": {
|
|
17885
|
+
await this.#ping(lc);
|
|
17886
|
+
break;
|
|
17887
|
+
}
|
|
17888
|
+
case "waitForPingAborted":
|
|
17889
|
+
break;
|
|
17890
|
+
case "tabHidden": {
|
|
17891
|
+
const hiddenError = new ClientError({
|
|
17892
|
+
kind: client_error_kind_enum_exports.Hidden,
|
|
17893
|
+
message: "Connection closed because tab was hidden"
|
|
17894
|
+
});
|
|
17895
|
+
this.#disconnect(lc, hiddenError);
|
|
15961
17896
|
break;
|
|
15962
17897
|
}
|
|
15963
|
-
case
|
|
15964
|
-
|
|
15965
|
-
lc,
|
|
15966
|
-
new ClientError({
|
|
15967
|
-
kind: client_error_kind_enum_exports.Hidden,
|
|
15968
|
-
message: "Connection closed because tab was hidden"
|
|
15969
|
-
})
|
|
15970
|
-
);
|
|
15971
|
-
this.#setOnline(false);
|
|
17898
|
+
case "stateChange":
|
|
17899
|
+
throwIfConnectionError(raceResult.result);
|
|
15972
17900
|
break;
|
|
17901
|
+
default:
|
|
17902
|
+
unreachable(raceResult);
|
|
15973
17903
|
}
|
|
15974
|
-
|
|
17904
|
+
break;
|
|
17905
|
+
}
|
|
17906
|
+
case connection_status_enum_exports.NeedsAuth: {
|
|
17907
|
+
lc.info?.(
|
|
17908
|
+
`Run loop paused in needs-auth state. Call zero.connection.connect({auth}) to resume.`,
|
|
17909
|
+
currentState.reason
|
|
17910
|
+
);
|
|
17911
|
+
await this.#connectionManager.waitForStateChange();
|
|
17912
|
+
break;
|
|
17913
|
+
}
|
|
17914
|
+
case connection_status_enum_exports.Error: {
|
|
17915
|
+
lc.info?.(
|
|
17916
|
+
`Run loop paused in error state. Call zero.connection.connect() to resume.`,
|
|
17917
|
+
currentState.reason
|
|
17918
|
+
);
|
|
17919
|
+
await this.#connectionManager.waitForStateChange();
|
|
15975
17920
|
break;
|
|
15976
17921
|
}
|
|
15977
17922
|
case connection_status_enum_exports.Closed:
|
|
15978
|
-
this.#rejectMessageError = void 0;
|
|
15979
17923
|
break;
|
|
17924
|
+
default:
|
|
17925
|
+
unreachable(currentState);
|
|
15980
17926
|
}
|
|
15981
17927
|
} catch (ex) {
|
|
15982
|
-
|
|
17928
|
+
const isClientClosedError = isClientError(ex) && ex.kind === client_error_kind_enum_exports.ClientClosed;
|
|
17929
|
+
if (!this.#connectionManager.is(connection_status_enum_exports.Connected) && !isClientClosedError) {
|
|
15983
17930
|
const level = isAuthError(ex) ? "warn" : "error";
|
|
15984
17931
|
const kind = isServerError(ex) ? ex.kind : "Unknown Error";
|
|
15985
17932
|
lc[level]?.("Failed to connect", ex, kind, {
|
|
@@ -15994,38 +17941,51 @@ ${error.errorBody.message}`, error);
|
|
|
15994
17941
|
"exception:",
|
|
15995
17942
|
ex
|
|
15996
17943
|
);
|
|
15997
|
-
|
|
15998
|
-
|
|
15999
|
-
|
|
16000
|
-
|
|
16001
|
-
|
|
16002
|
-
|
|
17944
|
+
const transition = getErrorConnectionTransition(ex);
|
|
17945
|
+
switch (transition.status) {
|
|
17946
|
+
case NO_STATUS_TRANSITION: {
|
|
17947
|
+
const backoffParams = getBackoffParams(transition.reason);
|
|
17948
|
+
if (backoffParams) {
|
|
17949
|
+
if (backoffParams.minBackoffMs !== void 0) {
|
|
17950
|
+
backoffMs = Math.max(backoffMs, backoffParams.minBackoffMs);
|
|
17951
|
+
}
|
|
17952
|
+
if (backoffParams.maxBackoffMs !== void 0) {
|
|
17953
|
+
backoffMs = Math.min(backoffMs, backoffParams.maxBackoffMs);
|
|
17954
|
+
}
|
|
17955
|
+
additionalConnectParams = backoffParams.reconnectParams;
|
|
17956
|
+
}
|
|
17957
|
+
lc.debug?.(
|
|
17958
|
+
"Sleeping",
|
|
17959
|
+
backoffMs,
|
|
17960
|
+
"ms before reconnecting due to error, state:",
|
|
17961
|
+
this.#connectionManager.state
|
|
17962
|
+
);
|
|
17963
|
+
await sleep(backoffMs);
|
|
17964
|
+
break;
|
|
16003
17965
|
}
|
|
16004
|
-
|
|
16005
|
-
|
|
16006
|
-
|
|
16007
|
-
|
|
16008
|
-
|
|
16009
|
-
|
|
16010
|
-
|
|
16011
|
-
|
|
17966
|
+
case connection_status_enum_exports.NeedsAuth: {
|
|
17967
|
+
lc.debug?.(
|
|
17968
|
+
"Auth error encountered, transitioning to needs-auth state"
|
|
17969
|
+
);
|
|
17970
|
+
this.#connectionManager.needsAuth(transition.reason);
|
|
17971
|
+
break;
|
|
17972
|
+
}
|
|
17973
|
+
case connection_status_enum_exports.Error: {
|
|
17974
|
+
lc.debug?.("Fatal error encountered, transitioning to error state");
|
|
17975
|
+
this.#connectionManager.error(transition.reason);
|
|
17976
|
+
break;
|
|
17977
|
+
}
|
|
17978
|
+
case connection_status_enum_exports.Disconnected: {
|
|
17979
|
+
this.#connectionManager.disconnected(transition.reason);
|
|
17980
|
+
break;
|
|
16012
17981
|
}
|
|
16013
|
-
|
|
16014
|
-
|
|
17982
|
+
case connection_status_enum_exports.Closed: {
|
|
17983
|
+
break;
|
|
16015
17984
|
}
|
|
16016
|
-
|
|
17985
|
+
default:
|
|
17986
|
+
unreachable(transition);
|
|
16017
17987
|
}
|
|
16018
17988
|
}
|
|
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
17989
|
}
|
|
16030
17990
|
}
|
|
16031
17991
|
async #puller(req, requestID) {
|
|
@@ -16061,17 +18021,18 @@ ${error.errorBody.message}`, error);
|
|
|
16061
18021
|
const pullResponseResolver = resolver11();
|
|
16062
18022
|
this.#pendingPullsByRequestID.set(requestID, pullResponseResolver);
|
|
16063
18023
|
try {
|
|
16064
|
-
const
|
|
16065
|
-
|
|
16066
|
-
|
|
16067
|
-
|
|
16068
|
-
|
|
16069
|
-
|
|
16070
|
-
switch (raceResult) {
|
|
16071
|
-
case TIMEOUT:
|
|
18024
|
+
const raceResult = await promiseRace({
|
|
18025
|
+
timeout: sleep(PULL_TIMEOUT_MS),
|
|
18026
|
+
success: pullResponseResolver.promise
|
|
18027
|
+
});
|
|
18028
|
+
switch (raceResult.key) {
|
|
18029
|
+
case "timeout":
|
|
16072
18030
|
lc.debug?.("Mutation recovery pull timed out");
|
|
16073
|
-
throw new
|
|
16074
|
-
|
|
18031
|
+
throw new ClientError({
|
|
18032
|
+
kind: client_error_kind_enum_exports.PullTimeout,
|
|
18033
|
+
message: "Pull timed out"
|
|
18034
|
+
});
|
|
18035
|
+
case "success": {
|
|
16075
18036
|
lc.debug?.("Returning mutation recovery pull response");
|
|
16076
18037
|
const response = await pullResponseResolver.promise;
|
|
16077
18038
|
return {
|
|
@@ -16087,19 +18048,31 @@ ${error.errorBody.message}`, error);
|
|
|
16087
18048
|
};
|
|
16088
18049
|
}
|
|
16089
18050
|
default:
|
|
16090
|
-
unreachable();
|
|
18051
|
+
unreachable(raceResult);
|
|
16091
18052
|
}
|
|
16092
18053
|
} finally {
|
|
16093
|
-
pullResponseResolver.reject(
|
|
18054
|
+
pullResponseResolver.reject(
|
|
18055
|
+
new ClientError({
|
|
18056
|
+
kind: client_error_kind_enum_exports.PullTimeout,
|
|
18057
|
+
message: "Pull timed out"
|
|
18058
|
+
})
|
|
18059
|
+
);
|
|
16094
18060
|
this.#pendingPullsByRequestID.delete(requestID);
|
|
16095
18061
|
}
|
|
16096
18062
|
}
|
|
16097
|
-
|
|
16098
|
-
|
|
18063
|
+
/**
|
|
18064
|
+
* Sets the authentication token on the replicache instance.
|
|
18065
|
+
*
|
|
18066
|
+
* @param auth - The authentication token to set.
|
|
18067
|
+
*/
|
|
18068
|
+
#setAuth(auth) {
|
|
18069
|
+
this.#rep.auth = toReplicacheAuthToken(auth);
|
|
16099
18070
|
}
|
|
16100
18071
|
/**
|
|
16101
18072
|
* A rough heuristic for whether the client is currently online and
|
|
16102
18073
|
* authenticated.
|
|
18074
|
+
*
|
|
18075
|
+
* @deprecated Use `connection` instead, which provides more detailed connection state.
|
|
16103
18076
|
*/
|
|
16104
18077
|
get online() {
|
|
16105
18078
|
return this.#onlineManager.online;
|
|
@@ -16111,15 +18084,14 @@ ${error.errorBody.message}`, error);
|
|
|
16111
18084
|
*
|
|
16112
18085
|
* @param listener - The listener to subscribe to.
|
|
16113
18086
|
* @returns A function to unsubscribe the listener.
|
|
18087
|
+
*
|
|
18088
|
+
* @deprecated Use `connection` instead, which provides more detailed connection state.
|
|
16114
18089
|
*/
|
|
16115
18090
|
onOnline = (listener) => this.#onlineManager.subscribe(listener);
|
|
16116
18091
|
/**
|
|
16117
18092
|
* 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
18093
|
*/
|
|
16122
|
-
async #ping(lc
|
|
18094
|
+
async #ping(lc) {
|
|
16123
18095
|
lc.debug?.("pinging");
|
|
16124
18096
|
const { promise, resolve } = resolver11();
|
|
16125
18097
|
this.#onPong = resolve;
|
|
@@ -16127,25 +18099,37 @@ ${error.errorBody.message}`, error);
|
|
|
16127
18099
|
const t0 = performance.now();
|
|
16128
18100
|
assert(this.#socket);
|
|
16129
18101
|
send(this.#socket, pingMessage);
|
|
16130
|
-
const
|
|
16131
|
-
promise,
|
|
16132
|
-
sleep(PING_TIMEOUT_MS),
|
|
16133
|
-
|
|
16134
|
-
|
|
18102
|
+
const raceResult = await promiseRace({
|
|
18103
|
+
waitForPong: promise,
|
|
18104
|
+
pingTimeout: sleep(PING_TIMEOUT_MS),
|
|
18105
|
+
stateChange: this.#connectionManager.waitForStateChange()
|
|
18106
|
+
});
|
|
16135
18107
|
const delta = performance.now() - t0;
|
|
16136
|
-
|
|
16137
|
-
|
|
16138
|
-
|
|
16139
|
-
|
|
16140
|
-
|
|
18108
|
+
switch (raceResult.key) {
|
|
18109
|
+
case "waitForPong": {
|
|
18110
|
+
lc.debug?.("ping succeeded in", delta, "ms");
|
|
18111
|
+
return;
|
|
18112
|
+
}
|
|
18113
|
+
case "pingTimeout": {
|
|
18114
|
+
lc.info?.("ping failed in", delta, "ms - disconnecting");
|
|
18115
|
+
const pingTimeoutError = new ClientError({
|
|
16141
18116
|
kind: client_error_kind_enum_exports.PingTimeout,
|
|
16142
|
-
message: "Server ping request
|
|
16143
|
-
})
|
|
16144
|
-
|
|
16145
|
-
|
|
18117
|
+
message: "Server ping request failed"
|
|
18118
|
+
});
|
|
18119
|
+
this.#disconnect(lc, pingTimeoutError);
|
|
18120
|
+
throw pingTimeoutError;
|
|
18121
|
+
}
|
|
18122
|
+
case "stateChange": {
|
|
18123
|
+
lc.debug?.(
|
|
18124
|
+
"ping aborted due to connection state change",
|
|
18125
|
+
raceResult.result
|
|
18126
|
+
);
|
|
18127
|
+
throwIfConnectionError(raceResult.result);
|
|
18128
|
+
break;
|
|
18129
|
+
}
|
|
18130
|
+
default:
|
|
18131
|
+
unreachable(raceResult);
|
|
16146
18132
|
}
|
|
16147
|
-
lc.debug?.("ping succeeded in", delta, "ms");
|
|
16148
|
-
return Success;
|
|
16149
18133
|
}
|
|
16150
18134
|
// Sends a set of metrics to the server. Throws unless the server
|
|
16151
18135
|
// returns 200.
|
|
@@ -16304,9 +18288,6 @@ function addWebSocketIDFromSocketToLogContext({ url }, lc) {
|
|
|
16304
18288
|
function addWebSocketIDToLogContext(wsid, lc) {
|
|
16305
18289
|
return lc.withContext("wsid", wsid);
|
|
16306
18290
|
}
|
|
16307
|
-
function promiseRace(ps) {
|
|
16308
|
-
return Promise.race(ps.map((p, i) => p.then(() => i)));
|
|
16309
|
-
}
|
|
16310
18291
|
function assertValidRunOptions2(_options) {
|
|
16311
18292
|
}
|
|
16312
18293
|
async function makeActiveClientsManager(clientGroupID, clientID, signal, onDelete) {
|
|
@@ -16326,12 +18307,15 @@ export {
|
|
|
16326
18307
|
dropDatabase,
|
|
16327
18308
|
dropAllDatabases,
|
|
16328
18309
|
TransactionClosedError,
|
|
18310
|
+
ApplicationError,
|
|
18311
|
+
error_kind_enum_exports,
|
|
18312
|
+
error_origin_enum_exports,
|
|
18313
|
+
error_reason_enum_exports,
|
|
16329
18314
|
transformRequestMessageSchema,
|
|
16330
18315
|
transformResponseMessageSchema,
|
|
16331
|
-
error_kind_enum_exports,
|
|
16332
18316
|
table,
|
|
16333
|
-
|
|
16334
|
-
|
|
18317
|
+
string4 as string,
|
|
18318
|
+
number3 as number,
|
|
16335
18319
|
boolean,
|
|
16336
18320
|
json,
|
|
16337
18321
|
enumeration,
|
|
@@ -16344,7 +18328,10 @@ export {
|
|
|
16344
18328
|
newQuerySymbol,
|
|
16345
18329
|
AbstractQuery,
|
|
16346
18330
|
clientToServer,
|
|
18331
|
+
client_error_kind_enum_exports,
|
|
18332
|
+
connection_status_enum_exports,
|
|
18333
|
+
ClientError,
|
|
16347
18334
|
update_needed_reason_type_enum_exports,
|
|
16348
18335
|
Zero
|
|
16349
18336
|
};
|
|
16350
|
-
//# sourceMappingURL=chunk-
|
|
18337
|
+
//# sourceMappingURL=chunk-COKJ5W7V.js.map
|