Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions packages/web/src/AppFragment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,28 @@ export default function AppFragment() {
return () => window.removeEventListener('hashchange', onHash)
}, [])

// First-visit autoload: if the user lands on the Pages site without
// any hash, route them to the first example so the canvas isn't
// empty. We use `replace` (not assign) so the empty URL doesn't
// clutter back/forward history. EXAMPLE_FLOWS[0] is what the user
// sees; reorder there if you want a different default.
//
// Edge cases handled:
// - A lone `#` with nothing after counts as empty (browsers report
// it as `'#'`, not `''`).
// - Preserve `?query=…` in the rewritten URL so any params the
// user pasted alongside the URL aren't silently dropped.
useEffect(() => {
const currentHash = window.location.hash
if (currentHash && currentHash !== '#') return
const first = EXAMPLE_FLOWS[0]
if (!first) return
const fragment = encodeFragment(first.yaml)
const { pathname, search } = window.location
history.replaceState(null, '', `${pathname}${search}#${fragment}`)
setHash(fragment)
}, [])

// Decode → parse. Both layers' failures collapse into `decodeError` for
// the user-visible banner; the typed flow is `null` in the error case.
const { decodedFlow, decodeError } = useMemo<{
Expand Down
41 changes: 30 additions & 11 deletions packages/web/src/lib/example-flows.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
/**
* Curated example flows shown on the empty state of the Pages deploy.
* Curated example flows shown in the sidebar of the Pages deploy.
*
* Each entry is the same YAML that lives in `examples/*.yaml` at the
* repo root, imported as a raw string via Vite's `?raw` query so the
* source-of-truth stays in one place. Vite inlines these into the
* bundle — together they're ~6 KB which is comfortable to ship.
* Each entry's YAML is the same file in `examples/*.yaml` at the repo
* root, imported as a raw string via Vite's `?raw` query so the source
* of truth stays in one place. Vite inlines them into the bundle.
*
* The `path` is overridden to `examples` for every entry so the sidebar
* tree groups all examples under a single `examples/` folder, even
* though the YAMLs' own `meta.path` values diverge (some use
* `e-commerce/orders`, `demos`, etc).
*/

import authFlow from '../../../../examples/auth-flow.yaml?raw'
import orderFlow from '../../../../examples/order-flow.yaml?raw'
import selfLoops from '../../../../examples/self-loops.yaml?raw'
import simpleCrud from '../../../../examples/simple-crud.yaml?raw'
import typeVariants from '../../../../examples/type-variants.yaml?raw'

export interface ExampleFlow {
id: string
Expand All @@ -19,29 +25,42 @@ export interface ExampleFlow {
yaml: string
}

// Path field is what the Sidebar component groups into folders. Each
// example's path mirrors the meta.path in its YAML so a Pages visitor
// sees the same directory tree the local app would display.
const EXAMPLES_ROOT = 'examples'

export const EXAMPLE_FLOWS: ExampleFlow[] = [
{
id: 'simple-crud',
title: 'Simple CRUD',
description: 'Basic REST API CRUD — the smallest useful flow.',
path: 'examples/crud',
path: EXAMPLES_ROOT,
yaml: simpleCrud,
},
{
id: 'auth-flow',
title: 'OAuth2 Login',
description: 'Browser → app → Google OAuth → DB + cache.',
path: 'examples/auth',
path: EXAMPLES_ROOT,
yaml: authFlow,
},
{
id: 'order-flow',
title: 'Order Processing',
description: 'Multi-service order pipeline with payment, audit, and retry.',
path: 'e-commerce/orders',
path: EXAMPLES_ROOT,
yaml: orderFlow,
},
{
id: 'self-loops',
title: 'Self-loops',
description: 'Steps where from = to (retries, recursion), plus broadcasts and multi-data.',
path: EXAMPLES_ROOT,
yaml: selfLoops,
},
{
id: 'type-variants',
title: 'Type Variants Showcase',
description: 'Five nodes of each type — shows the hue-cycle per-sprite coloring.',
path: EXAMPLES_ROOT,
yaml: typeVariants,
},
]
Loading