waygraph 0.16.0 → 0.16.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/browser.d.ts +2 -0
- package/dist/cli/commands/browser.js +109 -0
- package/dist/cli/commands/codemod-stubs.js +90 -2
- package/dist/cli/commands/pilot.d.ts +2 -0
- package/dist/cli/commands/pilot.js +102 -0
- package/dist/cli/commands/session-ops.d.ts +3 -0
- package/dist/cli/commands/session-ops.js +257 -0
- package/dist/cli/commands/session.js +20 -461
- package/dist/cli/run-chain.js +2 -2
- package/dist/cli/usage.d.ts +1 -1
- package/dist/cli/util.js +1 -1
- package/dist/demo/narration/demo-pace.d.ts +2 -2
- package/dist/demo/narration/demo-pace.js +1 -1
- package/dist/demo/narration/device.d.ts +2 -2
- package/dist/demo/narration/merge.d.ts +5 -3
- package/dist/demo/narration/merge.js +3 -7
- package/dist/demo/narration/narration.d.ts +9 -13
- package/dist/demo/narration/narration.js +5 -17
- package/dist/demo/narration/stub-ctx.js +3 -3
- package/dist/demo/narration/todo-dock.d.ts +5 -5
- package/dist/demo/overlay/cursor.d.ts +9 -2
- package/dist/demo/overlay/cursor.js +1 -1
- package/dist/demo/overlay/device-stage.d.ts +15 -2
- package/dist/demo/overlay/inpage/banner.d.ts +2 -1
- package/dist/demo/overlay/inpage/banner.js +3 -3
- package/dist/demo/overlay/inpage/caption.d.ts +1 -1
- package/dist/demo/overlay/inpage/core.d.ts +2 -1
- package/dist/demo/overlay/inpage/core.js +1 -7
- package/dist/demo/overlay/inpage/device-chip.d.ts +1 -1
- package/dist/demo/overlay/inpage/device-chip.js +6 -6
- package/dist/demo/overlay/inpage/network.d.ts +3 -2
- package/dist/demo/overlay/inpage/network.js +1 -12
- package/dist/demo/overlay/inpage/panel-chrome.d.ts +1 -1
- package/dist/demo/overlay/inpage/panel-chrome.js +1 -1
- package/dist/demo/overlay/inpage/stamp.d.ts +1 -1
- package/dist/demo/overlay/inpage/stamp.js +1 -1
- package/dist/demo/overlay/inpage/swipe-zoom.d.ts +1 -1
- package/dist/demo/overlay/inpage/swipe-zoom.js +1 -1
- package/dist/demo/overlay/inpage/todos.d.ts +2 -1
- package/dist/demo/overlay/inpage/todos.js +1 -2
- package/dist/demo/overlay/network-capture.d.ts +2 -2
- package/dist/demo/overlay/network-capture.js +1 -1
- package/dist/demo/overlay/overlay-css.js +1 -55
- package/dist/demo/overlay/overlay-stage.d.ts +19 -11
- package/dist/demo/overlay/overlay.d.ts +2 -2
- package/dist/demo/overlay/overlay.js +3 -2
- package/dist/demo/overlay/rings.d.ts +38 -18
- package/dist/demo/overlay/rings.js +21 -62
- package/dist/demo/overlay/ui/overlay.css +40 -0
- package/dist/demo/stepper/after.js +11 -34
- package/dist/demo/stepper/banner-log.d.ts +4 -6
- package/dist/demo/stepper/banner-log.js +3 -1
- package/dist/demo/stepper/before.js +6 -4
- package/dist/demo/stepper/demo-log.d.ts +26 -9
- package/dist/demo/stepper/demo-log.js +10 -27
- package/dist/demo/stepper/interaction-patch.d.ts +3 -2
- package/dist/demo/stepper/interaction-patch.js +22 -34
- package/dist/demo/stepper/panel-after.d.ts +17 -0
- package/dist/demo/stepper/panel-after.js +166 -0
- package/dist/demo/stepper/panel-before.d.ts +12 -0
- package/dist/demo/stepper/panel-before.js +241 -0
- package/dist/demo/stepper/slides.d.ts +16 -1
- package/dist/demo/stepper/slides.js +21 -5
- package/dist/demo/stepper/step-panels.d.ts +57 -9
- package/dist/demo/stepper/step-panels.js +10 -427
- package/dist/demo/stepper/stepper.js +1 -1
- package/dist/demo/stepper/teardown.d.ts +4 -5
- package/dist/demo/stepper/teardown.js +4 -6
- package/dist/demo/stepper/todo-advance.d.ts +3 -2
- package/dist/demo/stepper/todo-advance.js +2 -2
- package/dist/demo/stepper/view.d.ts +4 -14
- package/dist/demo/types.d.ts +69 -1
- package/dist/demo/verbose-log.js +1 -1
- package/dist/engine/block/action-page.d.ts +53 -0
- package/dist/engine/block/action-page.js +1 -0
- package/dist/engine/block/block.d.ts +24 -90
- package/dist/engine/block/block.js +2 -77
- package/dist/engine/block/branch.d.ts +17 -0
- package/dist/engine/block/branch.js +40 -0
- package/dist/engine/block/dialog.d.ts +13 -0
- package/dist/engine/block/dialog.js +37 -0
- package/dist/engine/block/kinds/method.d.ts +0 -2
- package/dist/engine/block/kinds/method.js +0 -1
- package/dist/engine/block/kinds/nav.js +1 -1
- package/dist/engine/flow/map-branch.d.ts +9 -0
- package/dist/engine/flow/map-branch.js +57 -0
- package/dist/engine/flow/map-builder.d.ts +7 -22
- package/dist/engine/flow/map-builder.js +6 -145
- package/dist/engine/flow/map-steps.d.ts +30 -0
- package/dist/engine/flow/map-steps.js +87 -0
- package/dist/engine/run/run.d.ts +1 -19
- package/dist/engine/run/run.js +0 -88
- package/dist/engine/stub/ring.d.ts +2 -4
- package/dist/engine/stub/ring.js +1 -0
- package/dist/engine/stub/stub.d.ts +16 -8
- package/dist/engine/trait/trait.js +1 -1
- package/dist/index.d.ts +15 -12
- package/dist/index.js +9 -7
- package/dist/live/auto/auto.d.ts +3 -15
- package/dist/live/auto/auto.js +10 -420
- package/dist/live/auto/explore.d.ts +2 -2
- package/dist/live/auto/mem.d.ts +11 -0
- package/dist/live/auto/mem.js +85 -0
- package/dist/live/auto/menu.d.ts +30 -0
- package/dist/live/auto/menu.js +335 -0
- package/dist/live/auto-session/auto-session.d.ts +23 -103
- package/dist/live/auto-session/auto-session.js +100 -370
- package/dist/live/auto-session/console.d.ts +4 -0
- package/dist/live/auto-session/console.js +41 -0
- package/dist/live/auto-session/files.d.ts +44 -0
- package/dist/live/auto-session/files.js +145 -0
- package/dist/live/auto-session/helpers.d.ts +5 -2
- package/dist/live/auto-session/helpers.js +17 -0
- package/dist/live/auto-session/inspect.d.ts +4 -0
- package/dist/live/auto-session/inspect.js +75 -0
- package/dist/live/auto-session/ipc.d.ts +3 -22
- package/dist/live/auto-session/ipc.js +7 -147
- package/dist/live/auto-session/open-browser.d.ts +6 -0
- package/dist/live/auto-session/open-browser.js +47 -0
- package/dist/live/pilot/pilot.d.ts +1 -1
- package/dist/live/pilot/pilot.js +2 -1
- package/dist/live/traverse/traverse.js +6 -200
- package/dist/live/traverse/worker.d.ts +37 -0
- package/dist/live/traverse/worker.js +200 -0
- package/dist/runner/plan/find.js +2 -2
- package/dist/runner/plan/plan.js +1 -1
- package/dist/runner/plan/seed-mem.js +5 -5
- package/dist/runner/plan/spec.js +1 -1
- package/examples/saucedemo/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
- package/examples/saucedemo/src/flows/checkout-then-browse-again.flow.ts +2 -1
- package/examples/saucedemo/src/flows/checkout.flow.ts +2 -1
- package/examples/saucedemo/src/flows/shop.flow.ts +2 -1
- package/examples/saucedemo/src/stubs/device-showcase.ts +37 -43
- package/examples/saucedemo/src/stubs/finish-order.ts +38 -0
- package/package.json +5 -1
- package/templates/quickstart/src/blocks/saucedemo-web/checkout-step-two/methods/finish-order.method.block.ts +2 -34
- package/templates/quickstart/src/flows/checkout-then-browse-again.flow.ts +2 -1
- package/templates/quickstart/src/flows/checkout.flow.ts +2 -1
- package/templates/quickstart/src/flows/shop.flow.ts +2 -1
- package/templates/quickstart/src/stubs/device-showcase.ts +37 -43
- package/templates/quickstart/src/stubs/finish-order.ts +38 -0
- package/templates/scaffold/src/flows/home/hello.flow.ts +3 -0
- package/templates/scaffold/src/map/(app_base)/home/_methods/assert-hello.method.block.ts +1 -9
|
@@ -1,34 +1,19 @@
|
|
|
1
|
+
import type { SomeBlock } from "../block/block.js";
|
|
2
|
+
import type { EffectBlock } from "../block/kinds/effect.js";
|
|
3
|
+
import type { AssertBlock, MethodBlock } from "../block/kinds/method.js";
|
|
4
|
+
import type { NavBlock } from "../block/kinds/nav.js";
|
|
5
|
+
import type { PageBlock } from "../block/kinds/page.js";
|
|
1
6
|
import type { Checkpoint } from "../checkpoint/checkpoint.js";
|
|
2
|
-
import type { Flow, FlowSettings } from "./flow.js";
|
|
3
7
|
import type { DemoPace } from "../stub/pace.js";
|
|
4
8
|
import type { HighlightStyleDefaults } from "../stub/ring.js";
|
|
5
|
-
import type {
|
|
6
|
-
import
|
|
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
|
+
import type { Flow, FlowSettings } from "./flow.js";
|
|
10
|
+
import { MapStepOpts } from "./map-steps.js";
|
|
10
11
|
type S = Checkpoint<"__start__">;
|
|
11
12
|
/**
|
|
12
13
|
* The one capability MapBuilder needs from Engine: turn the finished steps into a Flow with the engine's config. A
|
|
13
14
|
* function, not the Engine class, so engine.ts and map-builder.ts don't import each other.
|
|
14
15
|
*/
|
|
15
16
|
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
|
-
export interface MapStepOpts {
|
|
18
|
-
/**
|
|
19
|
-
* Fast-forward just this step, inline - no `.ffStart()/.ffEnd()` bracket needed. Consecutive
|
|
20
|
-
* `{ ff: true }` steps merge into ONE fast-forward block, same result as the explicit bracket
|
|
21
|
-
* form; a step without the flag closes an auto-opened window first.
|
|
22
|
-
* @example map().gotoPage(NavLoginBlock, { ff: true }).method(FillUsernameBlock, { ff: true })
|
|
23
|
-
*/
|
|
24
|
-
ff?: boolean;
|
|
25
|
-
/**
|
|
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).
|
|
28
|
-
* @example map().method(SetBearerTokenBlock, { pace: "blitz" })
|
|
29
|
-
*/
|
|
30
|
-
pace?: DemoPace;
|
|
31
|
-
}
|
|
32
17
|
/** Flow-level settings for `engine.map({ … })`: `memStub`, `sessionReset`, `expectedFailure`, `demoPace`, `highlightStyle`, `homeOrigin`. */
|
|
33
18
|
export interface MapBuilderOptions {
|
|
34
19
|
/**
|
|
@@ -1,148 +1,7 @@
|
|
|
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 { MemPage } from "../mem/mem.js";
|
|
3
1
|
import { fastForwardComposeBlock } from "../block/compose.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
/** The same Block, but it clears cookies and storage before it acts. Keeps the runtime markers. */
|
|
8
|
-
function resetBefore(block) {
|
|
9
|
-
const act = block.instruction.act.bind(block.instruction);
|
|
10
|
-
const next = {
|
|
11
|
-
...block,
|
|
12
|
-
instruction: {
|
|
13
|
-
...block.instruction,
|
|
14
|
-
async act(page, input, mem) {
|
|
15
|
-
await clearSessionState(page.context(), page);
|
|
16
|
-
return act(page, input, mem);
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
copyWaygraphRuntime(block, next);
|
|
21
|
-
Object.defineProperty(next, "__waygraphResetBefore", { value: true, enumerable: false, configurable: true });
|
|
22
|
-
return next;
|
|
23
|
-
}
|
|
24
|
-
/** Applies a step's `pace` option, keeping the Block's runtime markers. */
|
|
25
|
-
function paced(block, opts) {
|
|
26
|
-
if (opts?.pace === undefined)
|
|
27
|
-
return block;
|
|
28
|
-
const next = { ...block, demoPace: opts.pace };
|
|
29
|
-
copyWaygraphRuntime(block, next);
|
|
30
|
-
return next;
|
|
31
|
-
}
|
|
32
|
-
function mapKindOf(block) {
|
|
33
|
-
return block?.__waygraphKind;
|
|
34
|
-
}
|
|
35
|
-
function mapSaltOf(block) {
|
|
36
|
-
return block?.__waygraphSalt;
|
|
37
|
-
}
|
|
38
|
-
function mapNavUrlOf(block) {
|
|
39
|
-
const url = block?.__waygraphNavUrl;
|
|
40
|
-
return typeof url === "string" ? url : undefined;
|
|
41
|
-
}
|
|
42
|
-
const MAP_KIND_FACTORY_HINT = {
|
|
43
|
-
nav: "defineNavBlock/defineMemNavBlock",
|
|
44
|
-
page: "definePageBlock",
|
|
45
|
-
assert: "defineAssertBlock",
|
|
46
|
-
};
|
|
47
|
-
const MAP_SALT_FACTORY_HINT = {
|
|
48
|
-
method: "defineMethodBlock",
|
|
49
|
-
effect: "defineEffectBlock",
|
|
50
|
-
api: "defineApiBlock",
|
|
51
|
-
};
|
|
52
|
-
function assertMapKind(block, allowed, method) {
|
|
53
|
-
const kind = mapKindOf(block);
|
|
54
|
-
if (kind !== undefined && allowed.includes(kind))
|
|
55
|
-
return;
|
|
56
|
-
const wanted = allowed.map((k) => MAP_KIND_FACTORY_HINT[k] ?? k).join(" or ");
|
|
57
|
-
const found = kind ? `a Block of kind "${kind}"` : "an object with no waygraph kind marker at all";
|
|
58
|
-
throw new WaygraphError("WG_MAP_WRONG_KIND", MSG_MAP_WRONG_KIND(method, block?.name ?? "?", wanted, found));
|
|
59
|
-
}
|
|
60
|
-
function assertMapSalt(block, allowed, method) {
|
|
61
|
-
const salt = mapSaltOf(block);
|
|
62
|
-
if (salt !== undefined && allowed.includes(salt))
|
|
63
|
-
return;
|
|
64
|
-
const wanted = allowed.map((s) => MAP_SALT_FACTORY_HINT[s] ?? s).join(" or ");
|
|
65
|
-
const found = salt ? `a Block salted "${salt}"` : "an object with no waygraph salt marker at all";
|
|
66
|
-
throw new WaygraphError("WG_MAP_WRONG_SALT", MSG_MAP_WRONG_SALT(method, block?.name ?? "?", wanted, found));
|
|
67
|
-
}
|
|
68
|
-
function assertMapOrigin(block, homeOrigin, expect, method) {
|
|
69
|
-
if (!homeOrigin)
|
|
70
|
-
return; // not configured - can't validate, honest no-op
|
|
71
|
-
const navUrl = mapNavUrlOf(block);
|
|
72
|
-
if (navUrl === undefined)
|
|
73
|
-
return; // click-based/dynamic nav - not statically checkable
|
|
74
|
-
let targetOrigin;
|
|
75
|
-
let wantOrigin;
|
|
76
|
-
try {
|
|
77
|
-
targetOrigin = new URL(navUrl, homeOrigin).origin;
|
|
78
|
-
wantOrigin = new URL(homeOrigin).origin;
|
|
79
|
-
}
|
|
80
|
-
catch {
|
|
81
|
-
return; // malformed URL - not this check's job to validate that
|
|
82
|
-
}
|
|
83
|
-
const isExternal = targetOrigin !== wantOrigin;
|
|
84
|
-
if (expect === "internal" && isExternal) {
|
|
85
|
-
throw new WaygraphError("WG_MAP_WRONG_ORIGIN", MSG_MAP_WRONG_ORIGIN_INTERNAL(block.name, targetOrigin, wantOrigin));
|
|
86
|
-
}
|
|
87
|
-
if (expect === "external" && !isExternal) {
|
|
88
|
-
throw new WaygraphError("WG_MAP_WRONG_ORIGIN", MSG_MAP_WRONG_ORIGIN_EXTERNAL(block.name, targetOrigin, wantOrigin));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Builds the `Flow` object `MapBuilder.branch()` returns: run `before`, then dispatch on the
|
|
93
|
-
* resolved tag into whichever `routes` entry matches (same page/context/mem), or return that
|
|
94
|
-
* Checkpoint as-is when its route is `null`. Factored out so `withBlockVerify`/`modBlockVerify`
|
|
95
|
-
* can patch `before` and rebuild the same branched shape, exactly like a plain Flow's own.
|
|
96
|
-
*/
|
|
97
|
-
function buildBranchedFlow(before, routes) {
|
|
98
|
-
const run = (async (contextOrMem, memOrConfig, options) => {
|
|
99
|
-
if (contextOrMem instanceof MemPage) {
|
|
100
|
-
throw new WaygraphError("WG_MAP_BRANCH_SHARED_SESSION_UNSUPPORTED", MSG_MAP_BRANCH_SHARED_SESSION_UNSUPPORTED);
|
|
101
|
-
}
|
|
102
|
-
const context = contextOrMem;
|
|
103
|
-
const mem = memOrConfig;
|
|
104
|
-
const gotOwnPage = options?.page === undefined;
|
|
105
|
-
const page = options?.page ?? (await context.newPage());
|
|
106
|
-
const closeOnFinish = options?.closeOnFinish ?? gotOwnPage;
|
|
107
|
-
const first = (await before.run(context, mem, { ...options, page, closeOnFinish: false }));
|
|
108
|
-
const branchFlow = routes[first.result.__state];
|
|
109
|
-
if (!branchFlow) {
|
|
110
|
-
if (options?.closeOnFinish === false)
|
|
111
|
-
return { result: first.result, page: first.page };
|
|
112
|
-
if (closeOnFinish)
|
|
113
|
-
await first.page.close();
|
|
114
|
-
return first.result;
|
|
115
|
-
}
|
|
116
|
-
return branchFlow.run(context, mem, { ...options, page: first.page, closeOnFinish });
|
|
117
|
-
});
|
|
118
|
-
return {
|
|
119
|
-
resetSession: before.resetSession,
|
|
120
|
-
config: before.config,
|
|
121
|
-
...(before.expectedFailureReason !== undefined ? { expectedFailureReason: before.expectedFailureReason } : {}),
|
|
122
|
-
...(before.demoPace !== undefined ? { demoPace: before.demoPace } : {}),
|
|
123
|
-
...(before.highlightStyle !== undefined ? { highlightStyle: before.highlightStyle } : {}),
|
|
124
|
-
...(before.memStub !== undefined ? { memStub: before.memStub } : {}),
|
|
125
|
-
// Read by branchRoutes()/branchInfo() (branch-regression.ts) - real, ORDINARY (enumerable)
|
|
126
|
-
// properties, not hidden ones, specifically so a `{ ...flow, ... }` spread (withSettings) carries them
|
|
127
|
-
// through instead of silently dropping them -
|
|
128
|
-
// the same class of bug branch()'s missing copyWaygraphRuntime call already was.
|
|
129
|
-
__wgBranch: { before, routes },
|
|
130
|
-
// Static introspection (`waygraph graph`/list): the fixed prefix, plus every branch's own
|
|
131
|
-
// Blocks prefixed by the tag that leads to them - can't know at analysis time which one a real
|
|
132
|
-
// run takes, so this shows all of them rather than none.
|
|
133
|
-
blocks: () => [
|
|
134
|
-
...before.blocks(),
|
|
135
|
-
...Object.entries(routes).flatMap(([tag, f]) => f ? f.blocks().map((b) => ({ ...b, name: `${tag} -> ${b.name}` })) : []),
|
|
136
|
-
],
|
|
137
|
-
run,
|
|
138
|
-
withBlockVerify(block, verify) {
|
|
139
|
-
return buildBranchedFlow(before.withBlockVerify(block, verify), routes);
|
|
140
|
-
},
|
|
141
|
-
modBlockVerify(block, nameOrIndex, newCheck) {
|
|
142
|
-
return buildBranchedFlow(before.modBlockVerify(block, nameOrIndex, newCheck), routes);
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
}
|
|
2
|
+
import { MSG_MAP_BRANCH_NO_PRIOR_STEP, MSG_MAP_EMPTY, MSG_MAP_FF_ALREADY_OPEN, MSG_MAP_FF_EMPTY, MSG_MAP_FF_NOT_CLOSED, MSG_MAP_FF_NOT_OPEN, MSG_MAP_METHOD_GOT_ASSERT, WaygraphError, } from "../errors.js";
|
|
3
|
+
import { buildBranchedFlow } from "./map-branch.js";
|
|
4
|
+
import { assertMapKind, assertMapOrigin, assertMapSalt, mapKindOf, paced, resetBefore } from "./map-steps.js";
|
|
146
5
|
/**
|
|
147
6
|
* The flow builder behind `engine.map()` - see `map()`'s own doc
|
|
148
7
|
* comment for why this exists. Each step method is scoped to exactly the
|
|
@@ -220,7 +79,9 @@ export class MapBuilder {
|
|
|
220
79
|
if (ff.buffer.length === 0) {
|
|
221
80
|
throw new WaygraphError("WG_MAP_FF_EMPTY", MSG_MAP_FF_EMPTY(ff.name));
|
|
222
81
|
}
|
|
223
|
-
const composed = fastForwardComposeBlock(ff.name,
|
|
82
|
+
const composed = fastForwardComposeBlock(ff.name,
|
|
83
|
+
// The window's steps were typechecked as they were added; the one-step overload takes them as one Block.
|
|
84
|
+
ff.buffer);
|
|
224
85
|
return new MapBuilder(this.build, this.settings, [...this.steps, composed], this.homeOrigin, null);
|
|
225
86
|
}
|
|
226
87
|
/**
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type SomeBlock, type SomeDefinedBlock } from "../block/block.js";
|
|
2
|
+
import type { DemoPace } from "../stub/pace.js";
|
|
3
|
+
/** The same Block, but it clears cookies and storage before it acts. Keeps the runtime markers. */
|
|
4
|
+
export declare function resetBefore(block: SomeBlock): SomeBlock;
|
|
5
|
+
/** Applies a step's `pace` option, keeping the Block's runtime markers. */
|
|
6
|
+
export declare function paced(block: object, opts: MapStepOpts | undefined): SomeDefinedBlock;
|
|
7
|
+
export declare function mapKindOf(block: unknown): string | undefined;
|
|
8
|
+
export declare function mapSaltOf(block: unknown): string | undefined;
|
|
9
|
+
export declare function mapNavUrlOf(block: unknown): string | undefined;
|
|
10
|
+
export declare function assertMapKind(block: SomeBlock, allowed: readonly string[], method: string): void;
|
|
11
|
+
export declare function assertMapSalt(block: SomeBlock, allowed: readonly string[], method: string): void;
|
|
12
|
+
export declare function assertMapOrigin(block: SomeBlock, homeOrigin: string | undefined, expect: "internal" | "external", method: string): void;
|
|
13
|
+
export declare const MAP_KIND_FACTORY_HINT: Record<string, string>;
|
|
14
|
+
export declare const MAP_SALT_FACTORY_HINT: Record<string, string>;
|
|
15
|
+
/** Per-step options for the map builder: `ff` fast-forwards the step, `pace` sets its demo pace. */
|
|
16
|
+
export interface MapStepOpts {
|
|
17
|
+
/**
|
|
18
|
+
* Fast-forward just this step, inline - no `.ffStart()/.ffEnd()` bracket needed. Consecutive
|
|
19
|
+
* `{ ff: true }` steps merge into ONE fast-forward block, same result as the explicit bracket
|
|
20
|
+
* form; a step without the flag closes an auto-opened window first.
|
|
21
|
+
* @example map().gotoPage(NavLoginBlock, { ff: true }).method(FillUsernameBlock, { ff: true })
|
|
22
|
+
*/
|
|
23
|
+
ff?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Demo pace for just this step (`"blitz"` skips the typing animation and the pause after the action; `"fast"`, `"slow"`,
|
|
26
|
+
* or a number scale the narration gates).
|
|
27
|
+
* @example map().method(SetBearerTokenBlock, { pace: "blitz" })
|
|
28
|
+
*/
|
|
29
|
+
pace?: DemoPace;
|
|
30
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { copyWaygraphRuntime } from "../block/block.js";
|
|
2
|
+
import { MSG_MAP_WRONG_KIND, MSG_MAP_WRONG_ORIGIN_EXTERNAL, MSG_MAP_WRONG_ORIGIN_INTERNAL, MSG_MAP_WRONG_SALT, WaygraphError } from "../errors.js";
|
|
3
|
+
import { clearSessionState } from "./flow.js";
|
|
4
|
+
/** The same Block, but it clears cookies and storage before it acts. Keeps the runtime markers. */
|
|
5
|
+
export function resetBefore(block) {
|
|
6
|
+
const act = block.instruction.act.bind(block.instruction);
|
|
7
|
+
const next = {
|
|
8
|
+
...block,
|
|
9
|
+
instruction: {
|
|
10
|
+
...block.instruction,
|
|
11
|
+
async act(page, input, mem) {
|
|
12
|
+
await clearSessionState(page.context(), page);
|
|
13
|
+
return act(page, input, mem);
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
copyWaygraphRuntime(block, next);
|
|
18
|
+
Object.defineProperty(next, "__waygraphResetBefore", { value: true, enumerable: false, configurable: true });
|
|
19
|
+
return next;
|
|
20
|
+
}
|
|
21
|
+
/** Applies a step's `pace` option, keeping the Block's runtime markers. */
|
|
22
|
+
export function paced(block, opts) {
|
|
23
|
+
if (opts?.pace === undefined)
|
|
24
|
+
return block;
|
|
25
|
+
const next = { ...block, demoPace: opts.pace };
|
|
26
|
+
copyWaygraphRuntime(block, next);
|
|
27
|
+
return next;
|
|
28
|
+
}
|
|
29
|
+
export function mapKindOf(block) {
|
|
30
|
+
return block?.__waygraphKind;
|
|
31
|
+
}
|
|
32
|
+
export function mapSaltOf(block) {
|
|
33
|
+
return block?.__waygraphSalt;
|
|
34
|
+
}
|
|
35
|
+
export function mapNavUrlOf(block) {
|
|
36
|
+
const url = block?.__waygraphNavUrl;
|
|
37
|
+
return typeof url === "string" ? url : undefined;
|
|
38
|
+
}
|
|
39
|
+
export function assertMapKind(block, allowed, method) {
|
|
40
|
+
const kind = mapKindOf(block);
|
|
41
|
+
if (kind !== undefined && allowed.includes(kind))
|
|
42
|
+
return;
|
|
43
|
+
const wanted = allowed.map((k) => MAP_KIND_FACTORY_HINT[k] ?? k).join(" or ");
|
|
44
|
+
const found = kind ? `a Block of kind "${kind}"` : "an object with no waygraph kind marker at all";
|
|
45
|
+
throw new WaygraphError("WG_MAP_WRONG_KIND", MSG_MAP_WRONG_KIND(method, block?.name ?? "?", wanted, found));
|
|
46
|
+
}
|
|
47
|
+
export function assertMapSalt(block, allowed, method) {
|
|
48
|
+
const salt = mapSaltOf(block);
|
|
49
|
+
if (salt !== undefined && allowed.includes(salt))
|
|
50
|
+
return;
|
|
51
|
+
const wanted = allowed.map((s) => MAP_SALT_FACTORY_HINT[s] ?? s).join(" or ");
|
|
52
|
+
const found = salt ? `a Block salted "${salt}"` : "an object with no waygraph salt marker at all";
|
|
53
|
+
throw new WaygraphError("WG_MAP_WRONG_SALT", MSG_MAP_WRONG_SALT(method, block?.name ?? "?", wanted, found));
|
|
54
|
+
}
|
|
55
|
+
export function assertMapOrigin(block, homeOrigin, expect, method) {
|
|
56
|
+
if (!homeOrigin)
|
|
57
|
+
return; // not configured - can't validate, honest no-op
|
|
58
|
+
const navUrl = mapNavUrlOf(block);
|
|
59
|
+
if (navUrl === undefined)
|
|
60
|
+
return; // click-based/dynamic nav - not statically checkable
|
|
61
|
+
let targetOrigin;
|
|
62
|
+
let wantOrigin;
|
|
63
|
+
try {
|
|
64
|
+
targetOrigin = new URL(navUrl, homeOrigin).origin;
|
|
65
|
+
wantOrigin = new URL(homeOrigin).origin;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return; // malformed URL - not this check's job to validate that
|
|
69
|
+
}
|
|
70
|
+
const isExternal = targetOrigin !== wantOrigin;
|
|
71
|
+
if (expect === "internal" && isExternal) {
|
|
72
|
+
throw new WaygraphError("WG_MAP_WRONG_ORIGIN", MSG_MAP_WRONG_ORIGIN_INTERNAL(block.name, targetOrigin, wantOrigin));
|
|
73
|
+
}
|
|
74
|
+
if (expect === "external" && !isExternal) {
|
|
75
|
+
throw new WaygraphError("WG_MAP_WRONG_ORIGIN", MSG_MAP_WRONG_ORIGIN_EXTERNAL(block.name, targetOrigin, wantOrigin));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export const MAP_KIND_FACTORY_HINT = {
|
|
79
|
+
nav: "defineNavBlock/defineMemNavBlock",
|
|
80
|
+
page: "definePageBlock",
|
|
81
|
+
assert: "defineAssertBlock",
|
|
82
|
+
};
|
|
83
|
+
export const MAP_SALT_FACTORY_HINT = {
|
|
84
|
+
method: "defineMethodBlock",
|
|
85
|
+
effect: "defineEffectBlock",
|
|
86
|
+
api: "defineApiBlock",
|
|
87
|
+
};
|
package/dist/engine/run/run.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { MemPage } from "../mem/mem.js";
|
|
|
2
2
|
import type { Block } from "../block/block.js";
|
|
3
3
|
import type { Checkpoint } from "../checkpoint/checkpoint.js";
|
|
4
4
|
import type { Trait } from "../trait/trait.js";
|
|
5
|
-
import type { BrowserContext,
|
|
5
|
+
import type { BrowserContext, Page } from "@playwright/test";
|
|
6
6
|
import type { SomeBlock } from "../block/block.js";
|
|
7
7
|
/**
|
|
8
8
|
* Checks `block.requires` against `mem` and throws, naming every missing key at
|
|
@@ -125,21 +125,3 @@ export interface RunGraphOptions {
|
|
|
125
125
|
* }
|
|
126
126
|
*/
|
|
127
127
|
export declare function spawnTab<TOut extends Checkpoint<string>>(entry: Block<Checkpoint<"__start__">, TOut>, page: Page, mem: MemPage, maxSteps?: number): Promise<TOut>;
|
|
128
|
-
/**
|
|
129
|
-
* Wraps one `act()` interaction with a caption and highlight, for a Block
|
|
130
|
-
* author who wants to explicitly narrate a specific step rather than rely
|
|
131
|
-
* on the generic per-fill/per-click narration `waygraph chain
|
|
132
|
-
* WAYGRAPH_STEP=1` already does automatically -
|
|
133
|
-
* `await narrate(submitButton, "confirms the order", () => submitButton.click())`
|
|
134
|
-
* reads at the call site instead of being inferred.
|
|
135
|
-
*
|
|
136
|
-
* A true no-op everywhere except inside a `WAYGRAPH_STEP=1` run: it checks
|
|
137
|
-
* for a `window.__wgPositionRing` hook the step-mode overlay installs on
|
|
138
|
-
* the page before doing anything, so a headless/CI/automated run (nobody
|
|
139
|
-
* watching, per-character delays and highlight pauses would just be wasted
|
|
140
|
-
* time) pays zero extra cost - not even the boundingBox() lookup runs. The
|
|
141
|
-
* `action` itself always runs regardless; only the narration is
|
|
142
|
-
* conditional.
|
|
143
|
-
* @example await narrate(submitButton, "confirms the order", () => submitButton.click())
|
|
144
|
-
*/
|
|
145
|
-
export declare function narrate<T>(locator: Locator, caption: string, action: () => Promise<T>): Promise<T>;
|
package/dist/engine/run/run.js
CHANGED
|
@@ -2,7 +2,6 @@ import { WaygraphError, MSG_PREFLIGHT_MISSING_KEY, MSG_RUNGRAPH_MAX_STEPS, MSG_R
|
|
|
2
2
|
import { checkpoint } from "../checkpoint/checkpoint.js";
|
|
3
3
|
import { beginRun, endRun, isConnected, lastLeaf, stepEnded, stepFailed, stepStarted } from "./events.js";
|
|
4
4
|
import { runPrecondition, runVerify } from "../trait/trait.js";
|
|
5
|
-
import { ignorePageGone } from "../page-gone.js";
|
|
6
5
|
/**
|
|
7
6
|
* Checks `block.requires` against `mem` and throws, naming every missing key at
|
|
8
7
|
* once, if any are unset. `connect()` unions each Block's `requires` into the
|
|
@@ -144,90 +143,3 @@ export async function runGraph(entry, terminals, context, mem, maxSteps = 5000,
|
|
|
144
143
|
export async function spawnTab(entry, page, mem, maxSteps = 5000) {
|
|
145
144
|
return runGraph(entry, undefined, page.context(), mem, maxSteps);
|
|
146
145
|
}
|
|
147
|
-
/**
|
|
148
|
-
* Wraps one `act()` interaction with a caption and highlight, for a Block
|
|
149
|
-
* author who wants to explicitly narrate a specific step rather than rely
|
|
150
|
-
* on the generic per-fill/per-click narration `waygraph chain
|
|
151
|
-
* WAYGRAPH_STEP=1` already does automatically -
|
|
152
|
-
* `await narrate(submitButton, "confirms the order", () => submitButton.click())`
|
|
153
|
-
* reads at the call site instead of being inferred.
|
|
154
|
-
*
|
|
155
|
-
* A true no-op everywhere except inside a `WAYGRAPH_STEP=1` run: it checks
|
|
156
|
-
* for a `window.__wgPositionRing` hook the step-mode overlay installs on
|
|
157
|
-
* the page before doing anything, so a headless/CI/automated run (nobody
|
|
158
|
-
* watching, per-character delays and highlight pauses would just be wasted
|
|
159
|
-
* time) pays zero extra cost - not even the boundingBox() lookup runs. The
|
|
160
|
-
* `action` itself always runs regardless; only the narration is
|
|
161
|
-
* conditional.
|
|
162
|
-
* @example await narrate(submitButton, "confirms the order", () => submitButton.click())
|
|
163
|
-
*/
|
|
164
|
-
export async function narrate(locator, caption, action) {
|
|
165
|
-
const page = locator.page();
|
|
166
|
-
const active = await page
|
|
167
|
-
.evaluate(() => typeof globalThis.__wgPositionRing === "function")
|
|
168
|
-
.catch(() => false);
|
|
169
|
-
if (!active)
|
|
170
|
-
return action();
|
|
171
|
-
let owning = false;
|
|
172
|
-
try {
|
|
173
|
-
const box = await locator.boundingBox();
|
|
174
|
-
if (box) {
|
|
175
|
-
await page
|
|
176
|
-
.evaluate(({ box, caption }) => {
|
|
177
|
-
const w = globalThis;
|
|
178
|
-
if (w.__wgPositionRing)
|
|
179
|
-
w.__wgPositionRing(box, caption, "planned");
|
|
180
|
-
// The CLI's own automatic per-fill/per-click narration checks
|
|
181
|
-
// this before showing (and overwriting) its own guess - an
|
|
182
|
-
// explicitly authored caption should win, not get immediately
|
|
183
|
-
// replaced a moment later by the generic one.
|
|
184
|
-
w.__wgLastNarrate = Date.now();
|
|
185
|
-
// Also claim the ring itself: the auto-highlight click/fill
|
|
186
|
-
// patches each hide the ring right after THEIR own step
|
|
187
|
-
// finishes, which - if action() below does more than one thing
|
|
188
|
-
// (e.g. a click then a wait for a toast) - would wipe this
|
|
189
|
-
// caption after just the first sub-step instead of the whole
|
|
190
|
-
// narrated action. Their hideRing() calls no-op while this is
|
|
191
|
-
// true; narrate() below is the one that actually clears it.
|
|
192
|
-
w.__wgNarrateOwnsRing = true;
|
|
193
|
-
}, { box, caption })
|
|
194
|
-
.catch(ignorePageGone);
|
|
195
|
-
owning = true;
|
|
196
|
-
// The ring alone is pointless if action() fires on the very next
|
|
197
|
-
// tick - a click that navigates (e.g. a form submit) wipes the ring
|
|
198
|
-
// before a human can read the caption at all. Give it the same
|
|
199
|
-
// "pop for a few seconds" dwell as the CLI's own auto-highlight
|
|
200
|
-
// clicks before the real action runs.
|
|
201
|
-
await new Promise((resolve) => setTimeout(resolve, 650));
|
|
202
|
-
// Re-stamp __wgLastNarrate right before handing off to action() - the
|
|
203
|
-
// CLI's auto-highlight patches only treat a narrate() as "just
|
|
204
|
-
// handled" within a short window (500ms), which the dwell above
|
|
205
|
-
// already burned through. Without this, action()'s own click/fill
|
|
206
|
-
// (same patched Locator prototype) would stomp this caption with its
|
|
207
|
-
// own generic one a moment after it finally became visible.
|
|
208
|
-
await page
|
|
209
|
-
.evaluate(() => {
|
|
210
|
-
globalThis.__wgLastNarrate = Date.now();
|
|
211
|
-
})
|
|
212
|
-
.catch(ignorePageGone);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
catch {
|
|
216
|
-
// best-effort - the real action below still runs either way
|
|
217
|
-
}
|
|
218
|
-
try {
|
|
219
|
-
return await action();
|
|
220
|
-
}
|
|
221
|
-
finally {
|
|
222
|
-
if (owning) {
|
|
223
|
-
await page
|
|
224
|
-
.evaluate(() => {
|
|
225
|
-
const w = globalThis;
|
|
226
|
-
w.__wgNarrateOwnsRing = false;
|
|
227
|
-
if (w.__wgHideRing)
|
|
228
|
-
w.__wgHideRing();
|
|
229
|
-
})
|
|
230
|
-
.catch(ignorePageGone);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Checkpoint } from "../checkpoint/checkpoint.js";
|
|
2
1
|
/** Shared dwell fields on stubs, fixtures, and yap slides. */
|
|
3
2
|
export type FixtureDurationFields = {
|
|
4
3
|
/**
|
|
@@ -83,8 +82,8 @@ export interface WaygraphHighlightStub extends FixtureDurationFields {
|
|
|
83
82
|
/** A static stub phase: named ring slots to paint before or after a step. */
|
|
84
83
|
export type HighlightStubPhase = Record<string, WaygraphHighlightStub>;
|
|
85
84
|
/**
|
|
86
|
-
* One yap/slide in a multi-step demo caption sequence.
|
|
87
|
-
*
|
|
85
|
+
* One yap/slide in a multi-step demo caption sequence, painted with {@link StubCtx.slides}.
|
|
86
|
+
* The demo pauses on each (Next, or auto-next) before moving on.
|
|
88
87
|
*/
|
|
89
88
|
export interface WaygraphSlide extends FixtureDurationFields {
|
|
90
89
|
/** Primary caption (required). */
|
|
@@ -119,7 +118,6 @@ export type HighlightStyleDefaults = {
|
|
|
119
118
|
size?: HighlightSize;
|
|
120
119
|
weight?: HighlightWeight;
|
|
121
120
|
};
|
|
122
|
-
export type WaygraphSlidesOrFn<Out extends Checkpoint<string>> = readonly WaygraphSlide[] | ((out: Out) => readonly WaygraphSlide[]);
|
|
123
121
|
/** A ring or caption after its defaults and overrides are merged, ready to paint. */
|
|
124
122
|
export type ResolvedHighlight = WaygraphHighlightStub;
|
|
125
123
|
/** Map author aliases (`error` -> danger) to a canonical tone. */
|
package/dist/engine/stub/ring.js
CHANGED
|
@@ -2,7 +2,7 @@ import type { Checkpoint } from "../checkpoint/checkpoint.js";
|
|
|
2
2
|
import type { MemPage } from "../mem/mem.js";
|
|
3
3
|
import type { TodoDockState, TodoDockUiOpts, TodoListStyle, WaygraphTodoGroupInput, WaygraphTodoInput, WaygraphTodoItem, WaygraphTodosOpts } from "./todos.js";
|
|
4
4
|
import type { DeviceOrientation, DevicePreset, DeviceState, DeviceViewport } from "./viewport.js";
|
|
5
|
-
import type { HighlightStubPhase, ResolvedHighlight, WaygraphHighlightStub } from "./ring.js";
|
|
5
|
+
import type { HighlightStubPhase, ResolvedHighlight, WaygraphHighlightStub, WaygraphSlide } from "./ring.js";
|
|
6
6
|
/** Where the top banner sits. */
|
|
7
7
|
export type BannerPos = "left" | "center" | "right";
|
|
8
8
|
/** Banner UX, mirrors {@link TodoDockUiOpts}: pass `false` fields to opt out for this phase. */
|
|
@@ -87,10 +87,8 @@ export type StubPhaseFixtures = {
|
|
|
87
87
|
* LoginBlock.stubBefore((ctx) => {
|
|
88
88
|
* ctx.todos("sign-in", ["Enter email", "Enter password", "Click Sign in"], { index: 0 });
|
|
89
89
|
* ctx.zoom(1.35);
|
|
90
|
-
* ctx.
|
|
91
|
-
*
|
|
92
|
-
* submit: { selector: "#login-button", label: "Sign in" },
|
|
93
|
-
* });
|
|
90
|
+
* ctx.ring("email", { selector: "#email", label: "Email" });
|
|
91
|
+
* ctx.ring("submit", { selector: "#login-button", label: "Sign in" });
|
|
94
92
|
* })
|
|
95
93
|
* // Sequential plan: bump todoIndex in a later phase / a later Block's stubBefore
|
|
96
94
|
* .stubAfter((ctx) => {
|
|
@@ -109,9 +107,7 @@ export type StubCtx<Out extends Checkpoint<string> = Checkpoint<string>> = {
|
|
|
109
107
|
readonly out: Out | undefined;
|
|
110
108
|
/** Present on stubOnError when the step threw. */
|
|
111
109
|
readonly error: unknown | undefined;
|
|
112
|
-
/**
|
|
113
|
-
highlights(slots: HighlightStubPhase): void;
|
|
114
|
-
/** Set / overwrite one named ring. */
|
|
110
|
+
/** Paints one named ring this phase; the same id again replaces it. */
|
|
115
111
|
ring(id: string, stub: WaygraphHighlightStub): void;
|
|
116
112
|
/**
|
|
117
113
|
* Floating checklist: `ctx.todos("login", ["Enter email", "Enter password"], { title: "Sign in", index: 0 })`.
|
|
@@ -174,6 +170,15 @@ export type StubCtx<Out extends Checkpoint<string> = Checkpoint<string>> = {
|
|
|
174
170
|
caption(text: string): void;
|
|
175
171
|
/** Clears the caption (fades it out). */
|
|
176
172
|
hideCaption(): void;
|
|
173
|
+
/**
|
|
174
|
+
* Multi-step "yap" captions with Next between each, for explaining a longer process. In `stubBefore` they play
|
|
175
|
+
* before the step runs, in `stubAfter` after it lands; a slide with a `selector` rings it while it is up.
|
|
176
|
+
* @example ctx.slides([
|
|
177
|
+
* { caption: "Checkout is three screens", tag: "YAP" },
|
|
178
|
+
* { caption: "Overview confirms totals", selector: ".summary_info", duration: true },
|
|
179
|
+
* ]);
|
|
180
|
+
*/
|
|
181
|
+
slides(slides: readonly WaygraphSlide[]): void;
|
|
177
182
|
/** Shorthand for `bannerUi({ hidden: true })`. */
|
|
178
183
|
hideBanner(): void;
|
|
179
184
|
/**
|
|
@@ -226,6 +231,8 @@ export type StubPhaseResult = {
|
|
|
226
231
|
bannerUi?: BannerUiOpts;
|
|
227
232
|
caption?: string;
|
|
228
233
|
networkTabVisible?: boolean;
|
|
234
|
+
/** Slides to play in this phase ({@link StubCtx.slides}); empty when the stub set none. */
|
|
235
|
+
slides: WaygraphSlide[];
|
|
229
236
|
todoPos?: "left" | "right";
|
|
230
237
|
/** When true, keep other docks (multi-todo). Default false = replace. */
|
|
231
238
|
todoParallel?: boolean;
|
|
@@ -260,6 +267,7 @@ export type StubBagState = {
|
|
|
260
267
|
bannerUi?: BannerUiOpts | undefined;
|
|
261
268
|
caption?: string | undefined;
|
|
262
269
|
networkTabVisible?: boolean | undefined;
|
|
270
|
+
slides?: readonly WaygraphSlide[] | undefined;
|
|
263
271
|
todoPos?: "left" | "right" | undefined;
|
|
264
272
|
/** Author patched todo-dock UX this phase. */
|
|
265
273
|
todoDockUi?: TodoDockUiOpts | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// URLPattern is only a Node global from v23.8+ (and even then, Node's own, not a browser's) -
|
|
2
|
-
//
|
|
2
|
+
// Node 22 (the oldest supported) has no global at all. Side-effect import only: the polyfill package sets
|
|
3
3
|
// globalThis.URLPattern itself, but only when one doesn't already exist - so below Node 23.8 this
|
|
4
4
|
// becomes THE global, and from 23.8 up it's a no-op and the native one stays. Playwright's own
|
|
5
5
|
// waitForURL(pattern) checks `pattern instanceof globalThis.URLPattern` internally, so the instance
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import "./runtime/full-launch.js";
|
|
2
2
|
import "./runtime/run-log.js";
|
|
3
3
|
export type { Checkpoint, Start } from "./engine/checkpoint/checkpoint.js";
|
|
4
|
-
export type { Instruction, Block, DefinedBlock, SomeBlock, SomeDefinedBlock
|
|
4
|
+
export type { Instruction, Block, DefinedBlock, SomeBlock, SomeDefinedBlock } from "./engine/block/block.js";
|
|
5
|
+
export type { WaygraphInstanceOption } from "./engine/block/action-page.js";
|
|
5
6
|
export { connect } from "./engine/run/connect.js";
|
|
6
7
|
export { checkpoint } from "./engine/checkpoint/checkpoint.js";
|
|
7
8
|
export { MemKey, MemPage, key, keyGroup } from "./engine/mem/mem.js";
|
|
@@ -9,10 +10,12 @@ export { registerMemStub, seedMemStub, getMemStub } from "./engine/mem/mem-stub.
|
|
|
9
10
|
export { css, byText, byRole } from "./engine/trait/selector.js";
|
|
10
11
|
export { WaygraphError, WAYGRAPH_ERRORS } from "./engine/errors.js";
|
|
11
12
|
export type { WaygraphErrorCode } from "./engine/errors.js";
|
|
12
|
-
export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible, frameTextEquals, frameContainsText
|
|
13
|
-
export { runGraph, spawnTab,
|
|
13
|
+
export { Trait, urlMatches, textEquals, visible, disabled, enabled, frameVisible, frameTextEquals, frameContainsText } from "./engine/trait/trait.js";
|
|
14
|
+
export { runGraph, spawnTab, preflight, defineLayout } from "./engine/run/run.js";
|
|
14
15
|
export { Engine, map } from "./engine/engine.js";
|
|
15
|
-
export { branch
|
|
16
|
+
export { branch } from "./engine/block/branch.js";
|
|
17
|
+
export { withVerify, modVerify, modVerifyAll, defineBlock } from "./engine/block/block.js";
|
|
18
|
+
export { withDialog } from "./engine/block/dialog.js";
|
|
16
19
|
export { defineNavBlock, defineNavClickBlock, defineMemNavBlock } from "./engine/block/kinds/nav.js";
|
|
17
20
|
export { defineMethodBlock, defineAssertBlock } from "./engine/block/kinds/method.js";
|
|
18
21
|
export { definePageBlock } from "./engine/block/kinds/page.js";
|
|
@@ -24,8 +27,9 @@ export { MapBuilder } from "./engine/flow/map-builder.js";
|
|
|
24
27
|
export { branchRoutes, collectBranchFlows, runBranchRegression } from "./engine/flow/branch-regression.js";
|
|
25
28
|
export type { BranchEntry, BranchRunResult, RunBranchRegressionOptions } from "./engine/flow/branch-regression.js";
|
|
26
29
|
export type { ApiBlockOptions, ApiCallResult } from "./engine/block/kinds/api.js";
|
|
27
|
-
export type { MapStepOpts
|
|
28
|
-
export {
|
|
30
|
+
export type { MapStepOpts } from "./engine/flow/map-steps.js";
|
|
31
|
+
export type { MapFlowOpts } from "./engine/flow/map-builder.js";
|
|
32
|
+
export { resolveHighlightSlots, runStubPhase, hasAuthoredStubAfter, hasAuthoredStubOnError } from "./demo/narration/narration.js";
|
|
29
33
|
export { resolveFixtureDwellMs, normalizeDemoPace, resolveStepDemoPace, demoPaceScale, demoPaceIsBlitz, demoPaceIsFast, demoPaceIsSlow, demoPaceGateMs, formatDemoPaceBadge, formatDemoPaceLabel, FIXTURE_DURATION_MS_DEFAULT, FIXTURE_DURATION_FAST_MS_DEFAULT, FIXTURE_DURATION_SLOW_MS_DEFAULT } from "./demo/narration/demo-pace.js";
|
|
30
34
|
export { formatHighlightCaption, applyHighlightStyleDefaults, toneIconPrefix } from "./demo/narration/style.js";
|
|
31
35
|
export { normalizeHighlightTone, normalizeHighlightSize, normalizeHighlightWeight } from "./engine/stub/ring.js";
|
|
@@ -46,21 +50,21 @@ export type { MethodBlock, AssertBlock, AssertBlockOptions } from "./engine/bloc
|
|
|
46
50
|
export type { PageBlock, PageBlockOptions, PageMethodEntry } from "./engine/block/kinds/page.js";
|
|
47
51
|
export type { EffectBlock } from "./engine/block/kinds/effect.js";
|
|
48
52
|
export type { MapBuilderOptions } from "./engine/flow/map-builder.js";
|
|
49
|
-
export type { ActionPage } from "./engine/block/
|
|
53
|
+
export type { ActionPage } from "./engine/block/action-page.js";
|
|
50
54
|
export { discoverGraph, toMermaid, findOrphanBlocks, findBlockPath } from "./analysis/graph.js";
|
|
51
55
|
export { buildManifest } from "./manifest/manifest.js";
|
|
52
56
|
export { onRunEvent } from "./engine/run/events.js";
|
|
53
57
|
export type { RunEvent } from "./engine/run/events.js";
|
|
54
58
|
export type { Manifest, ManifestBlock, ManifestFlow } from "./manifest/manifest.js";
|
|
55
59
|
export type { WaygraphGraph, WaygraphNode, WaygraphEdge, SkippedBlock, OrphanBlock } from "./analysis/graph.js";
|
|
56
|
-
export { isFileSelectToken, parseBlocksSelect, matchBlocksSelect, globToRegExp
|
|
60
|
+
export { isFileSelectToken, parseBlocksSelect, matchBlocksSelect, globToRegExp } from "./manifest/select.js";
|
|
57
61
|
export type { BlocksSelect, BlocksSelectKind } from "./manifest/select.js";
|
|
58
62
|
export { EdgeLeaseCoordinator } from "./live/traverse/lease.js";
|
|
59
63
|
export { runTraverse } from "./live/traverse/traverse.js";
|
|
60
|
-
export type { TraverseOptions, TraverseSessionMode, TraverseWorkerResult
|
|
61
|
-
export { buildCoverageReport, collectGraphEdgeKeys, defaultCoverageOutPath, formatCoverageLine, normalizeHitKey, parseMinEdgeCoverage, writeCoverageReport
|
|
64
|
+
export type { TraverseOptions, TraverseSessionMode, TraverseWorkerResult } from "./live/traverse/traverse.js";
|
|
65
|
+
export { buildCoverageReport, collectGraphEdgeKeys, defaultCoverageOutPath, formatCoverageLine, normalizeHitKey, parseMinEdgeCoverage, writeCoverageReport } from "./live/traverse/coverage.js";
|
|
62
66
|
export type { TraverseCoverageReport } from "./live/traverse/coverage.js";
|
|
63
|
-
export { WG_UI_SEL, WG_READY_PANEL_SEL, WG_READY_AUTO_SEL, WG_READY_BANNER_SEL, readWgOverlayBeacon, readWgOverlayBeaconInPage, assertWgOverlayReady
|
|
67
|
+
export { WG_UI_SEL, WG_READY_PANEL_SEL, WG_READY_AUTO_SEL, WG_READY_BANNER_SEL, readWgOverlayBeacon, readWgOverlayBeaconInPage, assertWgOverlayReady } from "./demo/overlay/beacon.js";
|
|
64
68
|
export type { WgModalKind, WgBeaconRow } from "./demo/overlay/beacon.js";
|
|
65
69
|
export { AutoSession } from "./live/auto-session/auto-session.js";
|
|
66
70
|
export { stubFilePath } from "./live/auto-session/helpers.js";
|
|
@@ -75,7 +79,6 @@ export { resolveExtension, KNOWN_EXTENSIONS } from "./runtime/extensions.js";
|
|
|
75
79
|
export type { ExtensionSpec } from "./engine/config.js";
|
|
76
80
|
export type { WebServerConfig } from "./runtime/webserver.js";
|
|
77
81
|
export type { MapStart } from "./engine/engine.js";
|
|
78
|
-
export type { WaygraphSlidesOrFn } from "./engine/stub/ring.js";
|
|
79
82
|
export type { ConnectLayout } from "./engine/run/connect.js";
|
|
80
83
|
export type { EffectExtras } from "./engine/block/kinds/effect.js";
|
|
81
84
|
export type { BlockBase, RoutedBlockBase } from "./engine/checkpoint/route.js";
|