Files
buuh/docs/v8.md
T
Bendik Aagaard LynghaugandClaude Fable 5 37bd8adf81 docs: record the async-route (choo#653) design as a Phase 3 deliverable
Deliberately deferred so the SSR half (toStream) ships together with the
browser half — the missing server story is what stalled the original PR.
API shape goes to the RFC.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014NgfSjHE11oFpoSnLVKLXd
2026-09-08 17:44:13 +02:00

75 lines
4.0 KiB
Markdown

# choo v8 — branch notes
This branch is the working tree for the v8 modernization effort. The v7 code
at the repo root is untouched and stays authoritative until 8.0.0 ships;
everything new lives under `packages/`.
## Layout
- `packages/core``@choojs/core`: the Choo class, same API as choo v7
(`use`/`route`/`start`/`mount`/`toString`/`emit`), ported to ESM. The
nano* internals are consolidated into `lib/` as attributed ports:
- `lib/bus.js` ← nanobus 4.5.0
- `lib/router.js` ← nanorouter 4.0.0 + wayfarer 7.0.1 (+ trie)
- `lib/cache.js` ← choo component/cache.js + nanolru 1.0.0
- `lib/raf.js` ← nanoraf 3.1.0, `lib/href.js` ← nanohref 3.1.0
- `lib/timing.js` ← nanotiming 7.3.1 (unified on global `performance`)
- `lib/dom.js` ← document-ready 2.0.1 + scroll-to-anchor 1.0.0
- `lib/query.js` — nanoquery replaced by `URLSearchParams`
- `packages/html``@choojs/html`: the rendering package.
- `server.js` — server-side tagged template (← nanohtml 1.10.0 server,
transform branches removed; pure runtime)
- `browser.js` — runtime-only cached template tag: each template literal
is parsed once (WeakMap keyed on its strings array) into a <template>
plus hole instructions; renders clone and fill. Values never pass
through innerHTML. Document-level roots (<body> etc.) parse via
DOMParser since <template> drops them. Known limits: no dynamic tag
names, no holes in raw-text elements, SVG fragments need their <svg>
root, and (unlike v7) whitespace is preserved as authored — which is
what makes server and browser output byte-identical.
- `morph.js` — ← nanomorph 5.4.3, consolidated to one module
- `raw.js` — mark pre-encoded strings (works with both renderers)
- `packages/component``@choojs/component`: ← nanocomponent 6.6.0 +
on-load 3.4.1 as ES classes; the future island/hydration boundary.
- `examples/counter` — the isomorphic proof: one app module, mounted
zero-build in the browser via import map (`index.html`), string-rendered
in Node (`render.js`).
## Status vs the modernization plan
- [x] Phase 1: monorepo scaffold, ESM ports, choo v7 node test suite green
on `node --test` (Node ≥ 24), CI on GitHub Actions
- [x] URL normalization fix: WHATWG URL parsing, single decode with raw
fallback (no more URIError on '%'), NFC matching, per-segment
wildcard decode, decoded state.href
- [x] Phase 2 (core): browser renderer rewrite, `@choojs/component`,
zero-build counter example, full-app integration test in happy-dom
- [ ] Phase 2 (remaining): adoption-style hydration with mismatch
warnings, Playwright suite in a real browser, benchmarks vs
nanohtml v1 / µhtml
- [ ] Phase 3: v8 wiring (`toStream`, devtools, codemod). Includes the
answer to choojs/choo#653 (async/lazy routes): route handlers may
resolve lazily via native import(); browser renders previous tree
or a loading view until resolution, server awaits inside toStream
(toString stays sync and fails loudly). Deliberately deferred until
toStream exists so the SSR half ships with the browser half — the
missing server story is what stalled #653. API shape (thenable
handler vs lazy() wrapper vs loader-view option) goes to the RFC.
- [ ] Phase 4: bankai v10 (Vite 8/Rolldown shell, SSR middleware,
103 Early Hints, service worker, precompression)
- [ ] Phase 5: docs, examples, launch
## Deliberate changes from v7
- `choo()` still works without `new`; `Choo` is also a named export.
- nanoquery → `URLSearchParams` (same output shape, repeated keys → arrays).
- Assertions live in `lib/assert.js` so production builds can strip them.
- Everything targets Node ≥ 24 and Baseline Widely Available browsers; there
is no compile step and no transpilation anywhere.
## Attribution
All ported modules are MIT-licensed work by the original choojs/nano*
authors and contributors; per-file headers note the source package and
version. This branch exists to carry that work forward, not to replace it.