waygraph 0.14.0 → 0.15.1
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 +171 -21
- package/dist/cli.js +101 -5
- package/dist/engine.d.ts +161 -0
- package/dist/engine.js +230 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/map-check.d.ts +18 -0
- package/dist/map-check.js +140 -0
- package/dist/types.d.ts +21 -1
- package/dist/types.js +17 -1
- package/examples/routed-demo/.waygraph-auto/4d4902b7.log +0 -0
- package/examples/routed-demo/.waygraph-auto/51ef462e.log +0 -0
- package/examples/routed-demo/.waygraph-auto/71527ad9.log +0 -0
- package/examples/routed-demo/.waygraph-auto/ca16778e.log +0 -0
- package/examples/routed-demo/src/flows/routed-demo-map.flow.ts +39 -0
- package/examples/routed-demo/src/flows/routed-demo.flow.ts +5 -5
- package/examples/routed-demo/src/{routes/(base_app)/dashboard/methods → map/(app_base)/dashboard/_methods}/click-widget.block.ts +2 -2
- package/examples/routed-demo/src/{routes/(base_app)/dashboard/nav.block.ts → map/(app_base)/dashboard/_nav.block.ts} +2 -2
- package/examples/routed-demo/src/{routes/(base_app)/dashboard/page.block.ts → map/(app_base)/dashboard/_page.block.ts} +4 -4
- package/examples/routed-demo/src/{routes/(external)/docs/nav.block.ts → map/(external)/docs/_nav.block.ts} +2 -2
- package/examples/routed-demo/src/{routes/(external)/docs/page.block.ts → map/(external)/docs/_page.block.ts} +1 -1
- package/examples/routed-demo/test-results/.last-run.json +4 -0
- package/examples/routed-demo/tests/routed-demo-map.spec.ts +17 -0
- package/examples/saucedemo/.waygraph-auto/00d5336e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/083cc5b9.log +0 -0
- package/examples/saucedemo/.waygraph-auto/104751ef.log +0 -0
- package/examples/saucedemo/.waygraph-auto/175655f7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/2219f00b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/23e62571.log +0 -0
- package/examples/saucedemo/.waygraph-auto/42cc9113.log +0 -0
- package/examples/saucedemo/.waygraph-auto/439d30aa.log +0 -0
- package/examples/saucedemo/.waygraph-auto/4a85f496.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5c0eef7f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5d60da77.log +0 -0
- package/examples/saucedemo/.waygraph-auto/5fc3a33b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/61b6546d.log +0 -0
- package/examples/saucedemo/.waygraph-auto/650ed066.log +0 -0
- package/examples/saucedemo/.waygraph-auto/6d9aaad3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/78b21219.log +0 -0
- package/examples/saucedemo/.waygraph-auto/84d6d293.log +0 -0
- package/examples/saucedemo/.waygraph-auto/8a3eb088.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a2dd30dd.log +0 -0
- package/examples/saucedemo/.waygraph-auto/a87bb3ee.log +0 -0
- package/examples/saucedemo/.waygraph-auto/b81e074f.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ba58abb7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/bb9fd384.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c02ea583.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c2caf0a8.log +0 -0
- package/examples/saucedemo/.waygraph-auto/c3bdc714.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cd68bbc4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/cdc6db50.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d01906a7.log +0 -0
- package/examples/saucedemo/.waygraph-auto/d9e5f8a4.log +0 -0
- package/examples/saucedemo/.waygraph-auto/dec3076e.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e1973991.log +0 -0
- package/examples/saucedemo/.waygraph-auto/e8306a4b.log +0 -0
- package/examples/saucedemo/.waygraph-auto/ec88b3ef.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f34c9a26.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f5525d53.log +0 -0
- package/examples/saucedemo/.waygraph-auto/f90035b3.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fa687bc2.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fb66fba0.log +0 -0
- package/examples/saucedemo/.waygraph-auto/fc48fd76.log +0 -0
- package/package.json +1 -1
- package/templates/scaffold/scripts/fixture-server.mjs +11 -2
- package/templates/scaffold/src/flows/example.flow.ts +8 -6
- package/templates/scaffold/src/flows/mail-verify.flow.ts +8 -8
- package/templates/scaffold/src/flows/shop.flow.ts +6 -6
- package/templates/scaffold/src/{routes/(external)/docs/nav.block.ts → map/(app_base)/docs/_nav.block.ts} +5 -6
- package/templates/scaffold/src/{routes/(external)/docs/page.block.ts → map/(app_base)/docs/_page.block.ts} +2 -2
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/add-item.effect.block.ts +3 -3
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/assert-hello.method.block.ts +1 -1
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/assert-item-added.method.block.ts +3 -3
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/clear-cart.method.block.ts +9 -3
- package/templates/scaffold/src/{blocks/demo-web/methods → map/(app_base)/home/_methods}/remove-item.effect.block.ts +3 -3
- package/templates/scaffold/src/{blocks/demo-web/nav-home.block.ts → map/(app_base)/home/_nav.block.ts} +2 -2
- package/templates/scaffold/src/{blocks/demo-web/home.page.block.ts → map/(app_base)/home/_page.block.ts} +7 -7
- package/templates/scaffold/src/{blocks/demo-web → map/(app_base)/home}/nav-verification-link.block.ts +4 -4
- package/templates/scaffold/src/{blocks/demo-external/mailpit/methods → map/(external)/mailpit/_methods}/assert-email-content.method.block.ts +2 -2
- package/templates/scaffold/src/{blocks/demo-external/mailpit/methods → map/(external)/mailpit/_methods}/assert-email-received.method.block.ts +2 -2
- package/templates/scaffold/src/{blocks/demo-external/mailpit/methods → map/(external)/mailpit/_methods}/extract-email-link.method.block.ts +2 -2
- package/templates/scaffold/src/{blocks/demo-external/mailpit/methods → map/(external)/mailpit/_methods}/open-message.method.block.ts +2 -2
- package/templates/scaffold/src/{blocks/demo-external/mailpit/nav-mailpit-inbox.block.ts → map/(external)/mailpit/_nav.block.ts} +2 -2
- package/templates/scaffold/src/{blocks/demo-external/mailpit/mailpit-inbox.page.block.ts → map/(external)/mailpit/_page.block.ts} +5 -5
- package/templates/scaffold/src/states/demo.states.ts +2 -4
- package/templates/scaffold/tests/example.spec.ts +2 -2
- package/templates/scaffold/tests/mail-verify.spec.ts +1 -1
- package/templates/scaffold/src/blocks/SITE-MAP.md +0 -12
- package/templates/scaffold/src/blocks/demo-web/NAV.md +0 -29
- package/templates/scaffold/src/flows/routes-demo.flow.ts +0 -14
- /package/examples/routed-demo/src/{routes/(base_app)/dashboard/dashboard.sel.ts → map/(app_base)/dashboard/_sel.ts} +0 -0
- /package/examples/routed-demo/src/{routes/(external)/docs/docs.sel.ts → map/(external)/docs/_sel.ts} +0 -0
- /package/templates/scaffold/src/{routes/(external)/docs/docs.sel.ts → map/(app_base)/docs/_sel.ts} +0 -0
- /package/templates/scaffold/src/{blocks/demo-web → map/(app_base)/docs}/docs.html +0 -0
- /package/templates/scaffold/src/{blocks/demo-web/demo-sel.ts → map/(app_base)/home/_sel.ts} +0 -0
- /package/templates/scaffold/src/{blocks/demo-web → map/(app_base)/home}/home.html +0 -0
- /package/templates/scaffold/src/{blocks/demo-external/mailpit/mailpit-sel.ts → map/(external)/mailpit/_sel.ts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineNavBlock, Trait } from "waygraph";
|
|
2
2
|
import type { Docs } from "../../../states/routed-demo.states.js";
|
|
3
|
-
import { DocsSel, DOCS_URL } from "./
|
|
3
|
+
import { DocsSel, DOCS_URL } from "./_sel.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Kind: Nav
|
|
@@ -8,7 +8,7 @@ import { DocsSel, DOCS_URL } from "./docs.sel.js";
|
|
|
8
8
|
*
|
|
9
9
|
* `(external)` is a purely organizational group folder (Next.js route-group
|
|
10
10
|
* style, parens never affect the Checkpoint tag) - separates cross-origin/
|
|
11
|
-
* external tooling from the app's own `(
|
|
11
|
+
* external tooling from the app's own `(app_base)` pages, matching the
|
|
12
12
|
* already-established `*-external/` namespacing precedent from
|
|
13
13
|
* waygraph-mail-adapters.
|
|
14
14
|
*/
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { test, expect } from "@playwright/test";
|
|
2
|
+
import { MemPage, checkpoint } from "waygraph";
|
|
3
|
+
import { routedDemoMapFlow } from "../src/flows/routed-demo-map.flow.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Proof that `engine.map()` (the fluent, kind-checked flow builder) works
|
|
7
|
+
* end to end against a real browser/DOM, not just the in-memory fakes
|
|
8
|
+
* tests/nav/map-builder.spec.ts already covers in the main waygraph
|
|
9
|
+
* package - same real fixture server and real Blocks routed-demo.spec.ts
|
|
10
|
+
* already proves work via defineFlow/the CLI, this time built with
|
|
11
|
+
* .start().gotoPage(...).method(...).gotoPage(...).end() instead.
|
|
12
|
+
*/
|
|
13
|
+
test("engine.map()-built flow runs for real: Dashboard -> click widget -> Docs", async ({ context }) => {
|
|
14
|
+
const mem = new MemPage();
|
|
15
|
+
const result = await routedDemoMapFlow.run(context, mem);
|
|
16
|
+
expect(result).toEqual(checkpoint("Docs"));
|
|
17
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -8,7 +8,15 @@ import { readFileSync, existsSync } from "node:fs";
|
|
|
8
8
|
import { join, dirname, extname, normalize } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
10
|
|
|
11
|
-
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "../src/
|
|
11
|
+
const ROOT = join(dirname(fileURLToPath(import.meta.url)), "../src/map/(app_base)");
|
|
12
|
+
// Each fixture HTML file lives beside its own _page.block.ts under the
|
|
13
|
+
// Waygraph Map convention now (home/home.html, docs/docs.html) - no longer
|
|
14
|
+
// a single flat directory, so this maps the request filename to its own
|
|
15
|
+
// page's subfolder instead of assuming one shared ROOT holds every file.
|
|
16
|
+
const FILE_DIRS = {
|
|
17
|
+
"home.html": "home",
|
|
18
|
+
"docs.html": "docs",
|
|
19
|
+
};
|
|
12
20
|
const PORT = Number(process.env.WAYGRAPH_FIXTURE_PORT || 4177);
|
|
13
21
|
const HOST = process.env.WAYGRAPH_FIXTURE_HOST || "127.0.0.1";
|
|
14
22
|
|
|
@@ -23,7 +31,8 @@ const TYPES = {
|
|
|
23
31
|
const server = createServer((req, res) => {
|
|
24
32
|
const raw = (req.url || "/").split("?")[0] || "/";
|
|
25
33
|
const rel = raw === "/" ? "home.html" : raw.replace(/^\//, "");
|
|
26
|
-
const
|
|
34
|
+
const subdir = FILE_DIRS[rel];
|
|
35
|
+
const full = subdir ? normalize(join(ROOT, subdir, rel)) : normalize(join(ROOT, rel));
|
|
27
36
|
if (!full.startsWith(ROOT) || !existsSync(full)) {
|
|
28
37
|
res.writeHead(404, { "content-type": "text/plain" });
|
|
29
38
|
res.end("not found");
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { Engine, start, end, withTitle, withHighlightFixtures } from "waygraph";
|
|
2
|
-
import { NavHomeBlock } from "../
|
|
3
|
-
import { AssertHelloBlock } from "../
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import { NavHomeBlock } from "../map/(app_base)/home/_nav.block.js";
|
|
3
|
+
import { AssertHelloBlock } from "../map/(app_base)/home/_methods/assert-hello.method.block.js";
|
|
4
|
+
import { NavDocsBlock } from "../map/(app_base)/docs/_nav.block.js";
|
|
5
|
+
// Page hubs registered for auto/docs grouping (arrival-only after nav).
|
|
6
|
+
import "../map/(app_base)/home/_page.block.js";
|
|
7
|
+
import "../map/(app_base)/docs/_page.block.js";
|
|
6
8
|
|
|
7
9
|
const engine = new Engine();
|
|
8
10
|
|
|
9
|
-
/** Smoke: nav + assert (no mem). Green offline. */
|
|
11
|
+
/** Smoke: nav + assert (no mem), then nav to the sibling docs/ page. Green offline. */
|
|
10
12
|
export const exampleFlow = withHighlightFixtures(
|
|
11
13
|
withTitle(
|
|
12
|
-
engine.defineFlow([start, NavHomeBlock, AssertHelloBlock, end]),
|
|
14
|
+
engine.defineFlow([start, NavHomeBlock, AssertHelloBlock, NavDocsBlock, end]),
|
|
13
15
|
"Scaffold: Hello Waygraph",
|
|
14
16
|
),
|
|
15
17
|
{
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Engine, start, end, withTitle, withHighlightFixtures } from "waygraph";
|
|
2
|
-
import { NavMailpitInboxBlock } from "../
|
|
3
|
-
import { AssertEmailReceivedBlock } from "../
|
|
4
|
-
import { OpenMessageBlock } from "../
|
|
5
|
-
import { AssertEmailContentBlock } from "../
|
|
6
|
-
import { ExtractEmailLinkBlock } from "../
|
|
7
|
-
import { NavVerificationLinkBlock } from "../
|
|
8
|
-
import "../
|
|
9
|
-
import { MailpitSel } from "../
|
|
2
|
+
import { NavMailpitInboxBlock } from "../map/(external)/mailpit/_nav.block.js";
|
|
3
|
+
import { AssertEmailReceivedBlock } from "../map/(external)/mailpit/_methods/assert-email-received.method.block.js";
|
|
4
|
+
import { OpenMessageBlock } from "../map/(external)/mailpit/_methods/open-message.method.block.js";
|
|
5
|
+
import { AssertEmailContentBlock } from "../map/(external)/mailpit/_methods/assert-email-content.method.block.js";
|
|
6
|
+
import { ExtractEmailLinkBlock } from "../map/(external)/mailpit/_methods/extract-email-link.method.block.js";
|
|
7
|
+
import { NavVerificationLinkBlock } from "../map/(app_base)/home/nav-verification-link.block.js";
|
|
8
|
+
import "../map/(external)/mailpit/_page.block.js";
|
|
9
|
+
import { MailpitSel } from "../map/(external)/mailpit/_sel.js";
|
|
10
10
|
|
|
11
11
|
const engine = new Engine();
|
|
12
12
|
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
withHighlightFixtures,
|
|
7
7
|
withSessionReset,
|
|
8
8
|
} from "waygraph";
|
|
9
|
-
import { NavHomeBlock } from "../
|
|
10
|
-
import { AddItemBlock } from "../
|
|
11
|
-
import { AssertItemAddedBlock } from "../
|
|
12
|
-
import { RemoveItemBlock } from "../
|
|
13
|
-
import { ClearCartBlock } from "../
|
|
14
|
-
import "../
|
|
9
|
+
import { NavHomeBlock } from "../map/(app_base)/home/_nav.block.js";
|
|
10
|
+
import { AddItemBlock } from "../map/(app_base)/home/_methods/add-item.effect.block.js";
|
|
11
|
+
import { AssertItemAddedBlock } from "../map/(app_base)/home/_methods/assert-item-added.method.block.js";
|
|
12
|
+
import { RemoveItemBlock } from "../map/(app_base)/home/_methods/remove-item.effect.block.js";
|
|
13
|
+
import { ClearCartBlock } from "../map/(app_base)/home/_methods/clear-cart.method.block.js";
|
|
14
|
+
import "../map/(app_base)/home/_page.block.js";
|
|
15
15
|
|
|
16
16
|
const engine = new Engine();
|
|
17
17
|
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { defineNavBlock, Trait } from "waygraph";
|
|
2
2
|
import type { Docs } from "../../../states/demo.states.js";
|
|
3
|
-
import { DocsSel, DOCS_URL } from "./
|
|
3
|
+
import { DocsSel, DOCS_URL } from "./_sel.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Kind: Nav
|
|
7
|
-
* Route: (
|
|
7
|
+
* Route: (app_base)/docs/
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* openspec/changes/waygraph-map. `(external)` is purely organizational
|
|
9
|
+
* Same origin as home/ (same fixture server, different HTML file) - lives
|
|
10
|
+
* under (app_base), not (external). See README.md "Waygraph Map" and
|
|
11
|
+
* openspec/changes/waygraph-map. `(app_base)` is purely organizational
|
|
13
12
|
* (Next.js route-group style) - never part of the Checkpoint tag.
|
|
14
13
|
*/
|
|
15
14
|
export const NavDocsBlock = defineNavBlock<Docs>({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { definePageBlock, Trait } from "waygraph";
|
|
2
2
|
import type { Docs } from "../../../states/demo.states.js";
|
|
3
|
-
import { DocsSel } from "./
|
|
3
|
+
import { DocsSel } from "./_sel.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Kind: Page
|
|
7
|
-
* Route: (
|
|
7
|
+
* Route: (app_base)/docs/
|
|
8
8
|
* Arrival-only (nav.block.ts already landed on Docs).
|
|
9
9
|
*/
|
|
10
10
|
export const DocsPageBlock = definePageBlock<Docs>({
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
type Checkpoint,
|
|
5
5
|
type WaygraphInstanceOption,
|
|
6
6
|
} from "waygraph";
|
|
7
|
-
import type { ItemInCart } from "
|
|
8
|
-
import { SelectedItem } from "
|
|
9
|
-
import { DemoSel } from "../
|
|
7
|
+
import type { ItemInCart } from "../../../../states/demo.states.js";
|
|
8
|
+
import { SelectedItem } from "../../../../states/demo.mem-keys.js";
|
|
9
|
+
import { DemoSel } from "../_sel.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Kind: Effect
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineAssertBlock, Trait, type Trait as TraitType } from "waygraph";
|
|
2
|
-
import type { ItemInCart } from "
|
|
3
|
-
import { SelectedItem } from "
|
|
4
|
-
import { DemoSel } from "../
|
|
2
|
+
import type { ItemInCart } from "../../../../states/demo.states.js";
|
|
3
|
+
import { SelectedItem } from "../../../../states/demo.mem-keys.js";
|
|
4
|
+
import { DemoSel } from "../_sel.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Mem-aware Trait: which item's Remove button should be visible depends on
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { defineMethodBlock, checkpoint, Trait } from "waygraph";
|
|
2
|
-
import {
|
|
2
|
+
import type { ItemInCart, CartEmpty } from "../../../../states/demo.states.js";
|
|
3
|
+
import { DemoSel } from "../_sel.js";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Kind: Method
|
|
6
7
|
* Helper: defineMethodBlock
|
|
7
|
-
* Route:
|
|
8
|
+
* Route: (app_base)/home/_methods/
|
|
9
|
+
*
|
|
10
|
+
* Real, pre-existing bug found live while verifying the Waygraph Map
|
|
11
|
+
* rename: this Block had no explicit <In, Out> generic at all, so static
|
|
12
|
+
* discovery (`waygraph graph`) always skipped it silently ("no ...generic
|
|
13
|
+
* call found") - present before this move, not caused by it.
|
|
8
14
|
*/
|
|
9
|
-
export const ClearCartBlock = defineMethodBlock({
|
|
15
|
+
export const ClearCartBlock = defineMethodBlock<ItemInCart, CartEmpty>({
|
|
10
16
|
name: "clear-cart",
|
|
11
17
|
description: "Clears every item via the Clear cart control.",
|
|
12
18
|
instruction: {
|
|
@@ -4,9 +4,9 @@ import {
|
|
|
4
4
|
type Checkpoint,
|
|
5
5
|
type WaygraphInstanceOption,
|
|
6
6
|
} from "waygraph";
|
|
7
|
-
import type { CartEmpty } from "
|
|
8
|
-
import { SelectedItem } from "
|
|
9
|
-
import { DemoSel } from "../
|
|
7
|
+
import type { CartEmpty } from "../../../../states/demo.states.js";
|
|
8
|
+
import { SelectedItem } from "../../../../states/demo.mem-keys.js";
|
|
9
|
+
import { DemoSel } from "../_sel.js";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Kind: Effect
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { defineNavBlock, Trait } from "waygraph";
|
|
2
|
-
import { DemoSel, HOME_URL } from "./
|
|
2
|
+
import { DemoSel, HOME_URL } from "./_sel.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Kind: Nav
|
|
6
6
|
* Helper: defineNavBlock
|
|
7
|
-
* Route:
|
|
7
|
+
* Route: (app_base)/home/ (synthetic "/")
|
|
8
8
|
*/
|
|
9
9
|
export const NavHomeBlock = defineNavBlock({
|
|
10
10
|
name: "nav-home",
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { definePageBlock, Trait } from "waygraph";
|
|
2
|
-
import type { Home } from "
|
|
3
|
-
import { DemoSel } from "./
|
|
4
|
-
import { AddItemBlock } from "./
|
|
5
|
-
import { RemoveItemBlock } from "./
|
|
6
|
-
import { ClearCartBlock } from "./
|
|
7
|
-
import { AssertHelloBlock } from "./
|
|
2
|
+
import type { Home } from "../../../states/demo.states.js";
|
|
3
|
+
import { DemoSel } from "./_sel.js";
|
|
4
|
+
import { AddItemBlock } from "./_methods/add-item.effect.block.js";
|
|
5
|
+
import { RemoveItemBlock } from "./_methods/remove-item.effect.block.js";
|
|
6
|
+
import { ClearCartBlock } from "./_methods/clear-cart.method.block.js";
|
|
7
|
+
import { AssertHelloBlock } from "./_methods/assert-hello.method.block.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Kind: Page
|
|
11
11
|
* Helper: definePageBlock
|
|
12
|
-
* Route:
|
|
12
|
+
* Route: (app_base)/home/
|
|
13
13
|
*
|
|
14
14
|
* Hub for the offline home screen. Methods hang here for docs/auto grouping;
|
|
15
15
|
* edges in flows still reference the method Blocks directly.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { defineNavBlock, Trait } from "waygraph";
|
|
2
|
-
import type { HomeVerified } from "
|
|
3
|
-
import { EmailLink } from "
|
|
4
|
-
import { DemoSel } from "./
|
|
2
|
+
import type { HomeVerified } from "../../../states/demo.states.js";
|
|
3
|
+
import { EmailLink } from "../../../states/demo.mem-keys.js";
|
|
4
|
+
import { DemoSel } from "./_sel.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Kind: Nav
|
|
8
8
|
* Helper: defineNavBlock
|
|
9
|
-
* Route:
|
|
9
|
+
* Route: (app_base)/home/
|
|
10
10
|
*
|
|
11
11
|
* Navigates back into the app to the link extract-email-link read out of
|
|
12
12
|
* the real Mailpit message, then confirms the page actually reflects it
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineAssertBlock, type Trait } from "waygraph";
|
|
2
2
|
import type { MailpitMessageOpen } from "../../../../states/demo.states.js";
|
|
3
3
|
import { ExpectedEmailContent } from "../../../../states/demo.mem-keys.js";
|
|
4
|
-
import { MailpitSel } from "../
|
|
4
|
+
import { MailpitSel } from "../_sel.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Mem-aware Trait: the expected copy varies per email scenario, so it can't
|
|
@@ -22,7 +22,7 @@ const bodyContainsExpectedText: Trait = {
|
|
|
22
22
|
/**
|
|
23
23
|
* Kind: Assert
|
|
24
24
|
* Helper: defineAssertBlock
|
|
25
|
-
* Route: demo-external/mailpit/
|
|
25
|
+
* Route: demo-external/mailpit/_methods/
|
|
26
26
|
*
|
|
27
27
|
* "Does the email actually say what it's supposed to" - not just "does a
|
|
28
28
|
* link exist somewhere in it." Reads the message body straight out of the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineAssertBlock, type Trait } from "waygraph";
|
|
2
2
|
import type { MailpitInbox } from "../../../../states/demo.states.js";
|
|
3
3
|
import { ExpectedRecipient } from "../../../../states/demo.mem-keys.js";
|
|
4
|
-
import { MailpitSel } from "../
|
|
4
|
+
import { MailpitSel } from "../_sel.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Mem-aware Trait: the selector depends on which recipient this run expects,
|
|
@@ -28,7 +28,7 @@ const emailReceived: Trait = {
|
|
|
28
28
|
/**
|
|
29
29
|
* Kind: Assert
|
|
30
30
|
* Helper: defineAssertBlock
|
|
31
|
-
* Route: demo-external/mailpit/
|
|
31
|
+
* Route: demo-external/mailpit/_methods/
|
|
32
32
|
*
|
|
33
33
|
* "Did the email even arrive" - a lightweight existence check that does not
|
|
34
34
|
* open or consume the message, so it's safe to run before deciding to open
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { defineMethodBlock, checkpoint } from "waygraph";
|
|
2
2
|
import type { MailpitMessageOpen } from "../../../../states/demo.states.js";
|
|
3
3
|
import { EmailLink, ExpectedLinkPattern } from "../../../../states/demo.mem-keys.js";
|
|
4
|
-
import { MailpitSel } from "../
|
|
4
|
+
import { MailpitSel } from "../_sel.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Kind: Method
|
|
8
8
|
* Helper: defineMethodBlock
|
|
9
|
-
* Route: demo-external/mailpit/
|
|
9
|
+
* Route: demo-external/mailpit/_methods/
|
|
10
10
|
*
|
|
11
11
|
* Reads a link straight out of the open message's HTML preview iframe via a
|
|
12
12
|
* real DOM read (getAttribute) - no mail-catcher REST API - and stores it in
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { defineMethodBlock, checkpoint } from "waygraph";
|
|
2
2
|
import type { MailpitInbox, MailpitMessageOpen } from "../../../../states/demo.states.js";
|
|
3
3
|
import { ExpectedRecipient } from "../../../../states/demo.mem-keys.js";
|
|
4
|
-
import { MailpitSel } from "../
|
|
4
|
+
import { MailpitSel } from "../_sel.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Kind: Method
|
|
8
8
|
* Helper: defineMethodBlock
|
|
9
|
-
* Route: demo-external/mailpit/
|
|
9
|
+
* Route: demo-external/mailpit/_methods/
|
|
10
10
|
*
|
|
11
11
|
* Opens the newest inbox row addressed to the mem-set recipient (not bare
|
|
12
12
|
* inbox position - a prior run's leftover mail for a different recipient
|
|
@@ -4,9 +4,9 @@ import type { MailpitInbox } from "../../../states/demo.states.js";
|
|
|
4
4
|
/**
|
|
5
5
|
* Kind: Nav
|
|
6
6
|
* Helper: defineNavBlock
|
|
7
|
-
* Route:
|
|
7
|
+
* Route: (external)/mailpit/ (cross-origin - a real Mailpit web UI, not this app)
|
|
8
8
|
*
|
|
9
|
-
* Cross-origin tooling lives under
|
|
9
|
+
* Cross-origin tooling lives under (external)/, never (app_base)/ - this is
|
|
10
10
|
* a dev-inbox screen, not part of the app under test. `WAYGRAPH_MAIL_URL`
|
|
11
11
|
* defaults to Mailpit's own usual local port.
|
|
12
12
|
*/
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { definePageBlock, Trait } from "waygraph";
|
|
2
2
|
import type { MailpitInbox } from "../../../states/demo.states.js";
|
|
3
|
-
import { AssertEmailReceivedBlock } from "./
|
|
4
|
-
import { OpenMessageBlock } from "./
|
|
5
|
-
import { AssertEmailContentBlock } from "./
|
|
6
|
-
import { ExtractEmailLinkBlock } from "./
|
|
3
|
+
import { AssertEmailReceivedBlock } from "./_methods/assert-email-received.method.block.js";
|
|
4
|
+
import { OpenMessageBlock } from "./_methods/open-message.method.block.js";
|
|
5
|
+
import { AssertEmailContentBlock } from "./_methods/assert-email-content.method.block.js";
|
|
6
|
+
import { ExtractEmailLinkBlock } from "./_methods/extract-email-link.method.block.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Kind: Page
|
|
10
10
|
* Helper: definePageBlock
|
|
11
|
-
* Route:
|
|
11
|
+
* Route: (external)/mailpit/ (= http://127.0.0.1:8025/ by default)
|
|
12
12
|
*
|
|
13
13
|
* Hub for the Mailpit dev-inbox screen. Arrival-only (no url/click) -
|
|
14
14
|
* nav-mailpit-inbox owns the goto. Methods: confirm the email arrived, open
|
|
@@ -5,7 +5,7 @@ export type HomeVerified = Checkpoint<"HomeVerified">;
|
|
|
5
5
|
export type ItemInCart = Checkpoint<"ItemInCart">;
|
|
6
6
|
export type CartEmpty = Checkpoint<"CartEmpty">;
|
|
7
7
|
|
|
8
|
-
// --- Mailpit (external tool surface,
|
|
8
|
+
// --- Mailpit (external tool surface, src/map/(external)/mailpit/) ---
|
|
9
9
|
|
|
10
10
|
/** Mailpit inbox UI reached; message list visible. */
|
|
11
11
|
export type MailpitInbox = Checkpoint<"MailpitInbox">;
|
|
@@ -13,7 +13,5 @@ export type MailpitInbox = Checkpoint<"MailpitInbox">;
|
|
|
13
13
|
/** The message addressed to the expected recipient is open; preview iframe visible. */
|
|
14
14
|
export type MailpitMessageOpen = Checkpoint<"MailpitMessageOpen">;
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
/** Reached via src/routes/(external)/docs/ - see openspec/changes/waygraph-map. */
|
|
16
|
+
/** Reached via src/map/(app_base)/docs/ - see openspec/changes/waygraph-map. */
|
|
19
17
|
export type Docs = Checkpoint<"Docs">;
|
|
@@ -4,9 +4,9 @@ import { exampleFlow } from "../src/flows/example.flow.js";
|
|
|
4
4
|
import { shopFlow } from "../src/flows/shop.flow.js";
|
|
5
5
|
import { SelectedItem } from "../src/states/demo.mem-keys.js";
|
|
6
6
|
|
|
7
|
-
test("example flow reaches
|
|
7
|
+
test("example flow reaches Docs (home -> assert -> sibling docs/ page)", async ({ context }) => {
|
|
8
8
|
const result = await exampleFlow.run(context, new MemPage());
|
|
9
|
-
expect(result).toEqual(checkpoint("
|
|
9
|
+
expect(result).toEqual(checkpoint("Docs"));
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
test("shop flow adds then clears (Effect + Method)", async ({ context }) => {
|
|
@@ -4,7 +4,7 @@ import net from "node:net";
|
|
|
4
4
|
import { MemPage, checkpoint } from "waygraph";
|
|
5
5
|
import { mailVerifyFlow } from "../src/flows/mail-verify.flow.js";
|
|
6
6
|
import { ExpectedRecipient, ExpectedLinkPattern, ExpectedEmailContent } from "../src/states/demo.mem-keys.js";
|
|
7
|
-
import { HOME_URL } from "../src/
|
|
7
|
+
import { HOME_URL } from "../src/map/(app_base)/home/_sel.js";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* This scaffold has no real backend, so these tests play the role of "the
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
# Site map (scaffold)
|
|
2
|
-
|
|
3
|
-
Offline catalog uses one synthetic namespace (`demo-web/`) and a local
|
|
4
|
-
`home.html` fixture so `npm test` / `waygraph auto` need no network.
|
|
5
|
-
|
|
6
|
-
| Folder | URL | Notes |
|
|
7
|
-
|--------|-----|-------|
|
|
8
|
-
| `demo-web/` | `/` (synthetic) | Nav + Page hub + methods/effects |
|
|
9
|
-
| `demo-web/methods/` | same URL | assert, add/remove Effects, clear |
|
|
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. See **Consumer layout** docs.
|