waygraph 0.12.5 → 0.12.6

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
@@ -248,12 +248,13 @@ an opinionated Playwright," so a stealth-patched or otherwise customized launche
248
248
  the same `.launch()` shape as Playwright's own `chromium`/`firefox`/`webkit`.
249
249
 
250
250
  See **Getting started** above for `try demo`, `create-waygraph`, and `waygraph init`.
251
- Both scaffold commands emit the same offline tree (package.json, tsconfig, playwright.config,
252
- one example flow + `npm run check` / `npm run auto` / `npm run demo`).
251
+ Both scaffold commands emit the same offline tree (route-shaped `demo-web/` +
252
+ `methods/`, stubs, fixtures, one YAP slide). Layout:
253
+ [`docs/scaffold.html`](./docs/scaffold.html) · `templates/scaffold/STRUCTURE.md`.
253
254
 
254
255
  **Consumer layout (Next.js App Router):** block folders mirror `app/` page routes (`/`
255
256
  at the namespace root; no invented `landing/`/`root/`; sidebar = chrome + edges). See
256
- `create-waygraph/README.md` "Consumer layout" and mesh handout
257
+ [`docs/consumer.html`](./docs/consumer.html) and mesh handout
257
258
  `WAYGRAPH-CONSUMER-CONVENTION.md` - separate from this package API doc.
258
259
 
259
260
  Deliberately **not yet implemented** (tracked on the project board):
package/dist/cli.js CHANGED
@@ -3237,8 +3237,10 @@ function initCommand(projectName) {
3237
3237
  console.log(" waygraph check # nav hygiene + orphan Blocks");
3238
3238
  console.log(" waygraph auto # interactive explore (headed panel)");
3239
3239
  console.log(" waygraph auto --cli # same menus in the terminal");
3240
- console.log(" waygraph demo src/flows/example.flow.ts");
3240
+ console.log(" waygraph demo --blocks exampleFlow");
3241
3241
  console.log(" waygraph graph # static state graph JSON");
3242
+ console.log("");
3243
+ console.log(" Layout: see STRUCTURE.md (or https://deviate-dv8.github.io/waygraph/scaffold.html)");
3242
3244
  }
3243
3245
  async function checkCommand(projectDir) {
3244
3246
  const files = discoverBlocks(projectDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.12.5",
3
+ "version": "0.12.6",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",
@@ -0,0 +1,25 @@
1
+ # __PROJECT_NAME__
2
+
3
+ Offline waygraph scaffold (`data:` URL - no network for `npm test`).
4
+
5
+ ## Layout
6
+
7
+ See [STRUCTURE.md](./STRUCTURE.md). Package docs:
8
+ https://deviate-dv8.github.io/waygraph/scaffold.html
9
+
10
+ ## Commands
11
+
12
+ ```bash
13
+ npm install
14
+ npx playwright install chromium
15
+ npm test
16
+ npm run list
17
+ npm run check
18
+ npm run demo # headed step (manual Next)
19
+ npm run demo:auto-next
20
+ npm run auto
21
+ npm run auto:cli
22
+ ```
23
+
24
+ Point `package.json` `waygraph.baseUrl` at your real app when you leave the
25
+ `data:` demo. Keep route folders = app URLs (consumer layout).
@@ -0,0 +1,36 @@
1
+ # Offline scaffold layout (`waygraph init` / `create-waygraph`)
2
+
3
+ Shipped under `templates/scaffold/` in the **waygraph** package.
4
+ Same tree is what `npx waygraph init my-app` copies.
5
+
6
+ Docs (readable in the package site): [docs/scaffold.html](../../docs/scaffold.html)
7
+
8
+ ```text
9
+ .
10
+ ├── package.json # waygraph ^0.12.6, demo/run/auto scripts
11
+ ├── playwright.config.ts
12
+ ├── tsconfig.json
13
+ ├── STRUCTURE.md # this file
14
+ ├── README.md
15
+ ├── src/
16
+ │ ├── blocks/
17
+ │ │ ├── SITE-MAP.md # namespace map (consumer convention)
18
+ │ │ └── demo-web/ # synthetic site (data: URL) - mirrors app "/"
19
+ │ │ ├── NAV.md
20
+ │ │ ├── nav-home.block.ts
21
+ │ │ └── methods/
22
+ │ │ └── assert-hello.method.block.ts
23
+ │ ├── states/
24
+ │ │ └── demo.states.ts
25
+ │ └── flows/
26
+ │ └── example.flow.ts # withTitle + withHighlightFixtures
27
+ └── tests/
28
+ └── example.spec.ts
29
+ ```
30
+
31
+ **Rule of thumb:** route folders = app URL folders; `/` lives at the namespace
32
+ root (`demo-web/`). Methods hang under `methods/`. Chrome/shared UI would be
33
+ `shared/chrome/` (not invented for this offline hello).
34
+
35
+ Grow this into a real app by renaming `demo-web/` to your FE origin namespace
36
+ and adding one folder per `page.tsx` URL. See package docs **Consumer layout**.
@@ -10,15 +10,16 @@
10
10
  "check": "waygraph check",
11
11
  "auto": "waygraph auto",
12
12
  "auto:cli": "waygraph auto --cli",
13
- "demo": "waygraph demo src/flows/example.flow.ts",
14
- "run": "waygraph run src/flows/example.flow.ts",
13
+ "demo": "waygraph demo --blocks exampleFlow",
14
+ "demo:auto-next": "waygraph demo --blocks exampleFlow --auto-next --title \"Scaffold demo\"",
15
+ "run": "waygraph run --blocks exampleFlow",
15
16
  "graph": "waygraph graph"
16
17
  },
17
18
  "waygraph": {
18
- "baseUrl": "https://example.com"
19
+ "baseUrl": "about:blank"
19
20
  },
20
21
  "dependencies": {
21
- "waygraph": "^0.11.0"
22
+ "waygraph": "^0.12.6"
22
23
  },
23
24
  "devDependencies": {
24
25
  "@playwright/test": "^1.55.0",
@@ -0,0 +1,13 @@
1
+ # Site map (scaffold)
2
+
3
+ Offline hello uses one synthetic namespace (`demo-web/`) and a `data:` home URL
4
+ so `npm test` stays green without the network.
5
+
6
+ | Folder | URL | Notes |
7
+ |--------|-----|-------|
8
+ | `demo-web/` | `/` (synthetic) | Nav + methods for the hello page |
9
+ | `demo-web/methods/` | same URL | On-page asserts / future form acts |
10
+
11
+ When you wire a real app, rename `demo-web/` to your FE origin namespace and
12
+ add one folder per real `page.tsx` route. Grouping dirs without a page get no
13
+ `NAV.md`. Full contract: waygraph **Consumer layout** docs.
@@ -0,0 +1,20 @@
1
+ # demo-web / (synthetic home)
2
+
3
+ **URL:** `data:text/html,…` (offline hello - replace with your real `/`)
4
+
5
+ ## Nav-to
6
+
7
+ | From | Block | How |
8
+ |------|-------|-----|
9
+ | start | `nav-home` | `defineNavBlock` `url` → data HTML |
10
+
11
+ ## Methods
12
+
13
+ | Block | Kind | Notes |
14
+ |-------|------|-------|
15
+ | `assert-hello` | Method | Verify heading; demo stubs + fixtures |
16
+
17
+ ## States / mem-keys
18
+
19
+ - Checkpoint `Home` after nav
20
+ - Checkpoint `HomeVerified` after assert-hello
@@ -0,0 +1,51 @@
1
+ import { defineMethodBlock, checkpoint, Trait } from "waygraph";
2
+
3
+ /**
4
+ * Kind: Method
5
+ * Helper: defineMethodBlock
6
+ * Route: demo-web/methods/
7
+ *
8
+ * Same-URL assert after nav - shows stubBefore / stubAfter / stubOnError shape.
9
+ */
10
+ export const AssertHelloBlock = defineMethodBlock({
11
+ name: "assert-hello",
12
+ description: "Confirms the hello heading is still visible after arrival.",
13
+ instruction: {
14
+ async act(_page) {
15
+ // No DOM mutation - observe/verify own the proof.
16
+ },
17
+ async observe(page) {
18
+ await page.locator("h1").first().waitFor({ state: "visible", timeout: 5_000 });
19
+ return "ok" as const;
20
+ },
21
+ resolve: () => checkpoint("HomeVerified"),
22
+ verify: [Trait.text("h1", "Hello Waygraph"), Trait.visible("#sub")],
23
+ stubBefore: {
24
+ title: { selector: "h1", label: "Heading about to check" },
25
+ },
26
+ stubAfter: {
27
+ title: {
28
+ selector: "h1",
29
+ label: "Hello confirmed",
30
+ detail: "Offline scaffold proof point.",
31
+ duration: true,
32
+ },
33
+ sub: { selector: "#sub", label: "Subcopy", duration: 1500 },
34
+ },
35
+ stubOnError: {
36
+ title: {
37
+ selector: "h1",
38
+ label: "Heading at failure",
39
+ tag: "FAIL",
40
+ },
41
+ },
42
+ slides: [
43
+ {
44
+ caption: "Scaffold is route-shaped",
45
+ detail: "demo-web/ = synthetic /. Grow folders per real page.tsx.",
46
+ tag: "YAP",
47
+ duration: true,
48
+ },
49
+ ],
50
+ },
51
+ });
@@ -0,0 +1,25 @@
1
+ import { defineNavBlock, Trait } from "waygraph";
2
+
3
+ /** Offline hello page - swap `url` for a real app route when you graduate. */
4
+ export const HOME_URL =
5
+ 'data:text/html,<!doctype html><html><body><h1>Hello Waygraph</h1><p id="sub">Scaffold demo</p></body></html>';
6
+
7
+ /**
8
+ * Kind: Nav
9
+ * Helper: defineNavBlock
10
+ * Route: demo-web/ (synthetic "/")
11
+ */
12
+ export const NavHomeBlock = defineNavBlock({
13
+ name: "nav-home",
14
+ description: "Opens the offline hello page (data: URL).",
15
+ checkpoint: "Home",
16
+ url: HOME_URL,
17
+ verify: [Trait.text("h1", "Hello Waygraph")],
18
+ stubBefore: {},
19
+ stubAfter: {
20
+ title: { selector: "h1", label: "Home heading", duration: true },
21
+ },
22
+ stubOnError: {
23
+ title: { selector: "h1", label: "Home heading at failure" },
24
+ },
25
+ });
@@ -1,6 +1,28 @@
1
- import { Engine, start, end } from "waygraph";
2
- import { LoadPageBlock } from "../blocks/load-page.block.js";
1
+ import { Engine, start, end, withTitle, withHighlightFixtures } from "waygraph";
2
+ import { NavHomeBlock } from "../blocks/demo-web/nav-home.block.js";
3
+ import { AssertHelloBlock } from "../blocks/demo-web/methods/assert-hello.method.block.js";
3
4
 
4
5
  const engine = new Engine();
5
6
 
6
- export const exampleFlow = engine.defineFlow([start, LoadPageBlock, end]);
7
+ /**
8
+ * Offline example: nav to data: hello page, then assert heading.
9
+ * Flow fixtures override ticket-style copy on stubs (demo narration).
10
+ */
11
+ export const exampleFlow = withHighlightFixtures(
12
+ withTitle(
13
+ engine.defineFlow([start, NavHomeBlock, AssertHelloBlock, end]),
14
+ "Scaffold: Hello Waygraph",
15
+ ),
16
+ {
17
+ "assert-hello": {
18
+ stubAfter: {
19
+ title: {
20
+ label: "AC · Hello visible",
21
+ detail: "Replace this fixture copy with your ticket lines.",
22
+ tag: "AC",
23
+ duration: true,
24
+ },
25
+ },
26
+ },
27
+ },
28
+ );
@@ -0,0 +1,4 @@
1
+ import type { Checkpoint } from "waygraph";
2
+
3
+ export type Home = Checkpoint<"Home">;
4
+ export type HomeVerified = Checkpoint<"HomeVerified">;
@@ -2,7 +2,7 @@ import { test, expect } from "@playwright/test";
2
2
  import { MemPage, checkpoint } from "waygraph";
3
3
  import { exampleFlow } from "../src/flows/example.flow.js";
4
4
 
5
- test("example flow reaches Loaded", async ({ context }) => {
5
+ test("example flow reaches HomeVerified", async ({ context }) => {
6
6
  const result = await exampleFlow.run(context, new MemPage());
7
- expect(result).toEqual(checkpoint("Loaded"));
7
+ expect(result).toEqual(checkpoint("HomeVerified"));
8
8
  });
@@ -1,18 +0,0 @@
1
- import { defineBlock, checkpoint, Trait } from "waygraph";
2
- import type { Checkpoint } from "waygraph";
3
-
4
- export type Start = Checkpoint<"__start__">;
5
- export type Loaded = Checkpoint<"Loaded">;
6
-
7
- const PAGE_URL = "data:text/html,<h1>Hello Waygraph</h1>";
8
-
9
- export const LoadPageBlock = defineBlock<Start, Loaded>({
10
- name: "load-page",
11
- instruction: {
12
- async act(page) {
13
- await page.goto(PAGE_URL);
14
- },
15
- resolve: () => checkpoint("Loaded"),
16
- verify: [Trait.text("h1", "Hello Waygraph")],
17
- },
18
- });