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
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { WaygraphError, MSG_MAP_WRONG_KIND, MSG_MAP_WRONG_SALT, MSG_MAP_WRONG_ORIGIN_INTERNAL, MSG_MAP_WRONG_ORIGIN_EXTERNAL, MSG_MAP_BRANCH_SHARED_SESSION_UNSUPPORTED, MSG_MAP_FF_ALREADY_OPEN, MSG_MAP_FF_NOT_OPEN, MSG_MAP_FF_EMPTY, MSG_MAP_METHOD_GOT_ASSERT, MSG_MAP_BRANCH_NO_PRIOR_STEP, MSG_MAP_FF_NOT_CLOSED, MSG_MAP_EMPTY, } from "../errors.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { copyWaygraphRuntime } from "./block.js";
|
|
2
|
+
import { MemPage } from "../mem/mem.js";
|
|
3
|
+
import { fastForwardComposeBlock } from "../block/compose.js";
|
|
4
|
+
import { clearSessionState } from "./flow.js";
|
|
5
|
+
import { copyWaygraphRuntime } from "../block/block.js";
|
|
7
6
|
/** Per-step options every `MapBuilder` step method (`.gotoPage()`/`.method()`/`.assert()`) takes. */
|
|
8
7
|
/** The same Block, but it clears cookies and storage before it acts. Keeps the runtime markers. */
|
|
9
8
|
function resetBefore(block) {
|
|
@@ -24,7 +23,11 @@ function resetBefore(block) {
|
|
|
24
23
|
}
|
|
25
24
|
/** Applies a step's `pace` option, keeping the Block's runtime markers. */
|
|
26
25
|
function paced(block, opts) {
|
|
27
|
-
|
|
26
|
+
if (opts?.pace === undefined)
|
|
27
|
+
return block;
|
|
28
|
+
const next = { ...block, demoPace: opts.pace };
|
|
29
|
+
copyWaygraphRuntime(block, next);
|
|
30
|
+
return next;
|
|
28
31
|
}
|
|
29
32
|
function mapKindOf(block) {
|
|
30
33
|
return block?.__waygraphKind;
|
|
@@ -44,6 +47,7 @@ const MAP_KIND_FACTORY_HINT = {
|
|
|
44
47
|
const MAP_SALT_FACTORY_HINT = {
|
|
45
48
|
method: "defineMethodBlock",
|
|
46
49
|
effect: "defineEffectBlock",
|
|
50
|
+
api: "defineApiBlock",
|
|
47
51
|
};
|
|
48
52
|
function assertMapKind(block, allowed, method) {
|
|
49
53
|
const kind = mapKindOf(block);
|
|
@@ -113,15 +117,14 @@ function buildBranchedFlow(before, routes) {
|
|
|
113
117
|
});
|
|
114
118
|
return {
|
|
115
119
|
resetSession: before.resetSession,
|
|
116
|
-
|
|
120
|
+
config: before.config,
|
|
117
121
|
...(before.expectedFailureReason !== undefined ? { expectedFailureReason: before.expectedFailureReason } : {}),
|
|
118
|
-
...(before.highlightFixtures !== undefined ? { highlightFixtures: before.highlightFixtures } : {}),
|
|
119
122
|
...(before.demoPace !== undefined ? { demoPace: before.demoPace } : {}),
|
|
120
123
|
...(before.highlightStyle !== undefined ? { highlightStyle: before.highlightStyle } : {}),
|
|
121
124
|
...(before.memStub !== undefined ? { memStub: before.memStub } : {}),
|
|
122
125
|
// Read by branchRoutes()/branchInfo() (branch-regression.ts) - real, ORDINARY (enumerable)
|
|
123
|
-
// properties, not hidden ones, specifically so a `
|
|
124
|
-
//
|
|
126
|
+
// properties, not hidden ones, specifically so a `{ ...flow, ... }` spread (withSettings) carries them
|
|
127
|
+
// through instead of silently dropping them -
|
|
125
128
|
// the same class of bug branch()'s missing copyWaygraphRuntime call already was.
|
|
126
129
|
__wgBranch: { before, routes },
|
|
127
130
|
// Static introspection (`waygraph graph`/list): the fixed prefix, plus every branch's own
|
|
@@ -141,7 +144,7 @@ function buildBranchedFlow(before, routes) {
|
|
|
141
144
|
};
|
|
142
145
|
}
|
|
143
146
|
/**
|
|
144
|
-
*
|
|
147
|
+
* The flow builder behind `engine.map()` - see `map()`'s own doc
|
|
145
148
|
* comment for why this exists. Each step method is scoped to exactly the
|
|
146
149
|
* Block kind its name promises, checked at RUNTIME against the
|
|
147
150
|
* `__waygraphKind`/`__waygraphSalt` markers `defineNavBlock`/`definePageBlock`/
|
|
@@ -149,34 +152,35 @@ function buildBranchedFlow(before, routes) {
|
|
|
149
152
|
* (the same markers `graph.ts` and `map-check.ts` trust) - not just a type
|
|
150
153
|
* hint, since a hand-rolled object can satisfy the TypeScript `Block<In,Out>`
|
|
151
154
|
* shape without ever going through a real factory. Each call also
|
|
152
|
-
* typechecks the accumulated Checkpoint chain
|
|
153
|
-
* own tuple overloads do (a step's `In` must equal the previous step's
|
|
155
|
+
* typechecks the accumulated Checkpoint chain (a step's `In` must equal the previous step's
|
|
154
156
|
* `Out`) - this is what "no teleporting" means: there is no method on this
|
|
155
157
|
* builder that can skip from one Checkpoint to an unrelated one without a
|
|
156
158
|
* real, kind-correct Block in between.
|
|
157
159
|
*/
|
|
158
160
|
export class MapBuilder {
|
|
159
|
-
|
|
161
|
+
build;
|
|
162
|
+
settings;
|
|
160
163
|
steps;
|
|
161
164
|
homeOrigin;
|
|
162
165
|
ff;
|
|
163
166
|
constructor(
|
|
164
|
-
//
|
|
165
|
-
|
|
167
|
+
// From Engine.map(): see BuildFlowFn.
|
|
168
|
+
build, settings, steps, homeOrigin,
|
|
166
169
|
// `auto: true` = opened implicitly by a `{ ff: true }` step flag, not an explicit .ffStart() -
|
|
167
170
|
// closes silently at the next non-flagged step (or at .end()/.branch()) instead of demanding a
|
|
168
171
|
// matching .ffEnd(), since the author never opened anything they'd need to remember to close.
|
|
169
172
|
ff = null) {
|
|
170
|
-
this.
|
|
173
|
+
this.build = build;
|
|
174
|
+
this.settings = settings;
|
|
171
175
|
this.steps = steps;
|
|
172
176
|
this.homeOrigin = homeOrigin;
|
|
173
177
|
this.ff = ff;
|
|
174
178
|
}
|
|
175
179
|
/** @internal - use `engine.map()` or the standalone `map()` export. */
|
|
176
|
-
static begin(
|
|
177
|
-
return new MapBuilder(
|
|
180
|
+
static begin(build, settings, homeOrigin) {
|
|
181
|
+
return new MapBuilder(build, settings, [], homeOrigin, null);
|
|
178
182
|
}
|
|
179
|
-
/** Readable chain-opener
|
|
183
|
+
/** Readable chain-opener. Returns `this` unchanged; entirely optional. */
|
|
180
184
|
start() {
|
|
181
185
|
return this;
|
|
182
186
|
}
|
|
@@ -192,7 +196,7 @@ export class MapBuilder {
|
|
|
192
196
|
const ffName = typeof name === "string" && name.trim()
|
|
193
197
|
? name.trim()
|
|
194
198
|
: `ff-${this.steps.length + 1}`;
|
|
195
|
-
return new MapBuilder(this.
|
|
199
|
+
return new MapBuilder(this.build, this.settings, this.steps, this.homeOrigin, {
|
|
196
200
|
name: ffName,
|
|
197
201
|
buffer: [],
|
|
198
202
|
auto: false,
|
|
@@ -216,10 +220,8 @@ export class MapBuilder {
|
|
|
216
220
|
if (ff.buffer.length === 0) {
|
|
217
221
|
throw new WaygraphError("WG_MAP_FF_EMPTY", MSG_MAP_FF_EMPTY(ff.name));
|
|
218
222
|
}
|
|
219
|
-
const composed = fastForwardComposeBlock(ff.name,
|
|
220
|
-
|
|
221
|
-
ff.buffer);
|
|
222
|
-
return new MapBuilder(this.defineFlow, [...this.steps, composed], this.homeOrigin, null);
|
|
223
|
+
const composed = fastForwardComposeBlock(ff.name, ff.buffer);
|
|
224
|
+
return new MapBuilder(this.build, this.settings, [...this.steps, composed], this.homeOrigin, null);
|
|
223
225
|
}
|
|
224
226
|
/**
|
|
225
227
|
* `ff`: inline fast-forward, no `.ffStart()/.ffEnd()` bracket needed - `.method(X, { ff: true })`
|
|
@@ -232,7 +234,7 @@ export class MapBuilder {
|
|
|
232
234
|
appendStep(block, ff) {
|
|
233
235
|
if (ff) {
|
|
234
236
|
const win = this.ff ?? { name: `ff-${this.steps.length + 1}`, buffer: [], auto: true };
|
|
235
|
-
return new MapBuilder(this.
|
|
237
|
+
return new MapBuilder(this.build, this.settings, this.steps, this.homeOrigin, {
|
|
236
238
|
name: win.name,
|
|
237
239
|
buffer: [...win.buffer, block],
|
|
238
240
|
auto: win.auto,
|
|
@@ -243,20 +245,20 @@ export class MapBuilder {
|
|
|
243
245
|
}
|
|
244
246
|
if (this.ff) {
|
|
245
247
|
// Explicit .ffStart() window still open - absorbs a plain step too, same as always.
|
|
246
|
-
return new MapBuilder(this.
|
|
248
|
+
return new MapBuilder(this.build, this.settings, this.steps, this.homeOrigin, {
|
|
247
249
|
name: this.ff.name,
|
|
248
250
|
buffer: [...this.ff.buffer, block],
|
|
249
251
|
auto: false,
|
|
250
252
|
});
|
|
251
253
|
}
|
|
252
|
-
return new MapBuilder(this.
|
|
254
|
+
return new MapBuilder(this.build, this.settings, [...this.steps, block], this.homeOrigin, null);
|
|
253
255
|
}
|
|
254
256
|
/**
|
|
255
257
|
* Appends an internal navigation/page-arrival step - requires a Block from
|
|
256
258
|
* `defineNavBlock`/`defineMemNavBlock`/`definePageBlock`. Throws if given
|
|
257
259
|
* anything else, including a `homeOrigin`-mismatched static `url`.
|
|
258
260
|
* Compile-time: {@link NavBlock} or {@link PageBlock} only (not Assert/Method).
|
|
259
|
-
* `{ ff: true }`: fast-forward this one step inline - see
|
|
261
|
+
* `{ ff: true }`: fast-forward this one step inline - see `appendStep`'s own comment.
|
|
260
262
|
*/
|
|
261
263
|
gotoPage(block, opts) {
|
|
262
264
|
assertMapKind(block, ["nav", "page"], "gotoPage");
|
|
@@ -268,7 +270,7 @@ export class MapBuilder {
|
|
|
268
270
|
* Blocks in the Waygraph Map convention: mailpit, maildrop.cc) - same
|
|
269
271
|
* kind requirement as {@link gotoPage}, plus the inverse `homeOrigin` check.
|
|
270
272
|
* Compile-time: {@link NavBlock} or {@link PageBlock} only.
|
|
271
|
-
* `{ ff: true }`: fast-forward this one step inline - see
|
|
273
|
+
* `{ ff: true }`: fast-forward this one step inline - see `appendStep`'s own comment.
|
|
272
274
|
*/
|
|
273
275
|
gotoExternal(block, opts) {
|
|
274
276
|
assertMapKind(block, ["nav", "page"], "gotoExternal");
|
|
@@ -278,7 +280,7 @@ export class MapBuilder {
|
|
|
278
280
|
/**
|
|
279
281
|
* Appends a self-loop verification step - requires a Block from
|
|
280
282
|
* `defineAssertBlock`. Compile-time: {@link AssertBlock} only (not `.method()`).
|
|
281
|
-
* `{ ff: true }`: fast-forward this one step inline - see
|
|
283
|
+
* `{ ff: true }`: fast-forward this one step inline - see `appendStep`'s own comment.
|
|
282
284
|
*/
|
|
283
285
|
assert(block, opts) {
|
|
284
286
|
assertMapKind(block, ["assert"], "assert");
|
|
@@ -291,24 +293,25 @@ export class MapBuilder {
|
|
|
291
293
|
* Compile-time: {@link MethodBlock} or {@link EffectBlock} only - Assert
|
|
292
294
|
* Blocks must use `.assert()`. Runtime also rejects `__waygraphKind =
|
|
293
295
|
* "assert"` (those still carry method salt from the factory internals).
|
|
294
|
-
* `{ ff: true }`: fast-forward this one step inline - see
|
|
296
|
+
* `{ ff: true }`: fast-forward this one step inline - see `appendStep`'s own comment.
|
|
295
297
|
*/
|
|
296
298
|
method(block, opts) {
|
|
297
299
|
if (mapKindOf(block) === "assert") {
|
|
298
300
|
throw new WaygraphError("WG_MAP_WRONG_KIND", MSG_MAP_METHOD_GOT_ASSERT(block.name));
|
|
299
301
|
}
|
|
300
|
-
assertMapSalt(block, ["method", "effect"], "method");
|
|
302
|
+
assertMapSalt(block, ["method", "effect", "api"], "method");
|
|
301
303
|
return this.appendStep(paced(block, opts), opts?.ff);
|
|
302
304
|
}
|
|
303
305
|
/**
|
|
304
306
|
* Runs another flow's steps inline here, in the same page, browser and `mem`. This is how flows nest:
|
|
305
307
|
* `map().flow(loginFlow).flow(viewerFlow, { reset: true })`. With `{ reset: true }` cookies and storage are cleared
|
|
306
|
-
* right before the sub-flow's first step.
|
|
308
|
+
* right before the sub-flow's first step.
|
|
307
309
|
*/
|
|
308
310
|
flow(sub, opts) {
|
|
311
|
+
// The steps' types live in `sub`; at runtime this is one untyped walk, typed again as the sub-flow's last Checkpoint.
|
|
309
312
|
let next = this;
|
|
310
313
|
sub.blocks().forEach((info, i) => {
|
|
311
|
-
const block = i === 0 && opts?.reset ? resetBefore(info.block) : info.block;
|
|
314
|
+
const block = i === 0 && (opts?.reset ?? sub.resetSession) ? resetBefore(info.block) : info.block;
|
|
312
315
|
next = next.appendStep(block);
|
|
313
316
|
});
|
|
314
317
|
return next;
|
|
@@ -325,7 +328,7 @@ export class MapBuilder {
|
|
|
325
328
|
* Checkpoint to chain `.method()/.gotoPage()/.assert()/.end()` (or another `.branch()`) off of.
|
|
326
329
|
*
|
|
327
330
|
* Real gap this fixes: the plain `branch()` helper's `.next` routing is only ever consulted by
|
|
328
|
-
* `runGraph`'s own graph walk -
|
|
331
|
+
* `runGraph`'s own graph walk - `.end()` composes steps pairwise via `connect()`,
|
|
329
332
|
* which never looks at `.next` at all, so a Map-built Flow had no way to branch. This method
|
|
330
333
|
* branches at the Flow level instead: it finalizes the prefix, runs it, and picks the next Flow
|
|
331
334
|
* itself once the real tag is known - no engine-level routing involved.
|
|
@@ -336,7 +339,7 @@ export class MapBuilder {
|
|
|
336
339
|
*
|
|
337
340
|
* The route's first Block still sees `input.__state === "__start__"` in `act()`, not the tag that
|
|
338
341
|
* routed there - `runGraph` seeds every Flow's entry Block that way unconditionally, the same as
|
|
339
|
-
* any
|
|
342
|
+
* any single-Block Flow does. Read `page`/`mem`, not `input`,
|
|
340
343
|
* in `act()` - every real Block in this codebase already follows that convention.
|
|
341
344
|
*
|
|
342
345
|
* @example
|
|
@@ -352,32 +355,27 @@ export class MapBuilder {
|
|
|
352
355
|
const before = this.end();
|
|
353
356
|
const resolvedRoutes = {};
|
|
354
357
|
for (const [tag, fn] of Object.entries(routes)) {
|
|
355
|
-
resolvedRoutes[tag] = fn ? fn(new MapBuilder(this.
|
|
358
|
+
resolvedRoutes[tag] = fn ? fn(new MapBuilder(this.build, this.settings, [], this.homeOrigin, null)) : null;
|
|
356
359
|
}
|
|
357
360
|
return buildBranchedFlow(before, resolvedRoutes);
|
|
358
361
|
}
|
|
359
362
|
/**
|
|
360
|
-
* Finalizes this chain into a
|
|
361
|
-
* `
|
|
362
|
-
* `withTitle`/`withHighlightFixtures`/etc. decorator still apply exactly
|
|
363
|
-
* as they do today; this builder only changes how the chain is assembled,
|
|
364
|
-
* never what it produces. Throws if no step was ever added - an empty map
|
|
363
|
+
* Finalizes this chain into a runnable {@link Flow} with the settings given to `map({ ... })`;
|
|
364
|
+
* `withBlockVerify`/`modBlockVerify` work on it. Throws if no step was ever added - an empty map
|
|
365
365
|
* isn't a flow. An auto-opened `{ ff: true }` window (see {@link MapStepOpts})
|
|
366
366
|
* left open at `.end()` closes silently; an EXPLICIT `.ffStart()` left open
|
|
367
367
|
* still throws - the author opened that one and needs to close it themselves.
|
|
368
368
|
*/
|
|
369
|
-
|
|
370
|
-
end(options) {
|
|
369
|
+
end() {
|
|
371
370
|
if (this.ff && !this.ff.auto) {
|
|
372
371
|
throw new WaygraphError("WG_MAP_FF_NOT_CLOSED", MSG_MAP_FF_NOT_CLOSED(this.ff.name));
|
|
373
372
|
}
|
|
374
373
|
if (this.ff && this.ff.auto) {
|
|
375
|
-
return this.closeFf().end(
|
|
374
|
+
return this.closeFf().end();
|
|
376
375
|
}
|
|
377
376
|
if (this.steps.length === 0) {
|
|
378
377
|
throw new WaygraphError("WG_MAP_EMPTY", MSG_MAP_EMPTY);
|
|
379
378
|
}
|
|
380
|
-
|
|
381
|
-
return this.defineFlow(chain, options);
|
|
379
|
+
return this.build(this.steps, this.settings);
|
|
382
380
|
}
|
|
383
381
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MemPage } from "
|
|
1
|
+
import { MemPage } from "./mem/mem.js";
|
|
2
2
|
/**
|
|
3
3
|
* "Where am I" - reverse-matches a live `page` against every NavBlock /
|
|
4
4
|
* PageBlock in `library`, in order, returning the first one whose own `verify`
|
|
@@ -38,7 +38,6 @@ export async function locate(page, library, options) {
|
|
|
38
38
|
const traits = typeof verify === "function" ? verify(resolved) : (verify ?? []);
|
|
39
39
|
let allPass = true;
|
|
40
40
|
for (const trait of traits) {
|
|
41
|
-
// eslint-disable-next-line no-await-in-loop
|
|
42
41
|
if (!(await trait.check(page, mem))) {
|
|
43
42
|
allPass = false;
|
|
44
43
|
break;
|
|
@@ -6,18 +6,19 @@
|
|
|
6
6
|
*
|
|
7
7
|
* "Stub" here is unrelated to the other two meanings already in this
|
|
8
8
|
* codebase: `stubBefore`/`stubAfter`/`stubOnError` (demo narration fixtures,
|
|
9
|
-
* see
|
|
9
|
+
* see demo/narration/index.ts's `runStubPhase`) and `upload`'s `stub: "image"|"pdf"|
|
|
10
10
|
* "video"` (a placeholder file). This is a third, separate "stub."
|
|
11
11
|
*
|
|
12
|
-
* Opt-in only, per Flow (`
|
|
12
|
+
* Opt-in only, per Flow (`map({ memStub: true })`) or per-run (`--mem-stub` /
|
|
13
13
|
* WAYGRAPH_MEM_STUB=1) - a required key with no registered generator still
|
|
14
14
|
* fails preflight exactly as before. Registered per MemKey *instance*
|
|
15
15
|
* (identity, not `.name`), matching MemPage's own store - two keys sharing a
|
|
16
16
|
* debug name must never cross-contaminate here either.
|
|
17
17
|
*/
|
|
18
|
-
import type { MemKey } from "./mem
|
|
19
|
-
import type { MemPage } from "./mem
|
|
20
|
-
import type { Flow } from "
|
|
18
|
+
import type { MemKey } from "./mem.js";
|
|
19
|
+
import type { MemPage } from "./mem.js";
|
|
20
|
+
import type { Flow } from "../flow/flow.js";
|
|
21
|
+
import type { Checkpoint } from "../checkpoint/checkpoint.js";
|
|
21
22
|
/**
|
|
22
23
|
* Registers a fake-value generator for one required MemKey.
|
|
23
24
|
* @example registerMemStub(LoginCreds.key, () => ({
|
|
@@ -26,16 +27,16 @@ import type { Flow } from "./core.js";
|
|
|
26
27
|
* }));
|
|
27
28
|
*/
|
|
28
29
|
export declare function registerMemStub<T>(key: MemKey<T>, fake: () => T): void;
|
|
29
|
-
/** Used by waygraph's own `--mem-stub`-aware CLI seeding and by {@link seedMemStub} - flow authors normally use {@link registerMemStub}
|
|
30
|
+
/** Used by waygraph's own `--mem-stub`-aware CLI seeding and by {@link seedMemStub} - flow authors normally use {@link registerMemStub} and `map({ memStub: true })` instead. */
|
|
30
31
|
export declare function getMemStub<T>(key: MemKey<T>): (() => T) | undefined;
|
|
31
32
|
/**
|
|
32
33
|
* For a bare library `flow.run(mem, ...)` call outside the CLI (which has its
|
|
33
34
|
* own `--mem-stub`-aware seeding) - call this yourself before `run()` when
|
|
34
35
|
* `flow.memStub` is true, the same way external tooling already reads
|
|
35
36
|
* `flow.resetSession`/`flow.title`/etc. (`run()` itself never reads Flow
|
|
36
|
-
* flags
|
|
37
|
+
* flags; the settings come from `map({ ... })`).
|
|
37
38
|
* @example
|
|
38
39
|
* if (flow.memStub) seedMemStub(mem, flow);
|
|
39
40
|
* await flow.run(mem, config);
|
|
40
41
|
*/
|
|
41
|
-
export declare function seedMemStub(mem: MemPage, flow: Flow<
|
|
42
|
+
export declare function seedMemStub(mem: MemPage, flow: Flow<Checkpoint<string>>): void;
|
|
@@ -9,7 +9,7 @@ const registry = new Map();
|
|
|
9
9
|
export function registerMemStub(key, fake) {
|
|
10
10
|
registry.set(key, fake);
|
|
11
11
|
}
|
|
12
|
-
/** Used by waygraph's own `--mem-stub`-aware CLI seeding and by {@link seedMemStub} - flow authors normally use {@link registerMemStub}
|
|
12
|
+
/** Used by waygraph's own `--mem-stub`-aware CLI seeding and by {@link seedMemStub} - flow authors normally use {@link registerMemStub} and `map({ memStub: true })` instead. */
|
|
13
13
|
export function getMemStub(key) {
|
|
14
14
|
return registry.get(key);
|
|
15
15
|
}
|
|
@@ -18,7 +18,7 @@ export function getMemStub(key) {
|
|
|
18
18
|
* own `--mem-stub`-aware seeding) - call this yourself before `run()` when
|
|
19
19
|
* `flow.memStub` is true, the same way external tooling already reads
|
|
20
20
|
* `flow.resetSession`/`flow.title`/etc. (`run()` itself never reads Flow
|
|
21
|
-
* flags
|
|
21
|
+
* flags; the settings come from `map({ ... })`).
|
|
22
22
|
* @example
|
|
23
23
|
* if (flow.memStub) seedMemStub(mem, flow);
|
|
24
24
|
* await flow.run(mem, config);
|
|
@@ -55,7 +55,7 @@ export declare class MemPage {
|
|
|
55
55
|
* can only have string/symbol property names, not object instances - a `[key,
|
|
56
56
|
* value]` pair is the shape that keeps that identity-based guarantee.
|
|
57
57
|
*
|
|
58
|
-
* Overloaded per pair count (2-6,
|
|
58
|
+
* Overloaded per pair count (2-6, per-arity overloads like the old `defineFlow`'s
|
|
59
59
|
* overloads) rather than one fully-generic variadic signature - each pair binds
|
|
60
60
|
* its own type parameter independently, which TS checks reliably; a single
|
|
61
61
|
* self-referential mapped-tuple-over-a-rest-parameter type was tried first and
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
// Mem: the values a run carries between Blocks (credentials, the row just added), typed by MemKey.
|
|
2
|
+
import { WaygraphError, MSG_MEM_READ_BEFORE_SET } from "../errors.js";
|
|
2
3
|
/**
|
|
3
4
|
* A typed key into MemPage. The phantom `_phantom` field is never assigned - it
|
|
4
5
|
* exists only so TypeScript can infer `T` at each call site. The store is keyed by
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function isPageGone(err: unknown): boolean;
|
|
2
|
+
/** `.catch(ignorePageGone)`: the call is moot when the page went away; anything else is rethrown. */
|
|
3
|
+
export declare function ignorePageGone(err: unknown): undefined;
|
|
4
|
+
/** `.catch(ignoreTimeout)`: a probe that waited as long as it should (or whose page went away); anything else is rethrown. */
|
|
5
|
+
export declare function ignoreTimeout(err: unknown): undefined;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// The failures a page call may ignore, and nothing else: the page went away (a navigation or a close), or a probe ran
|
|
2
|
+
// out of time. Any other error is real and goes through.
|
|
3
|
+
import { errors } from "@playwright/test";
|
|
4
|
+
/** Playwright has no error class for a closed page or a destroyed document, only these messages. */
|
|
5
|
+
const GONE = /Target page, context or browser has been closed|Target closed|Browser has been closed|Execution context was destroyed|frame was detached|Frame has been detached|Session closed|Cannot find context with specified id|Failed to find context with id/i;
|
|
6
|
+
export function isPageGone(err) {
|
|
7
|
+
return err instanceof Error && GONE.test(err.message);
|
|
8
|
+
}
|
|
9
|
+
/** `.catch(ignorePageGone)`: the call is moot when the page went away; anything else is rethrown. */
|
|
10
|
+
export function ignorePageGone(err) {
|
|
11
|
+
if (isPageGone(err))
|
|
12
|
+
return undefined;
|
|
13
|
+
throw err;
|
|
14
|
+
}
|
|
15
|
+
/** `.catch(ignoreTimeout)`: a probe that waited as long as it should (or whose page went away); anything else is rethrown. */
|
|
16
|
+
export function ignoreTimeout(err) {
|
|
17
|
+
if (err instanceof errors.TimeoutError || isPageGone(err))
|
|
18
|
+
return undefined;
|
|
19
|
+
throw err;
|
|
20
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Block } from "../block/block.js";
|
|
2
|
+
import type { Checkpoint } from "../checkpoint/checkpoint.js";
|
|
3
|
+
import type { Trait } from "../trait/trait.js";
|
|
4
|
+
/**
|
|
5
|
+
* Structural twin of `run.ts`'s `Layout`, so this file needs no import from it. Any real `Layout` satisfies it with no
|
|
6
|
+
* cast at the `connect()` call site.
|
|
7
|
+
*/
|
|
8
|
+
export interface ConnectLayout {
|
|
9
|
+
name: string;
|
|
10
|
+
appliesTo: (tag: string) => boolean;
|
|
11
|
+
verify: Trait[] | ((out: any) => Trait[]);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Composes two Blocks into one, typechecked so this only compiles when A's output
|
|
15
|
+
* tag equals B's input tag. The composed Block's act runs A's full instruction
|
|
16
|
+
* (act -> observe? -> resolve) then hands the resulting Checkpoint into B's act;
|
|
17
|
+
* its own observe/resolve are simply B's, since B is what decides the final Out.
|
|
18
|
+
*
|
|
19
|
+
* `layouts`, if given, also runs against the intermediate Checkpoint (A's
|
|
20
|
+
* resolved output, right before B's act) - the same enforcement `runGraph`'s
|
|
21
|
+
* own loop already applies to a chain's FINAL Checkpoint, but a
|
|
22
|
+
* `map()`-built Flow never reaches that loop per-hop: `buildFlow`
|
|
23
|
+
* reduces the whole Block array into one `connect()`-composed super-Block, so
|
|
24
|
+
* every intermediate hop's verify (and now layout) has to run HERE, inside
|
|
25
|
+
* this recursive `act`, not in `runGraph`'s loop, which only ever sees the
|
|
26
|
+
* one composed Block run start to finish.
|
|
27
|
+
*/
|
|
28
|
+
export declare function connect<A extends Checkpoint<string>, B extends Checkpoint<string>, C extends Checkpoint<string>>(a: Block<A, B>, b: Block<B, C>, layouts?: readonly ConnectLayout[]): Block<A, C>;
|
|
@@ -1,11 +1,5 @@
|
|
|
1
|
-
import { runVerify, runPrecondition } from "
|
|
2
|
-
|
|
3
|
-
* Builds a Checkpoint - spells `__state` for you so no call site does it by hand.
|
|
4
|
-
* @example resolve: () => checkpoint("LoggedIn")
|
|
5
|
-
*/
|
|
6
|
-
export function checkpoint(tag) {
|
|
7
|
-
return { __state: tag };
|
|
8
|
-
}
|
|
1
|
+
import { runVerify, runPrecondition } from "../trait/trait.js";
|
|
2
|
+
import { isConnected, lastLeaf, stepEnded, stepStarted } from "./events.js";
|
|
9
3
|
/**
|
|
10
4
|
* Composes two Blocks into one, typechecked so this only compiles when A's output
|
|
11
5
|
* tag equals B's input tag. The composed Block's act runs A's full instruction
|
|
@@ -15,7 +9,7 @@ export function checkpoint(tag) {
|
|
|
15
9
|
* `layouts`, if given, also runs against the intermediate Checkpoint (A's
|
|
16
10
|
* resolved output, right before B's act) - the same enforcement `runGraph`'s
|
|
17
11
|
* own loop already applies to a chain's FINAL Checkpoint, but a
|
|
18
|
-
* `
|
|
12
|
+
* `map()`-built Flow never reaches that loop per-hop: `buildFlow`
|
|
19
13
|
* reduces the whole Block array into one `connect()`-composed super-Block, so
|
|
20
14
|
* every intermediate hop's verify (and now layout) has to run HERE, inside
|
|
21
15
|
* this recursive `act`, not in `runGraph`'s loop, which only ever sees the
|
|
@@ -25,11 +19,13 @@ export function connect(a, b, layouts) {
|
|
|
25
19
|
const bObserve = b.instruction.observe;
|
|
26
20
|
const bVerify = b.instruction.verify;
|
|
27
21
|
const requires = [...(a.requires ?? []), ...(b.requires ?? [])];
|
|
28
|
-
|
|
22
|
+
const connected = {
|
|
29
23
|
name: `${a.name} -> ${b.name}`,
|
|
30
24
|
...(requires.length > 0 ? { requires } : {}),
|
|
31
25
|
instruction: {
|
|
32
26
|
async act(page, input, mem) {
|
|
27
|
+
if (!isConnected(a))
|
|
28
|
+
stepStarted(a.name, input.__state);
|
|
33
29
|
await runPrecondition(a.instruction.precondition, input, page, mem, a.name);
|
|
34
30
|
await a.instruction.act(page, input, mem);
|
|
35
31
|
const aObserved = a.instruction.observe
|
|
@@ -44,6 +40,9 @@ export function connect(a, b, layouts) {
|
|
|
44
40
|
await runVerify(layout.verify, mid, page, mem, `${a.name} (layout: "${layout.name}")`);
|
|
45
41
|
}
|
|
46
42
|
}
|
|
43
|
+
stepEnded(lastLeaf(a), mid.__state);
|
|
44
|
+
if (!isConnected(b))
|
|
45
|
+
stepStarted(b.name, mid.__state);
|
|
47
46
|
await runPrecondition(b.instruction.precondition, mid, page, mem, b.name);
|
|
48
47
|
await b.instruction.act(page, mid, mem);
|
|
49
48
|
},
|
|
@@ -54,4 +53,6 @@ export function connect(a, b, layouts) {
|
|
|
54
53
|
...(bVerify ? { verify: bVerify } : {}),
|
|
55
54
|
},
|
|
56
55
|
};
|
|
56
|
+
Object.defineProperty(connected, "__wgLastLeaf", { value: lastLeaf(b), enumerable: false });
|
|
57
|
+
return connected;
|
|
57
58
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type RunEvent = {
|
|
2
|
+
type: "run:start";
|
|
3
|
+
runId: string;
|
|
4
|
+
at: number;
|
|
5
|
+
label?: string;
|
|
6
|
+
} | {
|
|
7
|
+
type: "step:start";
|
|
8
|
+
runId: string;
|
|
9
|
+
at: number;
|
|
10
|
+
index: number;
|
|
11
|
+
block: string;
|
|
12
|
+
from: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: "step:end";
|
|
15
|
+
runId: string;
|
|
16
|
+
at: number;
|
|
17
|
+
index: number;
|
|
18
|
+
block: string;
|
|
19
|
+
to: string;
|
|
20
|
+
ms: number;
|
|
21
|
+
} | {
|
|
22
|
+
type: "step:error";
|
|
23
|
+
runId: string;
|
|
24
|
+
at: number;
|
|
25
|
+
index: number;
|
|
26
|
+
block: string;
|
|
27
|
+
error: string;
|
|
28
|
+
ms: number;
|
|
29
|
+
} | {
|
|
30
|
+
type: "run:end";
|
|
31
|
+
runId: string;
|
|
32
|
+
at: number;
|
|
33
|
+
ok: boolean;
|
|
34
|
+
result?: string;
|
|
35
|
+
error?: string;
|
|
36
|
+
ms: number;
|
|
37
|
+
} | {
|
|
38
|
+
type: "run:artifact";
|
|
39
|
+
runId: string;
|
|
40
|
+
at: number;
|
|
41
|
+
kind: "video" | "trace" | "screenshot";
|
|
42
|
+
path: string;
|
|
43
|
+
};
|
|
44
|
+
/** What {@link onRunEvent} calls with each event. */
|
|
45
|
+
export type RunEventListener = (event: RunEvent) => void;
|
|
46
|
+
/** Subscribes to every run event in this process; returns the unsubscribe function. */
|
|
47
|
+
export declare function onRunEvent(listener: RunEventListener): () => void;
|
|
48
|
+
/**
|
|
49
|
+
* Opens a run, or joins the one already open (a flow nested in another, or a runner driving a chain step by step). Returns
|
|
50
|
+
* whether this call opened it, so only the opener closes it.
|
|
51
|
+
*/
|
|
52
|
+
export declare function beginRun(label?: string): boolean;
|
|
53
|
+
/** Closes the run when the matching `beginRun` opened it. */
|
|
54
|
+
export declare function endRun(opened: boolean, outcome: {
|
|
55
|
+
result?: string;
|
|
56
|
+
error?: unknown;
|
|
57
|
+
}): void;
|
|
58
|
+
export declare function stepStarted(block: string, from: string): void;
|
|
59
|
+
export declare function stepEnded(block: string, to: string): void;
|
|
60
|
+
/** The step that started last failed. */
|
|
61
|
+
export declare function stepFailed(error: unknown): void;
|
|
62
|
+
/** The id of the run open right now, if any. */
|
|
63
|
+
export declare function currentRunId(): string | undefined;
|
|
64
|
+
export declare function recordArtifact(kind: "video" | "trace" | "screenshot", path: string, runId?: string | undefined): void;
|
|
65
|
+
/** The last real Block inside a Block built by `connect` (or the Block itself). */
|
|
66
|
+
export declare function lastLeaf(block: object): string;
|
|
67
|
+
export declare function isConnected(block: object): boolean;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
// Run events: what happened, step by step, during a run. Core emits them; subscribers (the run log, the demo overlay,
|
|
2
|
+
// reports, Waygraph UI) listen. Emitting never throws into the run.
|
|
3
|
+
const listeners = new Set();
|
|
4
|
+
/** Subscribes to every run event in this process; returns the unsubscribe function. */
|
|
5
|
+
export function onRunEvent(listener) {
|
|
6
|
+
listeners.add(listener);
|
|
7
|
+
return () => listeners.delete(listener);
|
|
8
|
+
}
|
|
9
|
+
function emit(event) {
|
|
10
|
+
for (const listener of listeners) {
|
|
11
|
+
try {
|
|
12
|
+
listener(event);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
/* a broken subscriber never breaks a run */
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
let open;
|
|
20
|
+
/**
|
|
21
|
+
* Opens a run, or joins the one already open (a flow nested in another, or a runner driving a chain step by step). Returns
|
|
22
|
+
* whether this call opened it, so only the opener closes it.
|
|
23
|
+
*/
|
|
24
|
+
export function beginRun(label) {
|
|
25
|
+
if (open) {
|
|
26
|
+
open.depth += 1;
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
const at = Date.now();
|
|
30
|
+
open = { runId: `${new Date(at).toISOString().replace(/[:.]/g, "-")}-${crypto.randomUUID().slice(0, 8)}`, startedAt: at, depth: 1, index: 0 };
|
|
31
|
+
emit({ type: "run:start", runId: open.runId, at, ...(label ? { label } : {}) });
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
/** Closes the run when the matching `beginRun` opened it. */
|
|
35
|
+
export function endRun(opened, outcome) {
|
|
36
|
+
if (!open)
|
|
37
|
+
return;
|
|
38
|
+
open.depth -= 1;
|
|
39
|
+
if (!opened)
|
|
40
|
+
return;
|
|
41
|
+
const at = Date.now();
|
|
42
|
+
emit({
|
|
43
|
+
type: "run:end",
|
|
44
|
+
runId: open.runId,
|
|
45
|
+
at,
|
|
46
|
+
ok: outcome.error === undefined,
|
|
47
|
+
...(outcome.result !== undefined ? { result: outcome.result } : {}),
|
|
48
|
+
...(outcome.error !== undefined ? { error: outcome.error instanceof Error ? outcome.error.message : String(outcome.error) } : {}),
|
|
49
|
+
ms: at - open.startedAt,
|
|
50
|
+
});
|
|
51
|
+
open = undefined;
|
|
52
|
+
}
|
|
53
|
+
export function stepStarted(block, from) {
|
|
54
|
+
if (!open)
|
|
55
|
+
return;
|
|
56
|
+
const at = Date.now();
|
|
57
|
+
open.step = { index: open.index++, block, startedAt: at };
|
|
58
|
+
emit({ type: "step:start", runId: open.runId, at, index: open.step.index, block, from });
|
|
59
|
+
}
|
|
60
|
+
export function stepEnded(block, to) {
|
|
61
|
+
if (!open?.step)
|
|
62
|
+
return;
|
|
63
|
+
const at = Date.now();
|
|
64
|
+
emit({ type: "step:end", runId: open.runId, at, index: open.step.index, block, to, ms: at - open.step.startedAt });
|
|
65
|
+
open.step = undefined;
|
|
66
|
+
}
|
|
67
|
+
/** The step that started last failed. */
|
|
68
|
+
export function stepFailed(error) {
|
|
69
|
+
if (!open?.step)
|
|
70
|
+
return;
|
|
71
|
+
const at = Date.now();
|
|
72
|
+
const { index, block, startedAt } = open.step;
|
|
73
|
+
emit({ type: "step:error", runId: open.runId, at, index, block, error: error instanceof Error ? error.message : String(error), ms: at - startedAt });
|
|
74
|
+
open.step = undefined;
|
|
75
|
+
}
|
|
76
|
+
/** The id of the run open right now, if any. */
|
|
77
|
+
export function currentRunId() {
|
|
78
|
+
return open?.runId;
|
|
79
|
+
}
|
|
80
|
+
export function recordArtifact(kind, path, runId = open?.runId) {
|
|
81
|
+
if (runId)
|
|
82
|
+
emit({ type: "run:artifact", runId, at: Date.now(), kind, path });
|
|
83
|
+
}
|
|
84
|
+
/** The last real Block inside a Block built by `connect` (or the Block itself). */
|
|
85
|
+
export function lastLeaf(block) {
|
|
86
|
+
return block.__wgLastLeaf ?? block.name;
|
|
87
|
+
}
|
|
88
|
+
export function isConnected(block) {
|
|
89
|
+
return block.__wgLastLeaf !== undefined;
|
|
90
|
+
}
|