docs: add complete framework feature report
Quality / quality (ubuntu-latest) (push) Failing after 9m54s
Quality / quality (windows-latest) (push) Canceled after 0s

This commit is contained in:
2026-08-19 17:52:08 +05:30
parent e5de7b54a5
commit b3ed9689fa
2 changed files with 1698 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,302 @@
import { readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
import { join, relative } from "node:path";
import console from "node:console";
import process from "node:process";
import { format } from "prettier";
const root = process.cwd();
const json = (path) => JSON.parse(readFileSync(join(root, path), "utf8"));
const rootPackage = json("package.json");
const publicApi = json("docs/public-api-0.8.json");
const uiReference = json("packages/ui/component-reference.json");
function walk(dir, extension, out = []) {
for (const entry of readdirSync(dir)) {
const path = join(dir, entry);
const info = statSync(path);
if (info.isDirectory() && !["node_modules", "dist", ".wrnexus"].includes(entry))
walk(path, extension, out);
else if (path.endsWith(extension)) out.push(path);
}
return out;
}
const packageRows = readdirSync(join(root, "packages"), { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => {
const manifest = json(`packages/${entry.name}/package.json`);
return {
name: manifest.name,
version: manifest.version,
description: manifest.description ?? "—",
};
})
.sort((a, b) => a.name.localeCompare(b.name));
const wrnFiles = walk(join(root, "packages"), ".wrn").sort();
const packageBlocks = new Map();
for (const file of wrnFiles) {
const packageName = relative(join(root, "packages"), file).split(/[\\/]/)[0];
const list = packageBlocks.get(packageName) ?? [];
list.push(relative(root, file).replaceAll("\\", "/"));
packageBlocks.set(packageName, list);
}
const apiPackages = Object.entries(publicApi.packages);
const apiSymbolCount = apiPackages.reduce(
(total, [, entries]) =>
total + Object.values(entries).reduce((sum, symbols) => sum + symbols.length, 0),
0,
);
const lines = [];
const add = (...value) => lines.push(...value);
add(
"# WRNexusJS complete framework and `.wrn` report",
"",
`Generated for workspace version **${rootPackage.version}** from the checked-out source and generated references.`,
"",
"> Scope and source of truth: this report describes the checked-out implementation, not only the prose docs. The parser in `packages/syntax`, compiler/runtime code, package manifests, `docs/public-api-0.8.json`, and `packages/ui/component-reference.json` take precedence when older documents disagree.",
"",
"## 1. Executive summary",
"",
`- Workspace framework version: **${rootPackage.version}**. The 48 independently published packages have their own patch versions; see Appendix A.`,
"- Architecture: compiler-driven, SSR-first, Bun-native/full-stack, with Node-friendly selected tooling.",
"- Static routes retain the zero-framework-JavaScript goal; hydration is selective and islands are loaded only where declared.",
"- Current headline features include typed callable API blocks, reactive `if`/`each` control blocks, runtime-scoped state and functions, typed outputs, stores, React islands, HTML-aware editor tooling, package/plugin discovery, generated contracts, security gates, and multi-app RPC.",
`- Audited public API baseline: **${apiPackages.length} packages / ${apiSymbolCount} exported symbols** across root and subpath exports.`,
`- Audited packaged \`.wrn\` sources: **${wrnFiles.length}**; generated UI reference: **${uiReference.components.length} components**.`,
"",
"## 2. What a `.wrn` file is",
"",
"A `.wrn` file is a single compiler-owned source unit combining imports, a root declaration, typed data/state, runtime behavior, HTML view markup, styles, metadata, API handlers/bindings, and realtime handlers. It is parsed into the canonical AST owned by `@wrnexus/syntax`; `@wrnexus/compiler` turns that AST into SSR, browser, route, style, and metadata artifacts.",
"",
"Valid roots:",
"",
"| Root | Purpose |",
"| --- | --- |",
"| `page Name {}` | Routed page. |",
"| `component Name {}` | Reusable server-rendered component. |",
"| `layout Name {}` | Reusable page wrapper. |",
"| `global store Name {}` | Application-wide store. |",
"| `page store Name {}` | Page-lifetime store. |",
"",
"A file may start with static TypeScript imports. Component and layout symbols can be imported explicitly; compatibility discovery remains configurable for upgraded applications.",
"",
"## 3. Complete `.wrn` block and declaration catalog",
"",
"| Declaration/block | Shape | Meaning and current behavior |",
"| --- | --- | --- |",
"| `layout = LayoutSymbol` | root member | Preferred imported layout reference. String layout names remain a compatibility path. |",
'| `runtime = "…"` | root member | Targets: `server`, `client`, `universal`, `edge`, `worker`, `service-worker`. |',
'| `render = "…"` | root member | Modes: `static`, `server`, `hybrid`, `client`, `partial-static`. |',
'| `hydrate = "…"` | root member | `load`, `idle`, `visible`, `interaction`, `none`, or `media:<query>`; legacy `never` normalizes to `none`. |',
'| `client = "…"` | root member | Legacy alias for hydration configuration; `client {}` remains a different runtime-mode block. |',
"| `types {}` | raw TypeScript | Local type declarations emitted for checking. |",
"| `props {}` | typed declarations | Required without default; optional via `?`; defaults supported; legacy `@event name = function` is parsed for compatibility. |",
"| `outputs {}` | typed declarations | Canonical child-to-parent callable output contract, zero or one typed payload. |",
"| `state name = expr` / `state {}` | reactive data | Shared state; type annotation optional, initializer required. Arrays, objects, and multiline expressions are supported. |",
"| `server state {}` / `client state {}` | runtime-scoped data | State visible only in the declared runtime boundary. |",
"| `computed name = expr` / `computed {}` | derived data | Dependency-tracked cached values. |",
"| `effect {}` | reactive side effect | Runs after batched updates when referenced reactive values change. |",
"| `load server {}` / `load client {}` | loader | Runtime-specific loading; named/dependent/deferred forms are represented in the AST. |",
"| `action name(args) {}` | action | Named action, optionally schema-backed, exported for adapters. |",
"| `view {}` | HTML/template | HTML/component tree with expressions, events, directives, and reactive control blocks. |",
"| `style {}` | scoped CSS | Multiple blocks allowed; promoted into the document head with CSP/HMR/navigation support. |",
"| `seo {}` | metadata | Key/value SEO metadata. |",
"| `security {}` | policy metadata | Auth, CSRF, roles, rate-limit and organization-specific enforcement metadata. |",
"| `navigation {}` | navigation metadata | Page navigation policy/configuration consumed by runtime tooling. |",
"| `cache {}` | cache metadata | Declarative framework cache policy. |",
"| `functions {}` | shared helpers | Legacy/general shared helper body; runtime-specific function grammar is preferred where applicable. |",
"| `server { functions {} }` / `client { functions {} }` | mode helper block | Raw helpers scoped to SSR or browser execution. |",
"| `[async] server function name(args) {}` | callable function | Explicit server RPC boundary. |",
"| `[async] client function name(args) {}` | browser function | Explicit client callable function. |",
"| `[async] shared function name(args) {}` | universal helper | Explicit shared function. |",
"| `ssr { api … }` | render-time own-route data | Executes during render. Legacy bare response body is supported; sectioned `response`/`error` is supported; request parameters are intentionally forbidden. |",
"| `client { api … }` | callable own-route data | Sectioned form creates `api.name(input)` in browser scope; GET uses query parameters, other methods use JSON and CSRF. |",
"| `api METHOD /path {}` | route handler | Defines an application API endpoint/handler. Distinct from named data API bindings inside `ssr`/`client`. |",
"| `lifecycle { mount/update/unmount {} }` | component lifecycle | Hydrated lifecycle hooks. |",
"| `watch stateName {}` | watcher | Runs for changes to the named state. |",
"| `realtime name { on event(args) {} }` | websocket behavior | Declares named realtime handlers. |",
"| `persist {}` | store persistence | Storage (`memory`, `session`, `local`), included keys, version, migrations, and validation. |",
"| `lifecycle { serverInit/clientInit/hydrate/dispose {} }` | store lifecycle | Store-specific lifecycle form. |",
"",
"### View/template features",
"",
"- Standard HTML and custom/component tags; HTML void elements follow the platform list.",
"- Escaped `{expression}` interpolation. Raw HTML is an explicit security boundary.",
"- Browser event attributes: `@click`, `@window:scroll`, `@document:click`, and other event names.",
"- Conditional classes through `class:name='expression'`; visibility through `data-show`.",
'- Legacy loop attribute: `data-for="item, index in items key item.id"`, with optional `data-key`.',
"- Canonical control blocks: `{#if}`, `{:else if}`, `{:else}`, `{/if}` and `{#each list as item, index key expr}`, `{:empty}`, `{/each}`. Initial output is SSR and remains reactive after hydration.",
"- JSX-style expression props (`items={items}`, object/array expressions) are current; quoted expressions remain compatible. Literal HTML attributes remain quoted.",
"- React/TSX islands use imported `.tsx` components and `client:only`, `client:load`, `client:visible`, or `client:idle`. They are client-only in v1; island props must be JSON-serializable.",
"",
"### Typed callable API block (latest form)",
"",
"```wrn",
"client {",
" api searchUsers POST /api/users {",
" request { body { name?: string age?: number } }",
" response { return data.users }",
" error { return [] }",
" }",
"}",
"```",
"",
"Call it with `await api.searchUsers({ name })`. GET uses `request { parameters {} }`; non-GET uses `body {}`. Fields are type-only declarations checked against generated route contracts in `app/types/wrnexus.generated.api-checks.ts`. Success binds parsed JSON as `data`. `error {}` converts failure to its returned value; without it, non-2xx, network, and parse failures reject. Targets are restricted to the current apps `/api/*` routes. External APIs, custom headers, parameterized SSR calls, caching, and deduplication are deferred.",
"",
"Legacy API binding remains valid: `ssr { api users GET /api/users { return users } }`. Its bare body receives payload fields through the legacy dynamic scope. The sectioned form deliberately uses `data` so TypeScript can check it.",
"",
"## 4. Runtime, rendering, and data flow",
"",
"1. `@wrnexus/syntax` tokenizes/parses and emits stable diagnostics and AST nodes.",
"2. The compiler resolves imports/components/islands and generates SSR HTML functions, client modules, route/API exports, styles, metadata, and contracts.",
"3. Static pages ship no framework JS. Interactive pages receive only the required CSR runtime; island routes lazily receive React/island assets.",
"4. State changes batch, invalidate computed values, run effects/watchers, update expressions/classes/visibility, and rerender `if`/`each` regions.",
"5. Server functions use the RPC boundary; typed API blocks call same-app API routes; realtime blocks produce websocket handlers; stores bridge SSR and client state.",
"6. Generated types validate component props, outputs, functions, routes, and typed API-block request contracts during `tsc` and release checks.",
"",
"## 5. Framework feature inventory",
"",
"- Routing and rendering: filesystem pages/layouts, static/request/hybrid/client/partial-static rendering, route analysis, advanced routing, CSR navigation, layouts, streaming/SSR packages.",
"- Reactivity: state, computed values, effects, watchers, reactive attributes/events, SSR-to-client control blocks, loaders/actions, explicit hydration.",
"- Components/UI: application components, package-owned blocks, generated prop/output references, theming/tokens, 102 audited first-party UI components, app overrides/ejection.",
"- Data/backend: database drivers and migrations, repositories, cache, queue, pub/sub, realtime, GraphQL, route APIs, server functions, workspace RPC.",
"- Identity/security: auth, authorization, OAuth, JWT/JWKS, MFA/passkeys/recovery, CAPTCHA, encryption, SSRF defenses, CSP/CSRF, request limits, audit/security gates.",
"- Product capabilities: AI/RAG/provider adapters, content, i18n, image optimization, uploads, validation, PWA, native/mobile, analytics/tracking, observability.",
"- Developer experience: CLI create/dev/build/update/doctor/inspect/generate/eject/db/workspace operations, HMR, dev toolbar, language server, VS Code completion/HTML editing/formatting/diagnostics, playground, MCP, tests/benchmarks/release validation.",
"- Deployment: production builds, Docker and platform examples, migrations, package staging/integrity checks, SBOM and security/performance reports.",
"",
"## 6. Legacy-to-current migration map",
"",
"| Legacy/earlier approach | Current approach | Compatibility/status |",
"| --- | --- | --- |",
"| Compiler-owned/internal parsing imports | Canonical `@wrnexus/syntax` lexer/parser/AST/diagnostics | Compiler re-exports remain for compatibility; direct internals are deprecated. |",
"| Implicit component discovery everywhere | Explicit imports and generated contracts | Upgraded apps can retain `legacyComponentDiscovery`; unresolved symbols are reported rather than guessed. |",
'| `layout = "PublicLayout"` | Import layout and use `layout = PublicLayout` | String layouts remain behind compatibility configuration. |',
"| `@event changed = function` in props | `outputs { changed(payload: Type) }` | v0.6 migration converts declarations; ambiguous payloads become `unknown`. |",
'| `$emit("changed", value)` and `event.detail` | `output.changed(value)` and direct `payload` | Static cases auto-migrated; dynamic emit names require review. |',
"| Unclassified functions | `server function`, `client function`, or `shared function` | v0.6 classifies unambiguous cases; compatibility default can preserve ambiguous behavior. |",
"| Manually copied CAPTCHA JS/script tags | Package-discovered client runtime/assets | v0.4 removes tags and archives old assets under `.wrnexus/legacy-assets/0.4.0`. |",
"| Package components/routes/assets wired manually | Automatic package/plugin discovery and contribution registry | Current CLI/build/dev server inspect and consume contributions. |",
"| Only scalar/quoted dynamic props | Native arrays/objects and JSX-style unquoted expressions | Quoted expression attributes remain supported. |",
"| `data-for` and older each forms | `{#each …}{:empty}{/each}` | Legacy loop forms remain supported; canonical blocks offer keyed/empty/reactive behavior. |",
"| Static server-only `if`/`each` after hydration | Reactive client rerendering of control blocks | Current runtime updates branches/rows after state changes. |",
"| Bare `api` binding bodies and hand-written `fetch` for inputs | Sectioned typed callable client API blocks | Bare body stays supported; new form adds inputs, route-contract checking, CSRF, response/error transforms. |",
"| Generated API assertions in `.d.ts` | Assertions in real `wrnexus.generated.api-checks.ts` | Changed because `skipLibCheck` made `.d.ts` assertions inert. |",
"| Client functions accidentally retaining TypeScript | Compiler strips type syntax before browser-module emission | Fixed and regression-tested. |",
"| Markup merely highlighted as embedded HTML | Virtual HTML document plus HTML language service | Current editor adds tag/attribute completion, auto-close/rename, hover, Emmet, and folding; WRN formatter still owns formatting. |",
"| Framework-only component ecosystem | Optional React `.tsx` islands | React is isolated and lazy; zero-JS routes remain unchanged; island SSR/Fast Refresh are deferred. |",
"| Per-component/global style placement inconsistencies | `style {}` promoted to document head | Current pipeline supports CSP, HMR and CSR navigation. |",
"| Manually maintained API/component knowledge | Generated public API and component references plus validation gates | `check:public-api`, generated-type checks, UI visual contract and package audits detect drift. |",
"",
"Compatibility flags visible in generated/upgraded config include `legacyEmit`, `legacyEventProps`, `legacyComponentDiscovery`, `stringLayouts`, and `functions.legacyDefaultRuntime`. New projects default legacy flags off; migration-created configs may enable them to preserve behavior until source modernization is complete.",
"",
"## 7. Diagnostics, security, and correctness guarantees",
"",
"Stable diagnostics include parse/member/prop/state/hydration/runtime/accessibility codes and feature-specific diagnostics such as island prop or missing-React errors. Compiler, CLI doctor/build, type generation, and editor tooling share syntax ownership to reduce parser drift.",
"",
"Security properties include escaped output by default, CSP-aware styles/scripts, same-origin API restriction, CSRF on non-GET callable API requests, credential handling via same-origin cookies, safe serialization, SSRF policies, request limits, auth/authz metadata and middleware, secret/audit gates, and application-layer encryption where explicitly needed. Security metadata is declarative input; enforcement still belongs to installed middleware/plugins and route policy.",
"",
"## 8. Current limitations and deferred work",
"",
"- Typed API blocks do not target third-party URLs, accept custom author headers, parameterize SSR requests, or provide built-in request caching/deduplication.",
"- React islands are client-rendered in v1; island SSR/hydration and React Fast Refresh are deferred.",
"- Native compilation does not directly port data API blocks; native screens use generated backend helpers.",
"- HTML language features intentionally do not replace the WRN formatter.",
"- Generated type checks must stay fresh; `check:generated-types` is the enforcement gate.",
"",
"## 9. Documentation drift discovered by this audit",
"",
`- Root ` +
"`README.md`" +
` says 0.8.0, while the workspace manifest is ${rootPackage.version}.`,
`- ` +
"`packages/ui/README.md`" +
` says 85 components and ` +
"`docs/UI-COMPONENT-INVENTORY.md`" +
` says 891; the current generated component reference contains ${uiReference.components.length}.`,
"- `docs/WRN-LANGUAGE-SPEC-1.0.md` calls itself the 0.3.x contract and predates several implemented roots/members (stores, rendering modes, outputs, runtime-scoped state/functions, React islands, sectioned callable API blocks). Use it as historical baseline, not a complete 0.8.8 reference.",
"- Package patch versions are intentionally ahead of the workspace umbrella version in many packages. Consumers should use the actual package manifest/version selected by the release process.",
"",
"## 10. Recommended release verification",
"",
"Run `bun run check:production` for the complete production gate. Its chain covers workspace repair, generated types, public API, UI visual contract, 0.8 validation, framework/ASVS security, editor bundle freshness, typecheck, lint, component imports, package tests, formatting, and examples. Additional focused commands include `bun run test:all`, `bun run audit:packages`, `bun run test:package-kits`, `bun run validate:staging`, `bun run sbom`, and `bun run benchmark:framework`.",
"",
"## Appendix A — package/version inventory",
"",
"| Package | Version | Purpose |",
"| --- | --- | --- |",
);
for (const item of packageRows)
add(`| \`${item.name}\` | ${item.version} | ${item.description.replaceAll("|", "\\|")} |`);
add("", "## Appendix B — complete audited public export inventory", "");
for (const [packageName, entries] of apiPackages) {
const count = Object.values(entries).reduce((sum, symbols) => sum + symbols.length, 0);
add(`### \`${packageName}\` (${count} symbols)`, "");
for (const [subpath, symbols] of Object.entries(entries)) {
add(`- **${subpath}:** ${symbols.map((symbol) => `\`${symbol}\``).join(", ")}`);
}
add("");
}
add("## Appendix C — current UI component/block reference", "");
for (const component of uiReference.components) {
const props = component.props.length
? component.props
.map(
(prop) =>
`${prop.name}: ${prop.type}${prop.required ? " (required)" : ` = ${prop.default}`}`,
)
.join("; ")
: "none";
const outputs = component.outputs?.length
? component.outputs.map((output) => `${output.name}(${output.payloadType})`).join("; ")
: "none";
const slots = component.slots?.length ? component.slots.join(", ") : "none";
add(
`### \`${component.name}\``,
"",
`- Category: ${component.category}; mount: \`${component.mount}\`; source: \`${component.source}\`.`,
`- Purpose: ${component.purpose}`,
`- Props: ${props}`,
`- Outputs/events: ${outputs}`,
`- Slots: ${slots}`,
"",
);
}
add("## Appendix D — all other package-owned `.wrn` blocks", "");
for (const [packageName, files] of [...packageBlocks.entries()].sort(([a], [b]) =>
a.localeCompare(b),
)) {
if (packageName === "ui") continue;
add(
`### \`@wrnexus/${packageName}\` (${files.length})`,
"",
...files.map((file) => `- \`${file}\``),
"",
);
}
add(
"## Appendix E — authoritative files",
"",
"- Language parser/AST: `packages/syntax/src/parser.ts`, `v060.ts`, `api-sections.ts`, `spec.ts`.",
"- Compiler/runtime: `packages/compiler/src`, `packages/csr/src`, `packages/ssr/src`, `packages/dev-server/src`.",
"- Migration registry: `packages/cli/src/update.ts`.",
"- Public exports: `docs/public-api-0.8.json` (checked by `scripts/check-public-api.mjs`).",
"- UI blocks: `packages/ui/component-reference.json` and `packages/ui/COMPONENTS.md`.",
"- Latest feature designs: `docs/superpowers/specs/2026-08-19-typed-api-block-design.md`, `2026-08-18-react-islands-design.md`, and `2026-08-18-wrn-html-editing-design.md`.",
"",
"---",
"",
"This report is reproducible: run `node scripts/generate-complete-framework-report.mjs` after implementation or generated-reference changes.",
);
const report = await format(`${lines.join("\n")}\n`, { parser: "markdown" });
writeFileSync(join(root, "docs", "WRNEXUS-COMPLETE-FEATURE-REPORT.md"), report, "utf8");
console.log(`Wrote docs/WRNEXUS-COMPLETE-FEATURE-REPORT.md (${lines.length} lines).`);