waygraph 0.7.13 → 0.7.15

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 CHANGED
@@ -34,7 +34,7 @@ This README stays the in-repo API narrative; Pages is the same material for eyeb
34
34
  | Goal | Command |
35
35
  |------|---------|
36
36
  | Watch Sauce Demo step-through (temp dir only) | `npx waygraph try demo` |
37
- | Interactive explore (Add/Remove/Open details from live page) | `cd examples/saucedemo && npm i && npx waygraph auto .` |
37
+ | Interactive explore (Add/Remove/Open details from live page) | `cd examples/saucedemo && npm i && npx waygraph auto` |
38
38
  | Scaffold a new **offline** project (green `npm test` on a `data:` URL) | `npx create-waygraph my-app` **or** `npx waygraph init my-app` |
39
39
  | Add waygraph to an existing repo | `npm install waygraph @playwright/test` |
40
40
 
@@ -221,10 +221,10 @@ autoplay off** (manual "Run this step" / "Next"). Flags beat env:
221
221
 
222
222
  | Want | Command |
223
223
  |------|---------|
224
- | Manual watch | `waygraph demo shopFlow .` |
225
- | Auto-advance | `waygraph demo shopFlow . --autoplay` |
226
- | Same overlay on a chain | `waygraph chain "login then nav-cart" . --step` |
227
- | No overlay | `waygraph demo shopFlow . --no-step` |
224
+ | Manual watch | `waygraph demo shopFlow` |
225
+ | Auto-advance | `waygraph demo shopFlow --autoplay` |
226
+ | Same overlay on a chain | `waygraph chain "login then nav-cart" --step` |
227
+ | No overlay | `waygraph demo shopFlow --no-step` |
228
228
 
229
229
  `--step` = headed overlay. `--autoplay` = panel Auto-advance starts checked (timer;
230
230
  flip mid-run; manual click always wins). `chain` does **not** default to step — pass
@@ -234,14 +234,14 @@ flip mid-run; manual click always wins). `chain` does **not** default to step
234
234
  cursor travel + pulse before the real click; `url` NavBlocks still `goto`. Full page:
235
235
  https://deviate-dv8.github.io/waygraph/demo.html
236
236
 
237
- **Flow video (headless OK):** `waygraph chain "loginFlow({...}) then viewerBlockedFlow({...})" . --video`
237
+ **Flow video (headless OK):** `waygraph chain "loginFlow({...}) then viewerBlockedFlow({...})" --video`
238
238
  uses Playwright `recordVideo` and prints the `.webm` path when done (default dir:
239
239
  `.waygraph-videos/`). Lighter than help-center-clip-engine (no overlay/ffmpeg pipeline).
240
240
  Same flag works on `waygraph demo`. Programmatic: `Engine({ recordVideo: { dir: "./videos" } })`.
241
241
 
242
- **Project hygiene:** `waygraph check .` warns on nav outside NavBlocks **and** lists
242
+ **Project hygiene:** `waygraph check` warns on nav outside NavBlocks **and** lists
243
243
  **orphan Blocks** (a `*.block.ts` export not wired into any `.flow.ts` defineFlow array).
244
- Zero orphans is required before `waygraph chain auto <fromCheckpoint> <toCheckpoint> .`
244
+ Zero orphans is required before `waygraph chain auto <fromCheckpoint> <toCheckpoint>`
245
245
  builds a chain spec from the `waygraph auto` graph.
246
246
 
247
247
  ## Example
package/dist/cli.js CHANGED
@@ -2686,9 +2686,9 @@ function initCommand(projectName) {
2686
2686
  console.log(" npm install");
2687
2687
  console.log(" npx playwright install chromium");
2688
2688
  console.log(" npm test");
2689
- console.log(" waygraph check . # nav hygiene + orphan Blocks");
2690
- console.log(" waygraph auto . # interactive explore (headful picker)");
2691
- console.log(" waygraph graph . # static state graph JSON");
2689
+ console.log(" waygraph check # nav hygiene + orphan Blocks");
2690
+ console.log(" waygraph auto # interactive explore (headful picker)");
2691
+ console.log(" waygraph graph # static state graph JSON");
2692
2692
  }
2693
2693
  async function checkCommand(projectDir) {
2694
2694
  const files = discoverBlocks(projectDir);
@@ -2910,13 +2910,16 @@ Demo / step / autoplay (read this - agents get this wrong):
2910
2910
  an in-flight autoplay wait. Flags beat WAYGRAPH_* and reset the checkbox
2911
2911
  at process start (so --no-autoplay after a prior --autoplay session works).
2912
2912
 
2913
- Manual watch (default): waygraph demo shopFlow .
2914
- Auto-advance watch: waygraph demo shopFlow . --autoplay
2915
- Same overlay on a chain: waygraph chain "login then nav-cart" . --step
2916
- Unattended (no overlay): waygraph demo shopFlow . --no-step
2913
+ Manual watch (default): waygraph demo shopFlow
2914
+ Auto-advance watch: waygraph demo shopFlow --autoplay
2915
+ Same overlay on a chain: waygraph chain "login then nav-cart" --step
2916
+ Unattended (no overlay): waygraph demo shopFlow --no-step
2917
2917
  Onboarding (temp dir): npx waygraph try demo
2918
2918
  Explore (temp dir): npx waygraph try auto
2919
2919
 
2920
+ Project path is optional - omit it to use the current directory.
2921
+ You do not need a trailing "." (that is only shell shorthand for cwd).
2922
+
2920
2923
  Other run flags (chain / demo / try) - flags beat WAYGRAPH_* env:
2921
2924
  --base-url <url> base URL for relative page.goto()
2922
2925
  --title <text> persistent overlay banner title
@@ -2976,7 +2979,7 @@ Prefer flags (or npm scripts that pass them) over an ENV soup of WAYGRAPH_*.
2976
2979
  "chain auto" builds the spec from waygraph auto's graph (requires zero
2977
2980
  orphan Blocks - run waygraph check first):
2978
2981
 
2979
- waygraph chain auto LoggedIn OrderComplete .
2982
+ waygraph chain auto LoggedIn OrderComplete
2980
2983
 
2981
2984
  A Block with no requires needs no payload. One with several required
2982
2985
  keys takes one JSON object keyed by each key's own name instead of a
@@ -3030,11 +3033,11 @@ Prefer flags (or npm scripts that pass them) over an ENV soup of WAYGRAPH_*.
3030
3033
  "project" defaults to the current directory.
3031
3034
 
3032
3035
  Examples:
3033
- waygraph demo shopFlow .
3034
- waygraph demo shopFlow . --autoplay --title "Shop demo"
3035
- waygraph demo loginFlow . --base-url https://www.saucedemo.com
3036
- waygraph chain "login then nav-cart" . --step --no-autoplay
3037
- npm run demo # scaffold: waygraph demo exampleFlow .
3036
+ waygraph demo shopFlow
3037
+ waygraph demo shopFlow --autoplay --title "Shop demo"
3038
+ waygraph demo loginFlow --base-url https://www.saucedemo.com
3039
+ waygraph chain "login then nav-cart" --step --no-autoplay
3040
+ npm run demo # scaffold: waygraph demo exampleFlow
3038
3041
  `);
3039
3042
  process.exit(0);
3040
3043
  }
@@ -3099,7 +3102,7 @@ async function main() {
3099
3102
  const toTag = flags.positionals[2];
3100
3103
  if (!fromTag || !toTag) {
3101
3104
  console.error("waygraph chain auto: missing <fromCheckpoint> <toCheckpoint> [project]");
3102
- console.error(' e.g. waygraph chain auto LoggedIn OrderComplete .');
3105
+ console.error(' e.g. waygraph chain auto LoggedIn OrderComplete');
3103
3106
  process.exit(1);
3104
3107
  }
3105
3108
  const proj = resolve(flags.positionals[3] ?? process.cwd());
@@ -3130,7 +3133,7 @@ async function main() {
3130
3133
  applyRunFlags(flags);
3131
3134
  const spec = flags.positionals[0];
3132
3135
  if (!spec) {
3133
- console.error('waygraph demo: missing <flow|spec>, e.g. waygraph demo shopFlow .\n' +
3136
+ console.error('waygraph demo: missing <flow|spec>, e.g. waygraph demo shopFlow\n' +
3134
3137
  " Flags: --step/--no-step --autoplay/--no-autoplay --base-url <url> --title <text> --video [dir]");
3135
3138
  process.exit(1);
3136
3139
  }
@@ -3174,7 +3177,7 @@ async function main() {
3174
3177
  `${graph.skipped.length} Block(s) skipped (Out not resolvable), ` +
3175
3178
  `${orphans.length} orphan Block(s)`);
3176
3179
  if (orphans.length > 0) {
3177
- console.error("waygraph graph: orphan Blocks block chain auto shorthand - wire each into a .flow.ts (waygraph check .)");
3180
+ console.error("waygraph graph: orphan Blocks block chain auto shorthand - wire each into a .flow.ts (waygraph check)");
3178
3181
  }
3179
3182
  break;
3180
3183
  }
package/dist/graph.js CHANGED
@@ -98,7 +98,7 @@ export async function findOrphanBlocks(projectDir) {
98
98
  const exportName = m[1];
99
99
  if (referenced.has(exportName))
100
100
  continue;
101
- if (!/defineBlock|defineNavBlock/.test(src))
101
+ if (!/defineBlock|defineEffectBlock|defineMemEffectBlock|defineNavBlock|defineMemNavBlock/.test(src))
102
102
  continue;
103
103
  let block = exportNameToBlockName(exportName);
104
104
  try {
@@ -234,14 +234,17 @@ function resolveGenericArg(blockFilePath, arg) {
234
234
  return [inline[1]];
235
235
  return resolveTypeToTags(blockFilePath, arg);
236
236
  }
237
- /** Every `defineBlock<In, Out>(` call site in a file's own source, in order. */
237
+ /** Every `defineBlock` / `defineEffectBlock` / `defineMemEffectBlock` `<In, Out>` call site. */
238
238
  function extractDefineBlockGenerics(src) {
239
239
  // Each argument is either a plain identifier or an inline `Checkpoint<...>`
240
- // (its own angle brackets, so the outer defineBlock<...> pair alone won't
240
+ // (its own angle brackets, so the outer defineX<...> pair alone won't
241
241
  // balance correctly against a naive greedy match) - captured as a single
242
242
  // alternation so both shapes come out of the same two capture groups.
243
+ // Effect helpers are TypeScript salt over defineBlock - same In/Out edges.
243
244
  const arg = String.raw `(Checkpoint<[^>]*>|[A-Za-z_$][\w]*)`;
244
- const re = new RegExp(String.raw `defineBlock<\s*${arg}\s*,\s*${arg}\s*>`, "g");
245
+ const re = new RegExp(String.raw `define(?:Mem)?(?:Effect)?Block<\s*${arg}\s*,\s*${arg}\s*>`, "g");
246
+ // Matches: defineBlock | defineEffectBlock | defineMemEffectBlock
247
+ // (defineMemBlock alone is not a real helper - Mem* only prefixes Effect.)
245
248
  const calls = [];
246
249
  let m;
247
250
  while ((m = re.exec(src)) !== null) {
@@ -301,7 +304,11 @@ export async function discoverGraph(projectDir) {
301
304
  }
302
305
  const call = calls[callIndex++];
303
306
  if (!call) {
304
- skipped.push({ block: blockName, file: relFile, reason: "no defineBlock<In, Out> generic call found" });
307
+ skipped.push({
308
+ block: blockName,
309
+ file: relFile,
310
+ reason: "no defineBlock/defineEffectBlock<In, Out> generic call found",
311
+ });
305
312
  continue;
306
313
  }
307
314
  const fromTags = resolveGenericArg(file, call.in);
@@ -63,10 +63,10 @@ src/states/
63
63
  src/flows/
64
64
  ```
65
65
 
66
- `waygraph check .` should report zero warnings - every navigation goes through
66
+ `waygraph check` should report zero warnings - every navigation goes through
67
67
  a `defineNavBlock`, nothing else calls `page.goto`.
68
68
 
69
- `waygraph auto .` should discover Checkpoints as nodes and these Blocks as
69
+ `waygraph auto` should discover Checkpoints as nodes and these Blocks as
70
70
  edges (including cycles via logout / continue-shopping / back-to-products).
71
71
 
72
72
  ## Friendly demo run (DX)
@@ -74,10 +74,10 @@ edges (including cycles via logout / continue-shopping / back-to-products).
74
74
  Prefer flags (or npm scripts) over a pile of `WAYGRAPH_*` env vars:
75
75
 
76
76
  ```bash
77
- npm run demo # waygraph demo shopFlow . (STEP+headed; BASE_URL from package.json / playwright)
77
+ npm run demo # waygraph demo shopFlow (STEP+headed; BASE_URL from package.json / playwright)
78
78
  npm run demo:autoplay # --autoplay --title "Shop demo"
79
- waygraph demo shopFlow . --base-url https://www.saucedemo.com --title "Shop"
80
- waygraph chain "loginFlow" . --step --no-autoplay
79
+ waygraph demo shopFlow --base-url https://www.saucedemo.com --title "Shop"
80
+ waygraph chain "loginFlow" --step --no-autoplay
81
81
  ```
82
82
 
83
83
  Flags beat env: `--step` / `--no-step`, `--autoplay` / `--no-autoplay`,
@@ -7,19 +7,19 @@
7
7
  "scripts": {
8
8
  "typecheck": "tsc --noEmit",
9
9
  "test": "playwright test",
10
- "flows": "waygraph list .",
11
- "demo": "waygraph demo shopFlow .",
12
- "demo:step": "waygraph demo shopFlow . --step --no-autoplay --title \"Shop demo\"",
13
- "demo:autoplay": "waygraph demo shopFlow . --autoplay --title \"Shop demo\"",
14
- "auto": "waygraph auto .",
15
- "auto:cli": "waygraph auto . --cli",
16
- "graph": "waygraph graph .",
17
- "graph:mermaid": "waygraph graph . --mermaid",
10
+ "flows": "waygraph list",
11
+ "demo": "waygraph demo shopFlow",
12
+ "demo:step": "waygraph demo shopFlow --step --no-autoplay --title \"Shop demo\"",
13
+ "demo:autoplay": "waygraph demo shopFlow --autoplay --title \"Shop demo\"",
14
+ "auto": "waygraph auto",
15
+ "auto:cli": "waygraph auto --cli",
16
+ "graph": "waygraph graph",
17
+ "graph:mermaid": "waygraph graph --mermaid",
18
18
  "prove:login-branch": "node scripts/prove-wrong-login-runtime.mjs",
19
19
  "prove:graph": "node scripts/prove-auto-graph.mjs",
20
20
  "prove:add-to-cart-menu": "node scripts/prove-add-to-cart-menu.mjs",
21
21
  "prove": "npm run prove:login-branch && npm run prove:graph && npm run prove:add-to-cart-menu && npm test",
22
- "record": "waygraph chain \"loginFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"standard_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}}) then shopFlow({\\\"saucedemo.selectedItem\\\":{\\\"id\\\":\\\"sauce-labs-backpack\\\",\\\"name\\\":\\\"Sauce Labs Backpack\\\"}})\" . --video --no-step"
22
+ "record": "waygraph chain \"loginFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"standard_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}}) then shopFlow({\\\"saucedemo.selectedItem\\\":{\\\"id\\\":\\\"sauce-labs-backpack\\\",\\\"name\\\":\\\"Sauce Labs Backpack\\\"}})\" --video --no-step"
23
23
  },
24
24
  "waygraph": {
25
25
  "baseUrl": "https://www.saucedemo.com"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.7.13",
3
+ "version": "0.7.15",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",
@@ -63,10 +63,10 @@ src/states/
63
63
  src/flows/
64
64
  ```
65
65
 
66
- `waygraph check .` should report zero warnings - every navigation goes through
66
+ `waygraph check` should report zero warnings - every navigation goes through
67
67
  a `defineNavBlock`, nothing else calls `page.goto`.
68
68
 
69
- `waygraph auto .` should discover Checkpoints as nodes and these Blocks as
69
+ `waygraph auto` should discover Checkpoints as nodes and these Blocks as
70
70
  edges (including cycles via logout / continue-shopping / back-to-products).
71
71
 
72
72
  ## Friendly demo run (DX)
@@ -74,10 +74,10 @@ edges (including cycles via logout / continue-shopping / back-to-products).
74
74
  Prefer flags (or npm scripts) over a pile of `WAYGRAPH_*` env vars:
75
75
 
76
76
  ```bash
77
- npm run demo # waygraph demo shopFlow . (STEP+headed; BASE_URL from package.json / playwright)
77
+ npm run demo # waygraph demo shopFlow (STEP+headed; BASE_URL from package.json / playwright)
78
78
  npm run demo:autoplay # --autoplay --title "Shop demo"
79
- waygraph demo shopFlow . --base-url https://www.saucedemo.com --title "Shop"
80
- waygraph chain "loginFlow" . --step --no-autoplay
79
+ waygraph demo shopFlow --base-url https://www.saucedemo.com --title "Shop"
80
+ waygraph chain "loginFlow" --step --no-autoplay
81
81
  ```
82
82
 
83
83
  Flags beat env: `--step` / `--no-step`, `--autoplay` / `--no-autoplay`,
@@ -6,20 +6,20 @@
6
6
  "scripts": {
7
7
  "test": "playwright test",
8
8
  "typecheck": "tsc --noEmit",
9
- "check": "waygraph check .",
10
- "auto": "waygraph auto .",
11
- "auto:cli": "waygraph auto . --cli",
12
- "graph": "waygraph graph .",
13
- "graph:mermaid": "waygraph graph . --mermaid",
14
- "demo": "waygraph chain \"loginFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"standard_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}}) then shopFlow({\\\"saucedemo.selectedItem\\\":{\\\"id\\\":\\\"sauce-labs-backpack\\\",\\\"name\\\":\\\"Sauce Labs Backpack\\\"}}) then viewerBlockedFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"locked_out_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}})\" . --step --no-autoplay",
15
- "demo:autoplay": "waygraph chain \"loginFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"standard_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}}) then shopFlow({\\\"saucedemo.selectedItem\\\":{\\\"id\\\":\\\"sauce-labs-backpack\\\",\\\"name\\\":\\\"Sauce Labs Backpack\\\"}}) then viewerBlockedFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"locked_out_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}})\" . --step --autoplay",
16
- "record": "waygraph chain \"loginFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"standard_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}}) then shopFlow({\\\"saucedemo.selectedItem\\\":{\\\"id\\\":\\\"sauce-labs-backpack\\\",\\\"name\\\":\\\"Sauce Labs Backpack\\\"}}) then viewerBlockedFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"locked_out_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}})\" . --video --no-step"
9
+ "check": "waygraph check",
10
+ "auto": "waygraph auto",
11
+ "auto:cli": "waygraph auto --cli",
12
+ "graph": "waygraph graph",
13
+ "graph:mermaid": "waygraph graph --mermaid",
14
+ "demo": "waygraph chain \"loginFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"standard_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}}) then shopFlow({\\\"saucedemo.selectedItem\\\":{\\\"id\\\":\\\"sauce-labs-backpack\\\",\\\"name\\\":\\\"Sauce Labs Backpack\\\"}}) then viewerBlockedFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"locked_out_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}})\" --step --no-autoplay",
15
+ "demo:autoplay": "waygraph chain \"loginFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"standard_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}}) then shopFlow({\\\"saucedemo.selectedItem\\\":{\\\"id\\\":\\\"sauce-labs-backpack\\\",\\\"name\\\":\\\"Sauce Labs Backpack\\\"}}) then viewerBlockedFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"locked_out_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}})\" --step --autoplay",
16
+ "record": "waygraph chain \"loginFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"standard_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}}) then shopFlow({\\\"saucedemo.selectedItem\\\":{\\\"id\\\":\\\"sauce-labs-backpack\\\",\\\"name\\\":\\\"Sauce Labs Backpack\\\"}}) then viewerBlockedFlow({\\\"saucedemo.credentials\\\":{\\\"username\\\":\\\"locked_out_user\\\",\\\"password\\\":\\\"secret_sauce\\\"}})\" --video --no-step"
17
17
  },
18
18
  "waygraph": {
19
19
  "baseUrl": "https://www.saucedemo.com"
20
20
  },
21
21
  "dependencies": {
22
- "waygraph": "^0.7.13"
22
+ "waygraph": "^0.7.15"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@playwright/test": "^1.55.0",
@@ -6,11 +6,11 @@
6
6
  "scripts": {
7
7
  "typecheck": "tsc --noEmit",
8
8
  "test": "playwright test",
9
- "flows": "waygraph list .",
10
- "check": "waygraph check .",
11
- "auto": "waygraph auto .",
12
- "graph": "waygraph graph .",
13
- "demo": "waygraph demo exampleFlow ."
9
+ "flows": "waygraph list",
10
+ "check": "waygraph check",
11
+ "auto": "waygraph auto",
12
+ "graph": "waygraph graph",
13
+ "demo": "waygraph demo exampleFlow"
14
14
  },
15
15
  "waygraph": {
16
16
  "baseUrl": "https://example.com"