|
| 1 | +# Plan: Configurable pretty-link routing for 6.0.0 |
| 2 | + |
| 3 | +## Goal |
| 4 | + |
| 5 | +Align AppRun 6.0.0 with the 3.38.1 routing boundary: hash/native behavior without configuration, explicit `use_prettyLink()` or `true` for `/path` SPA navigation, and no false-mode boilerplate across ordinary examples and generated documentation. |
| 6 | + |
| 7 | +## Current Context |
| 8 | + |
| 9 | +- The uncommitted implementation already exposes `app.use_prettyLink(enabled = true)`, uses mutually exclusive listener wiring, removes hash-handler inference, and updates public declarations. |
| 10 | +- `src/apprun.ts` currently initializes its internal `prettyLinks` flag to `true`; this is the single framework control point that must return to the 3.38.1 value of `false`. |
| 11 | +- The default-on decision caused explicit false calls in Play iframe wrappers, complete HTML examples, `demo/main.ts`, `demo/apprun-play.html`, and 40 generated `docs/**/*.html` hosts. |
| 12 | +- `tests/apprun-routing-bootstrap.spec.ts` currently asserts default pathname routing and must be inverted to verify default hash/native routing plus explicit true. |
| 13 | +- `tests/pretty-link-examples.spec.ts` currently requires false calls in preview wrappers and generated documentation hosts; the revised policy must reject that boilerplate instead. |
| 14 | +- `README.md`, `WHATSNEW.md`, `MIGRATION.md`, routing references, and public type comments currently describe default-on behavior and must distinguish no call from the argument-free method call. |
| 15 | +- The TypeScript browser URL, sibling AppRun iframe runtime, synchronous compiled-script execution, CodeMirror selector fix, balanced invocation scanner, tracked Play bundle, and Play source map are independent fixes and remain in scope. |
| 16 | +- Verification remains Jest through `npm test`, the TypeScript/Rollup/Webpack pipeline through `npm run build`, ESLint through `npm run lint`, and the browser scenarios in `.docs/tests/test-explicit-pretty-links.md`. |
| 17 | + |
| 18 | +## Decisions |
| 19 | + |
| 20 | +- Initialize the internal `prettyLinks` flag to `false`; keep `app.use_prettyLink(enabled = true)` so `app.use_prettyLink()` is an explicit enable operation exactly like 3.38.1. |
| 21 | +- Install only hash initialization and `hashchange` when no call or false is selected. Install pathname initialization, `popstate`, and guarded anchor interception only after argument-free or explicit-true configuration. |
| 22 | +- Keep routing mode independent of registered `#` handlers and retain last-call-wins behavior before `DOMContentLoaded`. |
| 23 | +- Remove explicit false calls that exist only to counter the abandoned default-on policy: Play wrappers and hosts, generated documentation pages, complete non-routing examples, and the shared hash demo bootstrap. |
| 24 | +- Keep explicit routing calls where they teach or own routing: false in the hash-routing example, true in the path-routing example, CLI path SPA, add-components path SPA, and routing documentation. |
| 25 | +- Keep reusable Play bundles neutral about host routing. Under default-off, loading them must naturally preserve native host navigation without a host opt-out. |
| 26 | +- Preserve pinned TypeScript, sibling runtime resolution, classic compiled-script execution, editable CodeMirror input, `apprun-play.js` publishing, and its source map. |
| 27 | +- Do not add a feature flag, fallback detector, compatibility branch, or environment-specific routing mode. |
| 28 | + |
| 29 | +## Phased Tasks |
| 30 | + |
| 31 | +### Phase 1 - Reconcile the reversed default |
| 32 | + |
| 33 | +- [x] Update `.docs/reqs/2026/07/13/req-explicit-pretty-links.md` so no call or false means hash/native and argument-free or true means pretty links. |
| 34 | +- [x] Update `.docs/tests/test-explicit-pretty-links.md` so browser scenarios exercise default-off behavior and explicit enablement. |
| 35 | +- [x] Review the revised REQ, AP, and E2E spec together and confirm the 3.38.1 compatibility boundary is unambiguous. |
| 36 | + |
| 37 | +### Phase 2 - Restore the 3.38.1 framework default |
| 38 | + |
| 39 | +- [x] Update `src/apprun.ts` so `prettyLinks` initializes to `false` while `use_prettyLink(enabled = true)` remains unchanged. |
| 40 | +- [x] Update source and declaration comments in `src/apprun.ts`, `src/router.ts`, `src/types.ts`, and `apprun.d.ts` to describe default hash/native mode and explicit pretty-link enablement. |
| 41 | +- [x] Preserve mutually exclusive listeners, last-call precedence, no-init behavior, base-path normalization, and removal of hash-handler inference. |
| 42 | + |
| 43 | +### Phase 3 - Remove default-on configuration churn |
| 44 | + |
| 45 | +- [x] Remove preview-level false calls from `src/apprun-code.tsx`, `src/apprun-play.tsx`, and ordinary new-tab generation in `demo/components/play.tsx` without changing TypeScript loading or compiled-script timing. |
| 46 | +- [x] Remove false calls added solely for default-on behavior from `demo/main.ts`, `demo/apprun-play.html`, complete non-routing README/What's New examples, and all tracked generated documentation hosts. |
| 47 | +- [x] Keep false only in deliberate hash-routing guidance/examples and keep true in deliberate `/path` applications and examples. |
| 48 | +- [x] Remove the generated-host opt-out explanation from `docs/about/index.html` because reusable Play now inherits the framework's native-navigation default. |
| 49 | + |
| 50 | +### Phase 4 - Rewrite regression policy around opt-in pretty links |
| 51 | + |
| 52 | +- [x] Update `tests/apprun-routing-bootstrap.spec.ts` to execute default hash/native listeners and explicit argument-free/true path listeners. |
| 53 | +- [x] Update `tests/pretty-link-examples.spec.ts` so generic examples, Play wrappers, hash-default hosts, and generated docs contain no unnecessary false call. |
| 54 | +- [x] Retain coverage for multiline/nested/semicolonless invocation discovery, Play runtime alignment, source-map publishing, editor input, and the two explicit routing examples. |
| 55 | +- [x] Add built-bundle assertions that loading Play without configuration leaves native host links alone and that explicit true enables path interception. |
| 56 | + |
| 57 | +### Phase 5 - Align public guidance |
| 58 | + |
| 59 | +- [x] Update `README.md`, `WHATSNEW.md`, and `MIGRATION.md` to state that no call or false preserves hash/native behavior while argument-free or true enables pretty links. |
| 60 | +- [x] Update `ai/building-apprun-spa.md` and `skills/apprun/references/routing-navigation.md` so `/path` SPAs explicitly call true and generic examples remain configuration-free. |
| 61 | +- [x] Confirm documentation never describes argument-free `use_prettyLink()` as equivalent to making no call. |
| 62 | + |
| 63 | +### Phase 6 - Rebuild, verify, and review |
| 64 | + |
| 65 | +- [x] Run `npm test -- --runInBand tests/apprun-routing-bootstrap.spec.ts tests/router.spec.ts tests/typescript-declarations.spec.ts tests/pretty-link-examples.spec.ts` and record focused evidence. |
| 66 | +- [x] Run `npm test -- --runInBand`, `npm run build`, and `npm run lint`; retain generated Pages bundles and report only actual warnings or failures. |
| 67 | +- [x] Execute the built-bundle routing and Play scenarios from `.docs/tests/test-explicit-pretty-links.md`. |
| 68 | +- [x] Run `git diff --check` and repeated code review until no default-on wording, unnecessary false calls, stale generated-host changes, or major findings remain. |
| 69 | + |
| 70 | +## Validation |
| 71 | + |
| 72 | +- Focused routing tests: `npm test -- --runInBand tests/apprun-routing-bootstrap.spec.ts tests/router.spec.ts tests/typescript-declarations.spec.ts tests/pretty-link-examples.spec.ts`. |
| 73 | +- Full unit suite: `npm test -- --runInBand`. |
| 74 | +- Production build: `npm run build`. |
| 75 | +- Static analysis: `npm run lint`, reporting the existing warning baseline separately from errors. |
| 76 | +- Browser behavior: execute `.docs/tests/test-explicit-pretty-links.md` against built bundles and inspect click prevention, `pushState`, `hashchange`, `popstate`, compiler availability, and editor input. |
| 77 | +- Scope: `git diff --check`, `git status --short`, and a requirement-focused review of every remaining changed file. |
| 78 | + |
| 79 | +## Rollback / Risk |
| 80 | + |
| 81 | +- Applications that relied on the temporary uncommitted default-on behavior must explicitly call `app.use_prettyLink(true)`; this is intentional and matches 3.38.1. |
| 82 | +- The argument-free method call enables pretty links even though making no call leaves them disabled. Documentation and tests must keep that distinction explicit. |
| 83 | +- Removing false calls must not remove deliberate hash-mode teaching examples or disturb the Play compiler/runtime/editor fixes. |
| 84 | +- Generated documentation pages should return to their prior HTML except for independently required runtime asset changes; broad host-page churn is specifically rejected. |
| 85 | +- No schema, persisted data, dependency, package version, or release publication is involved. |
0 commit comments