waygraph 0.15.53 → 0.16.0
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/README.md +8 -3
- package/bin/waygraph +2 -2
- package/dist/analysis/check.d.ts +38 -0
- package/dist/analysis/check.js +87 -0
- package/dist/analysis/coverage-gap.d.ts +1 -1
- package/dist/analysis/coverage-gap.js +14 -37
- package/dist/analysis/flow-source.d.ts +9 -0
- package/dist/analysis/flow-source.js +25 -0
- package/dist/analysis/graph.d.ts +13 -14
- package/dist/analysis/graph.js +48 -371
- package/dist/analysis/map-check.js +4 -39
- package/dist/analysis/practices-check.d.ts +1 -1
- package/dist/analysis/practices-check.js +24 -45
- package/dist/cli/args.d.ts +23 -0
- package/dist/cli/args.js +20 -0
- package/dist/{cli.d.ts → cli/cli.d.ts} +0 -1
- package/dist/{cli.js → cli/cli.js} +10 -9
- package/dist/{commands → cli/commands}/agent-dive-scaffold.js +35 -64
- package/dist/cli/commands/agent-dive.js +42 -0
- package/dist/{commands → cli/commands}/check.d.ts +0 -1
- package/dist/cli/commands/check.js +104 -0
- package/dist/cli/commands/codemod-checkpoints.d.ts +18 -0
- package/dist/cli/commands/codemod-checkpoints.js +186 -0
- package/dist/cli/commands/codemod-flows.d.ts +18 -0
- package/dist/cli/commands/codemod-flows.js +284 -0
- package/dist/cli/commands/codemod-stubs.d.ts +10 -0
- package/dist/cli/commands/codemod-stubs.js +187 -0
- package/dist/{commands → cli/commands}/extensions.js +5 -4
- package/dist/{commands → cli/commands}/init.js +1 -2
- package/dist/{commands → cli/commands}/list.js +9 -7
- package/dist/cli/commands/manifest.d.ts +2 -0
- package/dist/cli/commands/manifest.js +20 -0
- package/dist/cli/commands/map.js +57 -0
- package/dist/{commands → cli/commands}/run.d.ts +0 -1
- package/dist/cli/commands/run.js +64 -0
- package/dist/{commands → cli/commands}/session.js +61 -88
- package/dist/{commands → cli/commands}/test.js +11 -14
- package/dist/cli/commands/traverse.js +105 -0
- package/dist/{commands → cli/commands}/try.js +29 -25
- package/dist/{commands → cli/commands}/upgrade.js +40 -4
- package/dist/cli/flags.d.ts +193 -16
- package/dist/cli/flags.js +179 -234
- package/dist/cli/run-chain.d.ts +1 -0
- package/dist/cli/run-chain.js +42 -7
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/usage.js +21 -53
- package/dist/cli/util.d.ts +2 -2
- package/dist/cli/util.js +2 -3
- package/dist/{highlights → demo/narration}/css.d.ts +1 -1
- package/dist/{highlights → demo/narration}/css.js +2 -3
- package/dist/{highlights → demo/narration}/demo-pace.d.ts +7 -11
- package/dist/{highlights → demo/narration}/demo-pace.js +9 -11
- package/dist/{highlights → demo/narration}/device.d.ts +4 -2
- package/dist/{highlights → demo/narration}/device.js +3 -1
- package/dist/demo/narration/merge.d.ts +8 -0
- package/dist/demo/narration/merge.js +71 -0
- package/dist/{highlights/run-phase.d.ts → demo/narration/narration.d.ts} +10 -14
- package/dist/{highlights/run-phase.js → demo/narration/narration.js} +25 -94
- package/dist/{highlights → demo/narration}/shorthand.d.ts +1 -1
- package/dist/demo/narration/stub-ctx.d.ts +8 -0
- package/dist/demo/narration/stub-ctx.js +164 -0
- package/dist/{highlights → demo/narration}/style.d.ts +1 -7
- package/dist/{highlights → demo/narration}/style.js +1 -41
- package/dist/{highlights → demo/narration}/todo-dock.d.ts +3 -3
- package/dist/{highlights → demo/narration}/todo-dock.js +13 -30
- package/dist/demo/overlay/auto-chrome.d.ts +7 -0
- package/dist/demo/overlay/auto-chrome.js +97 -0
- package/dist/{session/overlay-beacon.d.ts → demo/overlay/beacon.d.ts} +7 -0
- package/dist/{session/overlay-beacon.js → demo/overlay/beacon.js} +5 -0
- package/dist/demo/overlay/cursor.d.ts +12 -0
- package/dist/demo/overlay/cursor.js +142 -0
- package/dist/demo/overlay/device-stage.d.ts +13 -0
- package/dist/demo/overlay/device-stage.js +396 -0
- package/dist/demo/overlay/inpage/banner.d.ts +1 -0
- package/dist/demo/overlay/inpage/banner.js +160 -0
- package/dist/demo/overlay/inpage/caption.d.ts +2 -0
- package/dist/demo/overlay/inpage/caption.js +24 -0
- package/dist/demo/overlay/inpage/core.d.ts +1 -0
- package/dist/demo/overlay/inpage/core.js +345 -0
- package/dist/demo/overlay/inpage/device-chip.d.ts +1 -0
- package/dist/demo/overlay/inpage/device-chip.js +191 -0
- package/dist/demo/overlay/inpage/network.d.ts +9 -0
- package/dist/demo/overlay/inpage/network.js +200 -0
- package/dist/demo/overlay/inpage/panel-chrome.d.ts +1 -0
- package/dist/demo/overlay/inpage/panel-chrome.js +203 -0
- package/dist/demo/overlay/inpage/stamp.d.ts +1 -0
- package/dist/demo/overlay/inpage/stamp.js +46 -0
- package/dist/demo/overlay/inpage/swipe-zoom.d.ts +1 -0
- package/dist/demo/overlay/inpage/swipe-zoom.js +220 -0
- package/dist/demo/overlay/inpage/todos.d.ts +1 -0
- package/dist/demo/overlay/inpage/todos.js +294 -0
- package/dist/demo/overlay/locator-theater.d.ts +25 -0
- package/dist/demo/overlay/locator-theater.js +76 -0
- package/dist/demo/overlay/network-capture.d.ts +22 -0
- package/dist/demo/overlay/network-capture.js +127 -0
- package/dist/demo/overlay/overlay-css.d.ts +3 -0
- package/dist/demo/overlay/overlay-css.js +369 -0
- package/dist/demo/overlay/overlay-stage.d.ts +23 -0
- package/dist/demo/overlay/overlay-stage.js +106 -0
- package/dist/demo/overlay/overlay.d.ts +10 -0
- package/dist/demo/overlay/overlay.js +89 -0
- package/dist/{pilot-overlay/overlay-fixtures.d.ts → demo/overlay/phase-fixtures.d.ts} +2 -2
- package/dist/{pilot-overlay/overlay-fixtures.js → demo/overlay/phase-fixtures.js} +2 -2
- package/dist/{pilot-overlay/action-ring.js → demo/overlay/pilot/actions.js} +2 -1
- package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.d.ts +6 -5
- package/dist/{pilot-overlay → demo/overlay/pilot}/fixtures.js +19 -18
- package/dist/{pilot-overlay → demo/overlay/pilot}/shell.d.ts +2 -2
- package/dist/{pilot-overlay → demo/overlay/pilot}/shell.js +13 -22
- package/dist/demo/overlay/reattach.d.ts +7 -0
- package/dist/demo/overlay/reattach.js +23 -0
- package/dist/demo/overlay/rings.d.ts +33 -0
- package/dist/demo/overlay/rings.js +448 -0
- package/dist/{ui → demo/overlay/ui}/components/ring.js +2 -2
- package/dist/{ui → demo/overlay/ui}/overlay.css +4 -4
- package/dist/{ui → demo/overlay/ui}/shadow.d.ts +1 -1
- package/dist/{ui → demo/overlay/ui}/shadow.js +39 -2
- package/dist/demo/stepper/after.d.ts +3 -0
- package/dist/demo/stepper/after.js +113 -0
- package/dist/demo/stepper/banner-log.d.ts +37 -0
- package/dist/demo/stepper/banner-log.js +63 -0
- package/dist/demo/stepper/before.d.ts +4 -0
- package/dist/demo/stepper/before.js +110 -0
- package/dist/demo/stepper/demo-log.d.ts +31 -0
- package/dist/demo/stepper/demo-log.js +309 -0
- package/dist/demo/stepper/gate.d.ts +11 -0
- package/dist/demo/stepper/gate.js +78 -0
- package/dist/demo/stepper/interaction-patch.d.ts +3 -0
- package/dist/demo/stepper/interaction-patch.js +323 -0
- package/dist/demo/stepper/pacing.d.ts +21 -0
- package/dist/demo/stepper/pacing.js +23 -0
- package/dist/demo/stepper/slides.d.ts +11 -0
- package/dist/demo/stepper/slides.js +233 -0
- package/dist/demo/stepper/step-panels.d.ts +21 -0
- package/dist/demo/stepper/step-panels.js +589 -0
- package/dist/demo/stepper/stepper.d.ts +24 -0
- package/dist/demo/stepper/stepper.js +122 -0
- package/dist/demo/stepper/teardown.d.ts +48 -0
- package/dist/demo/stepper/teardown.js +179 -0
- package/dist/demo/stepper/todo-advance.d.ts +14 -0
- package/dist/demo/stepper/todo-advance.js +110 -0
- package/dist/demo/stepper/view.d.ts +68 -0
- package/dist/demo/stepper/view.js +31 -0
- package/dist/demo/types.d.ts +17 -0
- package/dist/demo/verbose-log.js +15 -0
- package/dist/{types.d.ts → engine/block/block.d.ts} +106 -91
- package/dist/{core → engine/block}/block.js +10 -53
- package/dist/{core → engine/block}/compose.d.ts +10 -7
- package/dist/{core → engine/block}/compose.js +1 -1
- package/dist/{core/blocks → engine/block/kinds}/api.d.ts +17 -12
- package/dist/{core/blocks → engine/block/kinds}/api.js +26 -18
- package/dist/{core/blocks → engine/block/kinds}/effect.d.ts +13 -18
- package/dist/engine/block/kinds/effect.js +17 -0
- package/dist/{core/blocks → engine/block/kinds}/method.d.ts +19 -29
- package/dist/{core/blocks → engine/block/kinds}/method.js +7 -21
- package/dist/{core/blocks → engine/block/kinds}/nav.d.ts +22 -31
- package/dist/{core/blocks → engine/block/kinds}/nav.js +6 -12
- package/dist/{core/blocks → engine/block/kinds}/page.d.ts +15 -20
- package/dist/{core/blocks → engine/block/kinds}/page.js +5 -7
- package/dist/engine/checkpoint/checkpoint.d.ts +22 -0
- package/dist/engine/checkpoint/checkpoint.js +8 -0
- package/dist/engine/checkpoint/route.d.ts +28 -0
- package/dist/engine/checkpoint/route.js +28 -0
- package/dist/{core → engine}/config.d.ts +7 -2
- package/dist/engine/config.js +6 -0
- package/dist/engine/engine.d.ts +45 -0
- package/dist/{core → engine}/engine.js +6 -10
- package/dist/engine/env.d.ts +59 -0
- package/dist/engine/env.js +83 -0
- package/dist/{errors.d.ts → engine/errors.d.ts} +23 -22
- package/dist/{errors.js → engine/errors.js} +22 -22
- package/dist/{core → engine/flow}/branch-regression.d.ts +8 -7
- package/dist/{core → engine/flow}/branch-regression.js +4 -3
- package/dist/engine/flow/flow.d.ts +162 -0
- package/dist/engine/flow/flow.js +244 -0
- package/dist/{core → engine/flow}/map-builder.d.ts +42 -40
- package/dist/{core → engine/flow}/map-builder.js +46 -48
- package/dist/{core → engine}/locate.d.ts +1 -1
- package/dist/{core → engine}/locate.js +1 -2
- package/dist/{mem-stub.d.ts → engine/mem/mem-stub.d.ts} +9 -8
- package/dist/{mem-stub.js → engine/mem/mem-stub.js} +2 -2
- package/dist/{mem-page.d.ts → engine/mem/mem.d.ts} +1 -1
- package/dist/{mem-page.js → engine/mem/mem.js} +2 -1
- package/dist/engine/page-gone.d.ts +5 -0
- package/dist/engine/page-gone.js +20 -0
- package/dist/engine/run/connect.d.ts +28 -0
- package/dist/{types.js → engine/run/connect.js} +11 -10
- package/dist/engine/run/events.d.ts +67 -0
- package/dist/engine/run/events.js +90 -0
- package/dist/engine/run/hooks.d.ts +16 -0
- package/dist/engine/run/hooks.js +8 -0
- package/dist/engine/run/launch.d.ts +13 -0
- package/dist/engine/run/launch.js +27 -0
- package/dist/{core/run-graph.d.ts → engine/run/run.d.ts} +9 -11
- package/dist/{core/run-graph.js → engine/run/run.js} +22 -11
- package/dist/engine/stub/pace.d.ts +12 -0
- package/dist/engine/stub/pace.js +2 -0
- package/dist/engine/stub/ring.d.ts +130 -0
- package/dist/engine/stub/ring.js +41 -0
- package/dist/engine/stub/stub.d.ts +268 -0
- package/dist/engine/stub/stub.js +1 -0
- package/dist/engine/stub/todos.d.ts +104 -0
- package/dist/engine/stub/todos.js +2 -0
- package/dist/engine/stub/viewport.d.ts +26 -0
- package/dist/engine/stub/viewport.js +2 -0
- package/dist/{trait.d.ts → engine/trait/trait.d.ts} +1 -1
- package/dist/index.d.ts +84 -36
- package/dist/index.js +44 -19
- package/dist/{session/auto-explore-run.d.ts → live/auto/auto.d.ts} +10 -16
- package/dist/{session/auto-explore-run.js → live/auto/auto.js} +164 -248
- package/dist/{session/auto-explore.d.ts → live/auto/explore.d.ts} +4 -14
- package/dist/{session/auto-explore.js → live/auto/explore.js} +21 -127
- package/dist/{auto-session/session.d.ts → live/auto-session/auto-session.d.ts} +1 -1
- package/dist/{auto-session/session.js → live/auto-session/auto-session.js} +27 -24
- package/dist/{auto-session → live/auto-session}/helpers.d.ts +16 -5
- package/dist/{auto-session → live/auto-session}/helpers.js +1 -1
- package/dist/{session/auto-session-ipc.d.ts → live/auto-session/ipc.d.ts} +7 -5
- package/dist/{session/auto-session-ipc.js → live/auto-session/ipc.js} +31 -16
- package/dist/{session/browser.d.ts → live/auto-session/start.d.ts} +1 -2
- package/dist/{session/browser.js → live/auto-session/start.js} +2 -3
- package/dist/{pilot-overlay → live/pilot}/panel.d.ts +1 -1
- package/dist/{pilot-overlay → live/pilot}/panel.js +23 -31
- package/dist/{session → live/pilot}/pilot.d.ts +4 -3
- package/dist/{session → live/pilot}/pilot.js +4 -4
- package/dist/{traverse → live/traverse}/coverage.d.ts +4 -0
- package/dist/{traverse → live/traverse}/coverage.js +3 -0
- package/dist/{traverse → live/traverse}/lease.d.ts +1 -0
- package/dist/{traverse → live/traverse}/lease.js +1 -0
- package/dist/{traverse/run.d.ts → live/traverse/traverse.d.ts} +4 -1
- package/dist/{traverse/run.js → live/traverse/traverse.js} +26 -43
- package/dist/manifest/manifest.d.ts +52 -0
- package/dist/manifest/manifest.js +93 -0
- package/dist/manifest/map-imports.d.ts +7 -0
- package/dist/manifest/map-imports.js +22 -0
- package/dist/manifest/maps.d.ts +33 -0
- package/dist/manifest/maps.js +62 -0
- package/dist/manifest/pack.d.ts +21 -0
- package/dist/manifest/pack.js +109 -0
- package/dist/manifest/project.d.ts +60 -0
- package/dist/manifest/project.js +101 -0
- package/dist/{session/block-inject.js → manifest/roots.js} +1 -18
- package/dist/manifest/scan.d.ts +19 -0
- package/dist/manifest/scan.js +57 -0
- package/dist/{blocks-select.d.ts → manifest/select.d.ts} +3 -0
- package/dist/{blocks-select.js → manifest/select.js} +2 -0
- package/dist/manifest/source.d.ts +23 -0
- package/dist/manifest/source.js +86 -0
- package/dist/runner/mode.d.ts +71 -0
- package/dist/runner/mode.js +1 -0
- package/dist/runner/modes/branches.d.ts +5 -0
- package/dist/runner/modes/branches.js +37 -0
- package/dist/runner/modes/demo.d.ts +3 -0
- package/dist/runner/modes/demo.js +13 -0
- package/dist/runner/modes/report.d.ts +2 -0
- package/dist/runner/modes/report.js +54 -0
- package/dist/runner/modes/run.d.ts +2 -0
- package/dist/runner/modes/run.js +3 -0
- package/dist/runner/options.d.ts +31 -0
- package/dist/runner/options.js +42 -0
- package/dist/runner/plan/find.d.ts +18 -0
- package/dist/runner/plan/find.js +65 -0
- package/dist/runner/plan/plan.d.ts +11 -0
- package/dist/runner/plan/plan.js +97 -0
- package/dist/runner/plan/seed-mem.d.ts +12 -0
- package/dist/runner/plan/seed-mem.js +98 -0
- package/dist/runner/plan/spec.d.ts +5 -0
- package/dist/runner/plan/spec.js +17 -0
- package/dist/runner/play-steps.d.ts +2 -0
- package/dist/runner/play-steps.js +59 -0
- package/dist/runner/runner.d.ts +4 -0
- package/dist/runner/runner.js +64 -0
- package/dist/runner/session.d.ts +9 -0
- package/dist/runner/session.js +87 -0
- package/dist/{browser.js → runtime/browser.js} +4 -2
- package/dist/{env-file.js → runtime/env-file.js} +7 -12
- package/dist/{extensions.d.ts → runtime/extensions.d.ts} +2 -5
- package/dist/{extensions.js → runtime/extensions.js} +3 -1
- package/dist/runtime/full-launch.d.ts +1 -0
- package/dist/runtime/full-launch.js +34 -0
- package/dist/runtime/global-flag.d.ts +5 -0
- package/dist/runtime/global-flag.js +18 -0
- package/dist/{playwright-config.d.ts → runtime/playwright-config.d.ts} +1 -1
- package/dist/{playwright.config.js → runtime/playwright.config.js} +3 -2
- package/dist/runtime/run-log.d.ts +2 -0
- package/dist/runtime/run-log.js +17 -0
- package/dist/{video-dir.js → runtime/video-dir.js} +3 -2
- package/dist/{config.d.ts → runtime/waygraph-config.d.ts} +8 -9
- package/dist/{config.js → runtime/waygraph-config.js} +21 -51
- package/dist/{webserver.js → runtime/webserver.js} +5 -30
- package/examples/routed-demo/config/waygraph.config.ts +20 -0
- package/examples/routed-demo/package.json +1 -4
- package/examples/routed-demo/scripts/fixture-server.mjs +1 -1
- package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +2 -4
- package/examples/routed-demo/src/flows/routed-demo.flow.ts +2 -3
- package/examples/routed-demo/src/map/(app_base)/dashboard/_methods/click-widget.block.ts +5 -4
- package/examples/routed-demo/src/map/(app_base)/dashboard/_nav.block.ts +3 -3
- package/examples/routed-demo/src/map/(app_base)/dashboard/_page.block.ts +3 -3
- package/examples/routed-demo/src/map/(external)/docs/_nav.block.ts +3 -3
- package/examples/routed-demo/src/map/(external)/docs/_page.block.ts +3 -3
- package/examples/routed-demo/src/states/routed-demo.states.ts +5 -3
- package/examples/routed-demo/tests/routed-demo.spec.ts +4 -4
- package/examples/routed-demo/tsconfig.json +1 -1
- package/examples/saucedemo/README.md +11 -12
- package/examples/saucedemo/config/waygraph.config.ts +17 -0
- package/examples/saucedemo/docs/CONVENTION.md +5 -7
- package/examples/saucedemo/docs/HELPERS.md +12 -12
- package/examples/saucedemo/package-lock.json +10 -3
- package/examples/saucedemo/package.json +12 -29
- package/examples/saucedemo/src/blocks/SITE-MAP.md +0 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/NAV.md +1 -5
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -52
- package/examples/saucedemo/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +21 -27
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -9
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +10 -76
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -29
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -48
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +13 -77
- package/examples/saucedemo/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
- package/examples/saucedemo/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
- package/examples/saucedemo/src/flows/api-demo.flow.ts +26 -18
- package/examples/saucedemo/src/flows/cart-bulk.flow.ts +19 -14
- package/examples/saucedemo/src/flows/cart-continue.flow.ts +10 -8
- package/examples/saucedemo/src/flows/cart-mem.flow.ts +7 -7
- package/examples/saucedemo/src/flows/catalog-logout.flow.ts +13 -8
- package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +26 -48
- package/examples/saucedemo/src/flows/checkout.flow.ts +70 -86
- package/examples/saucedemo/src/flows/device-showcase.flow.ts +24 -25
- package/examples/saucedemo/src/flows/login.flow.ts +11 -18
- package/examples/saucedemo/src/flows/mem-stub-demo.flow.ts +9 -20
- package/examples/saucedemo/src/flows/shop.flow.ts +15 -20
- package/examples/saucedemo/src/flows/smoke.flow.ts +12 -27
- package/examples/saucedemo/src/flows/stub-on-error.flow.ts +24 -43
- package/examples/saucedemo/src/flows/viewer-blocked.flow.ts +26 -34
- package/examples/saucedemo/src/states/checkout.mem-stubs.ts +11 -0
- package/examples/saucedemo/src/states/checkout.states.ts +21 -11
- package/examples/saucedemo/src/stubs/device-showcase.ts +191 -0
- package/examples/saucedemo/src/stubs/login.ts +37 -0
- package/examples/saucedemo/tests/auto-graph.spec.ts +4 -12
- package/examples/saucedemo/tests/chain-flow-episodes.spec.ts +7 -9
- package/examples/saucedemo/tests/submit-login-branch.spec.ts +18 -5
- package/package.json +12 -7
- package/templates/agents/waygraph-planner.agent.md +2 -2
- package/templates/quickstart/README.md +4 -7
- package/templates/quickstart/config/waygraph.config.ts +17 -0
- package/templates/quickstart/docs/CONVENTION.md +5 -6
- package/templates/quickstart/docs/HELPERS.md +11 -9
- package/templates/quickstart/package.json +14 -17
- package/templates/quickstart/src/blocks/SITE-MAP.md +13 -3
- package/templates/quickstart/src/blocks/saucedemo-web/NAV.md +1 -5
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-cart.block.ts +3 -52
- package/templates/quickstart/src/blocks/saucedemo-web/cart/nav-checkout-info.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-first-name.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-last-name.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/fill-postal-code.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-one/methods/submit-checkout-info.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +21 -27
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/inventory.page.block.ts +3 -9
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-all-to-cart.method.block.ts +4 -6
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/add-to-cart.effect.block.ts +10 -76
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-all-from-cart.method.block.ts +4 -6
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/methods/remove-from-cart.effect.block.ts +4 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory/nav-item-detail.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-inventory.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-back-to-products.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/inventory-item/nav-continue-shopping.block.ts +3 -3
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-password.method.block.ts +5 -29
- package/templates/quickstart/src/blocks/saucedemo-web/methods/fill-username.method.block.ts +5 -48
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-login.method.block.ts +13 -77
- package/templates/quickstart/src/blocks/saucedemo-web/methods/submit-logout.method.block.ts +5 -4
- package/templates/quickstart/src/blocks/saucedemo-web/nav-login.block.ts +3 -3
- package/templates/quickstart/src/flows/api-demo.flow.ts +45 -0
- package/templates/quickstart/src/flows/cart-bulk.flow.ts +19 -14
- package/templates/quickstart/src/flows/cart-continue.flow.ts +10 -8
- package/templates/quickstart/src/flows/cart-mem.flow.ts +7 -7
- package/templates/quickstart/src/flows/catalog-logout.flow.ts +13 -8
- package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +26 -48
- package/templates/quickstart/src/flows/checkout.flow.ts +70 -63
- package/templates/quickstart/src/flows/device-showcase.flow.ts +24 -25
- package/templates/quickstart/src/flows/login.flow.ts +11 -18
- package/templates/quickstart/src/flows/mem-stub-demo.flow.ts +12 -0
- package/templates/quickstart/src/flows/shop.flow.ts +15 -20
- package/templates/quickstart/src/flows/smoke.flow.ts +12 -27
- package/templates/quickstart/src/flows/stub-on-error.flow.ts +31 -0
- package/templates/quickstart/src/flows/viewer-blocked.flow.ts +26 -34
- package/templates/quickstart/src/states/checkout.mem-stubs.ts +11 -0
- package/templates/quickstart/src/states/checkout.states.ts +21 -11
- package/templates/quickstart/src/stubs/device-showcase.ts +191 -0
- package/templates/quickstart/src/stubs/login.ts +37 -0
- package/templates/quickstart/tests/chain-flow.spec.ts +7 -10
- package/templates/scaffold/README.md +2 -1
- package/templates/scaffold/STRUCTURE.md +5 -4
- package/templates/scaffold/config/waygraph.config.ts +1 -0
- package/templates/scaffold/gitignore +1 -0
- package/templates/scaffold/src/flows/README.md +2 -2
- package/templates/scaffold/src/map/(app_base)/docs/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/docs/_page.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_methods/add-item.effect.block.ts +4 -4
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-item-added.method.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_methods/clear-cart.method.block.ts +5 -4
- package/templates/scaffold/src/map/(app_base)/home/_methods/remove-item.effect.block.ts +4 -4
- package/templates/scaffold/src/map/(app_base)/home/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/_page.block.ts +3 -3
- package/templates/scaffold/src/map/(app_base)/home/nav-verification-link.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_keys.ts +21 -0
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-body.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-response-header.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/assert-status.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/pick-extension-interceptor.method.block.ts +5 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-body.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/read-response-headers.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/send-request.method.block.ts +5 -4
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-bearer-token.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-headers.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-json-body.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-method.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-query-params.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_methods/set-url.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/hoppscotch/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/hoppscotch/_page.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/hoppscotch/_states.ts +6 -0
- package/templates/scaffold/src/map/(external)/hoppscotch/settings/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/mailpit/_keys.ts +13 -0
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-content.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/mailpit/_methods/assert-email-received.method.block.ts +4 -4
- package/templates/scaffold/src/map/(external)/mailpit/_methods/extract-email-link.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/mailpit/_methods/open-message.method.block.ts +6 -5
- package/templates/scaffold/src/map/(external)/mailpit/_nav.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/mailpit/_page.block.ts +3 -3
- package/templates/scaffold/src/map/(external)/mailpit/_states.ts +9 -0
- package/templates/scaffold/src/map/README.md +7 -0
- package/templates/scaffold/src/states/README.md +4 -1
- package/templates/scaffold/src/states/demo.mem-keys.ts +1 -29
- package/templates/scaffold/src/states/demo.states.ts +14 -20
- package/templates/scaffold/tests/hoppscotch.spec.ts +1 -11
- package/templates/scaffold/tests/mail-verify.spec.ts +2 -2
- package/templates/skills/waygraph-blind-pilot.skill.md +2 -6
- package/templates/skills/waygraph-convention.skill.md +23 -14
- package/templates/skills/waygraph-pilot.skill.md +7 -4
- package/dist/auto-session/verbose-log.js +0 -16
- package/dist/auto-session.d.ts +0 -2
- package/dist/auto-session.js +0 -3
- package/dist/cli/discover.d.ts +0 -40
- package/dist/cli/discover.js +0 -148
- package/dist/commands/agent-dive.js +0 -52
- package/dist/commands/check.js +0 -192
- package/dist/commands/map.js +0 -29
- package/dist/commands/run.js +0 -104
- package/dist/commands/traverse.js +0 -177
- package/dist/core/block.d.ts +0 -109
- package/dist/core/blocks/effect.js +0 -23
- package/dist/core/config.js +0 -17
- package/dist/core/engine.d.ts +0 -198
- package/dist/core/flow.d.ts +0 -293
- package/dist/core/flow.js +0 -432
- package/dist/core.d.ts +0 -14
- package/dist/core.js +0 -15
- package/dist/highlights/merge.d.ts +0 -8
- package/dist/highlights/merge.js +0 -173
- package/dist/highlights/stub-ctx.d.ts +0 -10
- package/dist/highlights/stub-ctx.js +0 -331
- package/dist/highlights/types.d.ts +0 -607
- package/dist/highlights.d.ts +0 -9
- package/dist/highlights.js +0 -10
- package/dist/pilot-overlay.d.ts +0 -5
- package/dist/pilot-overlay.js +0 -6
- package/dist/runner/banner-log.js +0 -63
- package/dist/runner/chain-run.js +0 -102
- package/dist/runner/cursor.js +0 -140
- package/dist/runner/demo-log.js +0 -316
- package/dist/runner/device-stage.d.ts +0 -9
- package/dist/runner/device-stage.js +0 -420
- package/dist/runner/discovery.js +0 -105
- package/dist/runner/index.js +0 -2
- package/dist/runner/inpage/banner.d.ts +0 -21
- package/dist/runner/inpage/banner.js +0 -156
- package/dist/runner/inpage/caption.d.ts +0 -3
- package/dist/runner/inpage/caption.js +0 -23
- package/dist/runner/inpage/core.d.ts +0 -4
- package/dist/runner/inpage/core.js +0 -316
- package/dist/runner/inpage/device.d.ts +0 -3
- package/dist/runner/inpage/device.js +0 -211
- package/dist/runner/inpage/network.d.ts +0 -15
- package/dist/runner/inpage/network.js +0 -217
- package/dist/runner/inpage/panel-chrome.js +0 -192
- package/dist/runner/inpage/stamp.js +0 -46
- package/dist/runner/inpage/swipe-zoom.js +0 -220
- package/dist/runner/inpage/todos.js +0 -337
- package/dist/runner/interaction-patch.js +0 -384
- package/dist/runner/main.js +0 -469
- package/dist/runner/network-capture.d.ts +0 -9
- package/dist/runner/network-capture.js +0 -126
- package/dist/runner/overlay-css.d.ts +0 -3
- package/dist/runner/overlay-css.js +0 -377
- package/dist/runner/overlay-install.js +0 -90
- package/dist/runner/overlay-stage.js +0 -110
- package/dist/runner/rings.js +0 -514
- package/dist/runner/seed-mem.js +0 -110
- package/dist/runner/slides.js +0 -278
- package/dist/runner/step-mode.js +0 -703
- package/dist/runner/step-panels.js +0 -729
- package/dist/runner/teardown.js +0 -202
- package/dist/runner/todo-dock.js +0 -142
- package/dist/session/step-overlay.d.ts +0 -37
- package/dist/session/step-overlay.js +0 -244
- package/examples/routed-demo/playwright.config.ts +0 -21
- package/examples/saucedemo/playwright.config.ts +0 -19
- package/examples/saucedemo/scripts/drive-auto-cli.mjs +0 -93
- package/examples/saucedemo/scripts/prove-add-to-cart-menu.mjs +0 -126
- package/examples/saucedemo/scripts/prove-auto-graph.mjs +0 -92
- package/examples/saucedemo/scripts/prove-wrong-login-runtime.mjs +0 -63
- package/examples/saucedemo/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
- package/templates/quickstart/playwright.config.ts +0 -14
- package/templates/quickstart/scripts/drive-auto-cli.mjs +0 -93
- package/templates/quickstart/src/blocks/saucedemo-web/ff-owner-auth.block.ts +0 -22
- /package/dist/{commands → cli/commands}/agent-dive-scaffold.d.ts +0 -0
- /package/dist/{commands → cli/commands}/agent-dive.d.ts +0 -0
- /package/dist/{commands → cli/commands}/extensions.d.ts +0 -0
- /package/dist/{commands → cli/commands}/init.d.ts +0 -0
- /package/dist/{commands → cli/commands}/list.d.ts +0 -0
- /package/dist/{commands → cli/commands}/map.d.ts +0 -0
- /package/dist/{commands → cli/commands}/session.d.ts +0 -0
- /package/dist/{commands → cli/commands}/test.d.ts +0 -0
- /package/dist/{commands → cli/commands}/traverse.d.ts +0 -0
- /package/dist/{commands → cli/commands}/try.d.ts +0 -0
- /package/dist/{commands → cli/commands}/upgrade.d.ts +0 -0
- /package/dist/{highlights → demo/narration}/shorthand.js +0 -0
- /package/dist/{pilot-overlay/action-ring.d.ts → demo/overlay/pilot/actions.d.ts} +0 -0
- /package/dist/{ui → demo/overlay/ui}/components/ring.d.ts +0 -0
- /package/dist/{ui → demo/overlay/ui}/stylesheet.d.ts +0 -0
- /package/dist/{ui → demo/overlay/ui}/stylesheet.js +0 -0
- /package/dist/{ui → demo/overlay/ui}/tokens.d.ts +0 -0
- /package/dist/{ui → demo/overlay/ui}/tokens.js +0 -0
- /package/dist/{highlights → demo}/types.js +0 -0
- /package/dist/{auto-session → demo}/verbose-log.d.ts +0 -0
- /package/dist/{selector.d.ts → engine/trait/selector.d.ts} +0 -0
- /package/dist/{selector.js → engine/trait/selector.js} +0 -0
- /package/dist/{trait.js → engine/trait/trait.js} +0 -0
- /package/dist/{session/block-inject.d.ts → manifest/roots.d.ts} +0 -0
- /package/dist/{browser.d.ts → runtime/browser.d.ts} +0 -0
- /package/dist/{env-file.d.ts → runtime/env-file.d.ts} +0 -0
- /package/dist/{playwright-config.js → runtime/playwright-config.js} +0 -0
- /package/dist/{playwright.config.d.ts → runtime/playwright.config.d.ts} +0 -0
- /package/dist/{video-dir.d.ts → runtime/video-dir.d.ts} +0 -0
- /package/dist/{webserver.d.ts → runtime/webserver.d.ts} +0 -0
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type { Checkpoint } from "../checkpoint/checkpoint.js";
|
|
2
|
+
import type { RunGraphOptions } from "../run/run.js";
|
|
3
|
+
import type { EngineConfig } from "../config.js";
|
|
4
|
+
import type { BrowserContext, Page } from "@playwright/test";
|
|
5
|
+
import { MemPage } from "../mem/mem.js";
|
|
6
|
+
import type { Trait } from "../trait/trait.js";
|
|
7
|
+
import type { DemoPace } from "../stub/pace.js";
|
|
8
|
+
import type { HighlightStyleDefaults } from "../stub/ring.js";
|
|
9
|
+
import type { SomeBlock } from "../block/block.js";
|
|
10
|
+
/**
|
|
11
|
+
* A composed, runnable flow. Always begins from Checkpoint<"__start__">, same as
|
|
12
|
+
* runGraph's `entry`. `run(context, mem)` uses a context you already have (the
|
|
13
|
+
* usual case inside a `@playwright/test` file, via its `context` fixture) -
|
|
14
|
+
* there's no browser for this Flow to launch, so no config to pass. `run(mem,
|
|
15
|
+
* config?)` - no context - has the Engine launch and own its own browser for
|
|
16
|
+
* this one run instead, and closes it in `finally`; use this outside a
|
|
17
|
+
* Playwright test file, or when a flow genuinely needs its own browser instance
|
|
18
|
+
* rather than sharing the test's. `config` here overrides, per key, whatever
|
|
19
|
+
* `new Engine(...)` was constructed with - so one flow (module-level, imported
|
|
20
|
+
* by many specs) can still have every run choose its own `headless`/`slowMo`
|
|
21
|
+
* rather than being stuck with whatever the flow's own file happened to set.
|
|
22
|
+
*
|
|
23
|
+
* `withBlockVerify`/`modBlockVerify` do what {@link withVerify}/{@link modVerify}
|
|
24
|
+
* do for a single Block, one level up - a spec that only imports the finished
|
|
25
|
+
* Flow (not necessarily the individual Blocks it was built from) can still
|
|
26
|
+
* patch one Block's verify for just that call, without editing the flow's own
|
|
27
|
+
* file or hand-rebuilding its Block list. Addressed the same three ways
|
|
28
|
+
* `modVerify` already addresses a Trait - the Block reference itself
|
|
29
|
+
* (`LoginBlock`, imported like any other Block; typo-proof, refactor-safe,
|
|
30
|
+
* jump-to-definition works), a plain string name, or a numeric index into this
|
|
31
|
+
* Flow's Block list (position between `start`/`end`, 0-based) for a spec that
|
|
32
|
+
* genuinely doesn't have the Block imported and doesn't want to spell its
|
|
33
|
+
* name. A reference or string resolves by `.name` under the hood (a Block's
|
|
34
|
+
* own stable identity in this codebase, same as every error message elsewhere
|
|
35
|
+
* in this file already uses) rather than object identity - it stays
|
|
36
|
+
* resolvable even after an earlier patch already swapped that slot for a new
|
|
37
|
+
* object, since the name survives every `withVerify`/`modVerify` in the
|
|
38
|
+
* chain; an index is checked fresh against this Flow's current Block list
|
|
39
|
+
* each call, so it's still correct after a patch too. Returns a new Flow -
|
|
40
|
+
* the original is untouched, same as every other decorator in this module.
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* One Block's identity as exposed by graph introspection - {@link Flow.blocks},
|
|
44
|
+
* {@link ComposedBlock.steps} - without needing to execute anything. Does not
|
|
45
|
+
* include the Block's literal Checkpoint `In`/`Out` tags: those are TypeScript
|
|
46
|
+
* literal types, erased at runtime, and can only be recovered by a build-time
|
|
47
|
+
* static-analysis tool reading the source's own type annotations - see the
|
|
48
|
+
* `graph-visualization` openspec change for that piece.
|
|
49
|
+
*/
|
|
50
|
+
export interface BlockInfo {
|
|
51
|
+
name: string;
|
|
52
|
+
/** `branch()`'s routing table, if this Block has one - see {@link Block.routes}. */
|
|
53
|
+
routes?: Readonly<Record<string, string | null>>;
|
|
54
|
+
/**
|
|
55
|
+
* True when a session-reset boundary runs immediately before this Block: the first Block of a sub-flow nested with
|
|
56
|
+
* `.flow(sub, { reset: true })` (or a CLI chain segment whose flow has `sessionReset`). Absent on an ordinary Flow.
|
|
57
|
+
*/
|
|
58
|
+
resetSessionBefore?: boolean;
|
|
59
|
+
/**
|
|
60
|
+
* The actual Block, re-runnable on its own - e.g. step-through tooling that runs a Flow's Blocks one at a time.
|
|
61
|
+
* Introspection that only wants to read the shape (a visualizer) can ignore this and use `name`/`routes` alone.
|
|
62
|
+
*/
|
|
63
|
+
block: SomeBlock;
|
|
64
|
+
}
|
|
65
|
+
/** A runnable chain of Blocks built by `engine.map()`. `run(mem)` launches its own browser; `run(context, mem)` reuses one. */
|
|
66
|
+
export interface Flow<Out extends Checkpoint<string>> {
|
|
67
|
+
/**
|
|
68
|
+
* `map({ sessionReset: true })`: this Flow wants a fresh browser session when it runs after another one (nested with
|
|
69
|
+
* `.flow(sub)` or chained on the CLI). `run()` itself never reads it.
|
|
70
|
+
*/
|
|
71
|
+
readonly resetSession: boolean;
|
|
72
|
+
/** The engine config the Flow was built with (launcher, layouts); running one of its steps on its own uses it too. */
|
|
73
|
+
readonly config: EngineConfig;
|
|
74
|
+
/**
|
|
75
|
+
* `map({ expectedFailure })` - a display hint for a step-through overlay: this Flow is DESIGNED to throw
|
|
76
|
+
* (e.g. a blocked user's login attempt genuinely failing), not a bug in
|
|
77
|
+
* the demo itself. `run()` never reads this - the Flow still throws
|
|
78
|
+
* exactly as it would otherwise; only the overlay's error panel reads it,
|
|
79
|
+
* to show an informational "this is the point" panel instead of an
|
|
80
|
+
* alarming one indistinguishable from a real break.
|
|
81
|
+
*/
|
|
82
|
+
readonly expectedFailureReason?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Demo pacing for this Flow's episode (`map({ demoPace })`).
|
|
85
|
+
* `run()` ignores; step/demo applies per Block in the episode.
|
|
86
|
+
*/
|
|
87
|
+
readonly demoPace?: import("../stub/pace.js").DemoPace;
|
|
88
|
+
/**
|
|
89
|
+
* Default highlight size/weight/tone for this Flow's episode (`map({ highlightStyle })`).
|
|
90
|
+
* Per-slot stub/fixture values win. `run()` ignores.
|
|
91
|
+
*/
|
|
92
|
+
readonly highlightStyle?: import("../stub/ring.js").HighlightStyleDefaults;
|
|
93
|
+
/**
|
|
94
|
+
* `map({ memStub: true })` - opts into
|
|
95
|
+
* auto-filling `requires` keys with registered fake values
|
|
96
|
+
* (`registerMemStub`, `src/engine/mem/mem-stub.ts`) instead of failing preflight when
|
|
97
|
+
* the caller didn't supply them. `run()` never reads this - the CLI's own
|
|
98
|
+
* `--data`/`--mem-stub` seeding, or a bare-library caller's own explicit
|
|
99
|
+
* `seedMemStub(mem, flow)` call, is what actually fills mem before `run()`.
|
|
100
|
+
*/
|
|
101
|
+
readonly memStub?: boolean;
|
|
102
|
+
/**
|
|
103
|
+
* This Flow's constituent Blocks, in order between `start`/`end`, as plain
|
|
104
|
+
* data - for introspection/visualization tools, without running anything.
|
|
105
|
+
* @example loginFlow.blocks() // [{ name: "login" }, { name: "add-to-cart", routes: {...} }]
|
|
106
|
+
*/
|
|
107
|
+
blocks(): readonly BlockInfo[];
|
|
108
|
+
run(context: BrowserContext, mem: MemPage): Promise<Out>;
|
|
109
|
+
/**
|
|
110
|
+
* `options.closeOnFinish: false` hands the driven page back instead of
|
|
111
|
+
* closing it - use this overload (a literal `false`, not a `boolean`) to
|
|
112
|
+
* get the `{ result, page }` shape typed correctly.
|
|
113
|
+
* @example const { result, page } = await loginFlow.run(context, mem, { closeOnFinish: false });
|
|
114
|
+
*/
|
|
115
|
+
run(context: BrowserContext, mem: MemPage, options: RunGraphOptions & {
|
|
116
|
+
closeOnFinish: false;
|
|
117
|
+
}): Promise<{
|
|
118
|
+
result: Out;
|
|
119
|
+
page: Page;
|
|
120
|
+
}>;
|
|
121
|
+
/**
|
|
122
|
+
* `options.page` drives that already-open page instead of opening a new
|
|
123
|
+
* one - see {@link RunGraphOptions}.
|
|
124
|
+
* @example await loginFlow.run(context, mem, { page: existingPage });
|
|
125
|
+
*/
|
|
126
|
+
run(context: BrowserContext, mem: MemPage, options?: RunGraphOptions): Promise<Out>;
|
|
127
|
+
run(mem: MemPage, config?: EngineConfig): Promise<Out>;
|
|
128
|
+
/**
|
|
129
|
+
* Replaces the given Block's whole verify list, wherever it sits in this
|
|
130
|
+
* Flow - same rules as {@link withVerify}. Throws if no Block in this Flow
|
|
131
|
+
* matches.
|
|
132
|
+
* @example checkoutFlow.withBlockVerify(LoginBlock, [])
|
|
133
|
+
* @example checkoutFlow.withBlockVerify("login", [])
|
|
134
|
+
* @example checkoutFlow.withBlockVerify(0, [])
|
|
135
|
+
*/
|
|
136
|
+
withBlockVerify(block: SomeBlock | string | number, verify: Trait[] | ((out: any) => Trait[])): Flow<Out>;
|
|
137
|
+
/**
|
|
138
|
+
* Replaces one Trait inside the given Block's verify list - same rules as
|
|
139
|
+
* {@link modVerify}. Throws if no Block in this Flow matches, or if that
|
|
140
|
+
* Block has no verify trait at the given name/index.
|
|
141
|
+
* @example checkoutFlow.modBlockVerify(LoginBlock, "url-matches", Trait.url({ pathname: "/inventory.html" }))
|
|
142
|
+
*/
|
|
143
|
+
modBlockVerify(block: SomeBlock | string | number, nameOrIndex: string | number, newCheck: Trait["check"] | Trait): Flow<Out>;
|
|
144
|
+
}
|
|
145
|
+
export declare function buildFlow<Out extends Checkpoint<string>>(middle: readonly SomeBlock[], engineConfig: EngineConfig): Flow<Out>;
|
|
146
|
+
/** The settings `map({ ... })` gives a Flow. */
|
|
147
|
+
export interface FlowSettings {
|
|
148
|
+
memStub?: boolean;
|
|
149
|
+
sessionReset?: boolean;
|
|
150
|
+
expectedFailure?: string;
|
|
151
|
+
demoPace?: DemoPace;
|
|
152
|
+
highlightStyle?: HighlightStyleDefaults;
|
|
153
|
+
}
|
|
154
|
+
/** The Flow with its `map()` settings set; they survive `withBlockVerify`/`modBlockVerify` patches. */
|
|
155
|
+
export declare function withSettings<Out extends Checkpoint<string>>(flow: Flow<Out>, settings: FlowSettings): Flow<Out>;
|
|
156
|
+
export declare function clearSessionState(context: BrowserContext, page: Page): Promise<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Runs whole Flows one after another on the same page, context and mem - the runner's way of executing a CLI chain
|
|
159
|
+
* (`waygraph run "a then b"`) with each segment still its own episode. A Flow with `resetSession` gets its cookies and
|
|
160
|
+
* storage cleared right before it runs (skipped for the first one). Authors nest flows with `map().flow(sub)` instead.
|
|
161
|
+
*/
|
|
162
|
+
export declare function chainFlow(...flows: readonly Flow<Checkpoint<string>>[]): Flow<Checkpoint<string>>;
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
// A Flow: Blocks joined in order (connect), run as one with `run()`; map() builds them, with its settings (withSettings).
|
|
2
|
+
import { connect } from "../run/connect.js";
|
|
3
|
+
import { launchOwnContext } from "../run/launch.js";
|
|
4
|
+
import { WaygraphError, MSG_CHAINFLOW_BLOCK_NOT_FOUND_BY_INDEX, MSG_CHAINFLOW_BLOCK_NOT_FOUND_BY_NAME, MSG_CHAINFLOW_EMPTY, } from "../errors.js";
|
|
5
|
+
import { preflight, runGraph } from "../run/run.js";
|
|
6
|
+
import { MemPage } from "../mem/mem.js";
|
|
7
|
+
import { findBlockIndex, modVerify, withVerify } from "../block/block.js";
|
|
8
|
+
import { normalizeHighlightSize, normalizeHighlightTone, normalizeHighlightWeight } from "../stub/ring.js";
|
|
9
|
+
import { ignorePageGone } from "../page-gone.js";
|
|
10
|
+
export function buildFlow(middle, engineConfig) {
|
|
11
|
+
// Settings (sessionReset, memStub, ...) are added afterwards by withSettings, which re-applies them after any
|
|
12
|
+
// withBlockVerify/modBlockVerify patch so they survive.
|
|
13
|
+
// Layouts have to be threaded into every pairwise connect(), not just the
|
|
14
|
+
// trailing runGraph call - see connect()'s own doc comment in types.ts:
|
|
15
|
+
// buildFlow's reduce IS the only place a Flow's
|
|
16
|
+
// intermediate (non-final) Checkpoints are ever verified at all.
|
|
17
|
+
const chain = middle.reduce((a, b) => connect(a, b, engineConfig.layouts));
|
|
18
|
+
// Declared separately (not as the object-literal method below) so the
|
|
19
|
+
// three-overload `Flow.run` signature can be checked against the actual
|
|
20
|
+
// per-call-shape behavior, then attached with a cast - object-literal
|
|
21
|
+
// methods can't satisfy TS's per-overload implementation check the way a
|
|
22
|
+
// standalone function assigned to the property can.
|
|
23
|
+
const run = async function run(contextOrMem, memOrConfig, options) {
|
|
24
|
+
if (contextOrMem instanceof MemPage) {
|
|
25
|
+
const mem = contextOrMem;
|
|
26
|
+
const config = { ...engineConfig, ...memOrConfig };
|
|
27
|
+
// Checked again inside runGraph too, but doing it here first means a
|
|
28
|
+
// missing key fails before a browser process even launches, not just
|
|
29
|
+
// before a page opens - the same "fail loud, cheaply" guarantee
|
|
30
|
+
// run(context, mem) already has via an existing context.
|
|
31
|
+
preflight(mem, chain);
|
|
32
|
+
const { context, close } = await launchOwnContext(config);
|
|
33
|
+
try {
|
|
34
|
+
try {
|
|
35
|
+
return await runGraph(chain, undefined, context, mem, 5000, {
|
|
36
|
+
...(config.layouts !== undefined ? { layouts: config.layouts } : {}),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
// Playwright finalizes recordVideo on context.close(); skip when
|
|
41
|
+
// not recording so mem-only runs with stub contexts stay unchanged.
|
|
42
|
+
if (config.recordVideo) {
|
|
43
|
+
await context.close();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
finally {
|
|
48
|
+
await close();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const context = contextOrMem;
|
|
52
|
+
const mem = memOrConfig;
|
|
53
|
+
// Open (or reuse) the page here, not inside runGraph, so this method -
|
|
54
|
+
// not runGraph - decides whether to close it once the run is over; the
|
|
55
|
+
// page reference has to survive past runGraph's own return either way.
|
|
56
|
+
const gotOwnPage = options?.page === undefined;
|
|
57
|
+
const page = options?.page ?? (await context.newPage());
|
|
58
|
+
// Defaulting close-on-finish to `true` unconditionally would close a
|
|
59
|
+
// page the *caller* opened and handed in via `options.page` - the exact
|
|
60
|
+
// thing this option exists to let a caller keep driving. Only default to
|
|
61
|
+
// closing when this call opened the page itself (no `options.page`
|
|
62
|
+
// given), which is the one case that matches every `run(context, mem)`
|
|
63
|
+
// call from before this option existed. An explicit `closeOnFinish`
|
|
64
|
+
// always wins either way.
|
|
65
|
+
const closeOnFinish = options?.closeOnFinish ?? gotOwnPage;
|
|
66
|
+
const resolvedLayouts = options?.layouts ?? engineConfig.layouts;
|
|
67
|
+
const result = await runGraph(chain, undefined, context, mem, 5000, {
|
|
68
|
+
page,
|
|
69
|
+
closeOnFinish: false,
|
|
70
|
+
...(resolvedLayouts !== undefined ? { layouts: resolvedLayouts } : {}),
|
|
71
|
+
});
|
|
72
|
+
if (closeOnFinish) {
|
|
73
|
+
await page.close();
|
|
74
|
+
}
|
|
75
|
+
// The return *shape* only changes on an explicit `closeOnFinish: false`
|
|
76
|
+
// (the literal the `{ result, page }` overload is typed against) - not
|
|
77
|
+
// on the computed `closeOnFinish` default above. A caller who passed
|
|
78
|
+
// their own `page` and left `closeOnFinish` unset already holds that
|
|
79
|
+
// page reference; handing it back again in a different return shape
|
|
80
|
+
// would silently break the plain-`Out` overload their call actually
|
|
81
|
+
// matched at the type level.
|
|
82
|
+
if (options?.closeOnFinish === false) {
|
|
83
|
+
return { result, page };
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
86
|
+
};
|
|
87
|
+
return {
|
|
88
|
+
resetSession: false,
|
|
89
|
+
config: engineConfig,
|
|
90
|
+
blocks: () => middle.map((b) => ({
|
|
91
|
+
name: b.name,
|
|
92
|
+
block: b,
|
|
93
|
+
...(b.routes ? { routes: b.routes } : {}),
|
|
94
|
+
...(b.__waygraphResetBefore ? { resetSessionBefore: true } : {}),
|
|
95
|
+
})),
|
|
96
|
+
run: run,
|
|
97
|
+
withBlockVerify(block, verify) {
|
|
98
|
+
const index = findBlockIndex(middle, block);
|
|
99
|
+
const patched = [...middle];
|
|
100
|
+
patched[index] = withVerify(middle[index], verify);
|
|
101
|
+
return buildFlow(patched, engineConfig);
|
|
102
|
+
},
|
|
103
|
+
modBlockVerify(block, nameOrIndex, newCheck) {
|
|
104
|
+
const index = findBlockIndex(middle, block);
|
|
105
|
+
const patched = [...middle];
|
|
106
|
+
patched[index] = modVerify(middle[index], nameOrIndex, newCheck);
|
|
107
|
+
return buildFlow(patched, engineConfig);
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
/** The Flow with its `map()` settings set; they survive `withBlockVerify`/`modBlockVerify` patches. */
|
|
112
|
+
export function withSettings(flow, settings) {
|
|
113
|
+
const style = settings.highlightStyle;
|
|
114
|
+
const fields = {
|
|
115
|
+
...(settings.sessionReset ? { resetSession: true } : {}),
|
|
116
|
+
...(settings.memStub ? { memStub: true } : {}),
|
|
117
|
+
...(settings.expectedFailure !== undefined ? { expectedFailureReason: settings.expectedFailure } : {}),
|
|
118
|
+
...(settings.demoPace ? { demoPace: settings.demoPace } : {}),
|
|
119
|
+
...(style
|
|
120
|
+
? {
|
|
121
|
+
highlightStyle: {
|
|
122
|
+
...(style.tone !== undefined ? { tone: normalizeHighlightTone(style.tone) } : {}),
|
|
123
|
+
...(style.size !== undefined ? { size: normalizeHighlightSize(style.size) } : {}),
|
|
124
|
+
...(style.weight !== undefined ? { weight: normalizeHighlightWeight(style.weight) } : {}),
|
|
125
|
+
},
|
|
126
|
+
}
|
|
127
|
+
: {}),
|
|
128
|
+
};
|
|
129
|
+
if (Object.keys(fields).length === 0)
|
|
130
|
+
return flow;
|
|
131
|
+
return {
|
|
132
|
+
...flow,
|
|
133
|
+
...fields,
|
|
134
|
+
withBlockVerify: (block, verify) => withSettings(flow.withBlockVerify(block, verify), settings),
|
|
135
|
+
modBlockVerify: (block, nameOrIndex, newCheck) => withSettings(flow.modBlockVerify(block, nameOrIndex, newCheck), settings),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function locateInChain(flows, block) {
|
|
139
|
+
if (typeof block === "number") {
|
|
140
|
+
let remaining = block;
|
|
141
|
+
for (let fi = 0; fi < flows.length; fi++) {
|
|
142
|
+
const len = flows[fi].blocks().length;
|
|
143
|
+
if (remaining < len)
|
|
144
|
+
return { flowIndex: fi, localIndex: remaining };
|
|
145
|
+
remaining -= len;
|
|
146
|
+
}
|
|
147
|
+
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND", MSG_CHAINFLOW_BLOCK_NOT_FOUND_BY_INDEX(block, flows.length));
|
|
148
|
+
}
|
|
149
|
+
const blockName = typeof block === "string" ? block : block.name;
|
|
150
|
+
for (let fi = 0; fi < flows.length; fi++) {
|
|
151
|
+
const localIndex = flows[fi].blocks().findIndex((bi) => bi.name === blockName);
|
|
152
|
+
if (localIndex !== -1)
|
|
153
|
+
return { flowIndex: fi, localIndex };
|
|
154
|
+
}
|
|
155
|
+
throw new WaygraphError("WG_FLOW_BLOCK_NOT_FOUND", MSG_CHAINFLOW_BLOCK_NOT_FOUND_BY_NAME(blockName));
|
|
156
|
+
}
|
|
157
|
+
export async function clearSessionState(context, page) {
|
|
158
|
+
await context.clearCookies().catch(ignorePageGone);
|
|
159
|
+
await page
|
|
160
|
+
.evaluate(() => {
|
|
161
|
+
try {
|
|
162
|
+
localStorage.clear();
|
|
163
|
+
sessionStorage.clear();
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
/* storage blocked (e.g. about:blank) - nothing to clear anyway */
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
.catch(ignorePageGone);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Runs whole Flows one after another on the same page, context and mem - the runner's way of executing a CLI chain
|
|
173
|
+
* (`waygraph run "a then b"`) with each segment still its own episode. A Flow with `resetSession` gets its cookies and
|
|
174
|
+
* storage cleared right before it runs (skipped for the first one). Authors nest flows with `map().flow(sub)` instead.
|
|
175
|
+
*/
|
|
176
|
+
export function chainFlow(...flows) {
|
|
177
|
+
if (flows.length === 0) {
|
|
178
|
+
throw new WaygraphError("WG_CHAINFLOW_EMPTY", MSG_CHAINFLOW_EMPTY);
|
|
179
|
+
}
|
|
180
|
+
const run = async function run(contextOrMem, memOrConfig, options) {
|
|
181
|
+
if (contextOrMem instanceof MemPage) {
|
|
182
|
+
const mem = contextOrMem;
|
|
183
|
+
const config = memOrConfig;
|
|
184
|
+
// One browser for the WHOLE chain - each sub-flow's own run(mem,
|
|
185
|
+
// config) would otherwise each launch a separate browser, defeating
|
|
186
|
+
// the point of sequencing them (a fresh browser is itself a full
|
|
187
|
+
// session reset, silently making sessionReset a no-op).
|
|
188
|
+
const { context, close } = await launchOwnContext(config);
|
|
189
|
+
try {
|
|
190
|
+
try {
|
|
191
|
+
return await run(context, mem, { closeOnFinish: true });
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
await context.close();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
await close();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const context = contextOrMem;
|
|
202
|
+
const mem = memOrConfig;
|
|
203
|
+
const gotOwnPage = options?.page === undefined;
|
|
204
|
+
const page = options?.page ?? (await context.newPage());
|
|
205
|
+
const closeOnFinish = options?.closeOnFinish ?? gotOwnPage;
|
|
206
|
+
let result;
|
|
207
|
+
for (let i = 0; i < flows.length; i++) {
|
|
208
|
+
const flow = flows[i];
|
|
209
|
+
if (i > 0 && flow.resetSession) {
|
|
210
|
+
await clearSessionState(context, page);
|
|
211
|
+
}
|
|
212
|
+
const outcome = (await flow.run(context, mem, { page, closeOnFinish: false }));
|
|
213
|
+
result = outcome.result;
|
|
214
|
+
}
|
|
215
|
+
if (closeOnFinish) {
|
|
216
|
+
await page.close();
|
|
217
|
+
}
|
|
218
|
+
if (options?.closeOnFinish === false) {
|
|
219
|
+
return { result, page };
|
|
220
|
+
}
|
|
221
|
+
return result;
|
|
222
|
+
};
|
|
223
|
+
return {
|
|
224
|
+
config: flows[0].config,
|
|
225
|
+
resetSession: false,
|
|
226
|
+
blocks: () => flows.flatMap((flow, idx) => flow.blocks().map((bi, i) => ({
|
|
227
|
+
...bi,
|
|
228
|
+
...(i === 0 && idx > 0 && flow.resetSession ? { resetSessionBefore: true } : {}),
|
|
229
|
+
}))),
|
|
230
|
+
run: run,
|
|
231
|
+
withBlockVerify(block, verify) {
|
|
232
|
+
const { flowIndex, localIndex } = locateInChain(flows, block);
|
|
233
|
+
const patched = [...flows];
|
|
234
|
+
patched[flowIndex] = patched[flowIndex].withBlockVerify(localIndex, verify);
|
|
235
|
+
return chainFlow(...patched);
|
|
236
|
+
},
|
|
237
|
+
modBlockVerify(block, nameOrIndex, newCheck) {
|
|
238
|
+
const { flowIndex, localIndex } = locateInChain(flows, block);
|
|
239
|
+
const patched = [...flows];
|
|
240
|
+
patched[flowIndex] = patched[flowIndex].modBlockVerify(localIndex, nameOrIndex, newCheck);
|
|
241
|
+
return chainFlow(...patched);
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
}
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import type { NavBlock } from "
|
|
6
|
-
import type { PageBlock } from "
|
|
7
|
-
import type { AssertBlock, MethodBlock } from "
|
|
8
|
-
import type { EffectBlock } from "
|
|
1
|
+
import type { Checkpoint } from "../checkpoint/checkpoint.js";
|
|
2
|
+
import type { Flow, FlowSettings } from "./flow.js";
|
|
3
|
+
import type { DemoPace } from "../stub/pace.js";
|
|
4
|
+
import type { HighlightStyleDefaults } from "../stub/ring.js";
|
|
5
|
+
import type { NavBlock } from "../block/kinds/nav.js";
|
|
6
|
+
import type { PageBlock } from "../block/kinds/page.js";
|
|
7
|
+
import type { AssertBlock, MethodBlock } from "../block/kinds/method.js";
|
|
8
|
+
import type { EffectBlock } from "../block/kinds/effect.js";
|
|
9
|
+
import type { SomeBlock } from "../block/block.js";
|
|
9
10
|
type S = Checkpoint<"__start__">;
|
|
10
11
|
/**
|
|
11
|
-
* The one capability MapBuilder needs from Engine
|
|
12
|
-
*
|
|
13
|
-
* import each other (Engine.map() builds a MapBuilder; MapBuilder.end() calls back into
|
|
14
|
-
* defineFlow) - a real cycle check:structure forbids. This type is how that's avoided.
|
|
12
|
+
* The one capability MapBuilder needs from Engine: turn the finished steps into a Flow with the engine's config. A
|
|
13
|
+
* function, not the Engine class, so engine.ts and map-builder.ts don't import each other.
|
|
15
14
|
*/
|
|
16
|
-
export type
|
|
15
|
+
export type BuildFlowFn = (steps: readonly SomeBlock[], settings: FlowSettings) => Flow<Checkpoint<string>>;
|
|
16
|
+
/** Per-step options for the map builder: `ff` fast-forwards the step, `pace` sets its demo pace. */
|
|
17
17
|
export interface MapStepOpts {
|
|
18
18
|
/**
|
|
19
19
|
* Fast-forward just this step, inline - no `.ffStart()/.ffEnd()` bracket needed. Consecutive
|
|
@@ -24,11 +24,12 @@ export interface MapStepOpts {
|
|
|
24
24
|
ff?: boolean;
|
|
25
25
|
/**
|
|
26
26
|
* Demo pace for just this step (`"blitz"` skips the typing animation and the pause after the action; `"fast"`, `"slow"`,
|
|
27
|
-
* or a number scale the narration gates).
|
|
27
|
+
* or a number scale the narration gates).
|
|
28
28
|
* @example map().method(SetBearerTokenBlock, { pace: "blitz" })
|
|
29
29
|
*/
|
|
30
30
|
pace?: DemoPace;
|
|
31
31
|
}
|
|
32
|
+
/** Flow-level settings for `engine.map({ … })`: `memStub`, `sessionReset`, `expectedFailure`, `demoPace`, `highlightStyle`, `homeOrigin`. */
|
|
32
33
|
export interface MapBuilderOptions {
|
|
33
34
|
/**
|
|
34
35
|
* This project's own origin (e.g. `"https://app.example.com"`) - enables
|
|
@@ -37,22 +38,27 @@ export interface MapBuilderOptions {
|
|
|
37
38
|
* way; only the internal/external origin distinction is opt-in).
|
|
38
39
|
*/
|
|
39
40
|
homeOrigin?: string;
|
|
40
|
-
/** Fill missing `requires` keys from `registerMemStub` when the flow runs
|
|
41
|
+
/** Fill missing `requires` keys from `registerMemStub` when the flow runs. */
|
|
41
42
|
memStub?: boolean;
|
|
42
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* This flow wants a fresh browser session (cookies and storage cleared) when it runs after another one, in a CLI chain
|
|
45
|
+
* (`waygraph run "a then b"`) or nested with `.flow(sub)`: a second user signing in, a logged-out check.
|
|
46
|
+
*/
|
|
47
|
+
sessionReset?: boolean;
|
|
48
|
+
/** Marks a flow that is supposed to throw, with the reason shown in the demo. */
|
|
43
49
|
expectedFailure?: string;
|
|
44
|
-
/** Default demo pace for the whole flow
|
|
50
|
+
/** Default demo pace for the whole flow. */
|
|
45
51
|
demoPace?: DemoPace;
|
|
46
|
-
/** Default ring tone, size and weight for the whole flow
|
|
52
|
+
/** Default ring tone, size and weight for the whole flow. */
|
|
47
53
|
highlightStyle?: HighlightStyleDefaults;
|
|
48
54
|
}
|
|
49
55
|
/** What `.flow()` takes for the sub-flow it runs inline. */
|
|
50
56
|
export interface MapFlowOpts {
|
|
51
|
-
/** Clear cookies and storage right before the sub-flow, e.g. to start a second user fresh
|
|
57
|
+
/** Clear cookies and storage right before the sub-flow, e.g. to start a second user fresh. Defaults to the sub-flow's own `sessionReset`. */
|
|
52
58
|
reset?: boolean;
|
|
53
59
|
}
|
|
54
60
|
/**
|
|
55
|
-
*
|
|
61
|
+
* The flow builder behind `engine.map()` - see `map()`'s own doc
|
|
56
62
|
* comment for why this exists. Each step method is scoped to exactly the
|
|
57
63
|
* Block kind its name promises, checked at RUNTIME against the
|
|
58
64
|
* `__waygraphKind`/`__waygraphSalt` markers `defineNavBlock`/`definePageBlock`/
|
|
@@ -60,21 +66,21 @@ export interface MapFlowOpts {
|
|
|
60
66
|
* (the same markers `graph.ts` and `map-check.ts` trust) - not just a type
|
|
61
67
|
* hint, since a hand-rolled object can satisfy the TypeScript `Block<In,Out>`
|
|
62
68
|
* shape without ever going through a real factory. Each call also
|
|
63
|
-
* typechecks the accumulated Checkpoint chain
|
|
64
|
-
* own tuple overloads do (a step's `In` must equal the previous step's
|
|
69
|
+
* typechecks the accumulated Checkpoint chain (a step's `In` must equal the previous step's
|
|
65
70
|
* `Out`) - this is what "no teleporting" means: there is no method on this
|
|
66
71
|
* builder that can skip from one Checkpoint to an unrelated one without a
|
|
67
72
|
* real, kind-correct Block in between.
|
|
68
73
|
*/
|
|
69
74
|
export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
70
|
-
private readonly
|
|
75
|
+
private readonly build;
|
|
76
|
+
private readonly settings;
|
|
71
77
|
private readonly steps;
|
|
72
78
|
private readonly homeOrigin;
|
|
73
79
|
private readonly ff;
|
|
74
80
|
private constructor();
|
|
75
81
|
/** @internal - use `engine.map()` or the standalone `map()` export. */
|
|
76
|
-
static begin(
|
|
77
|
-
/** Readable chain-opener
|
|
82
|
+
static begin(build: BuildFlowFn, settings: FlowSettings, homeOrigin: string | undefined): MapBuilder<S>;
|
|
83
|
+
/** Readable chain-opener. Returns `this` unchanged; entirely optional. */
|
|
78
84
|
start(): MapBuilder<Out>;
|
|
79
85
|
/**
|
|
80
86
|
* Open a fast-forward window - steps until {@link ffEnd} collapse into one
|
|
@@ -103,7 +109,7 @@ export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
|
103
109
|
* `defineNavBlock`/`defineMemNavBlock`/`definePageBlock`. Throws if given
|
|
104
110
|
* anything else, including a `homeOrigin`-mismatched static `url`.
|
|
105
111
|
* Compile-time: {@link NavBlock} or {@link PageBlock} only (not Assert/Method).
|
|
106
|
-
* `{ ff: true }`: fast-forward this one step inline - see
|
|
112
|
+
* `{ ff: true }`: fast-forward this one step inline - see `appendStep`'s own comment.
|
|
107
113
|
*/
|
|
108
114
|
gotoPage<NextOut extends Checkpoint<string>>(block: (NavBlock<NextOut> | PageBlock<NextOut>) & {
|
|
109
115
|
name: string;
|
|
@@ -113,7 +119,7 @@ export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
|
113
119
|
* Blocks in the Waygraph Map convention: mailpit, maildrop.cc) - same
|
|
114
120
|
* kind requirement as {@link gotoPage}, plus the inverse `homeOrigin` check.
|
|
115
121
|
* Compile-time: {@link NavBlock} or {@link PageBlock} only.
|
|
116
|
-
* `{ ff: true }`: fast-forward this one step inline - see
|
|
122
|
+
* `{ ff: true }`: fast-forward this one step inline - see `appendStep`'s own comment.
|
|
117
123
|
*/
|
|
118
124
|
gotoExternal<NextOut extends Checkpoint<string>>(block: (NavBlock<NextOut> | PageBlock<NextOut>) & {
|
|
119
125
|
name: string;
|
|
@@ -121,7 +127,7 @@ export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
|
121
127
|
/**
|
|
122
128
|
* Appends a self-loop verification step - requires a Block from
|
|
123
129
|
* `defineAssertBlock`. Compile-time: {@link AssertBlock} only (not `.method()`).
|
|
124
|
-
* `{ ff: true }`: fast-forward this one step inline - see
|
|
130
|
+
* `{ ff: true }`: fast-forward this one step inline - see `appendStep`'s own comment.
|
|
125
131
|
*/
|
|
126
132
|
assert(block: AssertBlock<Out> & {
|
|
127
133
|
name: string;
|
|
@@ -133,7 +139,7 @@ export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
|
133
139
|
* Compile-time: {@link MethodBlock} or {@link EffectBlock} only - Assert
|
|
134
140
|
* Blocks must use `.assert()`. Runtime also rejects `__waygraphKind =
|
|
135
141
|
* "assert"` (those still carry method salt from the factory internals).
|
|
136
|
-
* `{ ff: true }`: fast-forward this one step inline - see
|
|
142
|
+
* `{ ff: true }`: fast-forward this one step inline - see `appendStep`'s own comment.
|
|
137
143
|
*/
|
|
138
144
|
method<NextOut extends Checkpoint<string>>(block: (MethodBlock<Out, NextOut> | EffectBlock<Out, NextOut>) & {
|
|
139
145
|
name: string;
|
|
@@ -141,7 +147,7 @@ export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
|
141
147
|
/**
|
|
142
148
|
* Runs another flow's steps inline here, in the same page, browser and `mem`. This is how flows nest:
|
|
143
149
|
* `map().flow(loginFlow).flow(viewerFlow, { reset: true })`. With `{ reset: true }` cookies and storage are cleared
|
|
144
|
-
* right before the sub-flow's first step.
|
|
150
|
+
* right before the sub-flow's first step.
|
|
145
151
|
*/
|
|
146
152
|
flow<NextOut extends Checkpoint<string>>(sub: Flow<NextOut>, opts?: MapFlowOpts): MapBuilder<NextOut>;
|
|
147
153
|
/**
|
|
@@ -156,7 +162,7 @@ export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
|
156
162
|
* Checkpoint to chain `.method()/.gotoPage()/.assert()/.end()` (or another `.branch()`) off of.
|
|
157
163
|
*
|
|
158
164
|
* Real gap this fixes: the plain `branch()` helper's `.next` routing is only ever consulted by
|
|
159
|
-
* `runGraph`'s own graph walk -
|
|
165
|
+
* `runGraph`'s own graph walk - `.end()` composes steps pairwise via `connect()`,
|
|
160
166
|
* which never looks at `.next` at all, so a Map-built Flow had no way to branch. This method
|
|
161
167
|
* branches at the Flow level instead: it finalizes the prefix, runs it, and picks the next Flow
|
|
162
168
|
* itself once the real tag is known - no engine-level routing involved.
|
|
@@ -167,7 +173,7 @@ export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
|
167
173
|
*
|
|
168
174
|
* The route's first Block still sees `input.__state === "__start__"` in `act()`, not the tag that
|
|
169
175
|
* routed there - `runGraph` seeds every Flow's entry Block that way unconditionally, the same as
|
|
170
|
-
* any
|
|
176
|
+
* any single-Block Flow does. Read `page`/`mem`, not `input`,
|
|
171
177
|
* in `act()` - every real Block in this codebase already follows that convention.
|
|
172
178
|
*
|
|
173
179
|
* @example
|
|
@@ -177,21 +183,17 @@ export declare class MapBuilder<Out extends Checkpoint<string>> {
|
|
|
177
183
|
* });
|
|
178
184
|
*/
|
|
179
185
|
branch<Routes extends {
|
|
180
|
-
[K in Out["__state"]]: ((m: MapBuilder<Extract<Out, Checkpoint<K>>>) => Flow<
|
|
186
|
+
[K in Out["__state"]]: ((m: MapBuilder<Extract<Out, Checkpoint<K>>>) => Flow<Checkpoint<string>>) | null;
|
|
181
187
|
}>(routes: Routes): Flow<{
|
|
182
188
|
[K in keyof Routes & string]: Routes[K] extends (m: any) => Flow<infer R> ? R : Extract<Out, Checkpoint<K>>;
|
|
183
189
|
}[keyof Routes & string]>;
|
|
184
190
|
/**
|
|
185
|
-
* Finalizes this chain into a
|
|
186
|
-
* `
|
|
187
|
-
* `withTitle`/`withHighlightFixtures`/etc. decorator still apply exactly
|
|
188
|
-
* as they do today; this builder only changes how the chain is assembled,
|
|
189
|
-
* never what it produces. Throws if no step was ever added - an empty map
|
|
191
|
+
* Finalizes this chain into a runnable {@link Flow} with the settings given to `map({ ... })`;
|
|
192
|
+
* `withBlockVerify`/`modBlockVerify` work on it. Throws if no step was ever added - an empty map
|
|
190
193
|
* isn't a flow. An auto-opened `{ ff: true }` window (see {@link MapStepOpts})
|
|
191
194
|
* left open at `.end()` closes silently; an EXPLICIT `.ffStart()` left open
|
|
192
195
|
* still throws - the author opened that one and needs to close it themselves.
|
|
193
196
|
*/
|
|
194
|
-
|
|
195
|
-
end(options?: FlowOptions): Flow<Out>;
|
|
197
|
+
end(): Flow<Out>;
|
|
196
198
|
}
|
|
197
199
|
export {};
|