Page not found
The address may be outdated or misspelled. No private or duplicate route is exposed here.
diff --git a/app/docs.test.ts b/app/docs.test.ts
index 0f2ab796..df1ccf11 100644
--- a/app/docs.test.ts
+++ b/app/docs.test.ts
@@ -14,31 +14,46 @@ const expected = [
"ai",
"auth",
"authz",
+ "benchmark",
+ "cache",
"captcha",
"cli",
"compiler",
+ "content",
"core",
"csr",
"db",
"dev-server",
"dev-toolbar",
"encryption",
+ "graphql",
"helpers",
"i18n",
+ "identity",
+ "image",
"jwt",
+ "language-server",
+ "mcp",
"mobile",
"native",
"oauth",
+ "observability",
+ "playground",
"plugin",
"pubsub",
+ "pwa",
"queue",
"reactive",
+ "realtime",
"router",
+ "security",
"ssr",
+ "store",
"styles",
"syntax",
"test",
"tracking",
+ "typecheck",
"ui",
"uploader",
"validation",
@@ -201,5 +216,13 @@ test("clicking a category hides packages from other categories", async () => {
.querySelectorAll(".package-card")
.filter((card) => (card as HTMLElement).style.display !== "none")
.map((card) => card.getAttribute("href"));
- expect(visible).toEqual(["/packages/db", "/packages/queue", "/packages/uploader"]);
+ expect(visible).toEqual([
+ "/packages/cache",
+ "/packages/content",
+ "/packages/db",
+ "/packages/graphql",
+ "/packages/queue",
+ "/packages/store",
+ "/packages/uploader",
+ ]);
});
diff --git a/app/pages/404.wrn b/app/pages/404.wrn
index 3be2cad2..11e7fbd3 100644
--- a/app/pages/404.wrn
+++ b/app/pages/404.wrn
@@ -7,10 +7,10 @@ page Pagenotfound {
view {
The address may be outdated or misspelled. No private or duplicate route is exposed here.
WRNexusJS 0.7.0 packages are not available from the public npm registry. Installation requires approval and private registry credentials supplied by WorkRoot. Never paste registry tokens into source control, issue reports, or support messages.
bunx @wrnexus/cli@0.7.0 create my-appAccess approval, response time, licensing terms, and support level remain owner-controlled. This site does not collect access requests directly.
WRNexusJS 0.8.0 packages are not available from the public npm registry. Installation requires approval and private registry credentials supplied by WorkRoot. Never paste registry tokens into source control, issue reports, or support messages.
bunx @wrnexus/cli@0.8.0 create my-appAccess approval, response time, licensing terms, and support level remain owner-controlled. This site does not collect access requests directly.
WRNexusJS is Bun-native and SSR-first. File discovery maps pages and API handlers; middleware enriches or short-circuits a request; the compiler turns .wrn declarations into server render functions and small feature runtimes.
core owns contexts, middleware, sessions and rooms; router discovers routes; compiler parses .wrn; ssr renders documents; csr supplies browser runtimes; dev-server and cli orchestrate development and builds.
Validation happens at trust boundaries. Session authentication establishes identity; authorization makes resource decisions. CSP, Trusted Types, CSRF, upload checks, WebSocket origins, request limits, and output escaping are layered controls—not substitutes for application policy.
Rooms are process-local unless connected through pub/sub. Redis-backed pub/sub distributes events. Queue durability depends on the selected driver and must be evaluated explicitly.
The gateway can dispatch multiple applications while preserving route, component, asset, config, and session boundaries. Validate host routing and isolation before production.
wrnexus build . produces dist/server.js and hashed/static assets. Run the server with Bun, apply migrations before traffic, terminate TLS at a trusted edge, and forward only expected proxy headers.
Mobile compatibility bridges SSR-safe Capacitor capabilities; native route generation is experimental and is not general web portability. Test each target platform.
app/routes.gen.ts, .wrnexus/, and dist/ are generated. The runtime is Bun-only. Preview packages are private. Historical compatibility and long-term support policy are not yet published.
WRNexusJS is Bun-native and SSR-first. File discovery maps pages and API handlers; middleware enriches or short-circuits a request; the compiler turns .wrn declarations into server render functions and small feature runtimes.
core owns contexts, middleware, sessions and rooms; router discovers routes; compiler parses .wrn; ssr renders documents; csr supplies browser runtimes; dev-server and cli orchestrate development and builds.
Validation happens at trust boundaries. Session authentication establishes identity; authorization makes resource decisions. CSP, Trusted Types, CSRF, upload checks, WebSocket origins, request limits, and output escaping are layered controls—not substitutes for application policy.
Rooms are process-local unless connected through pub/sub. Redis-backed pub/sub distributes events. Queue durability depends on the selected driver and must be evaluated explicitly.
The gateway can dispatch multiple applications while preserving route, component, asset, config, and session boundaries. Validate host routing and isolation before production.
wrnexus build . produces dist/server.js and hashed/static assets. Run the server with Bun, apply migrations before traffic, terminate TLS at a trusted edge, and forward only expected proxy headers.
Mobile compatibility bridges SSR-safe Capacitor capabilities; native route generation is experimental and is not general web portability. Test each target platform.
app/routes.gen.ts, .wrnexus/, and dist/ are generated. The runtime is Bun-only. Preview packages are private. Historical compatibility and long-term support policy are not yet published.
No comparative speed claims are published. A valid baseline must record scripts, commit, Bun/framework versions, hardware, OS, warmup, samples, workload, raw results, median, percentiles, memory, HTML size, browser JavaScript size, and run date.
The roadmap starts with WRNexusJS-only measurements before any maintained equivalent-workload comparison.
Documentation is aligned to all 38 installed packages. This release adds @wrnexus/helpers, original-request URL helpers, safe login redirects, working wrnexus workspace add, and forward-auth redirect propagation.
Run wrnexus update --latest and keep every @wrnexus/* package on 0.7.0. Existing applications must explicitly add @wrnexus/helpers before importing it; newly scaffolded applications include it automatically.
The packages use semantic-looking versions, but a formal compatibility and old-release support policy has not been approved. Preview consumers should treat minor releases as potentially requiring migration review.
Documentation is aligned to all 46 installed packages. This release adds @wrnexus/helpers, original-request URL helpers, safe login redirects, working wrnexus workspace add, and forward-auth redirect propagation.
Run wrnexus update --latest and keep every @wrnexus/* package on 0.8.0. Existing applications must explicitly add @wrnexus/helpers before importing it; newly scaffolded applications include it automatically.
The packages use semantic-looking versions, but a formal compatibility and old-release support policy has not been approved. Preview consumers should treat minor releases as potentially requiring migration review.
Examples are tied to installed 0.7.0 package documentation. The focused snippets in guides are source-verified; standalone runnable projects and CI compilation are tracked as remaining work.
Examples are tied to installed 0.8.0 package documentation. The focused snippets in guides are source-verified; standalone runnable projects and CI compilation are tracked as remaining work.
This path creates a server-rendered page, validated API route, middleware, and realtime next step. It requires approved registry access and Bun 1.3.x; this site was verified with Bun 1.3.14.
bunx @wrnexus/cli@0.7.0 create my-app
+ Preview guide · v0.8.0Build a contact inbox
This path creates a server-rendered page, validated API route, middleware, and realtime next step. It requires approved registry access and Bun 1.3.x; this site was verified with Bun 1.3.14.
1. Create the project
bunx @wrnexus/cli@0.8.0 create my-app
cd my-app
bun install
bun run dev
2. Know the structure
app/pages/ # file-based .wrn routes
@@ -39,7 +39,7 @@ export const POST = async (ctx) => {
}
7. Test and ship
bun run test
bun run build
bun dist/server.js
Next: deployment, database, authentication, and workspaces.
-
+
Export GET, POST, PUT, PATCH, or DELETE from app/api files. Validate request bodies, enforce authentication and authorization, cap request sizes, and return Web Responses.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Export GET, POST, PUT, PATCH, or DELETE from app/api files. Validate request bodies, enforce authentication and authorization, cap request sizes, and return Web Responses.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Configure session authentication, log users in through supported auth helpers, and read identity from context. Cookie flags, rotation, expiry, and secret storage remain deployment responsibilities.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Configure session authentication, log users in through supported auth helpers, and read identity from context. Cookie flags, rotation, expiry, and secret storage remain deployment responsibilities.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Authentication identifies; authorization decides. Enforce permissions in server routes and policies, including object ownership. UI hiding is never an authorization boundary.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Authentication identifies; authorization decides. Enforce permissions in server routes and policies, including object ownership. UI hiding is never an authorization boundary.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
wrnexus.config.ts owns styles, SEO, security, data, mobile, fonts, and profiles. Keep secrets in validated environment variables and review merged production configuration.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
wrnexus.config.ts owns styles, SEO, security, data, mobile, fonts, and profiles. Keep secrets in validated environment variables and review merged production configuration.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Configure SQLite or the installed supported driver, keep queries in named SQL blocks, generate typed functions, and apply migrations before traffic. Back up data and test rollback independently.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Configure SQLite or the installed supported driver, keep queries in named SQL blocks, generate typed functions, and apply migrations before traffic. Back up data and test rollback independently.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Run bun run build, apply migrations, and start dist/server.js with Bun. Configure TLS, proxy trust, environment validation, health checks, graceful restarts, logs, backups, and restrictive security headers.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Run bun run build, apply migrations, and start dist/server.js with Bun. Configure TLS, proxy trust, environment validation, health checks, graceful restarts, logs, backups, and restrictive security headers.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Define a v.object schema, use data-schema on the form, show field errors with data-error, and always call parseBody on the server. refine is server-only.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Define a v.object schema, use data-schema on the form, show field errors with data-error, and always call parseBody on the server. refine is server-only.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Store locale JSON under app/locales and use translation directives. Themes resolve CSS tokens; ensure contrast, system preference behavior, persistence, and non-color cues.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Store locale JSON under app/locales and use translation directives. Themes resolve CSS tokens; ensure contrast, system preference behavior, persistence, and non-color cues.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Middleware receives context and next. Return next() to continue or return a Response to stop. Put request limits and trust-boundary controls before business logic.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Middleware receives context and next. Return next() to continue or return a Response to stop. Put request limits and trust-boundary controls before business logic.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Mobile capabilities are experimental in this preview. Test Capacitor permissions and lifecycle on each platform; do not assume every .wrn or browser API converts to native.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Mobile capabilities are experimental in this preview. Test Capacitor permissions and lifecycle on each platform; do not assume every .wrn or browser API converts to native.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Use tracking middleware and sinks with redaction, sampling, stable request identifiers, alert ownership, and retention limits. Never capture registry tokens or session secrets.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Use tracking middleware and sinks with redaction, sampling, stable request identifiers, alert ownership, and retention limits. Never capture registry tokens or session secrets.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Pages are routable, components are reusable, and layouts provide shared slots. Mount a component with data-component and keep browser state scoped and minimal.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Pages are routable, components are reusable, and layouts provide shared slots. Mount a component with data-component and keep browser state scoped and minimal.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Pages, components, layouts, APIs, middleware, schemas, database files, locales, realtime rooms, and styles live under app. Never edit app/routes.gen.ts, .wrnexus, or dist by hand.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Pages, components, layouts, APIs, middleware, schemas, database files, locales, realtime rooms, and styles live under app. Never edit app/routes.gen.ts, .wrnexus, or dist by hand.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
The in-process driver cannot cross processes. Use Redis where instances must share events, define channel ownership, and design for reconnects and duplicate delivery.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
The in-process driver cannot cross processes. Use Redis where instances must share events, define channel ownership, and design for reconnects and duplicate delivery.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Queue behavior is preview-level. Treat in-process work as non-durable, make handlers idempotent, cap retries, record failures, and choose a production persistence strategy.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Queue behavior is preview-level. Treat in-process work as non-durable, make handlers idempotent, cap retries, record failures, and choose a production persistence strategy.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
defineRoom handles connection and messages. Validate message shapes, authorize subscriptions, restrict origins, bound payloads, and use pub/sub to scale across processes.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
defineRoom handles connection and messages. Validate message shapes, authorize subscriptions, restrict origins, bound payloads, and use pub/sub to scale across processes.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
A page filename defines its URL; index maps to the directory root and bracket segments are dynamic parameters. API files under app/api expose HTTP method functions and receive a Context.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
A page filename defines its URL; index maps to the directory root and bracket segments are dynamic parameters. API files under app/api expose HTTP method functions and receive a Context.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Use CSP, CSRF, Trusted Types, session hardening, validation, origin checks, upload restrictions, encryption, request limits, and explicit CORS. See the security policy for reporting.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Use CSP, CSRF, Trusted Types, session hardening, validation, origin checks, upload restrictions, encryption, request limits, and explicit CORS. See the security policy for reporting.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Use an ssr API binding, return the desired response field, and render it with a server #each block. Values are escaped. Avoid fetching private data through a route that lacks authorization.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Use an ssr API binding, return the desired response field, and render it with a server #each block. Values are escaped. Avoid fetching private data through a route that lacks authorization.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Use Bun tests and @wrnexus/test helpers. Cover server HTML, API status and validation, authorization failures, reactive behavior, and a production startup smoke test.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Use Bun tests and @wrnexus/test helpers. Cover server HTML, API status and validation, authorization failures, reactive behavior, and a production startup smoke test.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Confirm Bun and package versions, regenerate docs/routes through supported commands, read the first compiler diagnostic, check file naming, validate config, and reproduce under a production build.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Confirm Bun and package versions, regenerate docs/routes through supported commands, read the first compiler diagnostic, check file naming, validate config, and reproduce under a production build.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Back up and commit first, then use wrnexus update --latest as documented by the installed CLI. Review migrations and keep every @wrnexus package aligned. Current release: 0.7.0.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Back up and commit first, then use wrnexus update --latest as documented by the installed CLI. Review migrations and keep every @wrnexus package aligned. Current release: 0.8.0.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Configure named stores, accepted MIME/extensions, and maxBytes. Random keys avoid path traversal. Private files require an authenticated serving route; v1 buffers each file in memory.
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
Configure named stores, accepted MIME/extensions, and maxBytes. Random keys avoid path traversal. Private files require an authenticated serving route; v1 buffers each file in memory.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
A workspace runs isolated applications behind one domain-routing gateway. Add an application from the workspace root; the CLI scaffolds apps/reports and registers it in wrnexus.workspace.ts:
wrnexus workspace add reports --domain=reports.localhost
+ Preview guide · 0.8.0Workspaces and gateway
A workspace runs isolated applications behind one domain-routing gateway. Add an application from the workspace root; the CLI scaffolds apps/reports and registers it in wrnexus.workspace.ts:
wrnexus workspace add reports --domain=reports.localhost
bun install
bun run dev
Forward authentication
Point protected applications at a dedicated verifier endpoint. The verifier must return 2xx for an authenticated session, 401/403 to deny access, or an HTTP redirect to begin browser login.
// wrnexus.workspace.ts
{
@@ -28,8 +28,8 @@ export const GET = async (ctx: Context) => {
return redirectToLogin(ctx, "/login", {
allowedHosts: ["admin.localhost:3000", "reports.localhost:3000"],
});
-};
Always allowlist redirect hosts. After login, validate or sign the returnTo value before redirecting. Keep internal app ports private and open applications through the gateway port.
Release scope
This guide describes installed 0.7.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
-
+};Always allowlist redirect hosts. After login, validate or sign the returnTo value before redirecting. Keep internal app ports private and open applications through the gateway port.
This guide describes installed 0.8.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.
WRNexusJS v0.7.0
WRNexusJS is an SSR-first, Bun-native full-stack framework. Build typed pages, APIs, validated forms, realtime rooms, secure sessions, workspaces, and optional mobile experiences with the .wrn component language.
Private developer preview. Request access to the package registry.
page Dashboard {
+ WRNexusJS v0.8.0
Build from the server.
Ship only what matters.
WRNexusJS is an SSR-first, Bun-native full-stack framework. Build typed pages, APIs, validated forms, realtime rooms, secure sessions, workspaces, and optional mobile experiences with the .wrn component language.
Private developer preview. Request access to the package registry.
app/pages/dashboard.wrnpage Dashboard {
ssr { api tasks GET /api/tasks { return tasks } }
view {
<main>
@@ -35,10 +35,10 @@ export const POST = async (ctx) => {
return result.ok ? Response.json({ ok: true }, { status: 201 }) : result.response;
};
Request lifecycle
- RequestSecurity headers and request limits
- MiddlewareAuthentication, policy, and context
- File routePage or API handler
- Compiler + SSRSafe HTML and scoped runtime
- ResponseHTML, JSON, stream, or realtime upgrade
-Production proof
WorkRoot
Public creator/company site and approved WRNexusJS production showcase.
wrnexusjs.dev
This documentation application runs WRNexusJS 0.7.0.
-Capability status
Capability Status Details SSR, routing, compiler, APIs Preview Installed in 0.7.0; public support policy pending. Mobile/native Experimental Capacitor compatibility and native generation have platform limitations. Durable queues Experimental Production durability requires an appropriate driver strategy.
-Continue exploring
-
+Production proof
WorkRoot
Public creator/company site and approved WRNexusJS production showcase.
wrnexusjs.dev
This documentation application runs WRNexusJS 0.8.0.
+Capability status
Capability Status Details SSR, routing, compiler, APIs Preview Installed in 0.8.0; public support policy pending. Mobile/native Experimental Capacitor compatibility and native generation have platform limitations. Durable queues Experimental Production durability requires an appropriate driver strategy.
+Continue exploring
+
}
diff --git a/app/pages/language.wrn b/app/pages/language.wrn
index de8eb1ed..de95d38b 100644
--- a/app/pages/language.wrn
+++ b/app/pages/language.wrn
@@ -7,15 +7,15 @@ page Thewrnlanguage {
view {
- W WRNexusJS
+ W WRNexusJS
Browse documentation
- Language reference · 0.7.0The .wrn language
File anatomy
page Account {
+ Language reference · 0.8.0The .wrn language
File anatomy
page Account {
layout = "public"
seo { title = "Account" description = "Manage your account." }
state count = 0
view { <button @click="count++">Count {count}</button> }
}
Pages, components, layouts, props, and state
Pages are routes. Components declare default-valued props and may hold state. Layouts provide shared slots. Mount components with data-component; fill default or named slots with data-slot.
Interpolation, conditionals, and loops
Interpolation is HTML-escaped. Use server {#if} and {#each} for SSR data. Use data-show for reactive client visibility.
Events and directives
@click and other events execute in the reactive scope. Data attributes opt into forms, i18n, themes, realtime, uploader, browser, and mobile behavior. Consult the exact package page because availability varies.
Forms, i18n, themes, and realtime
form[data-schema] connects descriptors to client and server validation. Translation keys use {t:key}. Theme toggles use data-wire-theme-toggle. Realtime pages opt into a named room.
Escaping and security
Text interpolation is escaped by default. Do not construct trusted HTML from user input. Server-only refinements must be repeated at the authoritative mutation boundary.
Common compiler errors
- Use balanced braces; a literal brace must be escaped.
- Declare UI in
view, not JSX or hooks. - Use a valid page, component, or layout declaration matching the file role.
- Keep server loops tied to available SSR bindings.
- Check troubleshooting and compiler API for this release.
-
+
}
diff --git a/app/pages/license.wrn b/app/pages/license.wrn
index 934bcaed..c10e8eb6 100644
--- a/app/pages/license.wrn
+++ b/app/pages/license.wrn
@@ -7,10 +7,10 @@ page License {
view {
- W WRNexusJS
+ W WRNexusJS
Browse documentation
License
Owner decision requiredThis documentation repository contains no public license file, and the packages are unavailable from the public npm registry. No open-source license or redistribution right should be inferred.
Approved preview users must follow the private/commercial terms supplied by WorkRoot. Contact WorkRoot before copying, redistributing, or using WRNexusJS in production.
-
+
}
diff --git a/app/pages/packages.wrn b/app/pages/packages.wrn
index 13be1e1f..2b2a874b 100644
--- a/app/pages/packages.wrn
+++ b/app/pages/packages.wrn
@@ -12,10 +12,10 @@ page Packages {
W WRNexusJS
-
+
Browse documentation
- 31 focused packagesPackage reference
Everything in the framework, organized by responsibility and documented from the published 0.7.0 APIs.
Showing {category} packages
+ 46 focused packagesPackage reference
Everything in the framework, organized by responsibility and documented from the published 0.8.0 APIs.
Showing {category} packages
AI@wrnexus/ai
Server-side Anthropic client with generation and streaming.
Open documentation →
@@ -24,6 +24,12 @@ page Packages {
Security@wrnexus/authz
Role, permission, policy, and authorization guards.
Open documentation →
+
+ Tooling@wrnexus/benchmark
Framework benchmark scenarios and repeatable performance measurements.
Open documentation →
+
+
+ Data@wrnexus/cache
Memory and distributed caching with coordination and invalidation.
Open documentation →
+
Security@wrnexus/captcha
Managed CAPTCHA verification, middleware, and UI integration.
Open documentation →
@@ -33,6 +39,9 @@ page Packages {
Core@wrnexus/compiler
Parser and code generators for the .wrn language.
Open documentation →
+
+ Data@wrnexus/content
Content collections, validation, querying, and publishing workflows.
Open documentation →
+
Core@wrnexus/core
Contexts, middleware, security, sessions, caching, JSX, and realtime.
Open documentation →
@@ -51,15 +60,30 @@ page Packages {
Security@wrnexus/encryption
Hashing, HMAC, authenticated encryption, and key derivation.
Open documentation →
+
+ Data@wrnexus/graphql
GraphQL schemas, routes, and framework plugin integration.
Open documentation →
+
Tooling@wrnexus/helpers
Safe Context URL helpers and forward-auth login redirects.
Open documentation →
Frontend@wrnexus/i18n
Translation loading, locale resolution, and Intl formatting.
Open documentation →
+
+ Security@wrnexus/identity
Portable identity records, claims, and account linking.
Open documentation →
+
+
+ Frontend@wrnexus/image
Responsive image optimization, loaders, placeholders, and components.
Open documentation →
+
Security@wrnexus/jwt
HS256 JWT signing, verification, and bearer authentication.
Open documentation →
+
+ Tooling@wrnexus/language-server
Editor-neutral language intelligence for WRN files.
Open documentation →
+
+
+ Tooling@wrnexus/mcp
Model Context Protocol tools for WRNexus projects.
Open documentation →
+
Native@wrnexus/mobile
SSR-safe compatibility access to Capacitor plugins.
Open documentation →
@@ -69,24 +93,42 @@ page Packages {
Security@wrnexus/oauth
OAuth 2.0, PKCE, provider presets, and profile mapping.
Open documentation →
+
+ Runtime@wrnexus/observability
Structured logging, tracing, health, and integration adapters.
Open documentation →
+
+
+ Tooling@wrnexus/playground
Interactive framework examples and executable playground utilities.
Open documentation →
+
Core@wrnexus/plugin
Plugin contracts, lifecycle hooks, composition, and framework integration.
Open documentation →
Realtime@wrnexus/pubsub
In-process and Redis-backed publish/subscribe.
Open documentation →
+
+ Frontend@wrnexus/pwa
Progressive Web App manifests, service workers, and offline strategies.
Open documentation →
+
Data@wrnexus/queue
Background jobs with delay, concurrency, retry, and repetition.
Open documentation →
Frontend@wrnexus/reactive
Small type-safe reactive signal primitives.
Open documentation →
+
+ Realtime@wrnexus/realtime
Rooms, presence, messaging, history, streams, and UI components.
Open documentation →
+
Core@wrnexus/router
Filesystem discovery, route matching, and typed route generation.
Open documentation →
+
+ Security@wrnexus/security
Security headers, CSRF protection, rate limits, and safe rendering.
Open documentation →
+
Runtime@wrnexus/ssr
Secure HTML document rendering and SEO metadata.
Open documentation →
+
+ Data@wrnexus/store
Application state stores shared across server and browser runtimes.
Open documentation →
+
Frontend@wrnexus/styles
CSS pipeline, themes, fonts, profiles, and application config.
Open documentation →
@@ -99,6 +141,9 @@ page Packages {
Runtime@wrnexus/tracking
Error/event capture, middleware, filtering, and sinks.
Open documentation →
+
+ Tooling@wrnexus/typecheck
WRN-aware TypeScript diagnostics and virtual documents.
Open documentation →
+
Frontend@wrnexus/ui
Themeable server-rendered UI components and CSS.
Open documentation →
@@ -108,7 +153,7 @@ page Packages {
Security@wrnexus/validation
Typed schemas, coercion, validation, and browser descriptors.
Open documentation →
-
+
Server-side Anthropic client with generation and streaming.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ai@0.7.0Request preview access. Never put registry tokens in source control.
A tiny, zero-dependency Claude (Anthropic) client for WRNexusJS apps — generate and stream text with Claude from any server-side code.+
Server-side Anthropic client with generation and streaming.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ai@0.8.0Request preview access. Never put registry tokens in source control.
Provider-neutral AI orchestration for OpenAI, Anthropic, Google and local OpenAI-compatible models, with streaming, structured output, tools, embeddings, vector search/RAG, conversation persistence, templates, guardrails, usage events, fallback, rate limits and evaluation reports.
+A tiny, zero-dependency Claude (Anthropic) client for WRNexusJS apps — generate and stream text with Claude from any server-side code.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/ai is a thin, dependency-free wrapper over the Anthropic Messages API, built on fetch (Bun-native, no SDK). Use it in API routes, jobs, or middleware to call Claude. It defaults to the most capable model, claude-opus-4-8, reads your key from ANTHROPIC_API_KEY, and supports both one-shot generation and streaming.
createAIClient adds named-provider selection and fallback, capability discovery, validated JSON output, validated tool execution, abort-aware exponential retries, and per-provider circuit breakers. Attempt events intentionally contain metadata only: prompts, credentials, and raw model responses are never passed to telemetry.
import { anthropicProvider, createAIClient } from "@wrnexus/ai";
+
+const ai = createAIClient({
+ providers: [anthropicProvider()],
+ retry: { attempts: 3, baseDelayMs: 100, maxDelayMs: 2_000 },
+ circuitBreaker: { failureThreshold: 5, resetAfterMs: 30_000 },
+});
+
+const result = await ai.generateObject<{ title: string }>("Return a JSON title", {
+ validate: (value): value is { title: string } =>
+ typeof value === "object" && value !== null && "title" in value,
+});
+Providers can return normalized usage (inputTokens, outputTokens, totalTokens, and costUsd) and toolCalls. Use executeTools with a named, validated tool registry; unknown tools and invalid arguments are rejected before application code runs. deterministicAIProvider supplies ordered or computed offline responses for tests and examples without API keys or network calls.
// app/api/summarize.ts — summarize posted text
@@ -109,112 +125,7 @@ export const POST = async (ctx) => {
Zero dependencies — no @anthropic-ai/sdk; talks to the Messages API directly.
Defaults to claude-opus-4-8. Pass { model } for a different model (e.g.
"claude-sonnet-5" for speed/cost, "claude-haiku-4-5" for the fastest).
-Generated from the exact installed package declarations.
interface AIUsage {
- inputTokens?: number;
- outputTokens?: number;
- totalTokens?: number;
-}
-interface AIResult<T = string> {
- value: T;
- provider: string;
- model?: string;
- usage?: AIUsage;
- finishReason?: string;
- raw?: unknown;
-}
-interface AIProvider {
- name: string;
- generate(prompt: string | Message[], options?: GenerateOptions): Promise<AIResult<string>>;
- stream?(prompt: string | Message[], options?: GenerateOptions): AsyncGenerator<string, void, unknown>;
-}
-interface AIClientOptions {
- providers: AIProvider[];
- fallback?: boolean;
- onAttempt?: (provider: string, error?: unknown) => void | Promise<void>;
-}
-interface AIClient {
- generate(prompt: string | Message[], options?: GenerateOptions & {
- provider?: string;
- }): Promise<AIResult<string>>;
- generateObject<T>(prompt: string | Message[], options?: GenerateOptions & {
- provider?: string;
- validate?: (value: unknown) => value is T;
- }): Promise<AIResult<T>>;
- stream(prompt: string | Message[], options?: GenerateOptions & {
- provider?: string;
- }): AsyncGenerator<string, void, unknown>;
-}
-declare function anthropicProvider(config?: AIConfig): AIProvider;
-declare function aiProvider(name: string, client: AI): AIProvider;
-declare function createAIClient(options: AIClientOptions): AIClient;
-
-/**
- * @wrnexus/ai — a tiny, zero-dependency Claude (Anthropic) client for WRNexusJS apps.
- *
- * Use it in API routes, jobs, or anywhere server-side to generate text with Claude.
- * It talks to the Anthropic Messages API over `fetch` (no SDK dependency, Bun-native),
- * and defaults to the most capable model, `claude-opus-4-8`.
- *
- * import { createAI } from "@wrnexus/ai";
- * const ai = createAI(); // reads ANTHROPIC_API_KEY
- * const text = await ai.generate("Write a haiku about Bun.");
- *
- * Streaming (great for API routes):
- * export const POST = async (ctx) => ai.streamResponse(await ctx.req.text());
- */
-type Role = "user" | "assistant";
-interface Message {
- role: Role;
- content: string;
-}
-/** Reasoning effort — higher means deeper thinking + more tokens. */
-type Effort = "low" | "medium" | "high" | "xhigh" | "max";
-interface AIConfig {
- /** Anthropic API key. Default: `ANTHROPIC_API_KEY` from the environment. */
- apiKey?: string;
- /** Model id. Default: `claude-opus-4-8` (the most capable Claude model). */
- model?: string;
- /** Default max output tokens. Default: 4096. */
- maxTokens?: number;
- /** API base URL. Default: `https://api.anthropic.com`. */
- baseURL?: string;
- /** `anthropic-version` header. Default: `2023-06-01`. */
- version?: string;
-}
-interface GenerateOptions {
- /** System prompt — sets the assistant's role/behavior. */
- system?: string;
- /** Override the model for this call. */
- model?: string;
- /** Override max output tokens for this call. */
- maxTokens?: number;
- /** Enable adaptive extended thinking (slower, deeper reasoning). */
- thinking?: boolean;
- /** Reasoning effort / token spend (`output_config.effort`). */
- effort?: Effort;
- /** Full message history — supersedes the `prompt` argument when provided. */
- messages?: Message[];
- /** Abort the request. */
- signal?: AbortSignal;
-}
-/** Thrown when the API returns a non-2xx response or refuses the request. */
-declare class AIError extends Error {
- readonly status: number;
- readonly type: string;
- constructor(message: string, status?: number, type?: string);
-}
-interface AI {
- /** Generate a full text response (non-streaming). */
- generate(prompt: string | Message[], opts?: GenerateOptions): Promise<string>;
- /** Stream the response as text deltas, as they arrive. */
- stream(prompt: string | Message[], opts?: GenerateOptions): AsyncGenerator<string, void, unknown>;
- /** Stream straight to a `Response` (text/plain) — drop-in for an API route return. */
- streamResponse(prompt: string | Message[], opts?: GenerateOptions): Response;
-}
-/** Create a Claude client. Reads `ANTHROPIC_API_KEY` from the environment by default. */
-declare function createAI(config?: AIConfig): AI;
-
-export { type AI, type AIClient, type AIClientOptions, type AIConfig, AIError, type AIProvider, type AIResult, type AIUsage, type Effort, type GenerateOptions, type Message, type Role, aiProvider, anthropicProvider, createAI, createAIClient };
+Generated from the exact installed package declarations.
export { A as AI, a as AIAttemptEvent, b as AICircuitBreakerOptions, c as AIClient, d as AIClientOptions, e as AIConfig, f as AIError, AIGuardrail, g as AIProvider, h as AIProviderCapabilities, i as AIResult, j as AIRetryOptions, k as AITool, l as AIToolCall, m as AIUsage, ConversationStore, D as DeterministicAIProviderOptions, E as Effort, EmbeddingProvider, G as GenerateOptions, HttpAIProviderOptions, M as Message, R as Role, VectorMatch, VectorRecord, VectorStore, n as aiProvider, aiRateLimiter, o as anthropicProvider, p as createAI, q as createAIClient, createRagPipeline, r as deterministicAIProvider, evaluateAI, googleAIProvider, guardedProvider, localAIProvider, maxPromptLength, memoryConversationStore, memoryVectorStore, openAIEmbeddings, openAIProvider, promptTemplate } from './platform.js';
Copy-ready examples from the installed package documentation.
// app/api/summarize.ts — summarize posted text
import { createAI } from "@wrnexus/ai";
const ai = createAI();
@@ -238,9 +149,9 @@ export const POST = async (ctx) => {
maxTokens: 1_500,
});
};Authentication routes, sessions, forms, guards, and account flows.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/auth@0.7.0Request preview access. Never put registry tokens in source control.
Framework-native authentication, identity, account-security, and session management for WRNexusJS.
+Authentication routes, sessions, forms, guards, and account flows.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/auth@0.8.0Request preview access. Never put registry tokens in source control.
Framework-native authentication, identity, account-security, and session management for WRNexusJS.
bun run auth:dev
bun run validate:auth
-Read [SECURITY.md](./SECURITY.md) before production deployment.
Generated from the exact installed package declarations.
export { A as AuthEngine, c as createAuthEngine, i as inferIdentityType, n as normalizeEmail, a as normalizeIdentity, b as normalizePhone, d as normalizeUsername, p as publicUser, s as safeAuthReturnTo } from './engine-ZXtjHSyW.js';
-import { n as AuthRiskSignals, l as AuthRiskDecision } from './types-CbJKeaWh.js';
-export { A as AuthAccountStatus, a as AuthClock, b as AuthDeliveryMessage, c as AuthDeliveryProvider, d as AuthEngineOptions, e as AuthIdentity, f as AuthIdentityType, g as AuthImpersonationDecision, h as AuthMfaMethod, i as AuthPublicUser, j as AuthRandom, k as AuthResult, m as AuthRiskLevel, o as AuthSecretProtector, p as AuthSecurityEvent, q as AuthSession, r as AuthSessionVerificationHandler, s as AuthSignedInHandler, t as AuthSignedOutHandler, N as AuthStore, u as AuthSuccessfulSignUpAction, v as AuthSuccessfulSignUpHandler, w as AuthTokenPurpose, x as AuthTokenUrlInput, y as AuthUser, z as AuthenticatedContext, L as LoginAttempt, B as LoginInput, Q as MemoryPasskeyChallengeStore, O as OAuthAccount, C as OneTimeToken, D as OtpChallenge, P as PasskeyAuthenticationOptions, S as PasskeyChallengeKind, U as PasskeyChallengeRecord, V as PasskeyChallengeStore, E as PasskeyCredential, F as PasskeyProvider, G as PasskeyRegistrationOptions, H as PasskeyVerificationResult, I as PasswordBreachProvider, J as PasswordCredential, R as RecoveryCodeRecord, K as RegisterInput, T as TotpCredential, M as TrustedDevice, W as assertPasskeyProvider } from './types-CbJKeaWh.js';
+Read [SECURITY.md](./SECURITY.md) before production deployment.
+Package-owned UI blocks and route helpers
+Authentication forms continue to compose @wrnexus/ui inputs, buttons, cards, alerts, badges, avatars, and PIN controls. The package also provides:
+
+<AuthShell />
+<AuthProviderButtons />
+<AuthSecurityNotice />
+- complete sign-in, sign-up, MFA, passkey, recovery, account-status, session, and impersonation blocks
+
+Server helpers include authRoute, authSuccess, authFailure, requireAuthUser, optionalAuthUser, currentAuthSession, and authComponentProps.
Generated from the exact installed package declarations.
import { A as AuthEngine } from './engine-BDu0-aZp.js';
+export { c as createAuthEngine, i as inferIdentityType, n as normalizeEmail, a as normalizeIdentity, b as normalizePhone, d as normalizeUsername, p as publicUser, s as safeAuthReturnTo } from './engine-BDu0-aZp.js';
+import { o as AuthRiskSignals, m as AuthRiskDecision, s as AuthSession, B as AuthUser } from './types-BhwPi3qr.js';
+export { A as AUTH_SECURITY_EVENT_TYPES, a as AuthAccountStatus, b as AuthClock, c as AuthDeliveryMessage, d as AuthDeliveryProvider, e as AuthEngineOptions, f as AuthIdentity, g as AuthIdentityType, h as AuthImpersonationDecision, i as AuthMfaMethod, j as AuthPublicUser, k as AuthRandom, l as AuthResult, n as AuthRiskLevel, p as AuthSecretProtector, q as AuthSecurityEvent, r as AuthSecurityEventType, t as AuthSessionVerificationHandler, u as AuthSignedInHandler, v as AuthSignedOutHandler, U as AuthStore, w as AuthSuccessfulSignUpAction, x as AuthSuccessfulSignUpHandler, y as AuthTokenPurpose, z as AuthTokenUrlInput, C as AuthenticatedContext, K as KnownAuthSecurityEventType, L as LoginAttempt, D as LoginInput, V as MemoryPasskeyChallengeStore, O as OAuthAccount, E as OneTimeToken, F as OtpChallenge, P as PasskeyAuthenticationOptions, W as PasskeyChallengeKind, X as PasskeyChallengeRecord, Y as PasskeyChallengeStore, G as PasskeyCredential, H as PasskeyProvider, I as PasskeyRegistrationOptions, J as PasskeyVerificationResult, M as PasswordBreachProvider, N as PasswordCredential, R as RecoveryCodeRecord, Q as RegisterInput, T as TotpCredential, S as TrustedDevice, Z as assertPasskeyProvider } from './types-BhwPi3qr.js';
export { MemoryAuthStore } from './stores/memory.js';
export { SqlAuthStore } from './stores/sql.js';
export { AUTH_SESSION_KEY, authSession, clearAuthSession, establishAuthSession, getAuthSession, getAuthUser, isAuthenticatedContext, requireAuth } from './middleware.js';
-export { A as AuthHttpOptions, a as AuthPasskeyHttpOptions, b as AuthSchemaOverrides, c as AuthSchemaSet, d as authBrowserSchemaDescriptors, e as authBrowserSchemaMap, f as authSchemas, g as authenticatorConfirmSchema, h as authenticatorDisableSchema, i as authenticatorSetupSchema, j as changePasswordSchema, k as createAuthHttpHandlers, l as emptyActionSchema, m as impersonationStartSchema, n as invitationAcceptSchema, o as loginSchema, p as magicLinkConsumeSchema, q as magicLinkRequestSchema, r as mfaOtpRequestSchema, s as mfaSchema, t as otpIssueSchema, u as otpLoginCompleteSchema, v as otpLoginRequestSchema, w as otpSchema, x as passkeyAuthenticationOptionsSchema, y as passkeyAuthenticationVerifySchema, z as passkeyRegistrationOptionsSchema, B as passkeyRegistrationVerifySchema, C as passwordResetRequestSchema, D as passwordResetSchema, E as recoveryCodesSchema, F as registerSchema, G as resolveAuthSchemas, H as sessionRevokeSchema, I as signUpSchema, J as verificationRequestSchema, K as verificationTokenSchema } from './index-DS1geh2P.js';
+export { A as AuthHttpOptions, a as AuthPasskeyHttpOptions, b as AuthSchemaOverrides, c as AuthSchemaSet, d as authBrowserSchemaDescriptors, e as authBrowserSchemaMap, f as authSchemas, g as authenticatorConfirmSchema, h as authenticatorDisableSchema, i as authenticatorSetupSchema, j as changePasswordSchema, k as createAuthHttpHandlers, l as emptyActionSchema, m as impersonationStartSchema, n as invitationAcceptSchema, o as loginSchema, p as magicLinkConsumeSchema, q as magicLinkRequestSchema, r as mfaOtpRequestSchema, s as mfaSchema, t as otpIssueSchema, u as otpLoginCompleteSchema, v as otpLoginRequestSchema, w as otpSchema, x as passkeyAuthenticationOptionsSchema, y as passkeyAuthenticationVerifySchema, z as passkeyRegistrationOptionsSchema, B as passkeyRegistrationVerifySchema, C as passwordResetRequestSchema, D as passwordResetSchema, E as recoveryCodesSchema, F as registerSchema, G as resolveAuthSchemas, H as sessionRevokeSchema, I as signUpSchema, J as verificationRequestSchema, K as verificationTokenSchema } from './index-B4uaD0Z3.js';
export { AuthAuditIssue, AuthConfig, AuthPluginOptions, AuthRoutesConfig, authComponentsDir, authPlugin } from './plugin.js';
export { DefaultAuthRouteOptions, clearDefaultAuthEngine, getDefaultAuthEngine, getDefaultAuthRouteOptions, getDefaultAuthSchemas, hasDefaultAuthEngine, setDefaultAuthEngine, setDefaultAuthRouteOptions, setDefaultAuthSchemas, tryGetDefaultAuthEngine } from './runtime.js';
export { createAuthSecretProtector } from './protector.js';
export { decodeBase32, encodeBase32, generateTotp, generateTotpSecret, totpUri, verifyTotp } from './totp/index.js';
+import { Context } from '@wrnexus/core';
import '@wrnexus/oauth';
-import '@wrnexus/core';
import '@wrnexus/db';
import '@wrnexus/validation';
import '@wrnexus/plugin';
@@ -296,7 +306,23 @@ interface RiskPolicy {
}
declare function evaluateAuthRisk(signals?: AuthRiskSignals, policy?: RiskPolicy): AuthRiskDecision;
-export { AuthRiskDecision, AuthRiskSignals, type RiskPolicy, evaluateAuthRisk };
+type AuthRouteName = "signIn" | "signUp" | "signOut" | "forgotPassword" | "resetPassword" | "verifyEmail" | "verifyPhone" | "twoFactor" | "sessions" | "passkeys";
+declare function authRoute(name: AuthRouteName, options?: {
+ basePath?: string;
+ overrides?: Partial<Record<AuthRouteName, string>>;
+}): string;
+declare function authSuccess<T extends Record<string, unknown>>(data: T, init?: ResponseInit): Response;
+declare function authFailure(code: string, message: string, status?: number, details?: Record<string, unknown>): Response;
+declare function requireAuthUser(ctx: Context): AuthUser;
+declare function optionalAuthUser(ctx: Context): AuthUser | null;
+declare function currentAuthSession(engine: AuthEngine, sessionId: string | undefined): Promise<AuthSession | null>;
+declare function authComponentProps(input: Record<string, unknown>, defaults?: {
+ color?: string;
+ size?: string;
+ class?: string;
+}): Record<string, unknown>;
+
+export { AuthEngine, AuthRiskDecision, AuthRiskSignals, type AuthRouteName, AuthSession, AuthUser, type RiskPolicy, authComponentProps, authFailure, authRoute, authSuccess, currentAuthSession, evaluateAuthRisk, optionalAuthUser, requireAuthUser };
Copy-ready examples from the installed package documentation.
bun add @wrnexus/auth// app/lib/auth.ts
import { createAuthEngine, MemoryAuthStore } from "@wrnexus/auth";
@@ -358,9 +384,9 @@ export const auth = createAuthEngine({
migrations: true,
},
};Role, permission, policy, and authorization guards.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/authz@0.7.0Request preview access. Never put registry tokens in source control.
Composable authorization for WRNexusJS — role-based (RBAC), policy-based (PBAC), and attribute-based (ABAC) access control that reduces to a boolean check plus an authorize() guard.
+ Role, permission, policy, and authorization guards.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/authz@0.8.0Request preview access. Never put registry tokens in source control.
Composable authorization for WRNexusJS — role-based (RBAC), policy-based (PBAC), and attribute-based (ABAC) access control that reduces to a boolean check plus an authorize() guard.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/authz is a small, server-side authorization toolkit. It gives you three interchangeable models — RBAC (roles → permissions), PBAC (policy predicates), and ABAC (attribute matchers) — that all collapse to a boolean | Promise<boolean> decision. Wrap any decision in a Middleware guard (authorize, requireRole, requirePermission) to protect WRNexusJS routes. Reach for it whenever a route or action needs to be gated on who the user is, what roles they hold, or attributes of the user and the resource. It plugs into @wrnexus/core by reading ctx.user as the authorization subject.
Framework benchmark scenarios and repeatable performance measurements.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/benchmark@0.8.0Request preview access. Never put registry tokens in source control.
Deterministic benchmark execution, percentiles, baseline comparisons, and regression budgets for builds, SSR, hydration, stores, and application hot paths.
+import { runBenchmark, assertBenchmarkBudget } from "@wrnexus/benchmark";
+const result = await runBenchmark("render", render, { iterations: 100 });
+assertBenchmarkBudget(result, baseline, { p95Percent: 5 });Generated from the exact installed package declarations.
interface BenchmarkOptions {
+ iterations?: number;
+ warmup?: number;
+ clock?: () => number;
+ setup?: () => void | Promise<void>;
+ teardown?: () => void | Promise<void>;
+}
+interface BenchmarkResult {
+ name: string;
+ iterations: number;
+ totalMs: number;
+ meanMs: number;
+ minMs: number;
+ maxMs: number;
+ p50Ms: number;
+ p95Ms: number;
+ p99Ms: number;
+ operationsPerSecond: number;
+ samples: number[];
+}
+interface RegressionBudget {
+ meanPercent?: number;
+ p95Percent?: number;
+ maxAbsoluteMs?: number;
+ minOperationsPerSecond?: number;
+}
+interface RegressionViolation {
+ metric: "meanMs" | "p95Ms" | "maxMs" | "operationsPerSecond";
+ baseline?: number;
+ current: number;
+ limit: number;
+ message: string;
+}
+declare function percentile(values: readonly number[], quantile: number): number;
+declare function runBenchmark(name: string, operation: () => void | Promise<void>, options?: BenchmarkOptions): Promise<BenchmarkResult>;
+declare function compareBenchmark(current: BenchmarkResult, baseline: BenchmarkResult | undefined, budget?: RegressionBudget): RegressionViolation[];
+declare function assertBenchmarkBudget(current: BenchmarkResult, baseline: BenchmarkResult | undefined, budget: RegressionBudget): void;
+
+export { type BenchmarkOptions, type BenchmarkResult, type RegressionBudget, type RegressionViolation, assertBenchmarkBudget, compareBenchmark, percentile, runBenchmark };
+Copy-ready examples from the installed package documentation.
import { runBenchmark, assertBenchmarkBudget } from "@wrnexus/benchmark";
+const result = await runBenchmark("render", render, { iterations: 100 });
+assertBenchmarkBudget(result, baseline, { p95Percent: 5 });bun add @wrnexus/benchmarkMemory and distributed caching with coordination and invalidation.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/cache@0.8.0Request preview access. Never put registry tokens in source control.
Bounded in-memory/tag caching and HTTP response caching for WRNexusJS. Supports request deduplication, tag invalidation, ETags, fresh/stale states, and optional detached stale revalidation.
+import { connectCacheInvalidation, TagCache, responseCache } from "@wrnexus/cache";
+const cache = new TagCache({ ttlMs: 60_000, staleWhileRevalidateMs: 300_000 });
+export default responseCache({ cache, tags: ["products"] });
+TagCache bounds entries with LRU-style eviction, deduplicates concurrent loaders, and prevents an invalidated in-flight loader from repopulating stale data. Use lookup() when fresh/stale state matters, or getOrLoad() for stampede-safe loading.
For multi-instance applications, connect the cache to any compatible pub/sub bus (including @wrnexus/pubsub). Namespaces isolate applications sharing the same broker. Local invalidation happens first and the returned promise confirms cross-instance publication; failures remain visible to the caller.
import { connectCacheInvalidation, TagCache } from "@wrnexus/cache";
+import { createPubSub } from "@wrnexus/pubsub";
+import { redisDriver } from "@wrnexus/pubsub/redis";
+
+const cache = new TagCache({ maxEntries: 10_000 });
+const bus = createPubSub(redisDriver(process.env.REDIS_URL));
+const invalidation = connectCacheInvalidation(cache, bus, {
+ namespace: "storefront-production",
+ onError: (error) => logger.error("cache invalidation failed", { error }),
+});
+
+await invalidation.invalidateTag("products");
+await invalidation.delete("product:42");
+
+// Unsubscribes this cache only; the shared bus remains owned by the app.
+invalidation.close();
+await bus.close();
+CacheCoordinator keeps the four cache lifetimes explicit:
coordinator.request() creates request-only deduplication.coordinator.data caches loader/query results.coordinator.component caches reusable rendered fragments.coordinator.page caches complete safe documents.All cross-request layers are bounded, tag-aware, stale-while-revalidate capable, stampede-safe, and expose withLock() for exclusive per-key work. inspect() returns metadata without cached values. Development applications expose that inspection through the Cache panel and GET /__wrnexus/cache.
Pages and components can opt in declaratively:
+cache {
+ scope = "page"
+ strategy = "stale-while-revalidate"
+ ttl = "5m"
+ stale = "10m"
+ tags = ["catalog", "marketing"]
+ vary = ["tenant", "language"]
+}
+Omit scope to cache named loader data. Use scope = "page" for full-page caching. Component policies cache their rendered fragment. Authenticated user and tenant identities are always included automatically; page caches also vary by language, theme, and accent. Add header names or cookie:name entries for other application-specific variation. Pages containing CSRF forms are never stored in the full-page cache.
Generated from the exact installed package declarations.
import { Context, Middleware } from '@wrnexus/core';
+
+interface CacheEntry<V> {
+ value: V;
+ createdAt: number;
+ expiresAt: number;
+ staleUntil: number;
+ tags: string[];
+}
+type CacheLookup<V> = {
+ state: "miss";
+} | {
+ state: "fresh" | "stale";
+ entry: CacheEntry<V>;
+};
+interface CacheSetOptions {
+ ttlMs?: number;
+ staleWhileRevalidateMs?: number;
+ tags?: string[];
+}
+interface TagCacheOptions {
+ ttlMs?: number;
+ staleWhileRevalidateMs?: number;
+ maxEntries?: number;
+ clock?: () => number;
+ onEvent?: (event: CacheEvent) => void;
+}
+interface CacheEvent {
+ operation: "hit" | "stale" | "miss" | "set" | "delete" | "invalidate" | "clear" | "load";
+ key?: string;
+ tags?: string[];
+ at: number;
+}
+interface CacheSnapshotEntry {
+ key: string;
+ state: "fresh" | "stale";
+ createdAt: number;
+ expiresAt: number;
+ staleUntil: number;
+ tags: string[];
+}
+declare class TagCache<V = unknown> {
+ private entries;
+ private tagIndex;
+ private pending;
+ private locks;
+ private revisions;
+ private readonly ttlMs;
+ private readonly staleMs;
+ private readonly maxEntries;
+ private readonly clock;
+ private readonly onEvent?;
+ constructor(options?: TagCacheOptions);
+ private emit;
+ lookup(key: string): CacheLookup<V>;
+ get(key: string): V | undefined;
+ set(key: string, value: V, options?: CacheSetOptions): void;
+ private store;
+ getOrLoad(key: string, loader: () => V | Promise<V>, options?: CacheSetOptions): Promise<V>;
+ /** Serialize arbitrary cache-adjacent work for a key without storing its result. */
+ withLock<T>(key: string, task: () => T | Promise<T>): Promise<T>;
+ delete(key: string): boolean;
+ private removeEntry;
+ invalidateTag(tag: string): number;
+ invalidateTags(tags: Iterable<string>): number;
+ clear(): void;
+ get size(): number;
+ snapshot(): CacheSnapshotEntry[];
+ private revision;
+ private bump;
+}
+
+type CacheLayerName = "data" | "component" | "page";
+interface CacheInspection {
+ layers: Record<CacheLayerName, ReturnType<TagCache<unknown>["snapshot"]>>;
+ recentEvents: Array<CacheEvent & {
+ layer: CacheLayerName;
+ }>;
+}
+interface CacheCoordinatorOptions extends Omit<TagCacheOptions, "onEvent"> {
+ eventLimit?: number;
+ onEvent?: (event: CacheEvent & {
+ layer: CacheLayerName;
+ }) => void;
+}
+/** A request-lifetime cache: deduplicates work without leaking values between requests. */
+declare class RequestCache {
+ private pending;
+ getOrLoad<V>(key: string, loader: () => V | Promise<V>): Promise<V>;
+ clear(): void;
+}
+/** Owns the three cross-request cache layers and creates isolated request caches. */
+declare class CacheCoordinator {
+ readonly data: TagCache<unknown>;
+ readonly component: TagCache<unknown>;
+ readonly page: TagCache<unknown>;
+ private readonly events;
+ private readonly eventLimit;
+ constructor(options?: CacheCoordinatorOptions);
+ request(): RequestCache;
+ layer(name: CacheLayerName): TagCache<unknown>;
+ getOrLoad<V>(layer: CacheLayerName, key: string, loader: () => V | Promise<V>, options?: CacheSetOptions): Promise<V>;
+ invalidateTags(tags: Iterable<string>): number;
+ inspect(): CacheInspection;
+ clear(): void;
+}
+
+interface CachedResponse {
+ status: number;
+ statusText: string;
+ headers: [string, string][];
+ body: Uint8Array;
+ etag: string;
+}
+interface ResponseCacheOptions extends CacheSetOptions {
+ cache?: TagCache<CachedResponse>;
+ key?: (ctx: Context) => string;
+ vary?: string[];
+ shouldCache?: (ctx: Context, response: Response) => boolean;
+ /**
+ * Optional detached revalidator used for stale-while-revalidate. Middleware
+ * `next()` is deliberately never called after a response has been returned,
+ * because many middleware pipelines are single-use.
+ */
+ revalidate?: (ctx: Context) => Promise<Response>;
+ onRevalidateError?: (error: unknown, ctx: Context) => void;
+}
+declare function responseCache(options?: ResponseCacheOptions): Middleware;
+
+interface CacheInvalidationBus {
+ publish(topic: string, message: unknown): void | Promise<void>;
+ subscribe(pattern: string, handler: (message: unknown) => void | Promise<void>): () => void;
+}
+interface DistributedInvalidationOptions {
+ namespace?: string;
+ instanceId?: string;
+ onError?: (error: unknown) => void;
+}
+interface DistributedInvalidation {
+ invalidateTag(tag: string): Promise<number>;
+ invalidateTags(tags: Iterable<string>): Promise<number>;
+ delete(key: string): Promise<boolean>;
+ clear(): Promise<void>;
+ close(): void;
+}
+/**
+ * Propagate cache invalidations over any structurally compatible pub/sub bus.
+ * The bus is intentionally not closed because applications commonly share it.
+ */
+declare function connectCacheInvalidation<V>(cache: TagCache<V>, bus: CacheInvalidationBus, options?: DistributedInvalidationOptions): DistributedInvalidation;
+
+export { CacheCoordinator, type CacheCoordinatorOptions, type CacheEntry, type CacheEvent, type CacheInspection, type CacheInvalidationBus, type CacheLayerName, type CacheLookup, type CacheSetOptions, type CacheSnapshotEntry, type CachedResponse, type DistributedInvalidation, type DistributedInvalidationOptions, RequestCache, type ResponseCacheOptions, TagCache, type TagCacheOptions, connectCacheInvalidation, responseCache };
+Copy-ready examples from the installed package documentation.
import { connectCacheInvalidation, TagCache, responseCache } from "@wrnexus/cache";
+const cache = new TagCache({ ttlMs: 60_000, staleWhileRevalidateMs: 300_000 });
+export default responseCache({ cache, tags: ["products"] });import { connectCacheInvalidation, TagCache } from "@wrnexus/cache";
+import { createPubSub } from "@wrnexus/pubsub";
+import { redisDriver } from "@wrnexus/pubsub/redis";
+
+const cache = new TagCache({ maxEntries: 10_000 });
+const bus = createPubSub(redisDriver(process.env.REDIS_URL));
+const invalidation = connectCacheInvalidation(cache, bus, {
+ namespace: "storefront-production",
+ onError: (error) => logger.error("cache invalidation failed", { error }),
+});
+
+await invalidation.invalidateTag("products");
+await invalidation.delete("product:42");
+
+// Unsubscribes this cache only; the shared bus remains owned by the app.
+invalidation.close();
+await bus.close();cache {
+ scope = "page"
+ strategy = "stale-while-revalidate"
+ ttl = "5m"
+ stale = "10m"
+ tags = ["catalog", "marketing"]
+ vary = ["tenant", "language"]
+}Managed CAPTCHA verification, middleware, and UI integration.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/captcha@0.7.0Request preview access. Never put registry tokens in source control.
A first-class CAPTCHA and anti-automation package for WRNexusJS. It supports self-hosted challenges, a managed WRNexus service, external providers, form submission guards, page gates, accessible audio, adaptive risk checks, and a Tailwind-only .wrn component.
Managed CAPTCHA verification, middleware, and UI integration.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/captcha@0.8.0Request preview access. Never put registry tokens in source control.
A first-class CAPTCHA and anti-automation package for WRNexusJS. It supports self-hosted challenges, a managed WRNexus service, external providers, form submission guards, page gates, accessible audio, adaptive risk checks, and a Tailwind-only .wrn component.
bun add @wrnexus/captcha
WRNexusJS automatically discovers the package plugin, component, client runtime, styles, and DevToolbar audit. Use <Captcha /> directly after installation. The browser runtime is injected once only on responses that render a CAPTCHA; no script tag, public-file copy, or manual plugin registration is required. Call captchaPlugin(options) explicitly only when an application needs to override the discovered package configuration.
Applications may also implement CaptchaStore, CaptchaAudioRenderer, or use defineCaptchaProvider() for a completely custom service.
Generated from the exact installed package declarations.
export { CaptchaAudioRenderer, CaptchaBinding, CaptchaChallenge, CaptchaChallengeGenerator, CaptchaChallengeRecord, CaptchaChallengeType, CaptchaConcreteImageStyle, CaptchaDifficulty, CaptchaEngine, CaptchaEngineOptions, CaptchaFailureCode, CaptchaGeneratorContext, CaptchaGuardOptions, CaptchaHttpHandlers, CaptchaImageItem, CaptchaImageStyle, CaptchaMiddleware, CaptchaPageGateOptions, CaptchaPolicyMode, CaptchaPolicyOptions, CaptchaPresentation, CaptchaProvider, CaptchaProviderClientConfig, CaptchaProviderName, CaptchaResponseTokenRecord, CaptchaRiskResult, CaptchaRiskSignals, CaptchaStore, CaptchaVerificationResult, CreateCaptchaOptions, GeneratedCaptchaChallenge, VerifyCaptchaInput } from './types.js';
+Applications may also implement CaptchaStore, CaptchaAudioRenderer, or use defineCaptchaProvider() for a completely custom service.
+Helper and block kit
+The package exports captchaTokenFrom, captchaHeaders, captchaFields, verifyCaptcha, verifyCaptchaOrThrow, captchaResultResponse, and captchaContext for consistent server and client integration.
+Enable the CAPTCHA plugin to use the low-level <Captcha /> challenge plus complete UI-composed blocks:
+
+<CaptchaField />
+<CaptchaStatus />
+
+CaptchaField composes Card from @wrnexus/ui and keeps the CAPTCHA-specific size separate from the surrounding UI size.
Generated from the exact installed package declarations.
import { CaptchaVerificationResult, CaptchaProvider, CaptchaEngine, VerifyCaptchaInput } from './types.js';
+export { CaptchaAudioRenderer, CaptchaBinding, CaptchaChallenge, CaptchaChallengeGenerator, CaptchaChallengeRecord, CaptchaChallengeType, CaptchaConcreteImageStyle, CaptchaDifficulty, CaptchaEngineOptions, CaptchaFailureCode, CaptchaGeneratorContext, CaptchaGuardOptions, CaptchaHttpHandlers, CaptchaImageItem, CaptchaImageStyle, CaptchaMiddleware, CaptchaPageGateOptions, CaptchaPolicyMode, CaptchaPolicyOptions, CaptchaPresentation, CaptchaProviderClientConfig, CaptchaProviderName, CaptchaResponseTokenRecord, CaptchaRiskResult, CaptchaRiskSignals, CaptchaStore, CreateCaptchaOptions, GeneratedCaptchaChallenge } from './types.js';
export { CaptchaHttpOptions, CaptchaParseResult, CaptchaSessionGrant, DefaultCaptchaEngine, ParseWithCaptchaOptions, bindingHash, bytesToBase64Url, captchaGuard, captchaPageGate, clearCaptchaGrants, constantTimeEqual, createCaptchaEngine, createCaptchaHttpHandlers, defaultRandomBytes, evaluateCaptchaRisk, hmacSha256, parseWithCaptcha, randomId, sha256, shouldRequireCaptcha, validCaptchaGrant } from './server/index.js';
export { CaptchaAuditIssue, CaptchaPluginOptions, captchaComponentsDir, captchaPlugin } from './plugin.js';
export { MemoryCaptchaStore, MemoryCaptchaStoreOptions, createMemoryCaptchaStore } from './stores/memory.js';
@@ -268,9 +277,19 @@ export { ManagedCaptchaProvider, ManagedCaptchaProviderOptions, managedCapt
export { defineCaptchaProvider } from './providers/custom.js';
export { CAPTCHA_CONCRETE_IMAGE_STYLES, CAPTCHA_IMAGE_STYLES, CalculationCaptchaGenerator, ImageCaptchaGenerator, InvisibleCaptchaGenerator, ResolveCaptchaImageStyleOptions, ResolvedCaptchaImageStyle, Rgba, RgbaImage, TextCaptchaGenerator, alphaCaptchaGenerator, alphanumericCaptchaGenerator, bytesToBase64, calculationCaptchaGenerator, createImage, defaultCaptchaGenerators, defineCaptchaGenerator, drawGlyph, drawLine, drawText, encodePng, fillCircle, fillPolygon, fillRect, honeypotCaptchaGenerator, imageCaptchaGenerator, isCaptchaImageStyle, normalizeCaptchaImageStyle, normalizeCaptchaImageStyleList, notRobotCaptchaGenerator, numberCaptchaGenerator, pngDataUri, resolveCaptchaImageStyle, setPixel, timingCaptchaGenerator } from './challenges/index.js';
export { AssetAudioRenderer, AssetAudioRendererOptions, createAssetAudioRenderer, resolveCaptchaAudioAssetsDir } from './audio/index.js';
-import '@wrnexus/core';
+import { Context } from '@wrnexus/core';
import '@wrnexus/validation';
import '@wrnexus/plugin';
+
+declare function captchaTokenFrom(value: Request | Headers | FormData | URLSearchParams | Record<string, unknown>, field?: string): Promise<string | undefined> | string | undefined;
+declare function captchaHeaders(token: string): HeadersInit;
+declare function captchaFields(token: string, field?: string): Record<string, string>;
+declare function verifyCaptcha(providerOrEngine: CaptchaProvider | CaptchaEngine, input: VerifyCaptchaInput): Promise<CaptchaVerificationResult>;
+declare function verifyCaptchaOrThrow(providerOrEngine: CaptchaProvider | CaptchaEngine, input: VerifyCaptchaInput): Promise<CaptchaVerificationResult>;
+declare function captchaResultResponse(result: CaptchaVerificationResult): Response;
+declare function captchaContext(ctx: Context): CaptchaVerificationResult | null;
+
+export { CaptchaEngine, CaptchaProvider, CaptchaVerificationResult, VerifyCaptchaInput, captchaContext, captchaFields, captchaHeaders, captchaResultResponse, captchaTokenFrom, verifyCaptcha, verifyCaptchaOrThrow };
Copy-ready examples from the installed package documentation.
bun add @wrnexus/captchaimport {
createCaptchaEngine,
createCaptchaHttpHandlers,
@@ -312,9 +331,9 @@ export const HEAD = POST;<Captcha showListen="false" action="without-listen-button" />
<Captcha showAudio="false" action="without-audio-alternative" />Create, develop, build, generate, test, and maintain WRNexusJS apps.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/cli@0.7.0Request preview access. Never put registry tokens in source control.
The wrnexus command-line tool that scaffolds, runs, builds, tests, and manages WRNexusJS apps.
+ Create, develop, build, generate, test, and maintain WRNexusJS apps.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/cli@0.8.0Request preview access. Never put registry tokens in source control.
Production parity commands:
+wrnexus build .
+wrnexus preview . --port=3000
+wrnexus dev . --production-runtime
+preview refuses to start without dist/server.js and executes that exact artifact with the production profile. Production-runtime development rebuilds the same minified artifact after app, public, or configuration changes and keeps the last good server running when a rebuild fails.
The wrnexus command-line tool that scaffolds, runs, builds, tests, and manages WRNexusJS apps.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/cli provides the wrnexus executable — the single entry point for developing a WRNexusJS app. It runs the HMR dev server, produces a self-contained production build, scaffolds apps/pages/components, drives database migrations, regenerates typed routes and queries, runs tests, and manages configuration profiles. It also scaffolds multi-app monorepos and serves them behind a domain-routing gateway. This is a CLI/build-time package (it shells out to the Bun binary for the dev child and tests) and it also exports the workspace config types via a subpath.
bunx wrnexus dev
# or add scripts: "dev": "wrnexus dev .", "build": "wrnexus build ."
wrnexus dev . --services starts the application and the bounded local database, cache, mail, SMS, webhook, storage, queue, cron, authentication and metrics simulator. It generates a localhost/*.localhost development certificate under .wrnexus/certificates/ and serves both the application and service console over HTTPS. Trust that certificate locally to remove the browser warning. Use --services-http only when an external development proxy already terminates TLS.
wrnexus dev . --production-runtime rebuilds and executes dist/server.js with production resolution, serialization, caching, headers and assets. The supervisor keeps the last good process when a build fails. On a successful rebuild the opt-in production HMR socket reconnects, requests the new document and morphs it into the browser; ordinary wrnexus preview and deployed production servers never include that client.
wrnexus api generate [app-dir] (or api docs) derives operations from file routes and emits generated/api/openapi.json, safe static documentation, Postman collection, curl examples, and TypeScript, JavaScript, Java, Go and Python SDKs. Generate one client with wrnexus sdk generate <language> [app-dir].
Every command accepts an optional [app-dir] (defaults to .). Commands that read config or .env also accept --profile=<name> (see [Profiles](#profiles)).
| Command | Purpose | |||
|---|---|---|---|---|
wrnexus dev [app-dir] [--port=3000] | Start the development server with live reload / HMR. | |||
wrnexus build [app-dir] | Build a self-contained production server bundle + assets into dist/. | |||
wrnexus create <app-name> | Scaffold a new single app from an inline template. | |||
wrnexus workspace <name> | Scaffold a monorepo (apps/* + shared packages/*). | |||
wrnexus workspace add <name> | Add and register an app in the current workspace. | |||
wrnexus gateway [--port=3000] | Serve every workspace app behind one port, routed by domain. | |||
wrnexus production [workspace-dir] | Build, migrate, and serve every workspace app in production. | |||
wrnexus generate <type> <name> | Scaffold a page \ | component \ | api \ | schema. |
wrnexus generate routes | Regenerate the typed routes file (app/routes.gen.ts). | |||
wrnexus generate docker | Scaffold Dockerfile, .dockerignore, and docker-compose.yml. | |||
wrnexus generate mobile | Scaffold a Capacitor shell for iOS and Android. | |||
wrnexus mobile add <package...> | Install Capacitor plugins and sync native projects. | |||
wrnexus eject <name...> | Copy Wire UI component .wrn sources into app/components/. | |||
wrnexus db <cmd> | Database migrations and tooling (see [db](#wrnexus-db)). | |||
wrnexus test [app-dir] [--watch] | Run the app's tests via bun test (defaults to the test profile). | |||
wrnexus profiles [app-dir] | List config profiles and their .env files, marking the active one. | |||
wrnexus help | Print usage. |
wrnexus dev [app-dir] [--port=3000]wrnexus build [app-dir]dist/.wrnexus create <app-name>wrnexus workspace <name>apps/* + shared packages/*).wrnexus workspace add <name>wrnexus gateway [--port=3000]wrnexus production [workspace-dir]wrnexus generate <type> <name>page \component \api \schema.wrnexus generate routesapp/routes.gen.ts).wrnexus generate dockerDockerfile, .dockerignore, and docker-compose.yml.wrnexus generate mobilewrnexus mobile add <package...>wrnexus eject <name...>.wrn sources into app/components/.wrnexus db <cmd>wrnexus test [app-dir] [--watch]bun test (defaults to the test profile).wrnexus profiles [app-dir].env files, marking the active one.wrnexus compatibility checkwrnexus compatibility explainwrnexus compatibility upgradewrnexus helpwrnexus g is an alias for wrnexus generate.
Compatibility upgrades never happen implicitly. New applications pin compatibilityDate and frameworkBehaviour; existing applications use wrnexus compatibility explain before the backed-up, idempotent upgrade command.
wrnexus devSupervises a child dev-server process (from @wrnexus/dev-server). The child owns file watching and HMR: CSS and client-island edits update the live page over a WebSocket with no restart; when a server module changes, the child exits with a restart code and the supervisor respawns it (the browser reconnects and morphs in the new HTML). On startup it regenerates typed DB queries and typed routes (best effort). Use --port= to change the port (default 3000).
wrnexus dev . --port=8080
@@ -45,7 +57,8 @@ page wrnexuscli {
# Generated apps also provide: npm start
# Build and start together: npm run production
wrnexus createScaffolds a new app from an inline (dependency-free) template — package.json, .gitignore, config, and starter app/ files. Use npm run dev during development, npm run build && npm start for production, or npm run production to build and start in one command. The generated production server currently requires Bun even when npm is used to manage packages and scripts.
Scaffolds a complete v0.8 app from an inline template. The generated project includes strict TypeScript, ESLint and Prettier, editor recommendations, environment templates, database migrations, locales, schemas, tests, API/middleware/realtime examples, Tailwind and Iconify, PWA/mobile defaults, and the framework package kits. Its wrnexus.config.ts documents the current imports, types, stores, performance, observability, tenancy, build, navigation, theme, i18n, database, storage, realtime, security, and profile configuration.
Use bun run dev during development, bun run check for the complete typecheck/lint/test/format gate, bun run build && bun run start for production, or bun run production to build and start in one command.
wrnexus updatewrnexus update --latest performs a complete project upgrade. It hands control to the exact target CLI, backs up important project files under .wrnexus/update-backups/, updates every @wrnexus/* dependency, refreshes framework-owned references, and applies every versioned syntax/config/file migration between the project version and target version. After installation it runs the project's check and build scripts; the new version is recorded only after verification succeeds.
Use --dry-run to preview an upgrade or --no-verify when verification is intentionally handled elsewhere. Migrations never overwrite user-owned configuration wholesale: each release must provide a focused, idempotent transformation for any changed syntax or config contract.
wrnexus workspace and wrnexus gatewayworkspace <name> scaffolds a monorepo: several WRNexusJS apps under apps/* and shared libraries under packages/*, plus a wrnexus.workspace.ts that maps each app to the domains it serves. gateway runs every app behind one port and routes by Host header, with optional per-app auth and gateway-wide security (trusted hosts, rate limit, security headers, access log).
workspace <name> scaffolds a monorepo: complete v0.8 apps under apps/*, shared libraries under packages/*, root TypeScript/lint/format/editor/environment tooling, and a wrnexus.workspace.ts that maps each app to the domains it serves. gateway runs every app behind one port and routes by Host header, with optional per-app auth and gateway-wide security (trusted hosts, rate limit, security headers, access log). Newly added workspace apps use the same current scaffold.
wrnexus workspace acme
wrnexus gateway --port=3000
For a complete production start, use the first-class workspace orchestrator:
@@ -116,6 +129,7 @@ wrnexus gateway --port=3000wrnexus update --latest --dry-run
wrnexus update --latest
wrnexus doctor
+Use wrnexus doctor --fix [app-dir] to apply conservative repairs before the health check: create missing app/pages and a default config, align skewed @wrnexus/* dependency ranges, record the current migration marker, and format only syntax-valid .wrn files. Invalid JSON or WRN sources are reported/skipped instead of overwritten; repeat runs are idempotent.
Pass --profile=<name> to dev, build, db (or set WRNEXUS_PROFILE) to select a config profile. The CLI publishes WRNEXUS_PROFILE so config loaders and the dev child pick it up, and loads that profile's .env cascade (.env, .env.local, .env.<profile>, .env.<profile>.local) into process.env.
wrnexus dev --profile=uat
@@ -151,9 +165,9 @@ bun install
wrnexus gateway --port=3000wrnexus update --latest --dry-run
wrnexus update --latest
wrnexus doctorParser and code generators for the .wrn language.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/compiler@0.7.0Request preview access. Never put registry tokens in source control.
Compiler for the+.wrnlanguage — tokenizes, parses, and lowers.wrnpage and component files to TypeScript.
Parser and code generators for the .wrn language.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/compiler@0.8.0Request preview access. Never put registry tokens in source control.
Pages can select render = "partial-static" and divide their view with <Static> and <Dynamic> boundaries. The compiler emits a build-only shell renderer that never evaluates dynamic-boundary children. wrnexus build expands static component mounts into dist/partial-shells.json, records byte/region evidence in build-report.json, and embeds the shell in the production route manifest. At request time the production runtime retains request-aware layouts, locale/theme metadata and security nonces while streaming dynamic regions into stable placeholders.
Compiler for the.wrnlanguage — tokenizes, parses, and lowers.wrnpage and component files to TypeScript.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
+Production adapters use analyzeRuntimeImports before bundling. Edge, worker, service-worker, and browser targets reject Node filesystem, TCP, and process modules with WRN-RUNTIME-CAPABILITY. Package manifests can declare supported wrnexus.runtimes and required wrnexus.requires capabilities; discovery fails when the selected deployment cannot satisfy them.
action createUser using CreateUserSchema {
+ const user = await users.create(input)
+ invalidate("users")
+ return user
+}
+
+view {
+ <form @submit="createUser">...</form>
+}
+The compiler produces a schema-aware server registry, a fully inferred action client, and progressively enhanced form metadata. The shared runtime performs validation, authentication/permission checks, CSRF verification, serialization, invalidation reporting, and browser lifecycle events.
@wrnexus/compiler turns .wrn source into TypeScript that targets the framework's runtime primitives. A .wrn file declares either a page (a route) or a component (a reusable, prop-driven fragment) with blocks for state, view (plain HTML), seo, style, functions, api, ssr/client data bindings, and realtime websocket handlers. The pipeline is source → Lexer → parse() → PageAst → generate() → TypeScript. It is a build/server-side library — the WRNexusJS dev loader calls it to compile .wrn files on the fly, surfacing ParseError as a readable error page.
Static ES module imports may appear before the root declaration. Imported values are available to server-rendered expressions, including component props:
@@ -124,7 +138,7 @@ lx.next(); // { type: "lbrace", value: "{", pos: 1data-scope, data-text, data-on-*, data-for, data-component, __wrnexus*/__wire* helpers) — consume the output within a WRNexusJS app, e.g. via @wrnexus/core's dev loader.Generated from the exact installed package declarations.
import { PageAst as PageAst$1, StructuredImportDecl, WrnDiagnostic } from '@wrnexus/syntax';
-export { ActionBlock, ApiBlock, Attr, ComputedDecl, DataApiBlock, DataMode, EffectBlock, EventDecl, LexError, Lexer, LoadBlock, ModeFunctionsBlock, OutputDecl, PageAst, ParseError, PropDecl, RealtimeBlock, RuntimeFunctionDecl, SeoBlock, StateDecl, StateRuntime, StoreKind, StructuredImportDecl, ViewNode, WrnDiagnostic, assertValidAst, diagnose, diagnosticFromError, eraseFunctionTypes, formatDiagnostic, inferredRuntimeType, parse, runtimeTypeOf } from '@wrnexus/syntax';
+export { ActionBlock, ApiBlock, Attr, ComputedDecl, DataApiBlock, DataMode, EffectBlock, EventDecl, FormatWrnOptions, LexError, Lexer, LoadBlock, ModeFunctionsBlock, OutputDecl, PageAst, ParseError, PropDecl, RealtimeBlock, RuntimeFunctionDecl, SeoBlock, StateDecl, StateRuntime, StoreKind, StructuredImportDecl, ViewNode, WrnDiagnostic, assertValidAst, diagnose, diagnosticFromError, eraseFunctionTypes, formatDiagnostic, formatWrn, inferredRuntimeType, parse, runtimeTypeOf } from '@wrnexus/syntax';
import { PageAst } from '@wrnexus/syntax/parser';
/**
@@ -263,9 +277,43 @@ interface RuntimeRequirements {
needsServerRuntime: boolean;
hydrationStrategy: string | null;
reasons: string[];
+ optimization: OptimizationReport;
+ cachePolicy: Record<string, string>;
+ requiredPermission: string | null;
}
+interface OptimizationReport {
+ staticNodes: number;
+ reactiveRegions: number;
+ eliminatedBranches: number;
+ unusedState: string[];
+ unusedHandlers: string[];
+ constantProps: string[];
+ unusedLocalCssClasses: string[];
+ batchableStateUpdates: number;
+ memoizableComponents: string[];
+ preloadDependencies: string[];
+ serverOnlyModules: string[];
+}
+/** Safe compile-time folding for literal conditional branches. */
+declare function optimizeAst(ast: PageAst$1): {
+ ast: PageAst$1;
+ eliminatedBranches: number;
+};
+declare function analyzeOptimizations(ast: PageAst$1): OptimizationReport;
declare function analyzeRuntimeRequirements(ast: PageAst$1): RuntimeRequirements;
+type DeploymentRuntime = "bun" | "node" | "edge" | "worker" | "service-worker" | "browser";
+type RuntimeCapability = "filesystem" | "tcp" | "process" | "websocket" | "crypto" | "streams" | "background-tasks";
+interface RuntimeCapabilityDiagnostic {
+ code: "WRN-RUNTIME-CAPABILITY";
+ runtime: DeploymentRuntime;
+ module: string;
+ capability: RuntimeCapability;
+ message: string;
+}
+declare function runtimeCapabilities(runtime: DeploymentRuntime): ReadonlySet<RuntimeCapability>;
+declare function analyzeRuntimeImports(source: string, runtime: DeploymentRuntime): RuntimeCapabilityDiagnostic[];
+
declare class NativeCompileError extends Error {
constructor(message: string);
}
@@ -330,7 +378,7 @@ declare function compileWireFile(source: string, filePath?: string): string;
/** Richer entry point returning the AST and structured diagnostics. */
declare function compile(source: string, filePath?: string): CompileResult;
-export { type CompilationCache, type CompilationCacheEntry, type CompilationCacheOptions, type CompileResult, DependencyGraph, NativeCompileError, type RouteExecutionKind, type RuntimeRequirements, analyzeRuntimeRequirements, compilationKey, compile, compileNativeWireFile, compileWireFile, createCompilationCache, createComponentContract, createWrnSourceMap, generate, generateBrowserModule, generateDeclarations, generateNative, generateServerFunctionsModule, generateStoreBrowserModule, generateStoreModule, generateTargets, resolveWrnImport, resolveWrnImports, rpcManifest };
+export { type CompilationCache, type CompilationCacheEntry, type CompilationCacheOptions, type CompileResult, DependencyGraph, type DeploymentRuntime, NativeCompileError, type OptimizationReport, type RouteExecutionKind, type RuntimeCapability, type RuntimeCapabilityDiagnostic, type RuntimeRequirements, analyzeOptimizations, analyzeRuntimeImports, analyzeRuntimeRequirements, compilationKey, compile, compileNativeWireFile, compileWireFile, createCompilationCache, createComponentContract, createWrnSourceMap, generate, generateBrowserModule, generateDeclarations, generateNative, generateServerFunctionsModule, generateStoreBrowserModule, generateStoreModule, generateTargets, optimizeAst, resolveWrnImport, resolveWrnImports, rpcManifest, runtimeCapabilities };
Copy-ready examples from the installed package documentation.
import { compileWireFile } from "@wrnexus/compiler";
const ts = compileWireFile(`
@@ -359,9 +407,9 @@ const lx = new Lexer("page Home {");
lx.next(); // { type: "ident", value: "page", pos: 0 }
lx.next(); // { type: "ident", value: "Home", pos: 5 }
lx.next(); // { type: "lbrace", value: "{", pos: 10 }Content collections, validation, querying, and publishing workflows.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/content@0.8.0Request preview access. Never put registry tokens in source control.
Typed content collections for Markdown/MDX-like documents and remote CMS records. Collections validate frontmatter through any { parse(input) } schema, render escaped HTML, and expose draft preview, versions, references, headings, search indexes, pagination, RSS and sitemaps.
const posts = defineCollection({
+ name: "posts",
+ schema: PostSchema,
+ loader: localContentLoader("content/posts"),
+ previewToken: process.env.CONTENT_PREVIEW_TOKEN,
+});
+
+const published = await posts.load();
+const preview = await posts.load({ previewToken: request.headers.get("x-preview-token") ?? "" });
+Remote systems implement CmsAdapter, use cmsContentLoader, or return JSON records through remoteContentLoader. Markdown HTML is escaped by default; raw executable HTML is never trusted.
Generated from the exact installed package declarations.
type MdxComponent = (props: Record<string, string>, children: string) => string;
+/** Execute explicitly registered MDX components without evaluating arbitrary JavaScript. */
+declare function renderMdxComponents(source: string, components: Record<string, MdxComponent>): string;
+interface SyntaxLanguageBundle {
+ highlight(source: string): string;
+}
+declare function createIncrementalHighlighter(loaders: Record<string, () => SyntaxLanguageBundle | Promise<SyntaxLanguageBundle>>): {
+ languages: () => string[];
+ highlight(language: string, source: string): Promise<string>;
+ render(html: string): Promise<string>;
+};
+interface VendorAdapterOptions {
+ fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
+ token?: string;
+ map?: (entry: any) => {
+ id: string;
+ content: string;
+ source?: string;
+ };
+}
+declare function contentfulAdapter(space: string, environment?: string, options?: VendorAdapterOptions): {
+ list(collection: string): Promise<any>;
+};
+declare function sanityAdapter(project: string, dataset: string, options?: VendorAdapterOptions & {
+ apiVersion?: string;
+}): {
+ list(collection: string): Promise<any>;
+};
+declare function strapiAdapter(baseUrl: string, options?: VendorAdapterOptions): {
+ list(collection: string): Promise<any>;
+};
+
+interface ContentSchema<T> {
+ parse(input: unknown): T;
+}
+interface ContentEntry<T = Record<string, unknown>> {
+ id: string;
+ slug: string;
+ collection: string;
+ data: T;
+ body: string;
+ html: string;
+ excerpt: string;
+ headings: ContentHeading[];
+ draft: boolean;
+ version?: string;
+ source: string;
+}
+interface ContentHeading {
+ depth: number;
+ text: string;
+ slug: string;
+}
+interface ContentLoaderResult {
+ id: string;
+ source: string;
+ content: string;
+}
+interface ContentLoader {
+ load(): ContentLoaderResult[] | Promise<ContentLoaderResult[]>;
+}
+interface ContentCollectionOptions<T> {
+ name: string;
+ schema: ContentSchema<T>;
+ loader: ContentLoader;
+ includeDrafts?: boolean;
+ previewToken?: string;
+ references?: Record<string, ContentCollection<unknown>>;
+}
+interface ContentCollection<T> {
+ name: string;
+ load(options?: {
+ drafts?: boolean;
+ previewToken?: string;
+ version?: string;
+ }): Promise<ContentEntry<T>[]>;
+ get(id: string, options?: {
+ drafts?: boolean;
+ previewToken?: string;
+ version?: string;
+ }): Promise<ContentEntry<T> | null>;
+}
+declare function parseFrontmatter(source: string): {
+ data: Record<string, unknown>;
+ body: string;
+};
+declare function renderMarkdown(source: string): {
+ html: string;
+ headings: ContentHeading[];
+ excerpt: string;
+};
+declare function localContentLoader(directory: string): ContentLoader;
+declare function remoteContentLoader(url: string, options?: {
+ fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
+ headers?: HeadersInit;
+}): ContentLoader;
+declare function defineCollection<T>(options: ContentCollectionOptions<T>): ContentCollection<T>;
+declare function resolveContentReference(collections: Record<string, ContentCollection<unknown>>, reference: string): Promise<ContentEntry<unknown> | null>;
+declare function paginateContent<T>(entries: T[], page?: number, pageSize?: number): {
+ items: T[];
+ page: number;
+ pageSize: number;
+ total: number;
+ totalPages: number;
+ hasNext: boolean;
+ hasPrevious: boolean;
+};
+declare function createSearchIndex(entries: ContentEntry[]): {
+ id: string;
+ slug: string;
+ title: string;
+ text: string;
+}[];
+declare function searchContent(index: ReturnType<typeof createSearchIndex>, query: string): {
+ id: string;
+ slug: string;
+ title: string;
+ text: string;
+}[];
+declare function contentSitemap(entries: ContentEntry[], baseUrl: string): string;
+declare function contentRss(entries: ContentEntry[], options: {
+ title: string;
+ baseUrl: string;
+ description?: string;
+}): string;
+interface CmsAdapter {
+ list(collection: string): Promise<Array<{
+ id: string;
+ content: string;
+ source?: string;
+ }>>;
+}
+declare function cmsContentLoader(adapter: CmsAdapter, collection: string): ContentLoader;
+
+export { type CmsAdapter, type ContentCollection, type ContentCollectionOptions, type ContentEntry, type ContentHeading, type ContentLoader, type ContentLoaderResult, type ContentSchema, type MdxComponent, type SyntaxLanguageBundle, type VendorAdapterOptions, cmsContentLoader, contentRss, contentSitemap, contentfulAdapter, createIncrementalHighlighter, createSearchIndex, defineCollection, localContentLoader, paginateContent, parseFrontmatter, remoteContentLoader, renderMarkdown, renderMdxComponents, resolveContentReference, sanityAdapter, searchContent, strapiAdapter };
+Copy-ready examples from the installed package documentation.
const posts = defineCollection({
+ name: "posts",
+ schema: PostSchema,
+ loader: localContentLoader("content/posts"),
+ previewToken: process.env.CONTENT_PREVIEW_TOKEN,
+});
+
+const published = await posts.load();
+const preview = await posts.load({ previewToken: request.headers.get("x-preview-token") ?? "" });bun add @wrnexus/contentContexts, middleware, security, sessions, caching, JSX, and realtime.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/core@0.7.0Request preview access. Never put registry tokens in source control.
The framework core: the request Context, middleware contract, and the security, session, caching, streaming, realtime, and JSX primitives every other WRNexusJS package builds on.
+ Contexts, middleware, security, sessions, caching, JSX, and realtime.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/core@0.8.0Request preview access. Never put registry tokens in source control.
The framework core: the request Context, middleware contract, and the security, session, caching, streaming, realtime, and JSX primitives every other WRNexusJS package builds on.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/core is the shared foundation of WRNexusJS. It defines the Context object that flows through every middleware, page, and API route, plus the Middleware/Next contract they implement. On top of that it ships the building blocks a real app needs: cookie-backed sessions, password auth, CSRF protection, rate limiting, request logging, HTTP + in-memory caching, file uploads, streaming/SSE responses, WebSocket "rooms", security headers/CORS, and a server-side JSX runtime that renders to HTML strings. Everything here is server-side and Bun-native (it uses Bun.password, Bun.write, the web-standard Request/Response, and crypto). You depend on it directly and transitively through the rest of the framework.
requestLogger(options?)(RequestLoggerOptions?) => Middlewarectx.locals[requestIdKey]).RequestLoggerOptions: format ("pretty" default \| "json"), sink(line, record) (default console.log), requestIdKey (default "requestId"), now. RequestRecord = { time, id, method, path, status, durationMs }.
@wrnexus/coreresilientCall standardizes cancellation-aware timeouts, controlled retries, fixed or exponential backoff, fallback responses, circuit breaking, and bounded concurrency. Reuse a declarative circuit/bulkhead options object, or an explicit CircuitBreaker/Bulkhead instance, wherever calls must share health and capacity state.
import { resilientCall } from "@wrnexus/core";
+
+const paymentCircuit = { failures: 5, resetAfter: "30s" } as const;
+
+const status = await resilientCall({
+ timeout: "5s",
+ retries: 3,
+ retryDelay: "100ms",
+ backoff: "exponential",
+ circuitBreaker: paymentCircuit,
+ bulkhead: { concurrency: 20, queue: 100 },
+ run: (signal) => paymentProvider.checkStatus({ signal }),
+ fallback: () => ({ state: "unavailable" }),
+});
+CircuitBreaker.snapshot() reports closed, open, or half-open, failure and success counts, and the remaining retry delay for health endpoints and development tooling. Fail-fast conditions use stable WRN-RESILIENCE-* codes. Core's existing HealthRegistry, withIdempotency, and pluggable stores/locks cover health reporting, idempotent requests, and distributed coordination.
@wrnexus/core| Export | Kind | Notes |
|---|
| Directive | Purpose |
|---|---|
data-scope="count: 0, name: 'x'" | Declare reactive state on a subtree |
data-on-<event>="count++" | Run a statement in scope on a DOM event |
data-text="expr" | Bind an element's textContent to an expression |
data-show="expr" | Toggle visibility (display) on truthiness |
data-for="item in list" (opt. index and key item.id) | Per-item rendering; stable keys preserve DOM identity during reorder |
data-key="item.id" | Alternative key declaration for data-for templates |
{{expr}} or {expr} | Interpolation inside text nodes and attribute values |
data-wrnexus-csr="id" | Target for a generated CSR fetch binding (fetches /__wrnexus/csr?...) |
data-scope="count: 0, name: 'x'"data-on-<event>="count++"data-text="expr"textContent to an expressiondata-show="expr"Compiled conditional rendering and dynamic component cases omit inactive elements from the live DOM. data-show is a visibility directive for stateful controls and keeps its element mounted. Neither mechanism is authorization: never place secrets in client-rendered branches. Authorize on the server and return only data the current request may access.
data-for="item in list" (opt. index and key item.id) | Per-item rendering; stable keys preserve DOM identity during reorder |
data-key="item.id" | Alternative key declaration for data-for templates |
{{expr}} or {expr} | Interpolation inside text nodes and attribute values |
data-wrnexus-csr="id" | Target for a generated CSR fetch binding (fetches /__wrnexus/csr?...) |
Supported expression features: literals, identifiers, member access (a.b, a[b]), function/method calls, arrays, objects, arithmetic, comparison, equality, logical (&& ||), unary (! - +), and ternary. Statements support ++/--, assignment operators (= += -= *= /= %=), and bare expression/method calls. Rendering is dependency-tracked: a signal change only re-runs the renderers that actually read it.
Browser globals installed: window.__wrnexusHydrateScopes(root) and window.__wrnexusHydrateCsrFetches(root) — both idempotent, so re-running after a DOM swap or HMR morph is safe. Both run automatically on DOMContentLoaded.
Copy-ready examples from the installed package documentation.
import { getReactiveRuntime, getNavRuntime, getRealtimeRuntime } from "@wrnexus/csr";
const routes: Record<string, string> = {
@@ -295,9 +328,9 @@ Bun.serve({
<script src="/__wrnexus/realtime.js"></script>const room = wire.room("lobby");
room.on("chat", (msg) => console.log(msg.user, msg.text));
room.send({ type: "chat", user: "ada", text: "hi" });Database adapters, typed queries, models, migrations, and sessions.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/db@0.7.0Request preview access. Never put registry tokens in source control.
The database layer for WRNexusJS: TS models as the single source of truth for DDL, validation, and result typing, plus a driver-based Db client, migrations, and a sqlc-style query generator.
+ Database adapters, typed queries, models, migrations, and sessions.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/db@0.8.0Request preview access. Never put registry tokens in source control.
Run wrnexus db check in CI before deployment. The analyzer reports stable diagnostics for drops, renames, type changes, new/enforced required columns, and potentially blocking index creation, with an expand/backfill/switch/contract recommendation. wrnexus db migrate blocks critical issues in pending migrations. --allow-breaking is an explicit operator override; already-applied migrations do not block later releases.
The database layer for WRNexusJS: TS models as the single source of truth for DDL, validation, and result typing, plus a driver-based Db client, migrations, and a sqlc-style query generator.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/db is the server-side data layer. You describe tables as TypeScript models (the v column builder + table()); those models drive migrations, coerce raw DB rows into typed objects, and feed the query generator. A thin Driver interface is implemented by adapters for SQLite (bun:sqlite), Postgres/MySQL (Bun.SQL), and MongoDB. The Db client adds ergonomics — model-mapped all/one, transactions, createTable, pagination, and batched relation loading. A process-wide registry (getDb/setDb) exposes configured connections to pages and API routes. Reach for it whenever a WRNexusJS app needs persistence.
exec(sql, params?) — Promise<ExecResult> ({ changes, lastInsertId? }).tx(fn) — run fn(db) in a transaction; rolls back on throw. Nested tx reuses the current transaction.createTable(model) — runs the model's CREATE TABLE IF NOT EXISTS DDL.close().close() — idempotently rejects new top-level work, drains active queries andtransactions, then closes the underlying pool.
Every query is parameterized (positional params). createTableSql(model, dialect, ifNotExists?) renders CREATE TABLE directly; Dialect is "sqlite" | "postgres" | "mysql".
getDb / setDbsetDb(db) / setDb(name, db) — set the default or a named connection.registerDb(name, db) — alias of setDb(name, db).getDb(name = "default") — the default or a named Db (throws if unconfigured).hasDb(name?), databaseNames(), closeDatabases().hasDb(name?), databaseNames(), closeDatabases(). Registry shutdown clearsregistrations first, attempts every open database, and reports close failures together with AggregateError instead of leaking later pools.
const users = await getDb().all("SELECT * FROM users");
const events = await getDb("analytics").all("SELECT * FROM hits");
@@ -76,8 +80,8 @@ const events = await getDb("analytics").all("SELECT * FROM hits&q
parseMigration(name, content) → Migration ({ name, up, down }).loadMigrations(dir) — parse all .sql files, sorted by filename.appliedMigrations(db) — applied names, oldest first.migrate(db, dir) — apply all pending (each in a transaction); returns applied names.rollback(db, dir) — roll back the most recent; returns its name or null.migrate(db, dir, options?) — apply all pending (each in a transaction); returns applied names.rollback(db, dir, options?) — roll back the most recent; returns its name or null.status(db, dir) — { name, applied }[] for every migration file.scaffoldMigration(dir, name, dialect, models?) — write a new numbered migration; with models it generates CREATE/DROP for every table (referenced tables first via topological sort). Returns the file path.For deployments, { dryRun: true } reports pending names without applying their SQL, signal cancels safely between migrations, and the default database-backed lock prevents concurrent deploy runners. A live lock produces WRN-DB-MIGRATION-LOCKED; crash-stale locks expire after lockTimeoutMs (five minutes by default). Disable it with lock: false only when an external deploy coordinator already guarantees exclusivity.
const pending = await migrate(db, "app/db/migrations", { dryRun: true });
+await migrate(db, "app/db/migrations", {
+ signal: shutdownController.signal,
+ lockTimeoutMs: 10 * 60_000,
+});
MongoDB (document API):
import { mongo } from "@wrnexus/db/mongo";
@@ -149,10 +159,39 @@ const active = await repo.find({ active: true });
SessionBackend; getDb/setDb are wired by the WRNexusJS runtime from wrnexus.config.ts.
mongodb npm package is an optional, lazily-imported peer — install itonly if you use @wrnexus/db/mongo. The core package stays dependency-free.
Generated from the exact installed package declarations.
import { M as Model } from './schema-tVurYsbL.js';
+
+Repository and transaction helpers
+Repositories accept an immutable equality scope, normally { column: "tenant_id", value: ctx.tenant.id }. The scope is injected into every read, count, update and delete, while create overwrites any caller-supplied tenant value. This makes accidental cross-tenant CRUD through the repository API fail closed.
+import { createRepository, retryTransaction, databaseHealth, batch } from "@wrnexus/db";
+
+const users = createRepository<User>(db, {
+ table: "users",
+ allowedColumns: ["email", "name", "active"],
+});
+
+const user = await users.require(42);
+await users.update(42, { active: true });
+Repository identifiers are validated, writes may be restricted to an allowlist, and values always use query parameters. Infrastructure packages remain helper-only and do not add UI dependencies to server code.
+0.8 repository and transaction helpers
+import { createRepository, databaseHealth, firstOrThrow, retryTransaction } from "@wrnexus/db";
+
+const usersRepo = createRepository<User>(db, {
+ table: "users",
+ allowedColumns: ["email", "name", "active"],
+ maxListLimit: 250,
+});
+
+const users = await usersRepo.all({
+ orderBy: "name",
+ direction: "asc",
+ limit: 50,
+ offset: 0,
+});
+Repository SQL identifiers are validated and values remain parameterized. Placeholder generation is dialect-aware: PostgreSQL uses $1, $2, and SQLite/MySQL use ?. List limits are bounded.
+retryTransaction() retries recognized serialization, deadlock, and database-lock errors by default. Supply shouldRetry for application-specific retryable errors; ordinary validation or business errors are not retried automatically.
Generated from the exact installed package declarations.
import { M as Model } from './schema-tVurYsbL.js';
export { B as BaseType, C as Column, a as ColumnDef, b as Columns, t as table, v } from './schema-tVurYsbL.js';
-import { a as Db, b as Dialect, R as Row } from './driver-DA53QHkO.js';
-export { D as Driver, E as ExecResult, T as TxHandle, c as createDb, d as createTableSql } from './driver-DA53QHkO.js';
+import { a as Db, b as Dialect, R as Row, E as ExecResult } from './driver-DA53QHkO.js';
+export { D as Driver, T as TxHandle, c as createDb, d as createTableSql } from './driver-DA53QHkO.js';
/**
* A process-wide database registry. The framework configures it at server
@@ -200,6 +239,16 @@ interface Migration {
up: string;
down: string;
}
+interface MigrationRunOptions {
+ /** Return pending migration names without executing their SQL. */
+ dryRun?: boolean;
+ /** Stop safely between migrations. Active database statements cannot be interrupted portably. */
+ signal?: AbortSignal;
+ /** Coordinate migration runners through the database. Default true. */
+ lock?: boolean;
+ /** Allow recovery of a lock left by a crashed process. Default 5 minutes. */
+ lockTimeoutMs?: number;
+}
/** Split a migration file into its `up` and `down` SQL sections. */
declare function parseMigration(name: string, content: string): Migration;
/** Load and parse all migration files in a directory, sorted by filename. */
@@ -207,11 +256,13 @@ declare function loadMigrations(dir: string): Migration[];
/** Names of already-applied migrations, oldest first. */
declare function appliedMigrations(db: Db): Promise<string[]>;
/** Apply an ordered migration list (each in a transaction). Returns applied names. */
-declare function applyMigrations(db: Db, migrations: readonly Migration[]): Promise<string[]>;
+declare function applyMigrations(db: Db, migrations: readonly Migration[], options?: MigrationRunOptions): Promise<string[]>;
/** Apply all pending migrations from a directory. */
-declare function migrate(db: Db, dir: string): Promise<string[]>;
+declare function migrate(db: Db, dir: string, options?: MigrationRunOptions): Promise<string[]>;
/** Roll back the most recently applied migration. Returns its name, or null. */
-declare function rollback(db: Db, dir: string): Promise<string | null>;
+declare function rollback(db: Db, dir: string, options?: Omit<MigrationRunOptions, "dryRun"> & {
+ dryRun?: boolean;
+}): Promise<string | null>;
/** Full status: every migration file with whether it has been applied. */
declare function status(db: Db, dir: string): Promise<{
name: string;
@@ -224,6 +275,16 @@ declare function status(db: Db, dir: string): Promise<{
*/
declare function scaffoldMigration(dir: string, name: string, dialect: Dialect, models?: Model[]): string;
+interface MigrationSafetyIssue {
+ code: "WRN-DB-DROP-TABLE" | "WRN-DB-DROP-COLUMN" | "WRN-DB-RENAME" | "WRN-DB-TYPE-CHANGE" | "WRN-DB-SET-NOT-NULL" | "WRN-DB-ADD-REQUIRED" | "WRN-DB-BLOCKING-INDEX";
+ severity: "error" | "warning";
+ migration: string;
+ statement: string;
+ recommendation: string;
+}
+declare function analyzeMigrationSafety(migration: Migration): MigrationSafetyIssue[];
+declare function analyzeMigrations(migrations: readonly Migration[]): MigrationSafetyIssue[];
+
/**
* sqlc-style query generator. Annotated SQL in `app/db/queries/*.sql` becomes
* typed TS functions whose params + results are inferred from the TS models and
@@ -366,10 +427,64 @@ interface QueryPolicy {
onQuery?: (record: QueryRecord) => void | Promise<void>;
onIssue?: (issue: QueryIssue) => void | Promise<void>;
}
+declare function getDbPerformanceSnapshot(): {
+ queries: QueryRecord[];
+ issues: QueryIssue[];
+};
+declare function resetDbPerformanceSnapshot(): void;
declare function instrumentDb(db: Db, policy?: QueryPolicy): Db;
declare function queryOperation(sql: string): string;
-export { type CursorPage, type CursorPageOptions, Db, Dialect, type Migration, Model, type ModelRef, type PageOptions, type Paginated, type QueryDef, type QueryIssue, type QueryKind, type QueryPolicy, type QueryRecord, type RelationOptions, Row, appliedMigrations, applyMigrations, closeDatabases, cursorPaginate, databaseNames, generateQueriesFile, getDb, hasDb, instrumentDb, loadMigrations, loadRelated, migrate, optimisticUpdate, paginate, parseMigration, parseQueries, queryOperation, registerDb, registerLazyDb, rollback, scaffoldMigration, setDb, softDeleteClause, status, tenantScope };
+declare class RecordNotFoundError extends Error {
+ constructor(message?: string);
+}
+declare function firstOrThrow<T>(db: Db, sql: string, params?: unknown[], model?: Model<T>, message?: string): Promise<T>;
+declare function exists(db: Db, sql: string, params?: unknown[]): Promise<boolean>;
+declare function countRows(db: Db, table: string, where?: string, params?: unknown[]): Promise<number>;
+declare function withTransaction<T>(db: Db, callback: (tx: Db) => Promise<T>): Promise<T>;
+declare function retryTransaction<T>(db: Db, callback: (tx: Db, attempt: number) => Promise<T>, options?: {
+ attempts?: number;
+ baseDelayMs?: number;
+ maxDelayMs?: number;
+ jitter?: boolean;
+ shouldRetry?: (error: unknown) => boolean;
+}): Promise<T>;
+declare function batch<T>(values: readonly T[], size?: number): T[][];
+declare function databaseHealth(db: Db): Promise<{
+ ok: boolean;
+ latencyMs: number;
+ error?: string;
+}>;
+interface RepositoryListOptions<T extends Row> {
+ limit?: number;
+ offset?: number;
+ orderBy?: keyof T & string;
+ direction?: "asc" | "desc";
+}
+interface Repository<T extends Row> {
+ all(options?: RepositoryListOptions<T>): Promise<T[]>;
+ find(id: string | number): Promise<T | null>;
+ require(id: string | number): Promise<T>;
+ create(values: Partial<T>): Promise<ExecResult>;
+ update(id: string | number, values: Partial<T>): Promise<ExecResult>;
+ remove(id: string | number): Promise<ExecResult>;
+ exists(id: string | number): Promise<boolean>;
+ count(): Promise<number>;
+}
+declare function createRepository<T extends Row>(db: Db, input: {
+ table: string;
+ idColumn?: string;
+ model?: Model<T>;
+ allowedColumns?: readonly (keyof T & string)[];
+ maxListLimit?: number;
+ /** Immutable equality scope (normally tenant_id) applied to every operation. */
+ scope?: {
+ column: keyof T & string;
+ value: unknown;
+ };
+}): Repository<T>;
+
+export { type CursorPage, type CursorPageOptions, Db, Dialect, ExecResult, type Migration, type MigrationRunOptions, type MigrationSafetyIssue, Model, type ModelRef, type PageOptions, type Paginated, type QueryDef, type QueryIssue, type QueryKind, type QueryPolicy, type QueryRecord, RecordNotFoundError, type RelationOptions, type Repository, Row, analyzeMigrationSafety, analyzeMigrations, appliedMigrations, applyMigrations, batch, closeDatabases, countRows, createRepository, cursorPaginate, databaseHealth, databaseNames, exists, firstOrThrow, generateQueriesFile, getDb, getDbPerformanceSnapshot, hasDb, instrumentDb, loadMigrations, loadRelated, migrate, optimisticUpdate, paginate, parseMigration, parseQueries, queryOperation, registerDb, registerLazyDb, resetDbPerformanceSnapshot, retryTransaction, rollback, scaffoldMigration, setDb, softDeleteClause, status, tenantScope, withTransaction };
Copy-ready examples from the installed package documentation.
import { v, table, createDb } from "@wrnexus/db";
import { sqlite } from "@wrnexus/db/sqlite";
@@ -400,15 +515,19 @@ const pageTwo = await paginate(
db,
{ sql: "SELECT * FROM users ORDER BY id", model: users },
{ page: 2 },
-);import { mongo } from "@wrnexus/db/mongo";
+);const pending = await migrate(db, "app/db/migrations", { dryRun: true });
+await migrate(db, "app/db/migrations", {
+ signal: shutdownController.signal,
+ lockTimeoutMs: 10 * 60_000,
+});import { mongo } from "@wrnexus/db/mongo";
const mdb = await mongo(process.env.MONGO_URL!, "app");
const repo = mdb.collection(users);
await repo.insert({ email: "a@b.com" });
const active = await repo.find({ active: true });Development and production servers, HMR, assets, and gateways.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/dev-server@0.7.0Request preview access. Never put registry tokens in source control.
The WRNexusJS HTTP + WebSocket server runtime — request dispatch, SSR document assembly, live-reload (HMR), and the portable production handler.+
Development and production servers, HMR, assets, and gateways.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/dev-server@0.8.0Request preview access. Never put registry tokens in source control.
The WRNexusJS HTTP + WebSocket server runtime — request dispatch, SSR document assembly, live-reload (HMR), and the portable production handler.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
This package is the server runtime that powers a WRNexusJS app in both development and production. A single request runtime (createHandlers) owns HTTP/WebSocket dispatch and SSR document assembly; it knows nothing about _how_ modules and assets are produced, so the dev and prod entry points wire in different backends: dev uses dynamic module loading plus on-the-fly bundling and injects a live-reload client; prod uses a static, pre-built manifest with cache-immutable assets. The package also ships a multi-app gateway (route several apps by Host header behind one port) and a portable node:http adapter for WinterCG hosts. It is entirely server-side and Bun-native (Bun.serve, Bun.file, Bun.gzipSync).
In development, startServer also connects app/db/migrations (and app/db/<name>/migrations) and auto-applies migrations, then starts an in-process file watcher. CSS edits hot-swap live. Page, component, layout, API, middleware, realtime, schema, locale, and public-asset edits invalidate only their cached modules, rescan routes where necessary, and morph fresh HTML through the existing HMR WebSocket. The server process and active gateway stay running.
getWrnCompileMetrics() exposes cumulative content-addressed compiler cache hits, misses, successful compilations, errors, totalDurationMs, and lastDurationMs for the DevToolbar or custom diagnostics. Tests and embedded servers can call resetWrnCompileMetrics() to establish a fresh measurement window.
createHandlers(deps)The core runtime shared by dev and prod. It handles CORS preflight, /healthz and /__wrnexus/health, request-body size limits (413), HMR socket upgrades (/__wrnexus/hmr), realtime WebSocket upgrades (defineRoom default export or a raw websocket export), the middleware pipeline, API routes (/api/*), framework assets (/__wrnexus/*), public assets, and full SSR page rendering (component mounts, layouts, slots, i18n markers, per-page script selection, ETag/304, gzip).
interface RuntimeDeps {
@@ -222,23 +223,63 @@ await startGateway({
- Bun-only. Uses
Bun.serve (HTTP + WebSocket), Bun.file, and Bun.gzipSync. The full app also relies on bun:sqlite / Bun.SQL via @wrnexus/db.
- Orchestrates the whole framework:
@wrnexus/core (context, security, realtime registry), @wrnexus/router, @wrnexus/ssr (renderDocument), @wrnexus/csr (client runtimes), @wrnexus/compiler (.wrn → TS), @wrnexus/styles, @wrnexus/ui, @wrnexus/validation, @wrnexus/i18n, @wrnexus/db, and @wrnexus/pubsub (Redis-backed cross-process realtime).
-.wrn files are compiled to TypeScript into a hidden sibling .wrnexus/ cache dir and dynamically imported; the module cache means each edited server module needs a fresh process (dev) — hence the restart-on-change model.
+.wrn files compile into a content-addressed hidden .wrnexus/ cache. Targeted
+invalidation gives changed modules a fresh import identity without restarting the development server.
- Responses are gzipped when the client accepts it and the body is a buffered, compressible payload ≥ 1 KB; streaming/SSE responses opt out via
Cache-Control: no-transform.
</content>
-</invoke>
Generated from the exact installed package declarations.
import { Mode, Middleware, SeoConfig, SecurityConfig, RealtimeBus, RealtimeConnectMeta } from '@wrnexus/core';
+</invoke>
Generated from the exact installed package declarations.
import { Mode, Middleware, SeoConfig, SecurityConfig, HealthRegistry, RealtimeBus, RealtimeConnectMeta } from '@wrnexus/core';
import { Router } from '@wrnexus/router';
import { ResolvedTheme, MobileConfig, PwaConfig, ObservabilityConfig, TenancyConfig, NavigationConfig, StylesConfig, ThemeConfig } from '@wrnexus/styles';
import { ResolvedI18n, I18nConfig } from '@wrnexus/i18n';
import { StorageConfig } from '@wrnexus/uploader';
import { DevToolbarConfig, DevToolbarPlatformSnapshot, DevToolbarPanel } from '@wrnexus/dev-toolbar/types';
import { ClientRuntimeDefinition, PluginInput } from '@wrnexus/plugin';
+import { CacheCoordinator } from '@wrnexus/cache';
import { DevToolbarCollector } from '@wrnexus/dev-toolbar/server';
import { IncomingMessage, ServerResponse, Server } from 'node:http';
/** Exit code a dev-server child uses to request a clean supervisor restart. */
declare const RESTART_EXIT_CODE = 97;
+interface PartialBuildModule {
+ default?: unknown;
+ render?: (props?: Record<string, unknown>) => string | Promise<string>;
+ layout?: string | {
+ name?: string;
+ render?: (props?: Record<string, unknown>) => string;
+ };
+ __wrnexusBuildStaticShell?: (ctx?: Record<string, unknown>) => string | Promise<string>;
+}
+interface PartialBuildEntry {
+ name: string;
+ mod: PartialBuildModule;
+}
+/** Expand compiler component mounts at build time using only their pure render exports. */
+declare function expandStaticComponents(html: string, components: readonly PartialBuildEntry[], depth?: number): Promise<string>;
+/** Produce the body shell stored in dist; dynamic region bodies are never evaluated here. */
+declare function precomputePartialStaticShell(page: PartialBuildModule, components: readonly PartialBuildEntry[]): Promise<{
+ shell: string;
+ regions: number;
+}>;
+
+/**
+ * Request pipeline helpers: middleware execution and safe module loading.
+ * These are deliberately runtime-agnostic (no Bun APIs) so they could run on
+ * Node too.
+ */
+
+interface WrnCompileMetrics {
+ hits: number;
+ misses: number;
+ compilations: number;
+ errors: number;
+ totalDurationMs: number;
+ lastDurationMs: number;
+}
+declare function getWrnCompileMetrics(): Readonly<WrnCompileMetrics>;
+declare function resetWrnCompileMetrics(): void;
+
/**
* HMR hub — tracks connected browser HMR sockets and broadcasts update events.
*
@@ -349,6 +390,8 @@ interface RuntimeDeps {
security?: SecurityConfig;
/** Built-in request tracing and Server-Timing policy. */
observability?: ObservabilityConfig;
+ /** Dependency health checks used by `/readyz` and `/__wrnexus/ready`. */
+ health?: HealthRegistry;
/** Built-in tenant identity resolution. */
tenancy?: TenancyConfig;
/** Max request body size in bytes (413 above this). Default 10 MB. */
@@ -361,12 +404,16 @@ interface RuntimeDeps {
* bus (use the Redis pub/sub driver). Enables realtime across multiple apps.
*/
realtimeBus?: RealtimeBus;
+ /** Shared first-class data/component/page caches. */
+ cache?: CacheCoordinator;
+ /** Final document transform supplied by the plugin render lifecycle. */
+ renderHtml?: (html: string) => string | Promise<string>;
devToolbar?: {
config: DevToolbarConfig;
collector: DevToolbarCollector;
root: string;
platform?: DevToolbarPlatformSnapshot;
- panels?: DevToolbarPanel[];
+ panels?: DevToolbarPanel[] | (() => DevToolbarPanel[] | Promise<DevToolbarPanel[]>);
};
}
interface UpgradeServer {
@@ -500,7 +547,8 @@ declare function startGateway(opts: GatewayOptions): Promise<RunningGateway&g
* `wrnexus build` generates an entry that statically imports every route and
* component module and hands them here as a manifest. We rebuild the (cheap)
* route-matching tables from the raw patterns and run the exact same request
- * runtime as dev — just with production error pages and no live-reload client.
+ * runtime as dev. Normal preview/deploy output has no live-reload client; the
+ * supervised `dev --production-runtime` mode can explicitly enable it.
*/
type RouteModule = Record<string, unknown>;
@@ -509,6 +557,8 @@ interface ManifestRoute {
raw: string;
/** The statically-imported route module. */
mod: RouteModule;
+ /** Body shell precomputed by `wrnexus build` for a partial-static page. */
+ staticShell?: string;
}
interface ProdManifest {
pages: ManifestRoute[];
@@ -609,6 +659,8 @@ interface ProdOptions {
port?: number;
hostname?: string;
maxBodyBytes?: number;
+ /** Enable only for the CLI's supervised exact-production development mode. */
+ developmentRuntime?: boolean;
}
/**
* Build the portable request handler from a precompiled manifest — a
@@ -663,6 +715,11 @@ interface ServeOptions {
appDir: string;
port?: number;
hostname?: string;
+ /** Development TLS material. Production TLS is normally terminated by the deployment proxy. */
+ tls?: {
+ cert: string;
+ key: string;
+ };
mode?: Mode;
/** Inject the live-reload client (defaults to true in development). */
hmr?: boolean;
@@ -715,7 +772,7 @@ interface RunningServer {
}
declare function startServer(opts: ServeOptions): Promise<RunningServer>;
-export { type AssetServer, type FetchHandler, type GatewayApp, type GatewayAuth, type GatewayOptions, type GatewaySecurity, RESTART_EXIT_CODE, type RunningGateway, type RunningServer, type RuntimeDeps, type ServeOptions, type WsData, createHandlers, createProductionHandlers, createProductionServer, nodeListener, serveNode, startGateway, startServer, toRequest, writeResponse };
+export { type AssetServer, type FetchHandler, type GatewayApp, type GatewayAuth, type GatewayOptions, type GatewaySecurity, RESTART_EXIT_CODE, type RunningGateway, type RunningServer, type RuntimeDeps, type ServeOptions, type WrnCompileMetrics, type WsData, createHandlers, createProductionHandlers, createProductionServer, expandStaticComponents, getWrnCompileMetrics, nodeListener, precomputePartialStaticShell, resetWrnCompileMetrics, serveNode, startGateway, startServer, toRequest, writeResponse };
Copy-ready examples from the installed package documentation.
import { startServer } from "@wrnexus/dev-server";
const server = await startServer({
@@ -756,7 +813,7 @@ await startGateway({
});Development toolbar diagnostics, inspection, and runtime status.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/dev-toolbar@0.7.0Request preview access. Never put registry tokens in source control.
Development-only page quality toolbar for WRNexusJS.
+Development toolbar diagnostics, inspection, and runtime status.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/dev-toolbar@0.8.0Request preview access. Never put registry tokens in source control.
Development-only page quality toolbar for WRNexusJS.
security, images, links, and JavaScript
+@wrnexus/dev-serverServe DEV_TOOLBAR_RUNTIME at /__wrnexus/dev-toolbar.js and DEV_TOOLBAR_CSS at /__wrnexus/dev-toolbar.css, then inject this before </body> in development:
<script type="module" src="/__wrnexus/dev-toolbar.js" data-wrnexus-dev-toolbar></script>
-The browser runtime exposes window.__wrnexusDevToolbar.
Generated from the exact installed package declarations.
export { DevToolbarCategory, DevToolbarClientApi, DevToolbarConfig, DevToolbarElementTarget, DevToolbarFix, DevToolbarIssue, DevToolbarMetrics, DevToolbarPageReport, DevToolbarPanel, DevToolbarPlatformSnapshot, DevToolbarServerMessage, DevToolbarSeverity, DevToolbarSourceLocation } from './types.js';
+The browser runtime exposes window.__wrnexusDevToolbar.
+Plugin panels returned through devToolbarPanels() are automatically added to the application strip. Their issue category is filterable, and structured data is rendered as escaped diagnostic content so a plugin never needs to inject toolbar HTML.
Generated from the exact installed package declarations.
export { DevToolbarCategory, DevToolbarClientApi, DevToolbarConfig, DevToolbarElementTarget, DevToolbarFix, DevToolbarIssue, DevToolbarMetrics, DevToolbarPageReport, DevToolbarPanel, DevToolbarPlatformSnapshot, DevToolbarServerMessage, DevToolbarSeverity, DevToolbarSourceLocation } from './types.js';
export { DEV_TOOLBAR_RULES, DevToolbarRule, DevToolbarRuleContext, accessibilityRules, accessibleName, colorRules, contrastRatio, createFingerprint, createIssue, effectiveBackground, formRules, getStableSelector, htmlRules, imageRules, isVisible, linkRules, luminance, mediaRules, parseRgb, parseSource, performanceRules, responsiveRules, runDevToolbarRules, securityRules, seoRules } from './rules/index.js';
-export { DevToolbarApp, DevToolbarCollector, DevToolbarIssueListener, DevToolbarRegistry, DevToolbarRouteOptions, OpenEditorOptions, OpenEditorRequest, buildEditorCommand, createDevToolbarCollector, createDevToolbarRegistry, createServerIssue, handleDevToolbarRoute, issueFromError, openInEditor, resolveEditorFile, serializeDevToolbarJson } from './server/index.js';
+export { BuiltinPanelOptions, DevToolbarApp, DevToolbarCollector, DevToolbarIssueListener, DevToolbarRegistry, DevToolbarRouteOptions, OpenEditorOptions, OpenEditorRequest, buildEditorCommand, builtinDevToolbarPanels, createDevToolbarCollector, createDevToolbarRegistry, createServerIssue, handleDevToolbarRoute, issueFromError, openInEditor, resolveEditorFile, serializeDevToolbarJson } from './server/index.js';
export { DEV_TOOLBAR_CSS, DEV_TOOLBAR_RUNTIME } from './client/index.js';
Copy-ready examples from the installed package documentation.
<script type="module" src="/__wrnexus/dev-toolbar.js" data-wrnexus-dev-toolbar></script>import { runDevToolbarRules } from "@wrnexus/dev-toolbar";
const issues = runDevToolbarRules(context);Hashing, HMAC, authenticated encryption, and key derivation.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/encryption@0.7.0Request preview access. Never put registry tokens in source control.
Dependency-free crypto helpers for WRNexusJS: authenticated symmetric encryption (AES-256-GCM), hashing, and HMAC signing.-
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
-This package provides small, focused cryptographic primitives for server-side use: encrypting secrets/tokens/database fields at rest with AES-256-GCM, deriving keys from passwords via PBKDF2, computing SHA-256 digests, and signing/verifying payloads with HMAC-SHA256. It is built entirely on the standard Web Crypto API (crypto.subtle) plus btoa/atob and TextEncoder/TextDecoder — no third-party dependencies. Reach for it whenever you need to protect sensitive values or verify webhook signatures. All functions are async (Web Crypto is promise-based).
bun add @wrnexus/encryption
-Private package — the machine must be authenticated to the wrnexus npm org
-(a read token in ~/.npmrc). Requires Bun (Node is not supported).
-All keys are exchanged as base64 strings and all digests/signatures as hex strings.
-| Export | Signature | Description |
|---|---|---|
generateKey | () => Promise<string> | Generate a random 256-bit AES key, base64-encoded. Store it as a secret. |
deriveKey | (password: string, salt: string) => Promise<string> | Derive a base64 AES-256 key from a password + salt using PBKDF2 (100,000 iterations, SHA-256). |
encrypt | (plaintext: string, key: string) => Promise<string> | AES-256-GCM encrypt a string. Returns base64 of iv(12 bytes) ‖ ciphertext+tag. A fresh random IV is used each call. |
decrypt | (payload: string, key: string) => Promise<string> | Decrypt a value produced by encrypt. Throws if the key is wrong or the data was tampered with. |
sha256 | (data: string) => Promise<string> | SHA-256 hex digest of a string (e.g. content hashing, dedup keys). |
hmacSign | (data: string, secret: string) => Promise<string> | HMAC-SHA256 hex signature of data with secret (e.g. signing webhooks). |
hmacVerify | (data: string, secret: string, signature: string) => Promise<boolean> | Constant-time verify of an HMAC-SHA256 hex signature. |
Notes:
+Hashing, HMAC, authenticated encryption, and key derivation.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/encryption@0.8.0Request preview access. Never put registry tokens in source control.
Authenticated encryption, hashing, HMAC, key rotation, and optional encrypted HTTP exchanges for WRNexusJS.
+generateKey produces a 32-byte (256-bit) key via crypto.getRandomValues.encrypt/decrypt require a base64-encoded 256-bit key; anything else throws "Encryption key must be a base64 256-bit key".decrypt throws "Invalid ciphertext" if the payload is shorter than the 12-byte IV, and the underlying Web Crypto call throws on any authentication (tag) mismatch.hmacVerify compares in constant time (length check plus XOR accumulation) to avoid timing leaks.generateKey() — random 256-bit AES key encoded as base64.deriveKey(password, salt) — PBKDF2-derived AES key.encrypt(plaintext, key) / decrypt(payload, key) — AES-256-GCM.sha256(data) — SHA-256 digest.hmacSign(data, secret) / hmacVerify(...) — HMAC-SHA256.createKeyring(keys) — active/previous key management.seal() / open() — versioned ciphertext with key ID.Symmetric encryption of a secret at rest:
-import { generateKey, encrypt, decrypt } from "@wrnexus/encryption";
+Encrypted HTTP envelope
+import {
+ createEncryptedRequest,
+ createKeyring,
+ createMemoryReplayStore,
+ decryptEncryptedResponse,
+ encryptedExchange,
+} from "@wrnexus/encryption";
-const key = await generateKey(); // store this safely (env/secret manager)
+const keyring = createKeyring([{ id: "2026-08", secret: process.env.API_BODY_KEY!, active: true }]);
-const box = await encrypt("card #1234", key); // opaque base64 string, safe to persist
-const plain = await decrypt(box, key); // "card #1234"
-Deriving a key from a user password instead of a random key:
-import { deriveKey, encrypt } from "@wrnexus/encryption";
+const replayStore = createMemoryReplayStore();
-const key = await deriveKey("correct horse battery staple", "per-user-salt");
-const box = await encrypt("secret note", key);
-Hashing and webhook signature verification:
-import { sha256, hmacSign, hmacVerify } from "@wrnexus/encryption";
+// Server middleware.
+app.use(
+ encryptedExchange({
+ keyring,
+ replayStore,
+ maxAgeMs: 60_000,
+ maxBodyBytes: 1_048_576,
+ }),
+);
-const digest = await sha256("some content"); // 64-char hex string
-
-const signature = await hmacSign(rawBody, webhookSecret);
-const ok = await hmacVerify(rawBody, webhookSecret, incomingSignatureHeader);
-if (!ok) throw new Error("Invalid webhook signature");
-Requirements / Notes
+// Controlled service/native client.
+const request = await createEncryptedRequest(
+ "https://api.example.com/private/report",
+ { reportId: "report-1" },
+ { method: "POST", keyring },
+);
+const response = await fetch(request);
+const result = await decryptEncryptedResponse(response, request, { keyring });
+The envelope binds authenticated ciphertext to:
crypto.subtle, crypto.getRandomValues) and the global btoa/atob, TextEncoder/TextDecoder — all available in Bun's runtime.Generated from the exact installed package declarations.
interface EncryptionKey {
+HTTP method
+URL path and query
+request ID
+timestamp and expiry window
+encryption key ID
+optional replay-store consumption
+
+encryptedBody() decrypts request bodies only. encryptedExchange() also encrypts successful downstream responses while allowing application exceptions to propagate normally. encryptedFetch() provides a convenient controlled-client call.
+Security boundary
+Encrypted HTTP bodies do not replace TLS/HTTPS. Always use HTTPS.
+This layer is appropriate for service-to-service traffic, native/mobile applications, controlled agents, and selected fields protected with server-managed keys. It cannot conceal data from an end user when browser JavaScript receives the decryption key. Never ship a long-lived server encryption key to a browser.
+Use a shared replay store such as Redis in multi-instance deployments. The memory replay store is process-local.
Generated from the exact installed package declarations.
import { Middleware } from '@wrnexus/core';
+
+interface EncryptionKey {
id: string;
secret: string;
active?: boolean;
@@ -80,6 +91,66 @@ declare function open(sealed: string, keyring: EncryptionKeyring): Promise<st
declare function sealedKeyId(sealed: string): string | null;
declare function needsRotation(sealed: string, keyring: EncryptionKeyring): boolean;
+declare const ENCRYPTED_HTTP_CONTENT_TYPE = "application/wrn+json";
+declare const ENCRYPTED_HTTP_VERSION = "wrn-http-1";
+interface EncryptedHttpEnvelope {
+ version: typeof ENCRYPTED_HTTP_VERSION;
+ keyId: string;
+ requestId: string;
+ timestamp: number;
+ ciphertext: string;
+}
+interface ReplayStore {
+ consume(id: string, expiresAt: number): boolean | Promise<boolean>;
+}
+interface EncryptedHttpOptions {
+ keyring: EncryptionKeyring;
+ maxAgeMs?: number;
+ maxBodyBytes?: number;
+ replayStore?: ReplayStore;
+ now?: () => number;
+ /** Require the clear request-id header used to bind encrypted responses. Default true. */
+ requireRequestIdHeader?: boolean;
+}
+interface DecryptedHttpBody<T> {
+ body: T;
+ requestId: string;
+ timestamp: number;
+ keyId: string;
+}
+declare function createMemoryReplayStore(now?: () => number): ReplayStore;
+declare function encryptHttpBody<T>(body: T, input: {
+ keyring: EncryptionKeyring;
+ method?: string;
+ url: string | URL;
+ requestId?: string;
+ timestamp?: number;
+}): Promise<EncryptedHttpEnvelope>;
+declare function decryptHttpBody<T>(value: unknown, input: {
+ keyring: EncryptionKeyring;
+ method?: string;
+ url: string | URL;
+ maxAgeMs?: number;
+ replayStore?: ReplayStore;
+ now?: () => number;
+ expectedRequestId?: string;
+}): Promise<DecryptedHttpBody<T>>;
+declare function createEncryptedRequest<T>(url: string | URL, body: T, input: Omit<RequestInit, "body"> & {
+ keyring: EncryptionKeyring;
+ requestId?: string;
+}): Promise<Request>;
+declare function decryptRequest<T>(request: Request, options: EncryptedHttpOptions): Promise<DecryptedHttpBody<T>>;
+declare function encryptResponse<T>(body: T, request: Request, options: EncryptedHttpOptions & {
+ status?: number;
+ headers?: HeadersInit;
+}): Promise<Response>;
+declare function decryptEncryptedResponse<T>(response: Response, request: Request, options: EncryptedHttpOptions): Promise<DecryptedHttpBody<T>>;
+declare function encryptedFetch<TRequest, TResponse>(url: string | URL, body: TRequest, input: Omit<RequestInit, "body"> & EncryptedHttpOptions): Promise<TResponse>;
+declare function encryptedBody(options: EncryptedHttpOptions): Middleware;
+declare function encryptedExchange(options: EncryptedHttpOptions & {
+ encryptResponses?: boolean;
+}): Middleware;
+
/**
* @wrnexus/encryption — authenticated symmetric encryption (AES-256-GCM) via
* WebCrypto, dependency-free. Use it to encrypt secrets, tokens, or database
@@ -109,25 +180,40 @@ declare function decrypt(payload: string, key: string): Promise<string>;
/** Derive a base64 AES key from a password + salt (PBKDF2, 100k iterations). */
declare function deriveKey(password: string, salt: string): Promise<string>;
-export { type EncryptionKey, type EncryptionKeyring, createKeyring, decrypt, deriveKey, encrypt, generateKey, hmacSign, hmacVerify, needsRotation, open, seal, sealedKeyId, sha256 };
-Copy-ready examples from the installed package documentation.
import { generateKey, encrypt, decrypt } from "@wrnexus/encryption";
+export { type DecryptedHttpBody, ENCRYPTED_HTTP_CONTENT_TYPE, ENCRYPTED_HTTP_VERSION, type EncryptedHttpEnvelope, type EncryptedHttpOptions, type EncryptionKey, type EncryptionKeyring, type ReplayStore, createEncryptedRequest, createKeyring, createMemoryReplayStore, decrypt, decryptEncryptedResponse, decryptHttpBody, decryptRequest, deriveKey, encrypt, encryptHttpBody, encryptResponse, encryptedBody, encryptedExchange, encryptedFetch, generateKey, hmacSign, hmacVerify, needsRotation, open, seal, sealedKeyId, sha256 };
+Copy-ready examples from the installed package documentation.
import {
+ createEncryptedRequest,
+ createKeyring,
+ createMemoryReplayStore,
+ decryptEncryptedResponse,
+ encryptedExchange,
+} from "@wrnexus/encryption";
-const key = await generateKey(); // store this safely (env/secret manager)
+const keyring = createKeyring([{ id: "2026-08", secret: process.env.API_BODY_KEY!, active: true }]);
-const box = await encrypt("card #1234", key); // opaque base64 string, safe to persist
-const plain = await decrypt(box, key); // "card #1234"import { deriveKey, encrypt } from "@wrnexus/encryption";
+const replayStore = createMemoryReplayStore();
-const key = await deriveKey("correct horse battery staple", "per-user-salt");
-const box = await encrypt("secret note", key);import { sha256, hmacSign, hmacVerify } from "@wrnexus/encryption";
+// Server middleware.
+app.use(
+ encryptedExchange({
+ keyring,
+ replayStore,
+ maxAgeMs: 60_000,
+ maxBodyBytes: 1_048_576,
+ }),
+);
-const digest = await sha256("some content"); // 64-char hex string
-
-const signature = await hmacSign(rawBody, webhookSecret);
-const ok = await hmacVerify(rawBody, webhookSecret, incomingSignatureHeader);
-if (!ok) throw new Error("Invalid webhook signature");bun add @wrnexus/encryptionGraphQL schemas, routes, and framework plugin integration.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/graphql@0.8.0Request preview access. Never put registry tokens in source control.
Optional GraphQL endpoint plugin. Supply the executor from GraphQL.js, GraphQL Yoga, Mercurius, or another maintained engine; WRNexus owns bounded HTTP input, depth/alias limits, introspection policy, generic production errors and plugin route integration.
Generated from the exact installed package declarations.
export { G as GraphqlExecutionResult, a as GraphqlOptions, b as GraphqlRequest, c as createGraphqlHandler, default as graphqlPlugin } from './plugin.js';
+import '@wrnexus/plugin';
+Copy-ready examples from the installed package documentation.
bun add @wrnexus/graphqlimport * as graphql from "@wrnexus/graphql";Safe Context URL helpers and forward-auth login redirects.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/helpers@0.7.0Request preview access. Never put registry tokens in source control.
Safe convenience helpers for common WRNexusJS application flows. The package uses standard Context, URL, and Response values and has no runtime dependency beyond @wrnexus/core.
Safe Context URL helpers and forward-auth login redirects.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/helpers@0.8.0Request preview access. Never put registry tokens in source control.
Safe convenience helpers for common WRNexusJS application flows. The package uses standard Context, URL, and Response values and has no runtime dependency beyond @wrnexus/core.
bun add @wrnexus/helpers
The package is private, so the machine must be authenticated to the wrnexus npm organization.
Translation loading, locale resolution, and Intl formatting.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/i18n@0.7.0Request preview access. Never put registry tokens in source control.
Per-request translations plus locale-aware number, date, and currency formatting for WRNexusJS apps.-
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
-@wrnexus/i18n loads locale files from app/locales/<lang>.json, resolves the active language for each request (cookie → Accept-Language → default), and builds a t(key, params) translator used both in server code and in .wrn views. It also ships Intl-based formatting helpers and a tiny client runtime that wires up a language switcher. Translation lookup, language resolution, and HTML marker rewriting run server-side; only the small I18N_RUNTIME snippet runs in the browser.
bun add @wrnexus/i18n
-Private package — the machine must be authenticated to the wrnexus npm org
-(a read token in ~/.npmrc). Requires Bun (Node is not supported).
-| Export | Signature | Description | ||
|---|---|---|---|---|
loadLocales | (dir: string) => Record<string, Messages> | Reads every <lang>.json in dir into a { lang: messages } map. Missing dir → {}; a bad file is warned and skipped. | ||
resolveI18n | (messages: Record<string, Messages>, config?: I18nConfig) => ResolvedI18n | Merges loaded messages + config into a resolved bundle (default lang, supported langs, messages). | ||
resolveLang | `(i18n: ResolvedI18n, cookieValue: string \ | undefined, acceptLanguage: string \ | null) => string` | Picks the active language: matching cookie → best Accept-Language tag (falls back to base tag, e.g. en-US → en) → i18n.default. |
makeT | (i18n: ResolvedI18n, lang: string) => TFunction | Builds a translator resolving current language → default → the key itself, with {param} interpolation. |
| Export | Kind | Notes |
|---|---|---|
Messages | type | Record<string, unknown> — a locale's messages (supports nested/dotted keys). |
I18nConfig | interface | { default?: string; locales?: string[] }. |
ResolvedI18n | interface | { default: string; langs: string[]; messages: Record<string, Messages> }. |
LANG_COOKIE | const | "wire-lang" — the cookie the language is read from / written to. |
I18N_JS_HREF | const | "/__wrnexus/i18n.js" — URL the client runtime is served at. |
| Export | Signature | Description |
|---|---|---|
translateHtml | (html: string, t: TFunction) => string | Rewrites markers in rendered HTML: t:<attr>="key" → <attr>="<translation>" (attribute-escaped) and <tag data-t="key">…</tag> → element text becomes the translation (HTML-escaped). No-op unless a marker is present. |
renderI18nData | (i18n: ResolvedI18n, lang: string) => string | JS snippet setting window.__wireI18n = { lang, langs, default } for the client switcher. |
I18N_RUNTIME | const string | Browser IIFE that binds [data-wire-lang-set="es"] clicks and select[data-wire-lang] changes to set the wire-lang cookie and reload. Exposes window.__wireLang.set(lang). |
./format.ts)| Export | Signature | Example | ||
|---|---|---|---|---|
formatNumber | (value: number, lang: string, options?: Intl.NumberFormatOptions) => string | 1234.5 → "1,234.5" | ||
formatCurrency | (value: number, currency: string, lang: string) => string | 9.99, "USD" → "$9.99" | ||
formatDate | `(value: Date \ | number \ | string, lang: string, options?: Intl.DateTimeFormatOptions) => string` | defaults to { dateStyle: "medium" } |
formatRelativeTime | (value: number, unit: Intl.RelativeTimeFormatUnit, lang: string) => string | -3, "day" → "3 days ago" (numeric: "auto") | ||
plural | (count: number, forms: Partial<Record<Intl.LDMLPluralRule, string>>, lang: string) => string | picks CLDR form; # is replaced by count |
import {
- loadLocales,
- resolveI18n,
- resolveLang,
- makeT,
- translateHtml,
- LANG_COOKIE,
-} from "@wrnexus/i18n";
+ Frontend · Package reference@wrnexus/i18n
Translation loading, locale resolution, and Intl formatting.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/i18n@0.8.0
Request preview access. Never put registry tokens in source control.
Recursive locale loading, fallback resolution, SSR/browser translations, locale formatting, and language UI blocks for WRNexusJS.
+Locale files
+Both layouts can be used together:
+app/locales/en.json
+app/locales/en/common.json
+app/locales/en/auth.json
+app/locales/mr/common.json
+Namespaced files become keys such as common.save and auth.signIn.
+import { loadLocales, makeT, resolveI18n, resolveLang } from "@wrnexus/i18n";
-// app/locales/en.json, app/locales/es.json
-const messages = loadLocales("app/locales");
-const i18n = resolveI18n(messages, { default: "en", locales: ["en", "es"] });
+const i18n = resolveI18n(loadLocales("app/locales", { strict: true }), {
+ default: "en",
+ locales: ["en", "mr", "hi"],
+ fallbacks: { "mr-IN": ["mr", "en"] },
+ cookie: { name: "wire-lang", sameSite: "Lax", secure: true },
+});
-// Per request:
-const lang = resolveLang(i18n, req.cookies?.[LANG_COOKIE], req.headers.get("accept-language"));
+const lang = resolveLang(i18n, cookieValue, request.headers.get("accept-language"));
const t = makeT(i18n, lang);
-
-t("nav.home"); // dotted key → "Home"
-t("greeting", { name: "Ada" }); // "Hello, {name}" → "Hello, Ada"
-
-// After rendering a .wrn view, resolve translation markers in the HTML:
-const finalHtml = translateHtml(renderedHtml, t);
-app/locales/en.json:
-{
- "nav": { "home": "Home" },
- "greeting": "Hello, {name}"
-}
-Views: translation markers
-<h1 data-t="nav.home">Home</h1>
+t("common.hello", { name: "Ajay" });
+Resolution behavior
+
+- normalized BCP-47-style locale names
+- cookie preference
+- weighted
Accept-Language
+- wildcard language ranges
+- regional base fallback
+- explicit fallback chains
+- configured default language
+- automatic RTL for Arabic, Hebrew, Persian, Urdu, and related languages
+
+Locale JSON is size-limited and rejects prototype-pollution keys. Recursive namespace collisions are resolved safely.
+Views and runtime
+<h1 data-t="dashboard.title">Dashboard</h1>
<input t:placeholder="search.placeholder" />
-translateHtml replaces the element text for data-t and the attribute value for any t:<attr> (e.g. t:placeholder, t:aria-label).
-Client: language switcher
-import { renderI18nData, I18N_RUNTIME, I18N_JS_HREF } from "@wrnexus/i18n";
-
-// In the document <head>:
-const head = `
- <script>${renderI18nData(i18n, lang)}</script>
- <script src="${I18N_JS_HREF}"></script>
-`;
-
-// Serve I18N_RUNTIME at I18N_JS_HREF; then in markup:
-// <button data-wire-lang-set="es">Español</button>
-// <select data-wire-lang>…</select>
-Formatting
+Text and translated attributes are resolved during SSR. Active/fallback messages are serialized safely for the language runtime, which rebinds data-t markers after client navigation.
+Enable i18nPlugin() to use:
+
+<LanguageSwitcher />
+<LocaleStatus />
+
+LanguageSwitcher renders a native select[data-wire-lang]. The packaged runtime validates the selection against the configured locales, writes the configured language cookie, updates the document lang/dir attributes, emits wrnexus:language-change, and reloads so the next SSR request uses the same cookie. No application-owned browser script is required.
+Formatting
+
+formatNumber
+formatCurrency
+formatDate
+formatRelativeTime
+plural
+createLocaleFormatter
+translationCoverage
+Localization tooling can extract statically discoverable t("key"), i18n.t("key"), and data-i18n="key" usage, compare every locale with a reference, and create layout-stressing pseudo-locales:
+
import {
- formatNumber,
- formatCurrency,
- formatDate,
- formatRelativeTime,
- plural,
+ auditLocaleKeys,
+ createPseudoLocale,
+ extractTranslationKeysFromFiles,
} from "@wrnexus/i18n";
-formatNumber(1234.5, lang); // "1,234.5"
-formatCurrency(9.99, "USD", lang); // "$9.99"
-formatDate(Date.now(), lang); // "Jul 4, 2026"
-formatRelativeTime(-3, "day", lang); // "3 days ago"
-plural(2, { one: "# item", other: "# items" }, lang); // "2 items"
-Configuration
-resolveI18n accepts an I18nConfig:
-
-default — fallback language; used when nothing else matches. Ignored if it has
-no loaded messages, in which case the first supported language is used.
-locales — explicit supported-language list; defaults to the loaded locale names.
-
-Language resolution order at request time (resolveLang): a supported wire-lang cookie value → the first matching Accept-Language tag (or its base subtag) → the resolved default.
-Requirements / Notes
-
-- Bun-only. Locale loading uses
node:fs (existsSync, readdirSync,
-readFileSync) and node:path; formatting relies on the platform Intl APIs.
-- Works with [
@wrnexus/core](../core) — TFunction (the t(key, params) type)
-comes from core, and the resolved translator is exposed as ctx.t / ctx.lang in request handling.
-- Nested message objects are supported: keys are looked up whole first, then split
-on . to walk the object tree.
-
Complete TypeScript API
Generated from the exact installed package declarations.
import { TFunction } from '@wrnexus/core';
+const used = extractTranslationKeysFromFiles(sourceFiles);
+const coverage = auditLocaleKeys(messages, "en");
+const enXA = createPseudoLocale(messages.en);
+const arXB = createPseudoLocale(messages.en, { rtl: true });
+Pseudo-localization preserves interpolation placeholders and markup tags. RTL pseudo output uses Unicode direction controls, while runtime direction detection continues to derive rtl from Arabic and other RTL language subtags.
Complete TypeScript API
Generated from the exact installed package declarations.
import { TFunction } from '@wrnexus/core';
+export { I18nPluginOptions, i18nComponentsDir, default as i18nPlugin } from './plugin.js';
+import '@wrnexus/plugin';
/**
* Locale-aware formatting helpers (Intl-based) + pluralization. Pair with the
@@ -134,6 +100,25 @@ declare function formatRelativeTime(value: number, unit: Intl.RelativeTimeFormat
*/
declare function plural(count: number, forms: Partial<Record<Intl.LDMLPluralRule, string>>, lang: string): string;
+interface ExtractedTranslationKey {
+ key: string;
+ file?: string;
+ offset: number;
+}
+declare function extractTranslationKeys(source: string, file?: string): ExtractedTranslationKey[];
+declare function extractTranslationKeysFromFiles(files: Iterable<string>): ExtractedTranslationKey[];
+declare function flattenMessageKeys(messages: Messages, prefix?: string): string[];
+declare function auditLocaleKeys(messages: Record<string, Messages>, referenceLocale: string): Record<string, {
+ missing: string[];
+ extra: string[];
+}>;
+declare function pseudoLocalize(value: string, options?: {
+ rtl?: boolean;
+}): string;
+declare function createPseudoLocale(messages: Messages, options?: {
+ rtl?: boolean;
+}): Messages;
+
declare function flattenMessages(messages: Messages, prefix?: string, output?: Record<string, string>): Record<string, string>;
declare function localeFallbacks(locale: string, fallback?: string): string[];
declare function translationCoverage(i18n: ResolvedI18n): Record<string, {
@@ -150,108 +135,103 @@ interface LocaleFormatter {
relative(value: number, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions): string;
list(values: string[], options?: Intl.ListFormatOptions): string;
}
-declare function createLocaleFormatter(locale: string, timeZone?: string): LocaleFormatter;
-/** Lightweight plural templates: `{count, plural, one {# item} other {# items}}`. */
+declare function createLocaleFormatter(locale: string, timeZone?: string, calendar?: string): LocaleFormatter;
+/** ICU-style plural/select templates with exact values and recursive interpolation. */
declare function formatMessage(template: string, params: Record<string, string | number>, locale: string): string;
/**
- * @wrnexus/i18n — translations for pages and API responses.
- *
- * Locales live in `app/locales/<lang>.json`. Per request the active language is
- * resolved from the `wire-lang` cookie, then Accept-Language, then the default.
- * `ctx.t(key, params)` translates on the server; in `.wrn` views `{t:key}` and
- * `t:attr="key"` markers are resolved by `translateHtml` before the HTML is sent.
+ * @wrnexus/i18n — deterministic locale loading, fallback resolution, SSR
+ * translation markers, browser translation helpers, and UI language controls.
*/
type Messages = Record<string, unknown>;
-/** Load `<dir>/<lang>.json` files into a `{ lang: messages }` map. */
-declare function loadLocales(dir: string): Record<string, Messages>;
+interface LocaleLoadOptions {
+ /** Throw on invalid JSON instead of warning and continuing. */
+ strict?: boolean;
+ /** Maximum JSON file size. Default 1 MiB. */
+ maxFileBytes?: number;
+}
+interface I18nCookieConfig {
+ name?: string;
+ maxAge?: number;
+ path?: string;
+ sameSite?: "Strict" | "Lax" | "None";
+ secure?: boolean;
+}
interface I18nConfig {
- /** Default language, used as the fallback and when nothing else matches. */
default?: string;
- /** Explicit set of supported languages (defaults to the loaded locale names). */
locales?: string[];
+ /** Human-readable locale names used by package language controls. */
+ labels?: Record<string, string>;
+ /** Per-locale fallback override. Example: `{ "fr-CA": ["fr", "en"] }`. */
+ fallbacks?: Record<string, string[]>;
+ /** Locale direction overrides. Arabic/Hebrew/Persian/Urdu are RTL automatically. */
+ direction?: Record<string, "ltr" | "rtl">;
+ cookie?: I18nCookieConfig;
+ strict?: boolean;
}
interface ResolvedI18n {
default: string;
langs: string[];
messages: Record<string, Messages>;
+ fallbacks: Record<string, string[]>;
+ direction: Record<string, "ltr" | "rtl">;
+ labels: Record<string, string>;
+ cookie: Required<I18nCookieConfig>;
}
declare const LANG_COOKIE = "wire-lang";
declare const I18N_JS_HREF = "/__wrnexus/i18n.js";
-/** Merge loaded locale messages + config into a resolved i18n bundle. */
+declare function normalizeLocale(locale: string): string;
+/**
+ * Load both supported layouts:
+ * - `locales/en.json`
+ * - `locales/en/common.json`, `locales/en/auth.json`
+ *
+ * Namespaced files become `messages.en.common` and `messages.en.auth`.
+ */
+declare function loadLocales(dir: string, options?: LocaleLoadOptions): Record<string, Messages>;
+declare function localeDirection(locale: string, overrides?: Record<string, "ltr" | "rtl">): "ltr" | "rtl";
declare function resolveI18n(messages: Record<string, Messages>, config?: I18nConfig): ResolvedI18n;
-/** Build a `t()` for a language: current → default → the key itself. */
+declare function lookupMessage(messages: Messages | undefined, key: string): string | undefined;
+declare function interpolate(message: string, params?: Record<string, string | number>): string;
+declare function translationChain(i18n: ResolvedI18n, locale: string): string[];
declare function makeT(i18n: ResolvedI18n, lang: string): TFunction;
-/** Resolve the active language from a cookie, Accept-Language, then default. */
+/** Deeply apply tenant-specific translations without mutating the shared locale bundle. */
+declare function withTenantMessages(i18n: ResolvedI18n, overrides: Record<string, Messages>): ResolvedI18n;
+/** Load only common and route-specific messages for one locale. */
+declare function loadRouteMessages(directory: string, locale: string, route: string): Messages;
+declare function parseAcceptLanguage(value: string | null): string[];
declare function resolveLang(i18n: ResolvedI18n, cookieValue: string | undefined, acceptLanguage: string | null): string;
-/**
- * Resolve translation markers in rendered HTML:
- * t:<attr>="key" → <attr>="<translation>" (e.g. t:placeholder, t:aria-label)
- * <tag data-t="key">…</tag> → element text becomes the translation
- * Only runs when the HTML actually contains a marker.
- */
declare function translateHtml(html: string, t: TFunction): string;
-/** `window.__wireI18n = { lang, langs }` for the client language switcher. */
declare function renderI18nData(i18n: ResolvedI18n, lang: string): string;
-/**
- * Client runtime: binds `[data-wire-lang-set="es"]` elements to set the
- * `wire-lang` cookie and reload, so the server re-renders in the new language.
- */
declare const I18N_RUNTIME: string;
-export { I18N_JS_HREF, I18N_RUNTIME, type I18nConfig, LANG_COOKIE, type LocaleFormatter, type Messages, type ResolvedI18n, createLocaleFormatter, flattenMessages, formatCurrency, formatDate, formatMessage, formatNumber, formatRelativeTime, loadLocales, localeFallbacks, makeT, plural, renderI18nData, resolveI18n, resolveLang, translateHtml, translationCoverage };
-
Examples
Copy-ready examples from the installed package documentation.
Server: load, resolve, translate
import {
- loadLocales,
- resolveI18n,
- resolveLang,
- makeT,
- translateHtml,
- LANG_COOKIE,
-} from "@wrnexus/i18n";
+export { type ExtractedTranslationKey, I18N_JS_HREF, I18N_RUNTIME, type I18nConfig, type I18nCookieConfig, LANG_COOKIE, type LocaleFormatter, type LocaleLoadOptions, type Messages, type ResolvedI18n, auditLocaleKeys, createLocaleFormatter, createPseudoLocale, extractTranslationKeys, extractTranslationKeysFromFiles, flattenMessageKeys, flattenMessages, formatCurrency, formatDate, formatMessage, formatNumber, formatRelativeTime, interpolate, loadLocales, loadRouteMessages, localeDirection, localeFallbacks, lookupMessage, makeT, normalizeLocale, parseAcceptLanguage, plural, pseudoLocalize, renderI18nData, resolveI18n, resolveLang, translateHtml, translationChain, translationCoverage, withTenantMessages };
+
Examples
Copy-ready examples from the installed package documentation.
Namespaced files become keys such as common.save and auth.signIn.
import { loadLocales, makeT, resolveI18n, resolveLang } from "@wrnexus/i18n";
-// app/locales/en.json, app/locales/es.json
-const messages = loadLocales("app/locales");
-const i18n = resolveI18n(messages, { default: "en", locales: ["en", "es"] });
+const i18n = resolveI18n(loadLocales("app/locales", { strict: true }), {
+ default: "en",
+ locales: ["en", "mr", "hi"],
+ fallbacks: { "mr-IN": ["mr", "en"] },
+ cookie: { name: "wire-lang", sameSite: "Lax", secure: true },
+});
-// Per request:
-const lang = resolveLang(i18n, req.cookies?.[LANG_COOKIE], req.headers.get("accept-language"));
+const lang = resolveLang(i18n, cookieValue, request.headers.get("accept-language"));
const t = makeT(i18n, lang);
-
-t("nav.home"); // dotted key → "Home"
-t("greeting", { name: "Ada" }); // "Hello, {name}" → "Hello, Ada"
-
-// After rendering a .wrn view, resolve translation markers in the HTML:
-const finalHtml = translateHtml(renderedHtml, t);
Server: load, resolve, translate
{
- "nav": { "home": "Home" },
- "greeting": "Hello, {name}"
-}
Views: translation markers
<h1 data-t="nav.home">Home</h1>
-<input t:placeholder="search.placeholder" />
Client: language switcher
import { renderI18nData, I18N_RUNTIME, I18N_JS_HREF } from "@wrnexus/i18n";
-
-// In the document <head>:
-const head = `
- <script>${renderI18nData(i18n, lang)}</script>
- <script src="${I18N_JS_HREF}"></script>
-`;
-
-// Serve I18N_RUNTIME at I18N_JS_HREF; then in markup:
-// <button data-wire-lang-set="es">Español</button>
-// <select data-wire-lang>…</select>
Formatting
import {
- formatNumber,
- formatCurrency,
- formatDate,
- formatRelativeTime,
- plural,
+t("common.hello", { name: "Ajay" });
## Views and runtime
<h1 data-t="dashboard.title">Dashboard</h1>
+<input t:placeholder="search.placeholder" />
reference, and create layout-stressing pseudo-locales
import {
+ auditLocaleKeys,
+ createPseudoLocale,
+ extractTranslationKeysFromFiles,
} from "@wrnexus/i18n";
-formatNumber(1234.5, lang); // "1,234.5"
-formatCurrency(9.99, "USD", lang); // "$9.99"
-formatDate(Date.now(), lang); // "Jul 4, 2026"
-formatRelativeTime(-3, "day", lang); // "3 days ago"
-plural(2, { one: "# item", other: "# items" }, lang); // "2 items"
-
+const used = extractTranslationKeysFromFiles(sourceFiles);
+const coverage = auditLocaleKeys(messages, "en");
+const enXA = createPseudoLocale(messages.en);
+const arXB = createPseudoLocale(messages.en, { rtl: true });
+
Portable identity records, claims, and account linking.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/identity@0.8.0Request preview access. Never put registry tokens in source control.
Enterprise identity and governance for WRNexusJS: OIDC discovery, signed SAML adapter flows, LDAP/Active Directory synchronization adapters, SCIM provisioning, scoped API keys, service accounts, approval workflows, consent history, retention, subject export/deletion and audit.
+The package complements @wrnexus/auth (passkeys, MFA, devices, sessions, OAuth and audited impersonation) and @wrnexus/authz (RBAC, ABAC and policy decisions). Protocol-specific SAML and directory parsing is supplied through adapters so applications can select a maintained vendor SDK without weakening framework validation, replay protection or governance auditing.
Generated from the exact installed package declarations.
interface OidcMetadata {
+ issuer: string;
+ authorization_endpoint: string;
+ token_endpoint: string;
+ userinfo_endpoint?: string;
+ jwks_uri: string;
+ scopes_supported?: string[];
+}
+declare function discoverOidc(issuer: string, options?: {
+ fetch?: typeof fetch;
+}): Promise<OidcMetadata>;
+declare function oidcAuthorizationUrl(metadata: OidcMetadata, input: {
+ clientId: string;
+ redirectUri: string;
+ state: string;
+ nonce: string;
+ codeChallenge: string;
+ scopes?: string[];
+}): string;
+interface EnterpriseIdentity {
+ externalId: string;
+ username: string;
+ displayName?: string;
+ email?: string;
+ groups: string[];
+ active: boolean;
+ attributes?: Record<string, unknown>;
+}
+interface SamlAssertion {
+ id: string;
+ issuer: string;
+ audience: string;
+ recipient: string;
+ expiresAt: number;
+ identity: EnterpriseIdentity;
+}
+interface SamlAdapter {
+ createLoginRequest(input: {
+ requestId: string;
+ callbackUrl: string;
+ relayState: string;
+ }): Promise<string> | string;
+ verifySignedResponse(response: string): Promise<SamlAssertion>;
+}
+interface ReplayStore {
+ consume(id: string, expiresAt: number): Promise<boolean>;
+}
+declare function memoryReplayStore(now?: () => number): ReplayStore;
+declare function createSamlFederation(options: {
+ adapter: SamlAdapter;
+ issuer: string;
+ audience: string;
+ recipient: string;
+ replayStore?: ReplayStore;
+ now?: () => number;
+}): {
+ login: (input: {
+ requestId: string;
+ callbackUrl: string;
+ relayState: string;
+ }) => Promise<string> | string;
+ callback(encodedResponse: string): Promise<EnterpriseIdentity>;
+};
+interface DirectoryAdapter {
+ kind: "ldap" | "active-directory";
+ search(input: {
+ baseDn: string;
+ filter: string;
+ attributes: string[];
+ signal?: AbortSignal;
+ }): Promise<EnterpriseIdentity[]>;
+ authenticate?(username: string, password: string, signal?: AbortSignal): Promise<EnterpriseIdentity | null>;
+}
+declare function syncDirectory(adapter: DirectoryAdapter, options: {
+ baseDn: string;
+ filter?: string;
+ attributes?: string[];
+ signal?: AbortSignal;
+ upsert: (identity: EnterpriseIdentity) => void | Promise<void>;
+ disableMissing?: (externalIds: string[]) => void | Promise<void>;
+}): Promise<{
+ provider: "ldap" | "active-directory";
+ synchronized: number;
+}>;
+interface ScimUser extends EnterpriseIdentity {
+ id: string;
+ /** RFC 7643 field accepted at the HTTP boundary. */
+ userName?: string;
+ schemas?: string[];
+}
+interface ScimStore {
+ list(): Promise<ScimUser[]>;
+ get(id: string): Promise<ScimUser | null>;
+ create(user: Omit<ScimUser, "id">): Promise<ScimUser>;
+ update(id: string, user: Partial<ScimUser>): Promise<ScimUser | null>;
+ delete(id: string): Promise<boolean>;
+}
+declare function memoryScimStore(): ScimStore;
+declare function createScimHandler(options: {
+ store: ScimStore;
+ bearerToken: string;
+ basePath?: string;
+ maxBodyBytes?: number;
+}): (request: Request) => Promise<Response>;
+interface MachineCredential {
+ id: string;
+ ownerId: string;
+ kind: "api-key" | "service-account";
+ name: string;
+ scopes: string[];
+ secretHash: string;
+ createdAt: number;
+ expiresAt?: number;
+ revokedAt?: number;
+}
+declare function createMachineIdentityManager(now?: () => number): {
+ issue(input: {
+ ownerId: string;
+ name: string;
+ scopes: string[];
+ kind?: MachineCredential["kind"];
+ expiresAt?: number;
+ }): Promise<{
+ secret: string;
+ credential: {
+ secretHash: string;
+ id: string;
+ ownerId: string;
+ kind: "api-key" | "service-account";
+ name: string;
+ scopes: string[];
+ createdAt: number;
+ expiresAt?: number;
+ revokedAt?: number;
+ };
+ }>;
+ authenticate(secret: string, requiredScope?: string): Promise<{
+ secretHash: string;
+ id: string;
+ ownerId: string;
+ kind: "api-key" | "service-account";
+ name: string;
+ scopes: string[];
+ createdAt: number;
+ expiresAt?: number;
+ revokedAt?: number;
+ } | null>;
+ revoke(id: string): boolean;
+ list(ownerId: string): {
+ secretHash: string;
+ id: string;
+ ownerId: string;
+ kind: "api-key" | "service-account";
+ name: string;
+ scopes: string[];
+ createdAt: number;
+ expiresAt?: number;
+ revokedAt?: number;
+ }[];
+};
+interface GovernanceEvent {
+ id: string;
+ type: string;
+ subjectId: string;
+ actorId?: string;
+ createdAt: number;
+ data?: Record<string, unknown>;
+}
+declare function createGovernance(options?: {
+ now?: () => number;
+ audit?: (event: GovernanceEvent) => void | Promise<void>;
+ exportSubject?: (subjectId: string) => unknown | Promise<unknown>;
+ deleteSubject?: (subjectId: string) => void | Promise<void>;
+}): {
+ consent(subjectId: string, purpose: string, granted: boolean, version: string): Promise<{
+ granted: boolean;
+ version: string;
+ at: number;
+ }>;
+ consents(subjectId: string): {
+ [k: string]: {
+ granted: boolean;
+ version: string;
+ at: number;
+ };
+ };
+ request(subjectId: string, action: "export" | "delete"): Promise<{
+ id: `${string}-${string}-${string}-${string}-${string}`;
+ subjectId: string;
+ action: "export" | "delete";
+ status: "pending";
+ requestedAt: number;
+ }>;
+ decide(id: string, actorId: string, approved: boolean): Promise<{
+ decision: {
+ status: "approved" | "rejected";
+ decidedAt: number;
+ decidedBy: string;
+ id: string;
+ subjectId: string;
+ action: "export" | "delete";
+ requestedAt: number;
+ };
+ result: unknown;
+ }>;
+ enforceRetention(records: Array<{
+ subjectId: string;
+ createdAt: number;
+ }>, maxAgeMs: number, remove: (record: {
+ subjectId: string;
+ createdAt: number;
+ }) => void | Promise<void>): Promise<number>;
+};
+
+export { type DirectoryAdapter, type EnterpriseIdentity, type GovernanceEvent, type MachineCredential, type OidcMetadata, type ReplayStore, type SamlAdapter, type SamlAssertion, type ScimStore, type ScimUser, createGovernance, createMachineIdentityManager, createSamlFederation, createScimHandler, discoverOidc, memoryReplayStore, memoryScimStore, oidcAuthorizationUrl, syncDirectory };
+Copy-ready examples from the installed package documentation.
bun add @wrnexus/identityimport * as identity from "@wrnexus/identity";Responsive image optimization, loaders, placeholders, and components.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/image@0.8.0Request preview access. Never put registry tokens in source control.
Secure responsive-image planning, loader adapters, picture sources, preload hints, placeholders, and performance auditing for WRNexusJS.
+Build-time conversion is available through optimizeImage. It normalizes and bounds width/format variants, prevents variant explosions, writes deterministic filenames, and returns a manifest with dimensions and byte sizes:
import { optimizeImage } from "@wrnexus/image";
+
+const manifest = await optimizeImage("public/hero.jpg", {
+ outputDir: "public/generated/images",
+ widths: [480, 960, 1440],
+ formats: ["avif", "webp"],
+ quality: 80,
+});
+Install the optional sharp peer (bun add sharp) for the default AVIF/WebP processor. Build systems can instead supply an ImageProcessor adapter, which also makes transformation pipelines deterministic in tests.
import {
+ createResponsiveImage,
+ createPicture,
+ createCdnImageLoader,
+ createPathImageLoader,
+ createBlurPlaceholder,
+ imagePreload,
+ auditImage,
+} from "@wrnexus/image";
+
+const loader = createCdnImageLoader("https://images.example.com/transform");
+const picture = createPicture({
+ src: "/hero.jpg",
+ alt: "Product dashboard",
+ width: 1600,
+ height: 900,
+ widths: [480, 768, 1200, 1600],
+ formats: ["avif", "webp"],
+ sizes: "(max-width: 768px) 100vw, 1200px",
+ fetchPriority: "high",
+ loader,
+});
+Remote loaders require HTTPS. Source URLs are validated, dimensions and quality are bounded, placeholder colors are restricted to safe CSS colors, and preload attributes are escaped.
+Enable imagePlugin() and use:
<OptimizedImage /><Picture /><ImageCard />The package-owned blocks compose @wrnexus/ui where a complete UI block is appropriate while keeping the low-level image element lightweight.
Generated from the exact installed package declarations.
export { ImagePluginOptions, imageComponentsDir, default as imagePlugin } from './plugin.js';
+import '@wrnexus/plugin';
+
+interface ImageProcessorResult {
+ data: Uint8Array;
+ width: number;
+ height: number;
+}
+interface ImageProcessor {
+ transform(input: string, options: {
+ width: number;
+ format: Exclude<ImageFormat, "original">;
+ quality: number;
+ }): Promise<ImageProcessorResult>;
+}
+interface OptimizeImageOptions {
+ outputDir: string;
+ widths: number[];
+ formats?: Array<Exclude<ImageFormat, "original">>;
+ quality?: number;
+ maxVariants?: number;
+ processor?: ImageProcessor;
+}
+interface OptimizedImageVariant {
+ path: string;
+ width: number;
+ height: number;
+ format: Exclude<ImageFormat, "original">;
+ bytes: number;
+}
+interface OptimizedImageManifest {
+ source: string;
+ variants: OptimizedImageVariant[];
+}
+declare function optimizeImage(input: string, options: OptimizeImageOptions): Promise<OptimizedImageManifest>;
+
+type ImageFormat = "avif" | "webp" | "jpeg" | "png" | "original";
+interface ImageLoaderInput {
+ src: string;
+ width: number;
+ quality?: number;
+ format?: ImageFormat;
+}
+type ImageLoader = (input: ImageLoaderInput) => string;
+interface ImagePolicy {
+ remoteHosts?: string[];
+ allowedProtocols?: string[];
+ maxWidth?: number;
+ maxQuality?: number;
+}
+interface ResponsiveImageOptions extends ImagePolicy {
+ src: string;
+ alt: string;
+ width: number;
+ height: number;
+ widths?: number[];
+ sizes?: string;
+ quality?: number;
+ format?: ImageFormat;
+ loading?: "eager" | "lazy";
+ fetchPriority?: "high" | "low" | "auto";
+ decoding?: "async" | "sync" | "auto";
+ loader?: ImageLoader;
+ class?: string;
+}
+interface ResponsiveImageAttributes {
+ src: string;
+ srcset?: string;
+ sizes?: string;
+ alt: string;
+ width: string;
+ height: string;
+ loading: "eager" | "lazy";
+ decoding: "async" | "sync" | "auto";
+ fetchpriority?: "high" | "low" | "auto";
+ class?: string;
+}
+interface ImageAuditInput {
+ src: string;
+ width?: number;
+ height?: number;
+ renderedWidth?: number;
+ bytes?: number;
+ loading?: string;
+ fetchPriority?: string;
+ isLcp?: boolean;
+}
+interface ImageAuditIssue {
+ code: string;
+ severity: "error" | "warning" | "info";
+ message: string;
+}
+declare const defaultImageLoader: ImageLoader;
+declare function createResponsiveImage(options: ResponsiveImageOptions): ResponsiveImageAttributes;
+declare function auditImage(input: ImageAuditInput): ImageAuditIssue[];
+interface PictureSource {
+ type: string;
+ srcset: string;
+ sizes?: string;
+}
+interface PicturePlan {
+ image: ResponsiveImageAttributes;
+ sources: PictureSource[];
+}
+declare function normalizeImageWidths(widths: readonly number[], options?: {
+ min?: number;
+ max?: number;
+}): number[];
+declare function createCdnImageLoader(baseUrl: string, options?: {
+ sourceParam?: string;
+ widthParam?: string;
+ qualityParam?: string;
+ formatParam?: string;
+}): ImageLoader;
+declare function createPathImageLoader(prefix?: string): ImageLoader;
+declare function createPicture(options: ResponsiveImageOptions & {
+ formats?: ImageFormat[];
+}): PicturePlan;
+declare function createBlurPlaceholder(options?: {
+ width?: number;
+ height?: number;
+ color?: string;
+ accent?: string;
+}): string;
+declare function imagePreload(image: ResponsiveImageAttributes, options?: {
+ as?: string;
+ type?: string;
+ crossOrigin?: "anonymous" | "use-credentials";
+}): string;
+declare function imageCacheKey(input: ImageLoaderInput): string;
+
+export { type ImageAuditInput, type ImageAuditIssue, type ImageFormat, type ImageLoader, type ImageLoaderInput, type ImagePolicy, type ImageProcessor, type ImageProcessorResult, type OptimizeImageOptions, type OptimizedImageManifest, type OptimizedImageVariant, type PicturePlan, type PictureSource, type ResponsiveImageAttributes, type ResponsiveImageOptions, auditImage, createBlurPlaceholder, createCdnImageLoader, createPathImageLoader, createPicture, createResponsiveImage, defaultImageLoader, imageCacheKey, imagePreload, normalizeImageWidths, optimizeImage };
+Copy-ready examples from the installed package documentation.
import { optimizeImage } from "@wrnexus/image";
+
+const manifest = await optimizeImage("public/hero.jpg", {
+ outputDir: "public/generated/images",
+ widths: [480, 960, 1440],
+ formats: ["avif", "webp"],
+ quality: 80,
+});import {
+ createResponsiveImage,
+ createPicture,
+ createCdnImageLoader,
+ createPathImageLoader,
+ createBlurPlaceholder,
+ imagePreload,
+ auditImage,
+} from "@wrnexus/image";
+
+const loader = createCdnImageLoader("https://images.example.com/transform");
+const picture = createPicture({
+ src: "/hero.jpg",
+ alt: "Product dashboard",
+ width: 1600,
+ height: 900,
+ widths: [480, 768, 1200, 1600],
+ formats: ["avif", "webp"],
+ sizes: "(max-width: 768px) 100vw, 1200px",
+ fetchPriority: "high",
+ loader,
+});HS256 JWT signing, verification, and bearer authentication.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/jwt@0.7.0Request preview access. Never put registry tokens in source control.
Dependency-free JSON Web Tokens (HS256) via Web Crypto, plus a bearer-token auth middleware for WRNexusJS.+
HS256 JWT signing, verification, and bearer authentication.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/jwt@0.8.0Request preview access. Never put registry tokens in source control.
Dependency-free JSON Web Tokens (HS256) via Web Crypto, plus a bearer-token auth middleware for WRNexusJS.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/jwt signs and verifies stateless JSON Web Tokens using the HS256 (HMAC-SHA-256) algorithm. It has no runtime dependencies — signing and verification are implemented directly on the standard Web Crypto API (crypto.subtle), which Bun provides natively. It runs server-side and pairs with the session-based auth in @wrnexus/core, giving you a stateless option for API and mobile clients. Reach for it when you need bearer-token auth rather than cookie sessions.
are not supported.
@wrnexus/core](../core) for Context, Middleware, andctx.user; it complements the framework's cookie/session auth with a stateless bearer-token flow for API and mobile clients.
Generated from the exact installed package declarations.
import { Context, Middleware } from '@wrnexus/core';
+
+Access, refresh, scope, and cookie helpers
+import {
+ createAccessToken,
+ createRefreshToken,
+ verifyAccessToken,
+ verifyRefreshToken,
+ extractBearerToken,
+ requireScopes,
+ jwtCookie,
+} from "@wrnexus/jwt";
+The helpers add explicit type: "access" | "refresh" claims, scope checks, refresh-token family metadata, no-store token responses, and secure cookie defaults. __Host- cookies are rejected unless they use Path=/ and Secure; SameSite=None is rejected without Secure.
+0.8 helper kit
+import {
+ createTokenPair,
+ verifyAccessToken,
+ verifyRefreshToken,
+ extractBearerToken,
+ readJwtCookie,
+ jwtCookie,
+ clearJwtCookie,
+ requireScopes,
+} from "@wrnexus/jwt";
+
+const pair = await createTokenPair(user.id, {
+ accessSecret: process.env.JWT_ACCESS_SECRET!,
+ refreshSecret: process.env.JWT_REFRESH_SECRET!,
+ scopes: ["profile:read"],
+ family: sessionFamily,
+});
+The helper kit validates __Host- cookie invariants, cookie names and paths, SameSite=None security, typed access/refresh token types, scope requirements, and no-store token responses. In addition to local HS256 secrets/keyrings, the package verifies standards-based RS256 tokens through bounded remote JWKS caches:
+import { createRemoteJwks, verifyJwtWithJwks } from "@wrnexus/jwt";
+
+const jwks = createRemoteJwks("https://issuer.example/.well-known/jwks.json");
+const claims = await verifyJwtWithJwks(token, jwks, {
+ issuer: "https://issuer.example",
+ audience: "my-api",
+ maxAge: 300,
+});
+JWKS URLs must use HTTPS. Responses have key-count/byte limits, accept only RS256 signing RSA keys, deduplicate concurrent refreshes, cache imported public keys, and force an immediate refresh for an unknown kid so issuer rotation does not wait for cache expiry. Never use decoded-but-unverified claims for an authorization decision.
Generated from the exact installed package declarations.
import { Context, Middleware } from '@wrnexus/core';
interface JwtKey {
id: string;
@@ -107,6 +146,91 @@ declare function createJwtKeyring(keys: JwtKey[]): JwtKeyring;
declare function signWithKeyring(claims: JwtClaims, keyring: JwtKeyring, options?: SignOptions): Promise<string>;
declare function verifyWithKeyring<T extends JwtClaims = JwtClaims>(token: string, keyring: JwtKeyring, options?: VerifyOptions): Promise<T>;
+interface AccessTokenClaims extends JwtClaims {
+ sub: string;
+ type: "access";
+ scopes?: string[];
+}
+interface RefreshTokenClaims extends JwtClaims {
+ sub: string;
+ type: "refresh";
+ family?: string;
+}
+declare function extractBearerToken(value: Headers | Request | Context | string | null | undefined): string | undefined;
+declare function tryVerifyJwt<T extends JwtClaims = JwtClaims>(token: string | undefined, secret: string, options?: VerifyOptions): Promise<T | null>;
+declare function assertJwtClaims<T extends JwtClaims>(claims: T, requirements?: {
+ subject?: boolean;
+ type?: string;
+ required?: string[];
+}): T;
+declare function tokenScopes(claims: JwtClaims): string[];
+declare function hasScopes(claims: JwtClaims, required: readonly string[], mode?: "all" | "any"): boolean;
+declare function requireScopes(required: readonly string[], mode?: "all" | "any"): Middleware;
+declare function createAccessToken(subject: string, secret: string, options?: Omit<SignOptions, "expiresIn"> & {
+ expiresIn?: number;
+ scopes?: string[];
+ claims?: JwtClaims;
+}): Promise<string>;
+declare function createRefreshToken(subject: string, secret: string, options?: Omit<SignOptions, "expiresIn"> & {
+ expiresIn?: number;
+ family?: string;
+ claims?: JwtClaims;
+}): Promise<string>;
+declare function verifyAccessToken(token: string, secret: string, options?: VerifyOptions): Promise<AccessTokenClaims>;
+declare function verifyRefreshToken(token: string, secret: string, options?: VerifyOptions): Promise<RefreshTokenClaims>;
+declare function readJwtCookie(value: Headers | Request | string | null | undefined, name?: string): string | undefined;
+declare function jwtCookie(token: string, options?: {
+ name?: string;
+ maxAge?: number;
+ secure?: boolean;
+ sameSite?: "Strict" | "Lax" | "None";
+ path?: string;
+}): string;
+declare function clearJwtCookie(options?: Omit<Parameters<typeof jwtCookie>[1], "maxAge">): string;
+interface JwtTokenPair {
+ accessToken: string;
+ refreshToken: string;
+ tokenType: "Bearer";
+ expiresIn: number;
+}
+declare function createTokenPair(subject: string, input: {
+ accessSecret: string;
+ refreshSecret?: string;
+ accessExpiresIn?: number;
+ refreshExpiresIn?: number;
+ scopes?: string[];
+ family?: string;
+ accessOptions?: Omit<SignOptions, "expiresIn">;
+ refreshOptions?: Omit<SignOptions, "expiresIn">;
+}): Promise<JwtTokenPair>;
+declare function jwtResponse(accessToken: string, input?: {
+ refreshToken?: string;
+ expiresIn?: number;
+ tokenType?: string;
+ scope?: string[];
+}): Response;
+
+interface RemoteJwksOptions {
+ fetch?: typeof fetch;
+ cacheTtlMs?: number;
+ maxKeys?: number;
+ maxBytes?: number;
+ now?: () => number;
+}
+interface RemoteJwks {
+ resolve(kid: string, alg: string): Promise<CryptoKey>;
+ refresh(): Promise<void>;
+ clear(): void;
+ stats(): {
+ fetches: number;
+ hits: number;
+ keys: number;
+ expiresAt: number;
+ };
+}
+declare function createRemoteJwks(url: string, options?: RemoteJwksOptions): RemoteJwks;
+declare function verifyJwtWithJwks<T extends JwtClaims = JwtClaims>(token: string, jwks: RemoteJwks, options?: VerifyOptions): Promise<T>;
+
/**
* @wrnexus/jwt — dependency-free JSON Web Tokens (HS256) via WebCrypto, plus a
* bearer-token auth middleware. Pairs with the session auth in @wrnexus/core for
@@ -165,7 +289,7 @@ interface JwtAuthOptions {
*/
declare function jwtAuth(options: JwtAuthOptions): Middleware;
-export { type JwtAuthOptions, type JwtClaims, JwtError, type JwtKey, type JwtKeyring, type SignOptions, type VerifyOptions, createJwtKeyring, decodeJwt, jwtAuth, signJwt, signWithKeyring, verifyJwt, verifyWithKeyring };
+export { type AccessTokenClaims, type JwtAuthOptions, type JwtClaims, JwtError, type JwtKey, type JwtKeyring, type JwtTokenPair, type RefreshTokenClaims, type RemoteJwks, type RemoteJwksOptions, type SignOptions, type VerifyOptions, assertJwtClaims, clearJwtCookie, createAccessToken, createJwtKeyring, createRefreshToken, createRemoteJwks, createTokenPair, decodeJwt, extractBearerToken, hasScopes, jwtAuth, jwtCookie, jwtResponse, readJwtCookie, requireScopes, signJwt, signWithKeyring, tokenScopes, tryVerifyJwt, verifyAccessToken, verifyJwt, verifyJwtWithJwks, verifyRefreshToken, verifyWithKeyring };
Copy-ready examples from the installed package documentation.
import { signJwt, verifyJwt, jwtAuth, JwtError } from "@wrnexus/jwt";
const secret = process.env.JWT_SECRET!;
@@ -190,9 +314,9 @@ app.use(jwtAuth({ secret: process.env.JWT_SECRET! }));
// Optional auth — populate ctx.user when present, but don't 401
app.use(jwtAuth({ secret: process.env.JWT_SECRET!, required: false }));Editor-neutral language intelligence for WRN files.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/language-server@0.8.0Request preview access. Never put registry tokens in source control.
Editor-neutral Language Server Protocol support for .wrn files. It uses the canonical @wrnexus/syntax parser, diagnostics, accessibility rules, and formatter.
bunx wrnexus-language-server --stdio
+Capabilities include syntax, accessibility and TypeScript expression diagnostics, formatting, completion, hover, document symbols, go-to-definition, references, rename, and quick fixes. The custom wrnexus/virtualDocument request returns the mapped TypeScript representation of an open .wrn document for editor TypeScript plugins and safe refactoring tools. Any LSP 3.x client can launch the stdio command. Example Neovim configuration:
vim.lsp.start({
+ name = "wrnexus",
+ cmd = { "bunx", "wrnexus-language-server", "--stdio" },
+ root_dir = vim.fs.root(0, { "wrnexus.config.ts", "package.json", ".git" }),
+})
+JetBrains users can register the same command through an LSP client/plugin. The server does not require VS Code and never reads environment secrets or sends source over a network.
Generated from the exact installed package declarations.
interface WorkspaceCompletionItem {
+ label: string;
+ kind: number;
+ detail: string;
+ insertText?: string;
+ data?: Record<string, unknown>;
+}
+declare function workspaceCompletionItems(root: string): WorkspaceCompletionItem[];
+declare function clearWorkspaceIndexCache(root?: string): void;
+declare function extractComponentRefactor(document: TextDocument, range: Range, name: string): {
+ documentChanges: ({
+ kind: string;
+ uri: string;
+ textDocument?: undefined;
+ edits?: undefined;
+ } | {
+ textDocument: {
+ uri: string;
+ version: number | null;
+ };
+ edits: {
+ range: Range;
+ newText: string;
+ }[];
+ kind?: undefined;
+ uri?: undefined;
+ })[];
+};
+declare function htmlToWrn(html: string, name?: string): string;
+
+interface Position {
+ line: number;
+ character: number;
+}
+interface Range {
+ start: Position;
+ end: Position;
+}
+interface TextDocument {
+ uri: string;
+ text: string;
+ version?: number;
+}
+declare const WRN_COMPLETIONS: readonly ["page", "component", "layout", "props", "outputs", "state", "computed", "effect", "watch", "lifecycle", "load", "action", "api", "realtime", "view", "style", "runtime", "hydrate"];
+declare function offsetAt(text: string, position: Position): number;
+declare function positionAt(text: string, requestedOffset: number): Position;
+declare function wordAt(text: string, position: Position): {
+ word: string;
+ range: Range;
+} | null;
+declare function documentDiagnostics(document: TextDocument): {
+ range: {
+ start: {
+ line: number;
+ character: number;
+ };
+ end: {
+ line: number;
+ character: number;
+ };
+ };
+ severity: number;
+ code: string;
+ source: string;
+ message: string;
+}[];
+/** TypeScript representation consumed by editor TypeScript plugins and safe refactoring tools. */
+declare function virtualTypeScriptDocument(document: TextDocument): {
+ uri: string;
+ languageId: "typescript";
+ text: string;
+ mappings: Array<{
+ virtualStartLine: number;
+ virtualEndLine: number;
+ sourceStartLine: number;
+ sourceStartColumn: number;
+ }>;
+};
+declare function formatDocument(document: TextDocument, tabSize?: number, insertSpaces?: boolean): {
+ range: {
+ start: {
+ line: number;
+ character: number;
+ };
+ end: Position;
+ };
+ newText: string;
+}[];
+declare function documentSymbols(document: TextDocument): {
+ name: string;
+ kind: number;
+ range: {
+ start: Position;
+ end: Position;
+ };
+ selectionRange: {
+ start: Position;
+ end: Position;
+ };
+}[];
+declare function symbolLocations(document: TextDocument, position: Position): {
+ uri: string;
+ range: {
+ start: Position;
+ end: Position;
+ };
+}[];
+declare function definitionLocation(document: TextDocument, position: Position): {
+ uri: string;
+ range: {
+ start: Position;
+ end: Position;
+ };
+} | null;
+declare function hover(document: TextDocument, position: Position): {
+ contents: {
+ kind: string;
+ value: string;
+ };
+ range: Range;
+} | null;
+declare function completionItems(): {
+ label: "page" | "component" | "layout" | "props" | "outputs" | "state" | "computed" | "effect" | "watch" | "lifecycle" | "load" | "action" | "api" | "realtime" | "view" | "style" | "runtime" | "hydrate";
+ kind: number;
+ detail: string;
+}[];
+
+export { type Position, type Range, type TextDocument, WRN_COMPLETIONS, type WorkspaceCompletionItem, clearWorkspaceIndexCache, completionItems, definitionLocation, documentDiagnostics, documentSymbols, extractComponentRefactor, formatDocument, hover, htmlToWrn, offsetAt, positionAt, symbolLocations, virtualTypeScriptDocument, wordAt, workspaceCompletionItems };
+Copy-ready examples from the installed package documentation.
bunx wrnexus-language-server --stdiovim.lsp.start({
+ name = "wrnexus",
+ cmd = { "bunx", "wrnexus-language-server", "--stdio" },
+ root_dir = vim.fs.root(0, { "wrnexus.config.ts", "package.json", ".git" }),
+})Model Context Protocol tools for WRNexus projects.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/mcp@0.8.0Request preview access. Never put registry tokens in source control.
Editor-neutral Model Context Protocol server for AI development tools.
+bunx wrnexus-mcp --root=.
+It exposes current routes, components with props/events, database schema files, compiler diagnostics, runtime errors, dev-server health, framework documentation and installed packages. Files are resolved inside the configured application root and returned as bounded structured JSON.
Generated from the exact installed package declarations.
interface McpTool {
+ name: string;
+ description: string;
+ inputSchema: {
+ type: "object";
+ properties?: Record<string, unknown>;
+ additionalProperties?: boolean;
+ };
+}
+interface McpServerOptions {
+ maxFiles?: number;
+ maxFileBytes?: number;
+ fetch?: typeof fetch;
+ devServerUrl?: string;
+ runtimeErrors?: () => unknown[] | Promise<unknown[]>;
+}
+interface McpServer {
+ tools(): McpTool[];
+ call(name: string, args?: Record<string, unknown>): Promise<unknown>;
+ handle(message: unknown): Promise<Record<string, unknown> | null>;
+}
+declare function createFrameworkMcpServer(appRoot: string, options?: McpServerOptions): McpServer;
+
+export { type McpServer, type McpServerOptions, type McpTool, createFrameworkMcpServer };
+Copy-ready examples from the installed package documentation.
bunx wrnexus-mcp --root=.bun add @wrnexus/mcpSSR-safe compatibility access to Capacitor plugins.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/mobile@0.7.0Request preview access. Never put registry tokens in source control.
SSR-safe access to Capacitor plugins from WRNexusJS browser code.+
SSR-safe compatibility access to Capacitor plugins.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/mobile@0.8.0Request preview access. Never put registry tokens in source control.
SSR-safe access to Capacitor plugins from WRNexusJS browser code.
@wrnexus/mobile keeps optional native imports out of server rendering while giving browser-owned modules one consistent registry for Capacitor plugins. During SSR, mobile.isNative() is false and mobile.platform() is "web".
Install a plugin through the WRNexusJS CLI so the web and native projects stay aligned:
@@ -61,6 +61,14 @@ const status = network ? await network.getStatus() : { connected: true, conisNative() and platform() report the current Capacitor environment.Unavailable required plugins throw MobileUnavailableError with an actionable message.
The package also provides portable application-facing primitives:
+listenDeepLinks normalizes initial and live links with an allowed-scheme list.PushNotifications performs permission gating and validates registrations.SecureStorage namespaces and validates keys over an application-supplied encryptedKeychain/Keystore adapter; it does not mislabel browser localStorage as secure.
OfflineQueue persists bounded sync batches through a pluggable durable store.Copy-ready examples from the installed package documentation.
import { Camera, CameraResultType } from "@capacitor/camera";
import { mobile } from "@wrnexus/mobile";
@@ -169,7 +213,7 @@ const network = mobile.plugin<NetworkPlugin>("Network");
const status = network ? await network.getStatus() : { connected: true, connectionType: "unknown" };Cross-platform browser and Capacitor capability registry.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/native@0.7.0Request preview access. Never put registry tokens in source control.
Cross-platform capabilities for browsers, Capacitor WebViews, and compiled native apps.+
Cross-platform browser and Capacitor capability registry.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/native@0.8.0Request preview access. Never put registry tokens in source control.
Cross-platform capabilities for browsers, Capacitor WebViews, and compiled native apps.
@wrnexus/native exposes capabilities by name so application code can ask what the current platform supports before presenting an action. Browser capabilities use Web APIs; mobile capabilities use installed Capacitor plugins. platform() returns "server" during SSR, "browser" on the web, and the Capacitor platform in a native WebView.
bun add @wrnexus/native
@@ -64,6 +64,7 @@ const position = await native.run(
isMobile() and platform() report the current target safely during SSR.Built-ins include camera, clipboard.write, share, geolocation, network, haptics, storage, filesystem, notifications, and device information.
defineNativeManifest declares required capabilities and typed permissions, while PermissionManager normalizes permission query/request flows across platform adapters.
Use supports() before showing optional controls. Mobile capabilities require their matching Capacitor plugins to be installed and registered by the application.
Generated from the exact installed package declarations.
import { N as NativePlatform, a as NativeCapability, b as NativeRunOptions, c as NativeTarget } from './types-CDShWg0i.js';
export { d as NativeAdapter, e as NativeBrowserRuntime } from './types-CDShWg0i.js';
@@ -81,10 +82,11 @@ declare function supports(name: string, target?: NativeTarget): boolean;
declare function run<TResult = unknown>(name: string, options?: unknown, runOptions?: NativeRunOptions): Promise<TResult>;
declare function clearRegistry(): void;
+type NativePermission = "camera" | "geolocation" | "microphone" | "notifications" | "photos" | "storage" | (string & {});
interface NativeCapabilityManifestEntry {
name: string;
description?: string;
- permissions?: string[];
+ permissions?: NativePermission[];
targets?: NativeTarget[];
optional?: boolean;
}
@@ -100,14 +102,14 @@ declare function inspectNativeCapabilities(target?: NativeTarget): Array<
}>;
declare function missingNativeCapabilities(manifest: NativeCapabilityManifest, target?: NativeTarget): NativeCapabilityManifestEntry[];
interface PermissionAdapter {
- query(name: string): Promise<"granted" | "denied" | "prompt" | "unavailable">;
- request?(name: string): Promise<"granted" | "denied">;
+ query(name: NativePermission): Promise<"granted" | "denied" | "prompt" | "unavailable">;
+ request?(name: NativePermission): Promise<"granted" | "denied">;
}
declare class PermissionManager {
private readonly adapter;
constructor(adapter: PermissionAdapter);
- query(name: string): Promise<"denied" | "granted" | "prompt" | "unavailable">;
- ensure(name: string): Promise<boolean>;
+ query(name: NativePermission): Promise<"denied" | "granted" | "prompt" | "unavailable">;
+ ensure(name: NativePermission): Promise<boolean>;
}
declare const native: {
@@ -119,7 +121,7 @@ declare const native: {
supports: typeof supports;
};
-export { NativeCapability, type NativeCapabilityManifest, type NativeCapabilityManifestEntry, NativePlatform, NativeRunOptions, NativeTarget, NativeUnavailableError, type PermissionAdapter, PermissionManager, clearRegistry, defineNativeManifest, inspectNativeCapabilities, isMobile, missingNativeCapabilities, native, platform, register, registered, run, supports };
+export { NativeCapability, type NativeCapabilityManifest, type NativeCapabilityManifestEntry, type NativePermission, NativePlatform, NativeRunOptions, NativeTarget, NativeUnavailableError, type PermissionAdapter, PermissionManager, clearRegistry, defineNativeManifest, inspectNativeCapabilities, isMobile, missingNativeCapabilities, native, platform, register, registered, run, supports };
Copy-ready examples from the installed package documentation.
import { native } from "@wrnexus/native";
export async function shareCurrentPage() {
@@ -152,7 +154,7 @@ const position = await native.run(
);OAuth 2.0, PKCE, provider presets, and profile mapping.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/oauth@0.7.0Request preview access. Never put registry tokens in source control.
Dependency-free OAuth 2.0 sign-in for any provider, with PKCE and presets for Google, GitHub, and Discord.+
OAuth 2.0, PKCE, provider presets, and profile mapping.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/oauth@0.8.0Request preview access. Never put registry tokens in source control.
Dependency-free OAuth 2.0 sign-in for any provider, with PKCE and presets for Google, GitHub, and Discord.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/oauth implements the OAuth 2.0 Authorization Code flow (with PKCE) for server-side sign-in. It ships ready-made provider presets and a defineProvider helper for custom providers, then gives you two flow functions — startAuth (build the redirect) and completeAuth (exchange the code and fetch the user's profile). It has no runtime dependencies: it uses the platform fetch and WebCrypto only. Pairs naturally with @wrnexus/core's logIn to establish a session once you have a normalized profile.
state andverifier between startAuth and completeAuth (session or signed cookie).
@wrnexus/core](../core) — feed the normalized OAuthProfile intologIn to establish a session.
Generated from the exact installed package declarations.
interface OAuthStateRecord {
+logIn to establish a session. OIDC integrations can combine strict discovery with the rotating JWKS verifier:
+
+import { createRemoteJwks } from "@wrnexus/jwt";
+import { discoverOidc, verifyOidcIdToken } from "@wrnexus/oauth";
+
+const metadata = await discoverOidc("https://issuer.example");
+const jwks = createRemoteJwks(metadata.jwks_uri);
+const claims = await verifyOidcIdToken(idToken, {
+ issuer: metadata.issuer,
+ clientId: "client-id",
+ jwks,
+ nonce: expectedNonce,
+ accessToken,
+});
+Discovery requires an exact normalized issuer and HTTPS endpoints without URL credentials/fragments. ID-token verification checks the RS256 signature, expiry/not-before, issuer, audience, required OIDC claims, nonce, multi-audience azp, optional token age, and optional at_hash binding.
Generated from the exact installed package declarations.
import { JwtClaims, RemoteJwks } from '@wrnexus/jwt';
+
+interface OAuthStateRecord {
state: string;
verifier: string;
redirectUri: string;
@@ -171,6 +186,28 @@ interface OidcDiscovery {
revocation_endpoint?: string;
}
declare function discoverOidc(issuer: string, fetchImpl?: typeof fetch): Promise<OidcDiscovery>;
+interface OidcIdTokenClaims extends JwtClaims {
+ sub: string;
+ iss: string;
+ aud: string | string[];
+ exp: number;
+ iat: number;
+ nonce?: string;
+ azp?: string;
+ at_hash?: string;
+}
+interface VerifyOidcIdTokenOptions {
+ issuer: string;
+ clientId: string;
+ jwks: RemoteJwks;
+ nonce?: string;
+ accessToken?: string;
+ now?: number;
+ clockTolerance?: number;
+ maxAge?: number;
+}
+declare function validateOidcClaims(claims: JwtClaims, options: Pick<VerifyOidcIdTokenOptions, "clientId" | "nonce">): asserts claims is OidcIdTokenClaims;
+declare function verifyOidcIdToken(token: string, options: VerifyOidcIdTokenOptions): Promise<OidcIdTokenClaims>;
declare function validateOAuthReturnTo(value: string | undefined, origin: string, fallback?: string): string;
/**
@@ -262,7 +299,7 @@ declare function exchangeCode(provider: OAuthProvider, options: CompleteAuthOpti
/** Fetch + normalize the user's profile from the provider. */
declare function fetchProfile(provider: OAuthProvider, tokens: OAuthTokens, fetchImpl?: FetchLike): Promise<OAuthProfile>;
-export { type CompleteAuthOptions, type OAuthProfile, type OAuthProvider, type OAuthStateRecord, type OAuthStateStore, type OAuthTokens, type OidcDiscovery, type ProviderCredentials, type StartAuthOptions, type StartAuthResult, completeAuth, createOAuthState, defineProvider, discord, discoverOidc, exchangeCode, fetchProfile, github, google, memoryOAuthStateStore, randomToken, refreshOAuthTokens, startAuth, validateOAuthReturnTo };
+export { type CompleteAuthOptions, type OAuthProfile, type OAuthProvider, type OAuthStateRecord, type OAuthStateStore, type OAuthTokens, type OidcDiscovery, type OidcIdTokenClaims, type ProviderCredentials, type StartAuthOptions, type StartAuthResult, type VerifyOidcIdTokenOptions, completeAuth, createOAuthState, defineProvider, discord, discoverOidc, exchangeCode, fetchProfile, github, google, memoryOAuthStateStore, randomToken, refreshOAuthTokens, startAuth, validateOAuthReturnTo, validateOidcClaims, verifyOidcIdToken };
Copy-ready examples from the installed package documentation.
import { google, startAuth, completeAuth } from "@wrnexus/oauth";
import { logIn } from "@wrnexus/core";
@@ -313,7 +350,7 @@ const gitlab = defineProvider({
});Structured logging, tracing, health, and integration adapters.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/observability@0.8.0Request preview access. Never put registry tokens in source control.
Open-standard traces, metrics, logs, health checks, Web Vitals, error reporting and profiling.
+Use createOperationTracer() for database, cache, queue, realtime, server-action or custom application spans. Export through OTLP, Prometheus, Zipkin/Jaeger, or the Sentry-compatible error reporter; Grafana can consume the Prometheus or OTLP signals.
Privacy-conscious counters, gauges, histograms, HTTP middleware, Web Vitals ingestion, browser collection, and exporter adapters. Request bodies and user identifiers are not collected by default.
+export default {
+ observability: { enabled: true, serverTiming: true, sampleRate: 0.1, webVitals: true },
+};
+import {
+ createOtlpMetricExporter,
+ createOtlpTraceExporter,
+ createStructuredLogger,
+ metricsMiddleware,
+ traceMiddleware,
+} from "@wrnexus/observability";
+
+const traces = createOtlpTraceExporter("https://collector.example/v1/traces", {
+ serviceName: "checkout",
+ headers: { authorization: `Bearer ${process.env.OTLP_TOKEN}` },
+});
+
+export const tracing = traceMiddleware({
+ serviceName: "checkout",
+ sampleRate: 0.1,
+ exporter: traces,
+ onExportError(error) {
+ console.error("trace export failed", error);
+ },
+});
+
+export const metrics = metricsMiddleware();
+export const metricExporter = createOtlpMetricExporter("https://collector.example/v1/metrics", {
+ serviceName: "checkout",
+});
+
+export const logger = createStructuredLogger({ service: "checkout" });
+// Request middleware can create a correlated child from ctx.locals.
+logger
+ .child({
+ traceId: ctx.locals.traceId,
+ spanId: ctx.locals.spanId,
+ requestId: ctx.locals.requestId,
+ })
+ .info("order accepted", { orderId });
+The tracing middleware accepts and validates W3C traceparent, creates a child server span, stores correlation identifiers in ctx.locals, installs the framework tracer on ctx.tracer, and returns traceparent plus x-request-id. Export failures are isolated from application responses when onExportError is configured.
import { HealthRegistry } from "@wrnexus/core";
+import { createLivenessHandler, createReadinessHandler } from "@wrnexus/observability";
+
+const health = new HealthRegistry();
+health.register("database", async () =>
+ (await db.ping()) ? { status: "up" } : { status: "down" },
+);
+
+export const live = createLivenessHandler();
+export const ready = createReadinessHandler(health);
+Liveness reports whether the process can answer requests. Readiness returns HTTP 503 when a registered dependency is down. Dependency messages and details are hidden unless exposeDetails: true is explicitly selected for a trusted endpoint.
Generated from the exact installed package declarations.
export { MetricLabels, MetricPoint, MetricsRegistry } from './metrics.js';
+export { MetricExporter, MetricsMiddlewareOptions, WebVitalRecord, WebVitalsHandlerOptions, createHttpMetricExporter, createOtlpMetricExporter, createWebVitalsHandler, defaultMetrics, metricsMiddleware } from './server.js';
+export { WebVitalsClientOptions, webVitalsClient } from './client.js';
+export { SpanExporter, SpanRecord, TraceContext, TraceMiddlewareOptions, createOtlpTraceExporter, formatTraceparent, parseTraceparent, traceMiddleware } from './trace.js';
+export { HealthHandlerOptions, createLivenessHandler, createReadinessHandler } from './health.js';
+export { LogLevel, LogRecord, StructuredLogger, StructuredLoggerOptions, createStructuredLogger } from './logging.js';
+export { ErrorReporter, FrameworkSpanKind, LogExporter, OperationTracer, createJaegerExporter, createOperationTracer, createOtlpLogExporter, createPerformanceProfiler, createPrometheusPushExporter, createSentryCompatibleReporter, createZipkinExporter, renderPrometheus } from './integrations.js';
+import '@wrnexus/core';
+Copy-ready examples from the installed package documentation.
export default {
+ observability: { enabled: true, serverTiming: true, sampleRate: 0.1, webVitals: true },
+};import {
+ createOtlpMetricExporter,
+ createOtlpTraceExporter,
+ createStructuredLogger,
+ metricsMiddleware,
+ traceMiddleware,
+} from "@wrnexus/observability";
+
+const traces = createOtlpTraceExporter("https://collector.example/v1/traces", {
+ serviceName: "checkout",
+ headers: { authorization: `Bearer ${process.env.OTLP_TOKEN}` },
+});
+
+export const tracing = traceMiddleware({
+ serviceName: "checkout",
+ sampleRate: 0.1,
+ exporter: traces,
+ onExportError(error) {
+ console.error("trace export failed", error);
+ },
+});
+
+export const metrics = metricsMiddleware();
+export const metricExporter = createOtlpMetricExporter("https://collector.example/v1/metrics", {
+ serviceName: "checkout",
+});
+
+export const logger = createStructuredLogger({ service: "checkout" });
+// Request middleware can create a correlated child from ctx.locals.
+logger
+ .child({
+ traceId: ctx.locals.traceId,
+ spanId: ctx.locals.spanId,
+ requestId: ctx.locals.requestId,
+ })
+ .info("order accepted", { orderId });import { HealthRegistry } from "@wrnexus/core";
+import { createLivenessHandler, createReadinessHandler } from "@wrnexus/observability";
+
+const health = new HealthRegistry();
+health.register("database", async () =>
+ (await db.ping()) ? { status: "up" } : { status: "down" },
+);
+
+export const live = createLivenessHandler();
+export const ready = createReadinessHandler(health);Interactive framework examples and executable playground utilities.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/playground@0.8.0Request preview access. Never put registry tokens in source control.
A deployable, shareable .wrn playground with diagnostics, generated JavaScript, safe SSR-shaped HTML, sandboxed preview, reactive/UI examples, and version adapters.
Run wrnexus playground, or deploy createPlaygroundHandler().
Generated from the exact installed package declarations.
interface PlaygroundCompilation {
+ source: string;
+ generated: string;
+ client: string;
+ html: string;
+ interactiveHtml: string;
+ diagnostics: Array<{
+ code: string;
+ message: string;
+ severity: string;
+ }>;
+ version: string;
+}
+interface PlaygroundVersionAdapter {
+ version: string;
+ compile(source: string): Promise<Omit<PlaygroundCompilation, "source" | "version">>;
+}
+declare function compilePlayground(source: string, version?: string): PlaygroundCompilation;
+declare function encodePlaygroundShare(source: string): string;
+declare function decodePlaygroundShare(value: string): string;
+declare function comparePlaygroundVersions(source: string, adapters: PlaygroundVersionAdapter[]): Promise<{
+ current: PlaygroundCompilation;
+ comparisons: {
+ generated: string;
+ client: string;
+ html: string;
+ interactiveHtml: string;
+ diagnostics: Array<{
+ code: string;
+ message: string;
+ severity: string;
+ }>;
+ version: string;
+ }[];
+}>;
+declare function createPlaygroundHandler(options?: {
+ versions?: PlaygroundVersionAdapter[];
+ examples?: Record<string, string>;
+}): (request: Request) => Promise<Response>;
+
+export { type PlaygroundCompilation, type PlaygroundVersionAdapter, comparePlaygroundVersions, compilePlayground, createPlaygroundHandler, decodePlaygroundShare, encodePlaygroundShare };
+Copy-ready examples from the installed package documentation.
bun add @wrnexus/playgroundimport * as playground from "@wrnexus/playground";Plugin contracts, lifecycle hooks, composition, and framework integration.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/plugin@0.7.0Request preview access. Never put registry tokens in source control.
Deterministic WRNexusJS plugin contracts for configuration, AST/code transforms, diagnostics, development servers, production builds, and DevToolbar extensions.
-Use definePlugin() and declare enforce, before, or after when ordering matters. Duplicate names and dependency cycles are rejected.
Generated from the exact installed package declarations.
export { PageAst, WrnDiagnostic } from '@wrnexus/syntax';
-import { WrnexusPlugin, PluginInput, PluginContext, PluginRunner } from './types.js';
-export { ClientRuntimeDefinition, ClientRuntimeInject, ClientRuntimeLoad, ClientRuntimeType, PackageAssetDefinition, PackageMigrationDefinition, PackagePluginManifest, PackageRouteDefinition, PackageStyleDefinition, PluginCommand, PluginContributions, PluginDevToolbarPanel, PluginOrder, TransformContext, WrnexusPackageManifest } from './types.js';
+ Core · Package reference@wrnexus/plugin
Plugin contracts, lifecycle hooks, composition, and framework integration.
Install the package
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/plugin@0.8.0
Request preview access. Never put registry tokens in source control.
Least-privilege package permissions
+Package manifests declare every framework capability they register:
+{
+ "wrnexus": {
+ "permissions": ["routes", "migrations"],
+ "routes": [{ "kind": "api", "path": "/api/example", "entry": "./route.ts" }]
+ }
+}
+Applications can enable fail-closed grants:
+export default {
+ pluginPermissions: {
+ enforce: true,
+ grants: { "example-plugin": ["routes"] },
+ },
+};
+Discovery rejects used-but-undeclared capabilities with WRN-PLUGIN-PERMISSION-UNDECLARED and ungranted capabilities with WRN-PLUGIN-PERMISSION-DENIED. Permissions cover components, browser runtime, assets, styles, routes, middleware, migrations, config, transforms, diagnostics/tooling, and server/build hooks.
+Compatibility matrices
+Manifests can add compatibility: { bunMin: "1.3.0", os: ["linux", "darwin"] } alongside runtimes and requires. Use testPluginCompatibility(manifest, targets) in a package test to exercise the complete support matrix. Runtime discovery enforces the same Bun minimum, OS, runtime, and capability declarations used by the test kit.
+Deterministic WRNexusJS plugin contracts for configuration, AST/code transforms, diagnostics, development servers, production builds, and DevToolbar extensions.
+Use definePlugin() and declare enforce, before, or after when ordering matters. Duplicate names and dependency cycles are rejected.
+Complete lifecycle and contributions
+Plugins may implement setup, configure, configResolved, transformAst, transformCode, diagnostics, routes, configureServer, buildStart, buildEnd, render, deploy, shutdown, and hmrUpdate. The runner preserves resolved plugin order for every hook and executes setup exactly once.
+In addition to components, routes, middleware, assets, styles, runtimes, and migrations, plugins can contribute directives, cliCommands, virtualModules, deploymentAdapters, configSchemas, documentation, and typeDefinitions. Names are collision checked. Configuration schemas run after configuration resolution, CLI commands are callable as normal wrnexus commands, directives participate in AST transformation, and production builds materialize virtual modules and invoke matching contributed adapters.
Complete TypeScript API
Generated from the exact installed package declarations.
export { PageAst, WrnDiagnostic } from '@wrnexus/syntax';
+import { WrnexusPackageManifest, WrnexusPlugin, PluginInput, PluginContext, PluginRunner } from './types.js';
+export { ClientRuntimeDefinition, ClientRuntimeInject, ClientRuntimeLoad, ClientRuntimeType, PackageAssetDefinition, PackageMigrationDefinition, PackagePluginManifest, PackageRouteDefinition, PackageStyleDefinition, PluginCliCommand, PluginCommand, PluginConfigSchema, PluginContributions, PluginDeploymentAdapter, PluginDevToolbarPanel, PluginDirective, PluginOrder, PluginPermission, PluginVirtualModule, TransformContext } from './types.js';
export { assertContributionId, contentTypeForPath, defaultClientRuntimePath, defaultPackageAssetPath, definePackageManifest, normalizeClientRuntime, normalizePackageAsset, validateStyleIds } from './manifest.js';
export { DiscoverPluginOptions, discoverPlugins } from './discovery.js';
+interface PluginCompatibilityTarget {
+ runtime: "bun" | "node" | "edge" | "worker" | "service-worker" | "browser";
+ version?: string;
+ os?: "win32" | "linux" | "darwin" | string;
+ capabilities?: readonly string[];
+}
+interface PluginCompatibilityResult {
+ target: PluginCompatibilityTarget;
+ ok: boolean;
+ issues: Array<{
+ code: "WRN-PLUGIN-MATRIX-RUNTIME" | "WRN-PLUGIN-MATRIX-VERSION" | "WRN-PLUGIN-MATRIX-OS" | "WRN-PLUGIN-MATRIX-CAPABILITY";
+ message: string;
+ }>;
+}
+declare function testPluginCompatibility(manifest: WrnexusPackageManifest, targets: readonly PluginCompatibilityTarget[]): PluginCompatibilityResult[];
+
declare function definePlugin(plugin: WrnexusPlugin): WrnexusPlugin;
declare function flattenPlugins(input: PluginInput, output?: WrnexusPlugin[]): WrnexusPlugin[];
@@ -28,18 +65,21 @@ declare function flattenPlugins(input: PluginInput, output?: WrnexusPlugin[]): W
declare function resolvePlugins(input: PluginInput): WrnexusPlugin[];
declare function createPluginRunner(input: PluginInput, context: PluginContext): PluginRunner;
-export { PluginContext, PluginInput, PluginRunner, WrnexusPlugin, createPluginRunner, definePlugin, flattenPlugins, resolvePlugins };
-
Examples
Copy-ready examples from the installed package documentation.
Define an ordered plugin
import { definePlugin } from "@wrnexus/plugin";
-
-export default definePlugin({
- name: "analytics",
- enforce: "post",
-});
Resolve plugin execution order
import { resolvePlugins } from "@wrnexus/plugin";
-
-const ordered = resolvePlugins([corePlugin, analyticsPlugin]);
-
+export { type PluginCompatibilityResult, type PluginCompatibilityTarget, PluginContext, PluginInput, PluginRunner, WrnexusPackageManifest, WrnexusPlugin, createPluginRunner, definePlugin, flattenPlugins, resolvePlugins, testPluginCompatibility };
+Copy-ready examples from the installed package documentation.
{
+ "wrnexus": {
+ "permissions": ["routes", "migrations"],
+ "routes": [{ "kind": "api", "path": "/api/example", "entry": "./route.ts" }]
+ }
+}export default {
+ pluginPermissions: {
+ enforce: true,
+ grants: { "example-plugin": ["routes"] },
+ },
+};In-process and Redis-backed publish/subscribe.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/pubsub@0.7.0Request preview access. Never put registry tokens in source control.
Topic-based publish/subscribe with a pluggable driver — in-process by default, Redis for cross-process messaging.+
In-process and Redis-backed publish/subscribe.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/pubsub@0.8.0Request preview access. Never put registry tokens in source control.
Topic-based publish/subscribe with a pluggable driver — in-process by default, Redis for cross-process messaging.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/pubsub is a small server-side pub/sub bus. You publish messages to a topic and subscribe with topic patterns; handlers fire for matching topics. The default driver keeps everything in-process, and you can swap in the Redis driver (@wrnexus/pubsub/redis) to fan messages out across processes or hosts. It also backs @wrnexus/core's realtime bridge for horizontal scaling.
interface PubSub {
publish<T = unknown>(topic: string, message: T): Promise<void>;
subscribe<T = unknown>(pattern: string, handler: Handler<T>): () => void;
+ close(): Promise<void>;
}
type Handler<T = unknown> = (message: T, topic: string) => void | Promise<void>;
publish(topic, message) — resolves once the driver has dispatched the message.publish(topic, message) — resolves once the driver and in-memory async handlers finish.subscribe(pattern, handler) — returns an unsubscribe function.close() — idempotently rejects new work, clears local subscriptions, and closes the driver.Subscription patterns match in three ways:
@@ -49,13 +51,15 @@ type Handler<T = unknown> = (message: T, topic: string) => void | Promi }@wrnexus/pubsub/redis — redisDriver(url?)A cross-process driver backed by Redis. It speaks RESP over a raw TCP socket via Bun.connect, so it adds no npm dependency. url defaults to $REDIS_URL, then redis://localhost:6379. The URL may carry a password and a database index (e.g. redis://:secret@host:6379/2).
function redisDriver(url?: string): PubSubDriver & { close(): void };
+function redisDriver(url?: string, options?: RedisDriverOptions): PubSubDriver & { close(): void };
SUBSCRIBE; wildcard patterns (ns:*, *) usePSUBSCRIBE, whose glob semantics line up with this library's matching.
JSON.parsed on receipt; a payloadthat isn't valid JSON is delivered as the raw string.
close() tears down both the subscriber and publisher connections.are replayed. maxPending bounds unavailable-connection writes (default 1000); reconnectDelayMs and reconnectMaxDelayMs tune recovery (100ms/5000ms).
redis.ts uses a minimal RESP implementation exported from resp.ts (encodeCommand, parseReply, concat, and the RespValue type). These are implementation details of the Redis driver, not part of the public package entry.
Bun.connect; it throwsCopy-ready examples from the installed package documentation.
import { createPubSub } from "@wrnexus/pubsub";
const bus = createPubSub();
@@ -172,11 +193,11 @@ bus.subscribe("order:*", (msg, topic) => {
await bus.publish("order:created", { id: 7 });
-// on shutdown
-driver.close();Progressive Web App manifests, service workers, and offline strategies.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/pwa@0.8.0Request preview access. Never put registry tokens in source control.
Official PWA primitives for manifests, service workers, offline pages and precaching, runtime caching, background synchronization, push notifications, install/update events, offline mutation stores, and conflict resolution. createOfflineQueue() accepts a durable IndexedDB-style store and retries requests with stable idempotency headers.
Generated from the exact installed package declarations.
interface IndexedDbMigration {
+ version: number;
+ migrate(db: IDBDatabase, transaction: IDBTransaction): void;
+}
+declare function openPwaDatabase(name: string, migrations: IndexedDbMigration[], factory?: IDBFactory): Promise<IDBDatabase>;
+declare function indexedDbOfflineQueueStore(db: IDBDatabase, storeName?: string): OfflineQueueStore;
+declare const offlineQueueMigration: IndexedDbMigration;
+interface StoredPushSubscription {
+ id: string;
+ userId: string;
+ endpoint: string;
+ expirationTime?: number | null;
+ keys: {
+ p256dh: string;
+ auth: string;
+ };
+ createdAt: number;
+}
+interface PushSubscriptionStore {
+ put(value: StoredPushSubscription): Promise<void>;
+ remove(id: string): Promise<void>;
+ list(userId: string): Promise<StoredPushSubscription[]>;
+}
+declare function memoryPushSubscriptionStore(): PushSubscriptionStore;
+interface PushSqlClient {
+ query<T = Record<string, unknown>>(sql: string, parameters?: unknown[]): Promise<{
+ rows: T[];
+ }>;
+}
+declare function postgresPushSubscriptionStore(db: PushSqlClient): PushSubscriptionStore;
+declare const POSTGRES_PUSH_SUBSCRIPTION_SCHEMA = "CREATE TABLE IF NOT EXISTS wrnexus_push_subscriptions (id text PRIMARY KEY,user_id text NOT NULL,endpoint text NOT NULL,expiration_time bigint,p256dh text NOT NULL,auth text NOT NULL,created_at bigint NOT NULL); CREATE INDEX IF NOT EXISTS wrnexus_push_user ON wrnexus_push_subscriptions (user_id);";
+declare function createPushSubscriptionService(store: PushSubscriptionStore, options?: {
+ now?: () => number;
+ maxPerUser?: number;
+}): {
+ subscribe(userId: string, value: {
+ endpoint: string;
+ expirationTime?: number | null;
+ keys: {
+ p256dh: string;
+ auth: string;
+ };
+ }): Promise<{
+ keys: {
+ p256dh: string;
+ auth: string;
+ };
+ createdAt: number;
+ endpoint: string;
+ expirationTime?: number | null;
+ id: string;
+ userId: string;
+ }>;
+ unsubscribe: (id: string) => Promise<void>;
+ list: (userId: string) => Promise<StoredPushSubscription[]>;
+};
+declare function renderOfflineQueueReview(items: OfflineMutation[], conflicts?: Array<{
+ id: string;
+ message: string;
+}>): string;
+declare const PWA_REVIEW_RUNTIME = "document.addEventListener(\"click\",event=>{const button=event.target.closest(\"[data-pwa-retry],[data-pwa-remove],[data-pwa-client],[data-pwa-server]\");if(!button)return;const action=button.hasAttribute(\"data-pwa-retry\")?\"retry\":button.hasAttribute(\"data-pwa-remove\")?\"remove\":button.hasAttribute(\"data-pwa-client\")?\"client\":\"server\";const id=button.getAttribute(\"data-pwa-\"+action);dispatchEvent(new CustomEvent(\"wrnexus:pwa-review\",{detail:{action,id}}))});";
+
+type RuntimeCacheStrategy = "network-first" | "cache-first" | "stale-while-revalidate";
+interface RuntimeCacheRule {
+ pattern: string;
+ strategy: RuntimeCacheStrategy;
+ cacheName?: string;
+ methods?: string[];
+}
+interface ServiceWorkerOptions {
+ cacheName?: string;
+ offlineUrl?: string;
+ startUrl?: string;
+ cacheUrls?: string[];
+ runtimeCaching?: RuntimeCacheRule[];
+ backgroundSyncTag?: string;
+}
+interface WebManifestOptions {
+ name: string;
+ shortName?: string;
+ description?: string;
+ id?: string;
+ startUrl?: string;
+ scope?: string;
+ display?: "standalone" | "fullscreen" | "minimal-ui" | "browser";
+ themeColor?: string;
+ backgroundColor?: string;
+ icons?: Array<{
+ src: string;
+ sizes: string;
+ type?: string;
+ purpose?: string;
+ }>;
+ shortcuts?: unknown[];
+ screenshots?: unknown[];
+ categories?: string[];
+ lang?: string;
+}
+declare function createWebManifest(options: WebManifestOptions): {
+ id: string;
+ name: string;
+ short_name: string;
+ description: string | undefined;
+ start_url: string;
+ scope: string;
+ display: "standalone" | "fullscreen" | "minimal-ui" | "browser";
+ theme_color: string;
+ background_color: string;
+ icons: {
+ src: string;
+ sizes: string;
+ type?: string;
+ purpose?: string;
+ }[];
+ shortcuts: unknown[];
+ screenshots: unknown[];
+ categories: string[];
+ lang: string;
+};
+declare function generateServiceWorker(options?: ServiceWorkerOptions): string;
+interface OfflineMutation<T = unknown> {
+ id: string;
+ createdAt: number;
+ updatedAt: number;
+ endpoint: string;
+ method: string;
+ payload: T;
+ attempts: number;
+}
+interface OfflineQueueStore {
+ list(): Promise<OfflineMutation[]>;
+ put(item: OfflineMutation): Promise<void>;
+ remove(id: string): Promise<void>;
+}
+declare function memoryOfflineQueueStore(): OfflineQueueStore;
+type ConflictResolution<T> = {
+ action: "client" | "server" | "merge";
+ value: T;
+};
+declare function resolveOfflineConflict<T extends object>(client: T, server: T, strategy?: "client-wins" | "server-wins" | "last-write-wins" | ((client: T, server: T) => T)): ConflictResolution<T>;
+declare function createOfflineQueue(options?: {
+ store?: OfflineQueueStore;
+ fetch?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
+ maxItems?: number;
+ now?: () => number;
+}): {
+ enqueue<T>(input: Omit<OfflineMutation<T>, "id" | "createdAt" | "updatedAt" | "attempts">): Promise<OfflineMutation<T>>;
+ list: () => Promise<OfflineMutation<unknown>[]>;
+ sync(): Promise<{
+ id: string;
+ ok: boolean;
+ status?: number;
+ }[]>;
+ remove: (id: string) => Promise<void>;
+};
+declare function pwaClientRuntime(serviceWorkerUrl?: string): string;
+declare function subscribeToPush(registration: ServiceWorkerRegistration, publicKey: Uint8Array): Promise<PushSubscription>;
+
+export { type ConflictResolution, type IndexedDbMigration, type OfflineMutation, type OfflineQueueStore, POSTGRES_PUSH_SUBSCRIPTION_SCHEMA, PWA_REVIEW_RUNTIME, type PushSqlClient, type PushSubscriptionStore, type RuntimeCacheRule, type RuntimeCacheStrategy, type ServiceWorkerOptions, type StoredPushSubscription, type WebManifestOptions, createOfflineQueue, createPushSubscriptionService, createWebManifest, generateServiceWorker, indexedDbOfflineQueueStore, memoryOfflineQueueStore, memoryPushSubscriptionStore, offlineQueueMigration, openPwaDatabase, postgresPushSubscriptionStore, pwaClientRuntime, renderOfflineQueueReview, resolveOfflineConflict, subscribeToPush };
+Copy-ready examples from the installed package documentation.
bun add @wrnexus/pwaimport * as pwa from "@wrnexus/pwa";Background jobs with delay, concurrency, retry, and repetition.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/queue@0.7.0Request preview access. Never put registry tokens in source control.
A background job queue with delays, retries + exponential backoff, recurring jobs, and concurrent workers.+
Background jobs with delay, concurrency, retry, and repetition.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/queue@0.8.0Request preview access. Never put registry tokens in source control.
A background job queue with delays, retries + exponential backoff, recurring jobs, and concurrent workers.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/queue is a server-side in-process job queue. You register named workers, enqueue jobs (optionally delayed or recurring), and let the queue poll and run them on a timer — with per-job retry limits and doubling backoff between attempts. The default store lives in memory; the design allows a pluggable driver to back it with Redis/SQL for durability across restarts. Reach for it when you need to defer work (emails, webhooks, cleanup) off the request path without a heavyweight external broker. Tests can drive it deterministically via drain().
QueueOptions| Option | Type | Default | Description |
|---|---|---|---|
maxAttempts | number | 3 | Default max attempts per job before it is dead-lettered. |
backoffMs | number | 1000 | Base retry backoff in ms; doubles per attempt. |
pollMs | number | 250 | Poll interval used once start() is called (ms). |
onFailed | (job: Job, error: unknown) => void | — | Called when a job exhausts its attempts. |
now | () => number | Date.now | Clock injection for deterministic tests. |
maxAttemptsnumber3backoffMsnumber1000pollMsnumber250start() is called (ms).onFailed(job: Job, error: unknown) => voidconcurrencynumberdrain() call.capacitynumbernow() => numberDate.nowQueueThe object returned by createQueue.
| Method | Signature | Description |
|---|---|---|
add | add<T>(name, data: T, options?: AddOptions): Promise<Job<T>> | Enqueue a job under a worker name. Returns the created job. |
process | process<T>(name, handler: JobHandler<T>): void | Register the worker that runs jobs of the given name. |
drain | drain(now?: number): Promise<number> | Run every job whose runAt ≤ now, once. Returns how many ran. |
start | start(): void | Begin polling every pollMs. No-op if already started. |
stop | stop(): void | Stop the poll timer. |
size | size(): number | Number of jobs currently queued. |
addadd<T>(name, data: T, options?: AddOptions): Promise<Job<T>>processprocess<T>(name, handler: JobHandler<T>): voiddraindrain(now?: number): Promise<number>runAt ≤ now, once. Returns how many ran.startstart(): voidpollMs. No-op if already started.stopstop(): voidshutdownshutdown({ force? }): Promise<void>sizesize(): numberget/listget(id) / list(name?)cancelcancel(id): booleanfailedfailed(): Job[]retryretry(id): Promise<boolean>AddOptions| Option | Type | Description |
|---|---|---|
delayMs | number | Delay before the job becomes runnable (ms). |
maxAttempts | number | Max attempts before dead-lettering. Defaults to the queue's maxAttempts. |
repeat | number | Re-enqueue this job this many ms after each successful run (recurring). |
delayMsnumbermaxAttemptsnumbermaxAttempts.repeatnumberprioritynumberidempotencyKeystringJobHandler<T>type JobHandler<T = unknown> = (job: Job<T>) => void | Promise<void>;
+type JobHandler<T = unknown> = (
+ job: Job<T>,
+ context: { signal: AbortSignal },
+) => void | Promise<void>;
Job<T>interface Job<T = unknown> {
id: string; // e.g. "job_1"
@@ -66,6 +69,9 @@ queue.process<{ to: string }>("email", async (job) =&g
await queue.add("email", { to: "a@b.com" }, { delayMs: 5000, maxAttempts: 3 });
queue.start(); // begin polling; queue.stop() to halt
+Use context.signal in network/database calls so forced shutdown and active cancellation finish promptly. For process termination, prefer await queue.shutdown(); use { force: true } only after your grace period.
createDurableQueue({ store }) retains jobs until their handler succeeds and supports atomic leases when a driver implements QueueStore.claim. It exposes the same cancellation/shutdown behavior plus list, failed, and retry. The included memoryQueueStore() is useful for tests; production Redis/SQL drivers should make claim() atomic to prevent two workers executing one job.
Pass repeat to re-enqueue a job a fixed interval after each successful run:
queue.process("heartbeat", async () => ping());
@@ -89,6 +95,20 @@ await queue.add("task", {}, { delayMs: 5000 });
clock = 5000;
const ran = await queue.drain(); // => 1
+createWorkflowEngine(store) executes dependency-ordered steps and persists every transition, result, progress update, failure, cancellation, and approval record. Approval steps pause safely and can resume after a process restart because the snapshot lives in the supplied WorkflowStore.
const workflow = defineDurableWorkflow({
+ name: "publish-report",
+ steps: [
+ { name: "build", run: buildReport },
+ { name: "approve", dependsOn: ["build"], approval: true, run: (report) => report },
+ { name: "publish", dependsOn: ["approve"], run: publishReport },
+ ],
+});
+
+const run = await engine.start(workflow, input);
+await engine.approve(workflow, run.id, "approve", currentUser.id);
+Use memoryWorkflowStore() for tests. Production stores implement the small get, put, and list contract using the same transactional database or durable service as the application.
attempts < maxAttempts.pluggable driver is intended for backing it with Redis/SQL for durability.
@wrnexus/core for offloading work from the request path.Generated from the exact installed package declarations.
/**
+Generated from the exact installed package declarations.
import { ExecutionContext } from '@wrnexus/core';
+
+/**
* Persistence contract for the durable queue.
*
* Distributed drivers should implement `claim()` atomically and exclude leased
@@ -126,20 +148,142 @@ interface DurableQueueOptions {
workerId?: string;
maxAttempts?: number;
concurrency?: number;
+ capacity?: number;
leaseMs?: number;
backoff?: (attempt: number) => number;
now?: () => number;
onDeadLetter?: (job: Job, error: unknown) => void | Promise<void>;
+ context?: (job: Job, signal: AbortSignal) => ExecutionContext;
}
interface DurableQueue {
add<T>(name: string, data: T, options?: AddOptions): Promise<Job<T>>;
process<T>(name: string, handler: JobHandler<T>): void;
drain(): Promise<number>;
+ cancel(id: string): Promise<boolean>;
+ shutdown(options?: {
+ force?: boolean;
+ }): Promise<void>;
+ list(name?: string): Promise<Job[]>;
failed(): Job[];
retry(id: string): Promise<boolean>;
}
declare function createDurableQueue(options?: DurableQueueOptions): DurableQueue;
+interface RedisQueueClient {
+ get(key: string): Promise<string | null>;
+ set(key: string, value: string, options?: {
+ NX?: boolean;
+ PX?: number;
+ }): Promise<unknown>;
+ del(...keys: string[]): Promise<unknown>;
+ zadd(key: string, score: number, member: string): Promise<unknown>;
+ zrem(key: string, member: string): Promise<unknown>;
+ zrangebyscore(key: string, min: number, max: number, options?: {
+ limit: [number, number];
+ }): Promise<string[]>;
+ smembers(key: string): Promise<string[]>;
+ sadd(key: string, member: string): Promise<unknown>;
+ srem(key: string, member: string): Promise<unknown>;
+}
+/** Redis-backed queue store using only the common client command surface. */
+declare function redisQueueStore(client: RedisQueueClient, prefix?: string): QueueStore;
+interface SqlQueueClient {
+ query<T = Record<string, unknown>>(sql: string, parameters?: unknown[]): Promise<{
+ rows: T[];
+ }>;
+}
+/** PostgreSQL store with atomic SKIP LOCKED leasing and JSON payloads. */
+declare function postgresQueueStore(db: SqlQueueClient, table?: string): QueueStore;
+declare const POSTGRES_QUEUE_SCHEMA = "CREATE TABLE IF NOT EXISTS wrnexus_jobs (\n id text PRIMARY KEY, name text NOT NULL, payload jsonb NOT NULL, run_at bigint NOT NULL,\n priority integer NOT NULL DEFAULT 0, lease_owner text, lease_until bigint\n); CREATE INDEX IF NOT EXISTS wrnexus_jobs_due ON wrnexus_jobs (run_at, priority DESC);";
+
+interface ScheduledJob<T = unknown> {
+ name: string;
+ data: T;
+ everyMs: number;
+ options?: AddOptions;
+}
+interface QueueScheduler {
+ start(): void;
+ stop(): void;
+ tick(now?: number): Promise<number>;
+ snapshot(): {
+ running: boolean;
+ schedules: number;
+ nextRuns: Record<string, number>;
+ };
+}
+/** Restart-safe scheduler when used with a durable queue and stable idempotency buckets. */
+declare function createQueueScheduler(queue: DurableQueue, schedules: ScheduledJob[], options?: {
+ pollMs?: number;
+ now?: () => number;
+}): QueueScheduler;
+declare function addBatch<T>(queue: DurableQueue, name: string, values: T[], options?: AddOptions): Promise<Job<T>[]>;
+interface QueueDashboardSnapshot {
+ generatedAt: number;
+ pending: number;
+ failed: number;
+ byName: Record<string, number>;
+ oldestRunAt?: number;
+}
+declare function queueDashboardSnapshot(queue: DurableQueue): Promise<QueueDashboardSnapshot>;
+declare function renderQueueDashboard(snapshot: QueueDashboardSnapshot): string;
+/** Long-running scheduler/worker loop suitable for a dedicated process or container. */
+declare function runQueueDaemon(queue: DurableQueue, scheduler: QueueScheduler, options?: {
+ signal?: AbortSignal;
+ pollMs?: number;
+ onError?: (error: unknown) => void;
+}): Promise<void>;
+
+type WorkflowStatus = "pending" | "running" | "waiting-approval" | "completed" | "failed" | "cancelled";
+interface WorkflowStep$1<I = unknown, O = unknown> {
+ name: string;
+ dependsOn?: string[];
+ approval?: boolean;
+ run(input: I, context: WorkflowRunContext): O | Promise<O>;
+}
+interface WorkflowRunContext {
+ workflowId: string;
+ step: string;
+ results: Readonly<Record<string, unknown>>;
+ signal: AbortSignal;
+ progress(value: number, message?: string): void;
+}
+interface WorkflowSnapshot {
+ id: string;
+ name: string;
+ status: WorkflowStatus;
+ input: unknown;
+ results: Record<string, unknown>;
+ completed: string[];
+ waitingFor?: string;
+ progress: number;
+ message?: string;
+ error?: string;
+ updatedAt: number;
+}
+interface WorkflowStore {
+ get(id: string): Promise<WorkflowSnapshot | null>;
+ put(snapshot: WorkflowSnapshot): Promise<void>;
+ list(): Promise<WorkflowSnapshot[]>;
+}
+declare function memoryWorkflowStore(): WorkflowStore;
+interface WorkflowDefinition<I = unknown> {
+ name: string;
+ steps: WorkflowStep$1<any, any>[];
+ /** Compile-time input marker; definitions do not store runtime input values. */
+ readonly __input?: I;
+}
+interface WorkflowEngine {
+ start<I>(definition: WorkflowDefinition<I>, input: I, id?: string): Promise<WorkflowSnapshot>;
+ resume<I>(definition: WorkflowDefinition<I>, id: string): Promise<WorkflowSnapshot>;
+ approve<I>(definition: WorkflowDefinition<I>, id: string, step: string, actor: string): Promise<WorkflowSnapshot>;
+ cancel(id: string): Promise<boolean>;
+ get(id: string): Promise<WorkflowSnapshot | null>;
+ list(): Promise<WorkflowSnapshot[]>;
+}
+declare function createWorkflowEngine(store?: WorkflowStore): WorkflowEngine;
+declare function defineDurableWorkflow<I>(definition: WorkflowDefinition<I>): WorkflowDefinition<I>;
+
/**
* @wrnexus/queue — a background job queue with delays, retries + backoff, and
* concurrent workers. The default store is in-process; a pluggable driver lets
@@ -165,7 +309,13 @@ interface Job<T = unknown> {
idempotencyKey?: string;
createdAt: number;
}
-type JobHandler<T = unknown> = (job: Job<T>) => void | Promise<void>;
+interface JobContext {
+ /** Aborted when an active job is cancelled or the queue is force-stopped. */
+ signal: AbortSignal;
+ /** The same trusted context shape used by HTTP, actions, realtime and webhooks. */
+ execution: ExecutionContext;
+}
+type JobHandler<T = unknown> = (job: Job<T>, context: JobContext) => void | Promise<void>;
interface AddOptions {
/** Delay before the job becomes runnable (ms). */
delayMs?: number;
@@ -189,8 +339,11 @@ interface QueueOptions {
onFailed?: (job: Job, error: unknown) => void;
/** Maximum jobs executed in one drain. Default: unlimited. */
concurrency?: number;
+ /** Maximum queued + active jobs. Adds reject once this limit is reached. */
+ capacity?: number;
/** Clock injection (tests). Default Date.now. */
now?: () => number;
+ context?: (job: Job, signal: AbortSignal) => ExecutionContext;
}
interface Queue {
add<T>(name: string, data: T, options?: AddOptions): Promise<Job<T>>;
@@ -199,10 +352,16 @@ interface Queue {
drain(now?: number): Promise<number>;
start(): void;
stop(): void;
+ /** Stop accepting work and wait for active handlers (or abort them). */
+ shutdown(options?: {
+ force?: boolean;
+ }): Promise<void>;
size(): number;
get(id: string): Job | undefined;
list(name?: string): Job[];
cancel(id: string): boolean;
+ failed(): Job[];
+ retry(id: string): Promise<boolean>;
}
interface JobDefinition<I> {
name: string;
@@ -222,7 +381,7 @@ declare function defineWorkflow<T>(name: string, steps: Array<WorkflowS
declare function cronToInterval(cron: string): number;
declare function createQueue(options?: QueueOptions): Queue;
-export { type AddOptions, type DurableQueue, type DurableQueueOptions, type Job, type JobDefinition, type JobHandler, type Queue, type QueueOptions, type QueueStore, type WorkflowStep, createDurableQueue, createQueue, cronToInterval, defineJob, defineWorkflow, memoryQueueStore };
+export { type AddOptions, type DurableQueue, type DurableQueueOptions, type Job, type JobContext, type JobDefinition, type JobHandler, POSTGRES_QUEUE_SCHEMA, type Queue, type QueueDashboardSnapshot, type QueueOptions, type QueueScheduler, type QueueStore, type RedisQueueClient, type ScheduledJob, type SqlQueueClient, type WorkflowDefinition, type WorkflowEngine, type WorkflowRunContext, type WorkflowSnapshot, type WorkflowStatus, type WorkflowStep, type WorkflowStore, addBatch, createDurableQueue, createQueue, createQueueScheduler, createWorkflowEngine, cronToInterval, defineDurableWorkflow, defineJob, defineWorkflow, memoryQueueStore, memoryWorkflowStore, postgresQueueStore, queueDashboardSnapshot, redisQueueStore, renderQueueDashboard, runQueueDaemon };
Copy-ready examples from the installed package documentation.
import { createQueue } from "@wrnexus/queue";
const queue = createQueue({ maxAttempts: 3, backoffMs: 1000 });
@@ -249,10 +408,20 @@ queue.process("task", async () => {
await queue.add("task", {}, { delayMs: 5000 });
clock = 5000;
-const ran = await queue.drain(); // => 1const workflow = defineDurableWorkflow({
+ name: "publish-report",
+ steps: [
+ { name: "build", run: buildReport },
+ { name: "approve", dependsOn: ["build"], approval: true, run: (report) => report },
+ { name: "publish", dependsOn: ["approve"], run: publishReport },
+ ],
+});
+
+const run = await engine.start(workflow, input);
+await engine.approve(workflow, run.id, "approve", currentUser.id);Small type-safe reactive signal primitives.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/reactive@0.7.0Request preview access. Never put registry tokens in source control.
Tiny, type-safe reactive primitives (signals) with zero dependencies.+
Small type-safe reactive signal primitives.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/reactive@0.8.0Request preview access. Never put registry tokens in source control.
Tiny, type-safe reactive primitives (signals) with zero dependencies.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/reactive is the seed of WRNexusJS's reactivity layer: a minimal signal primitive that holds a value, notifies subscribers when it changes, and hands back an unsubscribe function. It is deliberately small and framework-agnostic — it powers nothing on its own, but is shaped so client islands (and later the .wrn compiler's state blocks) can build reactive bindings on top of it. Reach for it when you need observable state without pulling in a full reactivity library.
Copy-ready examples from the installed package documentation.
import { signal } from "@wrnexus/reactive";
const count = signal(0);
@@ -156,7 +206,7 @@ const user: Signal<{ name: string } | null> = signal(null);
user.set({ name: "Ada" });Rooms, presence, messaging, history, streams, and UI components.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/realtime@0.8.0Request preview access. Never put registry tokens in source control.
Typed rooms, secure message envelopes, browser room helpers, presence utilities, and complete realtime UI blocks for WRNexusJS.
+import { defineRoom } from "@wrnexus/realtime";
+
+export default defineRoom("support", {
+ async authorize(context) {
+ return Boolean(context.user);
+ },
+ message(client, message) {
+ client.broadcast(message);
+ },
+});
+The package re-exports the hardened realtime registry from @wrnexus/core, including authentication, origin checks, quotas, message-size limits, schema validation hooks, and room authorization.
import {
+ createRealtimeMessage,
+ createPresenceEvent,
+ createTypingEvent,
+ connectRoom,
+ sendRoomMessage,
+} from "@wrnexus/realtime";
+
+const room = connectRoom("support", { query: { ticket: "T-100" } });
+sendRoomMessage(
+ room,
+ createRealtimeMessage({
+ type: "message",
+ room: "support",
+ data: { text: "Hello" },
+ }),
+);
+Message IDs use Web Crypto. A runtime without secure randomness must provide an explicit message ID.
+Enable realtimePlugin() and use:
<RealtimeRoom /><RealtimeMessageBubble /><MessageComposer /><RoomStatus /><RoomMeta /><PresenceList /><TypingIndicator />These package-owned blocks compose existing @wrnexus/ui components such as Card, Alert, Avatar, Badge, Button, Input, and ChatBubble.
Incoming messages can be bounded and constrained:
+const message = parseRealtimeMessage(rawMessage, {
+ maxBytes: 64 * 1024,
+ maxDepth: 12,
+ allowedTypes: ["message", "typing", "presence"],
+ room: "support",
+});
+The parser rejects oversized payloads, circular/unsupported values, unsafe object keys, invalid message types, invalid room names, and room mismatches.
+createRealtimeHistory() keeps a bounded sequenced log per room. Clients acknowledge a sequence and resume(room, clientId) returns only missed events. A snapshot exposes room, message, acknowledgement, and sequence counts for monitoring without exposing payloads.
const history = createRealtimeHistory({ limitPerRoom: 100 });
+const entry = history.publish("support", message);
+history.acknowledge("support", clientId, entry.sequence);
+const missed = history.resume("support", clientId);
+realtimeSseResponse(stream, signal) converts the same sequenced envelope into standards-based Server-Sent Events with event IDs, event types, JSON data, cancellation, and no-cache headers.
Generated from the exact installed package declarations.
export { RawSocket, RealtimeBridge, RealtimeBus, RealtimeConnectMeta, RealtimeEnvelope, RealtimeHandler, RealtimeRegistry, RealtimeRegistryOptions, RealtimeSecurityOptions, RealtimeSocket, Room, RoomAuthInfo, RoomClient, RoomDefinition, RoomHandlers, Target, bridgeRealtime, createRealtimeRegistry, defineRoom, isRoomDefinition } from '@wrnexus/core';
+export { RealtimePluginOptions, realtimeComponentsDir, default as realtimePlugin } from './plugin.js';
+import '@wrnexus/plugin';
+
+type RealtimeMessageType = string;
+interface RealtimeMessage<T = unknown> {
+ id: string;
+ type: RealtimeMessageType;
+ room?: string;
+ senderId?: string;
+ senderName?: string;
+ sentAt: string;
+ data: T;
+ meta?: Record<string, string | number | boolean | null>;
+}
+interface CreateRealtimeMessageOptions<T> {
+ id?: string;
+ type: string;
+ room?: string;
+ senderId?: string;
+ senderName?: string;
+ sentAt?: string | Date;
+ data: T;
+ meta?: Record<string, string | number | boolean | null>;
+}
+interface ParseRealtimeMessageOptions {
+ maxBytes?: number;
+ maxDepth?: number;
+ allowedTypes?: readonly string[];
+ room?: string;
+}
+interface RealtimePresence {
+ userId: string;
+ name?: string;
+ avatar?: string;
+ status?: "online" | "away" | "busy" | "offline";
+ joinedAt?: string;
+ lastSeenAt?: string;
+ meta?: Record<string, string | number | boolean | null>;
+}
+interface RealtimeRoomMeta {
+ id: string;
+ name: string;
+ description?: string;
+ memberCount?: number;
+ onlineCount?: number;
+ createdAt?: string;
+ updatedAt?: string;
+ private?: boolean;
+ tags?: string[];
+}
+declare function assertRealtimeRoomName(name: string): string;
+declare function createRealtimeMessage<T>(options: CreateRealtimeMessageOptions<T>): RealtimeMessage<T>;
+declare function isRealtimeMessage(value: unknown): value is RealtimeMessage;
+declare function parseRealtimeMessage<T = unknown>(value: string | unknown, options?: ParseRealtimeMessageOptions): RealtimeMessage<T>;
+declare function createPresenceEvent(action: "join" | "leave" | "update", presence: RealtimePresence, room?: string): RealtimeMessage<{
+ action: "join" | "leave" | "update";
+ presence: RealtimePresence;
+}>;
+declare function createTypingEvent(userId: string, typing: boolean, options?: {
+ room?: string;
+ name?: string;
+}): RealtimeMessage<{
+ userId: string;
+ name?: string;
+ typing: boolean;
+}>;
+declare function roomMemberSummary(members: readonly RealtimePresence[]): {
+ total: number;
+ online: number;
+ away: number;
+ busy: number;
+};
+
+interface BrowserRoomConnection {
+ readonly name: string;
+ send(message: unknown): BrowserRoomConnection;
+ on(type: string | ((message: unknown) => void), callback?: (message: unknown) => void): BrowserRoomConnection;
+ close(): void;
+}
+interface WrnexusRealtimeWindow extends Window {
+ wire?: {
+ room?: (name: string, query?: string) => BrowserRoomConnection;
+ };
+}
+declare function roomQuery(params: Record<string, string | number | boolean | null | undefined>): string;
+declare function connectRoom(name: string, options?: {
+ query?: Record<string, string | number | boolean | null | undefined>;
+ window?: WrnexusRealtimeWindow;
+}): BrowserRoomConnection;
+declare function sendRoomMessage<T>(room: BrowserRoomConnection, message: RealtimeMessage<T> | T): BrowserRoomConnection;
+
+interface SequencedRealtimeMessage<T = unknown> {
+ sequence: number;
+ message: RealtimeMessage<T>;
+}
+interface RealtimeHistorySnapshot {
+ rooms: number;
+ messages: number;
+ acknowledgements: number;
+ oldestSequence?: number;
+ latestSequence?: number;
+}
+interface RealtimeHistoryOptions {
+ limitPerRoom?: number;
+ maxClients?: number;
+}
+interface RealtimeHistory {
+ publish<T>(room: string, message: RealtimeMessage<T>): SequencedRealtimeMessage<T>;
+ replay(room: string, afterSequence?: number, limit?: number): SequencedRealtimeMessage[];
+ acknowledge(room: string, clientId: string, sequence: number): void;
+ acknowledged(room: string, clientId: string): number;
+ resume(room: string, clientId: string, limit?: number): SequencedRealtimeMessage[];
+ snapshot(): RealtimeHistorySnapshot;
+ clear(room?: string): void;
+}
+declare function createRealtimeHistory(options?: RealtimeHistoryOptions): RealtimeHistory;
+declare function createAcknowledgement(room: string, sequence: number, clientId: string): RealtimeMessage<{
+ sequence: number;
+ clientId: string;
+}>;
+declare function realtimeSseResponse(stream: ReadableStream<SequencedRealtimeMessage>, signal?: AbortSignal): Response;
+
+interface DatabaseChange<T = unknown> {
+ table: string;
+ operation: "insert" | "update" | "delete";
+ key?: string | number;
+ record?: T;
+ occurredAt: number;
+}
+interface DatabaseChangeSource {
+ subscribe(handler: (change: DatabaseChange) => void | Promise<void>): () => void;
+}
+declare function databaseChangeFeed(source: DatabaseChangeSource, publish: (topic: string, change: DatabaseChange) => void | Promise<void>, options?: {
+ prefix?: string;
+ allowTables?: string[];
+}): () => void;
+interface FileStreamFrame {
+ streamId: string;
+ index: number;
+ total: number;
+ bytes: Uint8Array;
+}
+declare function frameFileStream(streamId: string, bytes: Uint8Array, options?: {
+ chunkBytes?: number;
+ maxBytes?: number;
+}): FileStreamFrame[];
+declare function createFileStreamReceiver(options?: {
+ maxBytes?: number;
+ maxStreams?: number;
+}): {
+ accept(frame: FileStreamFrame): Uint8Array | null;
+ snapshot: () => {
+ activeStreams: number;
+ bufferedBytes: number;
+ };
+};
+
+export { type BrowserRoomConnection, type CreateRealtimeMessageOptions, type DatabaseChange, type DatabaseChangeSource, type FileStreamFrame, type ParseRealtimeMessageOptions, type RealtimeHistory, type RealtimeHistoryOptions, type RealtimeHistorySnapshot, type RealtimeMessage, type RealtimeMessageType, type RealtimePresence, type RealtimeRoomMeta, type SequencedRealtimeMessage, type WrnexusRealtimeWindow, assertRealtimeRoomName, connectRoom, createAcknowledgement, createFileStreamReceiver, createPresenceEvent, createRealtimeHistory, createRealtimeMessage, createTypingEvent, databaseChangeFeed, frameFileStream, isRealtimeMessage, parseRealtimeMessage, realtimeSseResponse, roomMemberSummary, roomQuery, sendRoomMessage };
+Copy-ready examples from the installed package documentation.
import { defineRoom } from "@wrnexus/realtime";
+
+export default defineRoom("support", {
+ async authorize(context) {
+ return Boolean(context.user);
+ },
+ message(client, message) {
+ client.broadcast(message);
+ },
+});import {
+ createRealtimeMessage,
+ createPresenceEvent,
+ createTypingEvent,
+ connectRoom,
+ sendRoomMessage,
+} from "@wrnexus/realtime";
+
+const room = connectRoom("support", { query: { ticket: "T-100" } });
+sendRoomMessage(
+ room,
+ createRealtimeMessage({
+ type: "message",
+ room: "support",
+ data: { text: "Hello" },
+ }),
+);const message = parseRealtimeMessage(rawMessage, {
+ maxBytes: 64 * 1024,
+ maxDepth: 12,
+ allowedTypes: ["message", "typing", "presence"],
+ room: "support",
+});const history = createRealtimeHistory({ limitPerRoom: 100 });
+const entry = history.publish("support", message);
+history.acknowledge("support", clientId, entry.sequence);
+const missed = history.resume("support", clientId);Filesystem discovery, route matching, and typed route generation.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/router@0.7.0Request preview access. Never put registry tokens in source control.
File-based router that maps an app/ directory onto route tables and matches request paths against them.
+ Filesystem discovery, route matching, and typed route generation.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/router@0.8.0Request preview access. Never put registry tokens in source control.
File-based router that maps an app/ directory onto route tables and matches request paths against them.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/router scans an application's app/ directory once at startup and builds route tables for pages, API endpoints, realtime channels, middleware, server-rendered .wrn components, layouts, and validation schemas. It also compiles URL patterns (/users/[id]) into RegExps and matches request paths against them. Request input is never turned into a file path, which makes the router immune to path traversal. This is a server-side package used by the WRNexusJS runtime to resolve incoming requests, plus a codegen helper for compile-time typed links.
Security headers, CSRF protection, rate limits, and safe rendering.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/security@0.8.0Request preview access. Never put registry tokens in source control.
Secure-by-default utilities for WRNexusJS: bounded HTML-safe serialization, prototype-pollution rejection, URL policy, secure cookies, request hardening, security presets, and SSRF-safe remote fetches.
+import { safeFetch, securityPreset, setSecureCookie } from "@wrnexus/security";
+
+export default { security: securityPreset("strict") };
+const response = await safeFetch(remoteUrl, { allowedHosts: ["api.example.com"] });
+setSecureCookie(ctx, "__Host-session", sessionId);Generated from the exact installed package declarations.
export { S as SafeFetchOptions, a as SafeUrlPolicy, i as isPrivateAddress, b as isSafeUrl, s as safeFetch, c as sanitizeUrl, v as validateUrl } from './fetch-DNyX0J_D.js';
+export { SecureSerializeOptions, secureJsonStringify, serializeForHtml } from './serialization.js';
+import { CookieOptions, Context, RequestLimitsConfig, Middleware, SecurityConfig } from '@wrnexus/core';
+export { TrustedHtmlPolicy, TrustedHtmlValue, createTrustedHtml, isTrustedHtml, unwrapTrustedHtml } from './trusted-html.js';
+
+declare class SecurityError extends Error {
+ readonly code: string;
+ readonly status: number;
+ constructor(code: string, message: string, status?: number, options?: ErrorOptions);
+}
+
+interface SafeObjectOptions {
+ maxDepth?: number;
+ maxKeys?: number;
+ allowInstances?: boolean;
+}
+declare function isDangerousObjectKey(key: string): boolean;
+declare function assertSafeObject(value: unknown, options?: SafeObjectOptions): void;
+declare function safeMerge<T extends Record<string, unknown>>(target: T, ...sources: Array<Record<string, unknown> | undefined | null>): T;
+
+interface SecureCookieOptions extends CookieOptions {
+ hostOnly?: boolean;
+}
+declare function secureCookieOptions(ctx: Pick<Context, "url">, options?: SecureCookieOptions): CookieOptions;
+declare function setSecureCookie(ctx: Pick<Context, "url" | "cookies">, name: string, value: string, options?: SecureCookieOptions): void;
+
+type RequestHardeningOptions = RequestLimitsConfig;
+declare function requestHardening(options?: RequestHardeningOptions): Middleware;
+
+type SecurityPreset = "balanced" | "strict" | "api";
+declare function securityPreset(preset?: SecurityPreset): SecurityConfig;
+
+export { type RequestHardeningOptions, type SafeObjectOptions, type SecureCookieOptions, SecurityError, type SecurityPreset, assertSafeObject, isDangerousObjectKey, requestHardening, safeMerge, secureCookieOptions, securityPreset, setSecureCookie };
+Copy-ready examples from the installed package documentation.
import { safeFetch, securityPreset, setSecureCookie } from "@wrnexus/security";
+
+export default { security: securityPreset("strict") };
+const response = await safeFetch(remoteUrl, { allowedHosts: ["api.example.com"] });
+setSecureCookie(ctx, "__Host-session", sessionId);bun add @wrnexus/securitySecure HTML document rendering and SEO metadata.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ssr@0.7.0Request preview access. Never put registry tokens in source control.
Server-side rendering: wraps a page's HTML body in a complete HTML document with a metadata-driven <head>.
+ Secure HTML document rendering and SEO metadata.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ssr@0.8.0Request preview access. Never put registry tokens in source control.
Server-side rendering: wraps a page's HTML body in a complete HTML document with a metadata-driven <head>.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
Pages in WRNexusJS return an HTML string for the body. @wrnexus/ssr takes that body and produces a full HTML document — building the <head> from page metadata and global SEO defaults, resolving canonical/Open Graph/Twitter tags, and injecting module preloads and <script type="module"> tags. It is deliberately server-only: nothing in this package touches the DOM or ships to the browser, keeping server code genuinely server-only. Reach for it on the server when turning a rendered page body into a response document.
Copy-ready examples from the installed package documentation.
import { renderDocument } from "@wrnexus/ssr";
const html = renderDocument({
@@ -213,7 +224,7 @@ return new Response(html, {
return new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } });Application state stores shared across server and browser runtimes.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/store@0.8.0Request preview access. Never put registry tokens in source control.
Typed global and page-scoped WRNexusJS stores with runtime-specific state, computed values, actions, lifecycle hooks, persistence, SSR isolation, and HMR support.
+Use defineStore() to declare a store and createStoreContainer() to create an isolated request or browser container. Store definitions are framework helpers and do not require UI components.
Generated from the exact installed package declarations.
import { StoreMutation, StoreFunction, StoreDefinition, StoreInstance, StoreCombinedState } from './types.js';
+export { PersistenceStorage, StoreActionContext, StoreActionDefinition, StoreInstanceCore, StoreKind, StoreLifecycleContext, StorePersistenceConfig, StoreRuntime } from './types.js';
+
+declare function defineStore<S extends object, C extends object = Record<string, never>, A extends Record<string, StoreFunction> = Record<string, StoreFunction>, CS extends object = Record<string, never>, SS extends object = Record<string, never>>(definition: StoreDefinition<S, C, A, CS, SS>): StoreDefinition<S, C, A, CS, SS>;
+interface StoreContainerOptions {
+ runtime: "server" | "client";
+ request?: unknown;
+ routeId?: string;
+ hydration?: Record<string, unknown>;
+ onMutation?: (mutation: StoreMutation) => void;
+}
+declare class StoreContainer {
+ readonly runtime: "server" | "client";
+ readonly request?: unknown;
+ readonly routeId?: string;
+ private readonly instances;
+ private readonly hydration;
+ private readonly onMutation?;
+ private readonly lastMutations;
+ constructor(options: StoreContainerOptions);
+ use<S extends object, C extends object, A extends Record<string, StoreFunction>, CS extends object, SS extends object>(definition: StoreDefinition<S, C, A, CS, SS>): Promise<StoreInstance<StoreCombinedState<S, CS, SS>, C, A>>;
+ serialize(): Record<string, unknown>;
+ inspect(): Array<{
+ name: string;
+ kind: "global" | "page";
+ state: Readonly<Record<string, unknown>>;
+ computed: Readonly<Record<string, unknown>>;
+ lastAction?: string;
+ changed: string[];
+ hydrationSource: "server" | "persistence" | "initial";
+ }>;
+ hotUpdate<S extends object, C extends object, A extends Record<string, StoreFunction>, CS extends object, SS extends object>(definition: StoreDefinition<S, C, A, CS, SS>): Promise<{
+ preserved: string[];
+ reset: string[];
+ }>;
+ disposePageStores(): Promise<void>;
+ dispose(): Promise<void>;
+}
+declare function createStoreContainer(options: StoreContainerOptions): StoreContainer;
+declare function createStoreInstance<S extends object, C extends object, A extends Record<string, StoreFunction>, CS extends object, SS extends object>(definition: StoreDefinition<S, C, A, CS, SS>, options: Omit<StoreContainerOptions, "hydration"> & {
+ hydration?: unknown;
+}): StoreInstance<StoreCombinedState<S, CS, SS>, C, A>;
+
+export { StoreCombinedState, StoreContainer, type StoreContainerOptions, StoreDefinition, StoreFunction, StoreInstance, StoreMutation, createStoreContainer, createStoreInstance, defineStore };
+Copy-ready examples from the installed package documentation.
bun add @wrnexus/storeimport * as store from "@wrnexus/store";CSS pipeline, themes, fonts, profiles, and application config.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/styles@0.7.0Request preview access. Never put registry tokens in source control.
Global CSS bundling, the+--wire-*design-token theme system, and thewrnexus.config.tsapp-config loader for WRNexusJS apps.
CSS pipeline, themes, fonts, profiles, and application config.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/styles@0.8.0Request preview access. Never put registry tokens in source control.
Compose local or package foundations in order; later layers override earlier ones and the application has final base-config precedence:
+export default defineConfig({
+ extends: ["@workroot/wrnexus-enterprise", "./layers/company"],
+ profiles: { production: { port: 8080 } },
+});
+A directory layer exports wrnexus.layer.ts (JavaScript/MJS are supported). A package can provide that conventional file or declare wrnexus.layer in its package.json. Layers may extend other layers and carry the complete app configuration, including plugins that contribute layouts, components, routes, middleware, and migrations. plugins and head compose; other arrays intentionally replace earlier values. Cycles and missing/invalid entries fail with stable WRN-CONFIG-LAYER-* diagnostics. wrnexus config --explain lists every resolved layer source.
Global CSS bundling, the--wire-*design-token theme system, and thewrnexus.config.tsapp-config loader for WRNexusJS apps.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
This package owns three server-side concerns that shape every page a WRNexusJS app renders:
@@ -176,7 +183,7 @@ const themeJs = renderThemeRuntime(theme); // served at THEME_JS_HREFPeer package:@wrnexus/core supplies the SeoConfig and SecurityConfig types referenced by AppConfig.
THEME_CSS_HREF), and the theme runtime (THEME_JS_HREF) are wired into pages by the framework's server; this package only produces their contents.Generated from the exact installed package declarations.
import { PerformanceBudgets, SeoConfig, SecurityConfig } from '@wrnexus/core';
-import { PluginInput } from '@wrnexus/plugin';
+import { PluginInput, PluginPermission } from '@wrnexus/plugin';
import { StorageConfig } from '@wrnexus/uploader';
/**
@@ -191,7 +198,12 @@ import { StorageConfig } from '@wrnexus/uploader';
* present before the first paint. The reserved token key `color-scheme` is
* emitted as the native CSS property instead of a custom property.
*/
-type ThemeTokens = Record<string, string>;
+type ThemeSemanticColor = "primary" | "secondary" | "info" | "success" | "warning" | "danger" | "error";
+type ThemeToken = "color-scheme" | "color-bg" | "color-background" | "color-foreground" | "color-surface" | "color-surface-2" | "color-surface-raised" | "color-surface-muted" | "color-text" | "color-text-muted" | "color-text-subtle" | "color-muted" | "color-border" | "color-border-strong" | "color-code-background" | "color-code-surface" | "color-code-text" | "color-code-muted" | "color-code-border" | `color-${ThemeSemanticColor}` | `color-${ThemeSemanticColor}-${"hover" | "active" | "contrast" | "soft" | "muted" | "text"}` | `color-on-${"primary" | "secondary"}` | "radius" | "radius-sm" | "shadow-1" | "shadow-sm" | "shadow-md" | "shadow-lg" | "space-section" | "space-section-sm" | "container-max" | "font-sans";
+/** Known tokens get autocomplete while applications may add namespaced custom tokens. */
+type ThemeTokens = Partial<Record<ThemeToken, string>> & Record<string, string>;
+declare function defineThemeTokens<T extends ThemeTokens>(tokens: T): T;
+declare function themeVar(token: ThemeToken, fallback?: string): string;
declare const THEME_PALETTE_NAMES: readonly ["blue", "indigo", "violet", "emerald", "cyan", "rose", "amber", "slate"];
type ThemePaletteName = (typeof THEME_PALETTE_NAMES)[number];
/** Required semantic colors for a custom application palette. */
@@ -345,6 +357,26 @@ declare function fontCspSources(fonts?: FontConfig): {
font: string[];
};
+declare const CURRENT_COMPATIBILITY_DATE = "2026-08-02";
+declare const CURRENT_FRAMEWORK_BEHAVIOUR = 1;
+interface CompatibilityPolicy {
+ compatibilityDate?: string;
+ frameworkBehaviour?: number;
+}
+interface CompatibilityReport {
+ configuredDate?: string;
+ effectiveDate: string;
+ currentDate: string;
+ configuredBehaviour?: number;
+ effectiveBehaviour: number;
+ currentBehaviour: number;
+ needsUpgrade: boolean;
+ future: boolean;
+ messages: string[];
+}
+declare function isCompatibilityDate(value: string): boolean;
+declare function resolveCompatibility(policy: CompatibilityPolicy): CompatibilityReport;
+
/**
* App configuration loader (`wrnexus.config.ts`).
*
@@ -453,6 +485,15 @@ interface PwaConfig {
cacheUrls?: string[];
/** Service-worker cache key. Change it to invalidate existing PWA caches. */
cacheName?: string;
+ /** Ordered URL rules for runtime caching. Patterns are regular-expression source strings. */
+ runtimeCaching?: Array<{
+ pattern: string;
+ strategy: "network-first" | "cache-first" | "stale-while-revalidate";
+ cacheName?: string;
+ methods?: string[];
+ }>;
+ /** Background Sync tag used by the offline mutation queue. */
+ backgroundSyncTag?: string;
}
type DevToolbarPosition = "bottom-center" | "bottom-left" | "bottom-right";
interface DevToolbarConfig {
@@ -548,9 +589,16 @@ interface CompatibilityConfig {
legacyComponentDiscovery?: boolean;
stringLayouts?: boolean;
}
-interface AppConfig {
+interface AppConfig extends CompatibilityPolicy {
+ /** Ordered reusable configuration layers; the application always has final precedence. */
+ extends?: string | string[];
/** Compiler/dev/build plugins, resolved in deterministic pre/normal/post order. */
plugins?: PluginInput;
+ /** Optional least-privilege enforcement for automatically discovered packages. */
+ pluginPermissions?: {
+ enforce?: boolean;
+ grants?: Record<string, PluginPermission[]>;
+ };
/** WRN v0.6 explicit import and compatibility resolution. */
imports?: ImportsConfig;
/** TypeScript-backed .wrn type checking and declaration generation. */
@@ -598,6 +646,17 @@ interface AppConfig {
i18n?: {
default?: string;
locales?: string[];
+ labels?: Record<string, string>;
+ fallbacks?: Record<string, string[]>;
+ direction?: Record<string, "ltr" | "rtl">;
+ cookie?: {
+ name?: string;
+ maxAge?: number;
+ path?: string;
+ sameSite?: "Strict" | "Lax" | "None";
+ secure?: boolean;
+ };
+ strict?: boolean;
};
/** Default database connection (driver + url); reached with `getDb()`. */
db?: {
@@ -647,6 +706,11 @@ declare function resolveProfile(options?: {
explicit?: string;
mode?: Mode;
}): string;
+interface ResolvedConfigLayers {
+ config: AppConfig;
+ sources: string[];
+}
+declare function resolveConfigLayers(appRoot: string, application: AppConfig): Promise<ResolvedConfigLayers>;
/** Load the raw `wrnexus.config.*` (with the `profiles` map intact), or `{}`. */
declare function loadRawConfig(appRoot: string): Promise<AppConfig>;
/** Load `wrnexus.config.*`, applying the active profile's overrides. */
@@ -746,7 +810,7 @@ declare function auditCssPerformance(source: string): CssPerformanceAuditIssue[]
*/
declare function renderStyles(ctx: StyleProcessContext, styles?: StylesConfig): Promise<string>;
-export { ACCENT_COOKIE, type AppConfig, type BuildConfig, type ConfigIssue, type ContrastResult, type CssPerformanceAuditIssue, type CssTokenAudit, type CustomThemePalette, DEFAULT_THEMES, type DevToolbarConfig, type ExperimentalConfig, type ExplainedConfig, type FontConfig, type FontDisplay, type GoogleFont, type LocalFontFace, type MobileConfig, type Mode, type NavigationConfig, type ObservabilityConfig, type PerformanceConfig, type PwaConfig, type ResolvedTheme, type StyleProcessContext, type StyleSource, type StylesConfig, type Mode as StylesMode, THEME_COOKIE, THEME_CSS_HREF, THEME_JS_HREF, THEME_PALETTES, THEME_PALETTE_NAMES, type TenancyConfig, type ThemeAccentConfig, type ThemeConfig, type ThemePaletteName, type ThemeTokens, auditCssPerformance, auditWireTokens, bundleCss, contrast, defineConfig, explainAppConfig, findStyleEntry, fontCspSources, headToString, loadAppConfig, loadEnv, loadRawConfig, normalizeStyleSources, renderFontHead, renderProductionFontHead, renderStyles, renderThemeCss, renderThemeRuntime, resolveAccentName, resolveProfile, resolveThemeConfig, resolveThemeName, tailwindSourceDirectives, validateAppConfig };
+export { ACCENT_COOKIE, type AppConfig, type BuildConfig, CURRENT_COMPATIBILITY_DATE, CURRENT_FRAMEWORK_BEHAVIOUR, type CompatibilityPolicy, type CompatibilityReport, type ConfigIssue, type ContrastResult, type CssPerformanceAuditIssue, type CssTokenAudit, type CustomThemePalette, DEFAULT_THEMES, type DevToolbarConfig, type ExperimentalConfig, type ExplainedConfig, type FontConfig, type FontDisplay, type GoogleFont, type LocalFontFace, type MobileConfig, type Mode, type NavigationConfig, type ObservabilityConfig, type PerformanceConfig, type PwaConfig, type ResolvedConfigLayers, type ResolvedTheme, type StyleProcessContext, type StyleSource, type StylesConfig, type Mode as StylesMode, THEME_COOKIE, THEME_CSS_HREF, THEME_JS_HREF, THEME_PALETTES, THEME_PALETTE_NAMES, type TenancyConfig, type ThemeAccentConfig, type ThemeConfig, type ThemePaletteName, type ThemeSemanticColor, type ThemeToken, type ThemeTokens, auditCssPerformance, auditWireTokens, bundleCss, contrast, defineConfig, defineThemeTokens, explainAppConfig, findStyleEntry, fontCspSources, headToString, isCompatibilityDate, loadAppConfig, loadEnv, loadRawConfig, normalizeStyleSources, renderFontHead, renderProductionFontHead, renderStyles, renderThemeCss, renderThemeRuntime, resolveAccentName, resolveCompatibility, resolveConfigLayers, resolveProfile, resolveThemeConfig, resolveThemeName, tailwindSourceDirectives, themeVar, validateAppConfig };
Copy-ready examples from the installed package documentation.
import type { AppConfig } from "@wrnexus/styles";
export default {
@@ -817,9 +881,9 @@ const themeJs = renderThemeRuntime(theme); // served at THEME_JS_HREF<button data-wire-theme-toggle>Toggle theme</button>
<button data-wire-theme-set="brand">Brand theme</button>Editor syntax definitions and language tooling for .wrn files.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/syntax@0.7.0Request preview access. Never put registry tokens in source control.
Canonical WRN lexer, parser, AST, language metadata, source positions, and stable diagnostics. Framework tooling should import this package instead of implementing a separate .wrn parser.
Editor syntax definitions and language tooling for .wrn files.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/syntax@0.8.0Request preview access. Never put registry tokens in source control.
Canonical WRN lexer, parser, AST, language metadata, source positions, and stable diagnostics. Framework tooling should import this package instead of implementing a separate .wrn parser.
See docs/WRN-LANGUAGE-SPEC-1.0.md in the WRNexusJS repository.
Generated from the exact installed package declarations.
export { LexError, Lexer } from './tokenizer.js';
-export { A as ActionBlock, a as ApiBlock, b as Attr, C as ComputedDecl, D as DataApiBlock, c as DataMode, E as EffectBlock, d as EventDecl, F as FunctionParameterDecl, e as FunctionRuntime, L as LifecycleBlock, f as LoadBlock, M as ModeFunctionsBlock, O as OutputDecl, P as PageAst, g as ParseError, h as PersistDecl, i as PropDecl, R as RealtimeBlock, j as RealtimeHandler, k as RuntimeFunctionDecl, S as SeoBlock, l as StateDecl, m as StateRuntime, n as StoreKind, o as StoreLifecycleDecl, p as StructuredImportDecl, V as VOID_ELEMENTS, q as ViewNode, W as WatchBlock, r as parse, s as parseComputedDeclarations, t as parseHtmlView, u as parseOutputs, v as parsePersist, w as parseRuntimeFunctions, x as parseStateDeclarations, y as parseStoreLifecycle, z as parseStructuredImports, B as stripRuntimeFunctionModifiers } from './parser-BGaF5Zdu.js';
+export { FormatWrnOptions, formatWrn } from './formatter.js';
+export { A as ActionBlock, a as ApiBlock, b as Attr, C as ComputedDecl, D as DataApiBlock, c as DataMode, E as EffectBlock, d as EventDecl, F as FunctionParameterDecl, e as FunctionRuntime, L as LifecycleBlock, f as LoadBlock, M as ModeFunctionsBlock, O as OutputDecl, P as PageAst, g as ParseError, h as PersistDecl, i as PropDecl, R as RealtimeBlock, j as RealtimeHandler, k as RuntimeFunctionDecl, S as SeoBlock, l as StateDecl, m as StateRuntime, n as StoreKind, o as StoreLifecycleDecl, p as StructuredImportDecl, V as VOID_ELEMENTS, q as ViewNode, W as WatchBlock, r as parse, s as parseComputedDeclarations, t as parseHtmlView, u as parseOutputs, v as parsePersist, w as parseRuntimeFunctions, x as parseStateDeclarations, y as parseStoreLifecycle, z as parseStructuredImports, B as stripRuntimeFunctionModifiers } from './parser-CTLO4mcT.js';
export { RuntimeType, eraseFunctionTypes, inferredRuntimeType, runtimeTypeOf, validateTypedInitializer } from './types.js';
import { WrnDiagnostic } from './diagnostics.js';
export { DiagnoseOptions, WrnDiagnosticSeverity, WrnSourcePosition, assertValidAst, classifyParseError, containsReadonlyPropMutation, diagnose, diagnosticFromError, formatDiagnostic, isHydrationStrategy, isRuntimeTarget, positionAt } from './diagnostics.js';
@@ -48,7 +49,7 @@ const ast = parse('component Greeting { view { <p>Hello</p>
const summary = diagnosticSummary(diagnose(source));WRNexusJS-aware component, route, and browser testing utilities.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/test@0.7.0Request preview access. Never put registry tokens in source control.
Testing utilities for WRNexusJS apps — component rendering, reactive-DOM mounting, route handler calls, and a full in-process app harness, plus a one-import re-export of bun:test.
+ WRNexusJS-aware component, route, and browser testing utilities.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/test@0.8.0Request preview access. Never put registry tokens in source control.
Testing utilities for WRNexusJS apps — component rendering, reactive-DOM mounting, route handler calls, and a full in-process app harness, plus a one-import re-export of bun:test.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/test is the server-side test toolkit you reach for when writing tests for a WRNexusJS app. It runs under bun test (invoked via wrnexus test) and gives you a single import surface: the bun:test primitives (test, expect, mock, …) re-exported alongside WRNexusJS-aware helpers that compile .wrn components, hydrate server HTML in a DOM, invoke API route handlers, and boot the real app on an ephemeral port for integration tests.
Boots the app at projectRoot on an ephemeral port (port: 0) for integration tests covering pages, API routes, middleware, and the full request pipeline. Loads env and app config for the given profile (default "test") so it picks up your test database/env. The server runs in development mode with HMR disabled. Remember to await app.close() when done.
The CLI supports focused suites by file or directory convention:
+wrnexus test unit # *.unit.test.ts or test/unit/**
+wrnexus test component # *.component.test.ts or test/component/**
+wrnexus test api # *.api.test.ts or test/api/**
+wrnexus test accessibility # *.a11y.test.ts / *.accessibility.test.ts
+wrnexus test performance # *.performance.test.ts / *.benchmark.test.ts
+wrnexus test browser # Playwright project when configured
+wrnexus test visual # Playwright tests tagged @visual
+Pass the application directory after the level, for example wrnexus test component examples/basic-app. A focused command fails clearly when no matching suite exists instead of silently running unrelated tests.
import { test, expect, renderComponent, mountHtml, createHarness } from "@wrnexus/test";
test("counter renders its label", async () => {
@@ -138,6 +147,38 @@ declare class MemoryCookieJar {
clear(): void;
}
+interface TransactionalDatabase {
+ tx<T>(callback: (transaction: TransactionalDatabase) => Promise<T>): Promise<T>;
+}
+/** Run test work in a real transaction and always force rollback. */
+declare function withDatabaseRollback<T>(db: TransactionalDatabase, run: (transaction: TransactionalDatabase) => T | Promise<T>): Promise<T>;
+declare function createFactory<T extends Record<string, unknown>>(build: (sequence: number) => T): {
+ build(overrides?: Partial<T>): T;
+ buildMany(count: number, overrides?: Partial<T>): T[];
+ reset(): void;
+};
+interface BrowserArtifactPage {
+ screenshot(options: {
+ path: string;
+ fullPage?: boolean;
+ }): Promise<unknown>;
+ context(): {
+ tracing?: {
+ stop(options: {
+ path: string;
+ }): Promise<unknown>;
+ };
+ };
+}
+declare function captureBrowserArtifacts(page: BrowserArtifactPage, testName: string, options?: {
+ root?: string;
+ screenshot?: boolean;
+ trace?: boolean;
+}): Promise<{
+ screenshot?: string;
+ trace?: string;
+}>;
+
/**
* @wrnexus/test — testing utilities for WRNexusJS apps. Runs on `bun test` (via
* `wrnexus test`). Import everything from one place:
@@ -193,8 +234,14 @@ interface HarnessOptions {
*/
declare function createHarness(projectRoot: string, options?: HarnessOptions): Promise<Harness>;
-export { type Deferred, type Harness, type HarnessOptions, type JsonResponse, MemoryCookieJar, type TestRequestOptions, type WaitForOptions, callRoute, createHarness, deferred, expectProblem, mountHtml, readJsonResponse, renderComponent, testContext, testRequest, waitFor };
-Copy-ready examples from the installed package documentation.
import { test, expect, renderComponent, mountHtml, createHarness } from "@wrnexus/test";
+export { type BrowserArtifactPage, type Deferred, type Harness, type HarnessOptions, type JsonResponse, MemoryCookieJar, type TestRequestOptions, type TransactionalDatabase, type WaitForOptions, callRoute, captureBrowserArtifacts, createFactory, createHarness, deferred, expectProblem, mountHtml, readJsonResponse, renderComponent, testContext, testRequest, waitFor, withDatabaseRollback };
+Copy-ready examples from the installed package documentation.
wrnexus test unit # *.unit.test.ts or test/unit/**
+wrnexus test component # *.component.test.ts or test/component/**
+wrnexus test api # *.api.test.ts or test/api/**
+wrnexus test accessibility # *.a11y.test.ts / *.accessibility.test.ts
+wrnexus test performance # *.performance.test.ts / *.benchmark.test.ts
+wrnexus test browser # Playwright project when configured
+wrnexus test visual # Playwright tests tagged @visualimport { test, expect, renderComponent, mountHtml, createHarness } from "@wrnexus/test";
test("counter renders its label", async () => {
const html = await renderComponent(SRC, { start: 3, label: "Hits" });
@@ -220,7 +267,7 @@ test("health endpoint", async () => {
});Error/event capture, middleware, filtering, and sinks.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/tracking@0.7.0Request preview access. Never put registry tokens in source control.
Error tracking for WRNexusJS apps: capture exceptions manually or via middleware and fan them out to pluggable sinks.+
Error/event capture, middleware, filtering, and sinks.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/tracking@0.8.0Request preview access. Never put registry tokens in source control.
Error tracking for WRNexusJS apps: capture exceptions manually or via middleware and fan them out to pluggable sinks.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/tracking is a small, server-side error-capture layer. You create a tracker with one or more sinks, then feed it errors — either manually with tracker.capture(err, context) or automatically by mounting tracker.middleware() in your request pipeline. A consoleSink is included; forwarding to Sentry, Datadog, or any other backend is just a matter of writing a tiny sink. Reach for it when you want a single, sink-agnostic place to route application errors. Sinks run best-effort — a throwing sink never breaks the request.
WRN-aware TypeScript diagnostics and virtual documents.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/typecheck@0.8.0Request preview access. Never put registry tokens in source control.
Static type checking for .wrn declarations, props, state, outputs, functions, stores, and generated virtual TypeScript files.
The package is compiler tooling rather than a browser UI package, so its public kit consists of programmatic typecheck helpers and diagnostics.
Generated from the exact installed package declarations.
import { PageAst } from '@wrnexus/syntax';
+export { componentContract, storeContract } from './contracts.js';
+export { findAppRoot, loadApplicationTypes } from './project.js';
+
+interface WrnTypeDiagnostic {
+ code: string;
+ category: "error" | "warning" | "info";
+ message: string;
+ file: string;
+ line: number;
+ column: number;
+ length: number;
+ expected?: string;
+ received?: string;
+ hint?: string;
+ related?: {
+ file: string;
+ line: number;
+ column: number;
+ message: string;
+ };
+}
+interface TypecheckOptions {
+ filePath?: string;
+ appRoot?: string;
+ strict?: boolean;
+ noImplicitAny?: boolean;
+ strictNullChecks?: boolean;
+ checkRuntimeBoundaries?: boolean;
+}
+interface SourceMapping {
+ virtualStartLine: number;
+ virtualEndLine: number;
+ sourceStartLine: number;
+ sourceStartColumn: number;
+}
+interface VirtualTypeScriptModule {
+ ast: PageAst;
+ fileName: string;
+ code: string;
+ mappings: SourceMapping[];
+}
+declare function virtualTypeScriptModule(source: string, filePath?: string, appRoot?: string): VirtualTypeScriptModule;
+declare function checkWrnSource(source: string, options?: TypecheckOptions): WrnTypeDiagnostic[];
+declare function checkWrnFile(filePath: string, options?: Omit<TypecheckOptions, "filePath">): WrnTypeDiagnostic[];
+
+export { type TypecheckOptions, type VirtualTypeScriptModule, type WrnTypeDiagnostic, checkWrnFile, checkWrnSource, virtualTypeScriptModule };
+Copy-ready examples from the installed package documentation.
bun add @wrnexus/typecheckimport * as typecheck from "@wrnexus/typecheck";Themeable server-rendered UI components and CSS.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ui@0.7.0Request preview access. Never put registry tokens in source control.
First-party Wire UI component library — a set of themeable .wrn components plus a single tokenized stylesheet.
+ Themeable server-rendered UI components and CSS.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/ui@0.8.0Request preview access. Never put registry tokens in source control.
First-party Wire UI component library — a set of themeable .wrn components plus a single tokenized stylesheet.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
@wrnexus/ui ships a library of server-rendered .wrn components (layout, form controls, and feedback UI) together with one themeable stylesheet, ui.css. The components are auto-discovered by the framework router — you don't import them in code. Once the package's component directory is on the router's scan path, you mount any component in a page with data-component="<name>". Every visual is driven by var(--wire-*) theme tokens, so components restyle instantly when the theme changes. The tiny JS surface (src/index.ts) exists only so the toolchain (CLI build + dev server) can locate the component directory and stylesheet.
Browse interactive examples and complete component usage in the dedicated WRNexusJS component showcase.
Validated local/S3 uploads and secure file serving.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/uploader@0.7.0Request preview access. Never put registry tokens in source control.
Config-driven file uploads + serving for WRNexusJS. Declare named storage stores (local disk or any S3-compatible backend) in wrnexus.config.ts, upload with one function call, drop a drag-and-drop widget on a page, and serve files back — public or private. Zero external dependencies (S3 is signed with a built-in AWS SigV4 implementation, like the rest of the framework).
Validated local/S3 uploads and secure file serving.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/uploader@0.8.0Request preview access. Never put registry tokens in source control.
Config-driven file uploads + serving for WRNexusJS. Declare named storage stores (local disk or any S3-compatible backend) in wrnexus.config.ts, upload with one function call, drop a drag-and-drop widget on a page, and serve files back — public or private. Zero external dependencies (S3 is signed with a built-in AWS SigV4 implementation, like the rest of the framework).
// wrnexus.config.ts
@@ -88,6 +88,7 @@ await getStore("docs").driver.delete(files[0].key);
import { serveFromStore } from "@wrnexus/uploader";
export const GET = serveFromStore("docs"); // your middleware decides who gets in
Uploads can participate in security and media pipelines without changing storage drivers. Pass a scan hook to reject malware/DLP findings before storage, and afterStore to enqueue image/video processing or indexing. If post-processing throws, WRNexus deletes the newly written object so a partially accepted upload is never left behind.
| Export | What |
|---|---|
handleUpload(opts) | POST route handler → JSON { ok, files } |
upload(store, req, opts) | Parse + validate + store; returns { files } |
serveFromStore(store) | Route handler that streams an object back (gate it for private) |
getStore(name?) / hasStorage(name?) | Reach a store's driver (put/get/delete/publicUrl) |
configureStorage(config, root) | Build the registry (the framework calls this at startup) |
s3Driver / localDriver / signS3 | Lower-level building blocks |
@aws-sdk); tested against local S3 semantics.Live AWS/R2 connectivity depends on your credentials + bucket policy.
Generated from the exact installed package declarations.
import { Context } from '@wrnexus/core';
+
+Helper and component kit
+Use formatFileSize, uploadAccept, uploadedFileMap, uploaderAttributes, and assertUploadedFiles to keep upload forms and server validation consistent.
+Enable uploaderPlugin() for:
+
+<UploadDropzone />
+<UploadStatus />
+
+The complete blocks compose Card, Alert, and Badge from @wrnexus/ui; the specialized upload runtime remains responsible for the native file input and secure transport behavior. Large files can use createResumableUploadManager. Sessions are bounded and expiring; chunks may arrive out of order, carry SHA-256 checksums, and are idempotent when retried. Conflicting retries reject, and the object is assembled only after every exact-sized chunk is present.
+const uploads = createResumableUploadManager({
+ driver: getStore("documents").driver,
+ sessions: redisUploadSessionStore,
+ chunkSize: 5 * 1024 * 1024,
+ maxBytes: 500 * 1024 * 1024,
+ accept: ["application/pdf"],
+});
+
+const session = await uploads.create({ name: "report.pdf", size, type });
+await uploads.uploadChunk(session.id, index, bytes, sha256);
+The included memory session store is intended for one-process apps and tests. Multi-instance production deployments should implement ResumableSessionStore with shared durable storage and atomic session updates, and periodically call prune() for abandoned uploads.
Generated from the exact installed package declarations.
import { Context } from '@wrnexus/core';
+export { UploaderPluginOptions, uploaderComponentsDir, default as uploaderPlugin } from './plugin.js';
+import '@wrnexus/plugin';
/**
* Storage driver contract + config types.
@@ -227,6 +249,25 @@ interface UploadOptions {
accept?: string[];
/** Key prefix, e.g. `"avatars"` → keys become `avatars/<yyyy>/<mm>/<rand>.<ext>`. */
prefix?: string;
+ /** Virus/DLP/content scanner invoked before bytes enter storage. Throw or return unsafe to reject. */
+ scan?: (file: UploadScanInput) => UploadScanResult | Promise<UploadScanResult>;
+ /** Image/video/indexing hook invoked after storage. Failure removes the just-written object. */
+ afterStore?: (file: UploadedFile & {
+ bytes: Uint8Array;
+ store: Store;
+ }) => void | Promise<void>;
+}
+interface UploadScanInput {
+ name: string;
+ type: string;
+ size: number;
+ bytes: Uint8Array;
+ store: Store;
+}
+interface UploadScanResult {
+ safe: boolean;
+ reason?: string;
+ scanner?: string;
}
/** A 4xx-carrying error so `handleUpload` can map it to a status. */
declare class UploadError extends Error {
@@ -401,7 +442,145 @@ interface SignedFileToken {
declare function createSignedFileToken(input: SignedFileToken, secret: string): Promise<string>;
declare function verifySignedFileToken(token: string, secret: string, now?: number): Promise<SignedFileToken | null>;
-export { type LocalStoreConfig, type PutMeta, type S3StoreConfig, type SignedFileToken, type StorageConfig, type StorageDriver, type Store, type StoreAccess, type StoreConfig, type StoredObject, UPLOADS_PREFIX, UPLOAD_JS_HREF, UPLOAD_RUNTIME, UploadError, type UploadInspection, type UploadOptions, type UploadPolicy, UploadPolicyError, type UploadedFile, accepts, configureStorage, contentTypeOf, createSignedFileToken, encodeKey, enforceUploadPolicy, extForType, extOf, getStore, handleUpload, hasStorage, inspectUpload, localDriver, s3Driver, safeObjectKey, serveFromStore, serveStoredFile, sha256Hex, signS3, sniffContentType, storeNames, storedUrl, upload, verifySignedFileToken };
+declare function formatFileSize(bytes: number, locale?: string): string;
+declare function uploadAccept(value: string | readonly string[]): string;
+declare function uploadedFileMap(files: readonly UploadedFile[]): Record<string, UploadedFile>;
+declare function uploaderAttributes(options?: {
+ store?: string;
+ endpoint?: string;
+ accept?: string | readonly string[];
+ maxBytes?: number;
+ multiple?: boolean;
+ field?: string;
+ label?: string;
+}): Record<string, string | boolean>;
+declare function assertUploadedFiles(files: readonly UploadedFile[], options?: {
+ min?: number;
+ max?: number;
+}): readonly UploadedFile[];
+
+interface ResumableUploadSession {
+ id: string;
+ key: string;
+ name: string;
+ type: string;
+ size: number;
+ chunkSize: number;
+ totalChunks: number;
+ createdAt: number;
+ expiresAt: number;
+ chunks: Record<number, Uint8Array>;
+ digests: Record<number, string>;
+}
+interface ResumableSessionStore {
+ get(id: string): Promise<ResumableUploadSession | null>;
+ put(session: ResumableUploadSession): Promise<void>;
+ delete(id: string): Promise<void>;
+ list(): Promise<ResumableUploadSession[]>;
+}
+declare function memoryResumableSessionStore(): ResumableSessionStore;
+interface ResumableUploadManagerOptions {
+ driver: StorageDriver;
+ sessions?: ResumableSessionStore;
+ maxBytes?: number;
+ chunkSize?: number;
+ maxSessions?: number;
+ ttlMs?: number;
+ accept?: string[];
+ prefix?: string;
+ publicUrl?: (key: string) => string | null;
+ now?: () => number;
+}
+interface CreateResumableUpload {
+ name: string;
+ type?: string;
+ size: number;
+ chunkSize?: number;
+}
+interface ResumableChunkResult {
+ receivedChunks: number;
+ totalChunks: number;
+ complete: boolean;
+ file?: UploadedFile;
+}
+interface ResumableUploadManager {
+ create(input: CreateResumableUpload): Promise<ResumableUploadSession>;
+ uploadChunk(id: string, index: number, data: Uint8Array, sha256?: string): Promise<ResumableChunkResult>;
+ status(id: string): Promise<{
+ received: number[];
+ totalChunks: number;
+ expiresAt: number;
+ } | null>;
+ cancel(id: string): Promise<boolean>;
+ prune(): Promise<number>;
+}
+declare function createResumableUploadManager(options: ResumableUploadManagerOptions): ResumableUploadManager;
+
+interface QuotaUsage {
+ owner: string;
+ bytes: number;
+ objects: number;
+ updatedAt: number;
+}
+interface QuotaStore {
+ get(owner: string): Promise<QuotaUsage>;
+ reserve(owner: string, bytes: number, limits: {
+ bytes: number;
+ objects?: number;
+ }): Promise<boolean>;
+ release(owner: string, bytes: number): Promise<void>;
+}
+declare function memoryQuotaStore(): QuotaStore;
+interface QuotaSqlClient {
+ query<T = any>(sql: string, parameters?: unknown[]): Promise<{
+ rows: T[];
+ }>;
+}
+/** PostgreSQL quota accounting using a single atomic conditional upsert. */
+declare function postgresQuotaStore(db: QuotaSqlClient, table?: string): QuotaStore;
+declare const POSTGRES_QUOTA_SCHEMA = "CREATE TABLE IF NOT EXISTS wrnexus_storage_quota (owner text PRIMARY KEY, bytes bigint NOT NULL DEFAULT 0, objects integer NOT NULL DEFAULT 0, updated_at bigint NOT NULL);";
+interface MultipartObjectClient {
+ create(key: string, meta: PutMeta): Promise<string>;
+ uploadPart(uploadId: string, key: string, part: number, bytes: Uint8Array): Promise<string>;
+ complete(uploadId: string, key: string, parts: Array<{
+ part: number;
+ etag: string;
+ }>): Promise<void>;
+ abort(uploadId: string, key: string): Promise<void>;
+}
+declare function multipartUpload(client: MultipartObjectClient, key: string, bytes: Uint8Array, meta: PutMeta, options?: {
+ partBytes?: number;
+ concurrency?: number;
+}): Promise<void>;
+interface TemporaryObject {
+ key: string;
+ expiresAt: number;
+}
+declare function createTemporaryObjectCleaner(driver: StorageDriver, options?: {
+ now?: () => number;
+ limit?: number;
+}): {
+ track(key: string, ttlMs: number): void;
+ cleanup(at?: number): Promise<number>;
+ snapshot: () => {
+ tracked: number;
+ nextExpiry: number | undefined;
+ };
+};
+interface VideoTranscodeOptions {
+ format: "mp4" | "webm";
+ width?: number;
+ height?: number;
+ videoBitrateKbps?: number;
+}
+declare function ffmpegVideoTranscoder(options?: {
+ executable?: string;
+ spawn?: (args: string[]) => {
+ exited: Promise<number>;
+ };
+}): (input: string, output: string, config: VideoTranscodeOptions) => Promise<void>;
+
+export { type CreateResumableUpload, type LocalStoreConfig, type MultipartObjectClient, POSTGRES_QUOTA_SCHEMA, type PutMeta, type QuotaSqlClient, type QuotaStore, type QuotaUsage, type ResumableChunkResult, type ResumableSessionStore, type ResumableUploadManager, type ResumableUploadManagerOptions, type ResumableUploadSession, type S3StoreConfig, type SignedFileToken, type StorageConfig, type StorageDriver, type Store, type StoreAccess, type StoreConfig, type StoredObject, type TemporaryObject, UPLOADS_PREFIX, UPLOAD_JS_HREF, UPLOAD_RUNTIME, UploadError, type UploadInspection, type UploadOptions, type UploadPolicy, UploadPolicyError, type UploadScanInput, type UploadScanResult, type UploadedFile, type VideoTranscodeOptions, accepts, assertUploadedFiles, configureStorage, contentTypeOf, createResumableUploadManager, createSignedFileToken, createTemporaryObjectCleaner, encodeKey, enforceUploadPolicy, extForType, extOf, ffmpegVideoTranscoder, formatFileSize, getStore, handleUpload, hasStorage, inspectUpload, localDriver, memoryQuotaStore, memoryResumableSessionStore, multipartUpload, postgresQuotaStore, s3Driver, safeObjectKey, serveFromStore, serveStoredFile, sha256Hex, signS3, sniffContentType, storeNames, storedUrl, upload, uploadAccept, uploadedFileMap, uploaderAttributes, verifySignedFileToken };
Copy-ready examples from the installed package documentation.
// wrnexus.config.ts
import type { AppConfig } from "@wrnexus/styles";
@@ -451,9 +630,9 @@ await getStore("docs").driver.delete(files[0].key);// app/api/files/[key].ts
import { serveFromStore } from "@wrnexus/uploader";
export const GET = serveFromStore("docs"); // your middleware decides who gets inTyped schemas, coercion, validation, and browser descriptors.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/validation@0.7.0Request preview access. Never put registry tokens in source control.
One fluent schema, validated on the server (API bodies, env vars) and mirrored to an eval-free browser validator for forms.+
Typed schemas, coercion, validation, and browser descriptors.
After WorkRoot approves private registry access, install the release-aligned package:
bun add @wrnexus/validation@0.8.0Request preview access. Never put registry tokens in source control.
One fluent schema, validated on the server (API bodies, env vars) and mirrored to an eval-free browser validator for forms.
Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.
+Use ContractRegistry with defineContract or defineEvent to publish the same schema descriptors for APIs, actions, webhooks, realtime, queues, cron, pub/sub, plugins, configuration, and environment variables.
import { ContractRegistry, defineEvent, v } from "@wrnexus/validation";
+
+export const contracts = new ContractRegistry().register(
+ defineEvent({
+ name: "user.created",
+ version: 1,
+ consumers: ["notification-worker", "audit-service"],
+ payload: v.object({ userId: v.string().uuid(), createdAt: v.string().date() }),
+ }),
+);
+Export the registry from app/contracts.ts, then accept a baseline with wrnexus contracts snapshot. CI can run wrnexus contracts check; removed contracts/fields, required-field additions, type changes, narrowed enums, and tighter validation fail with stable WRN-CONTRACT-* diagnostics and list known consumers. A generated wrnexus.contracts.json can be used instead of a module.
Define a schema once with the fluent v builder, then reuse it in three places: .parse() runs server-side and returns coerced values plus per-field errors; .describe() emits a plain-JSON SchemaDescriptor that the browser runtime interprets (no eval, no bundled validator); and helpers like parseBody and parseEnv wire schemas straight into API routes and startup config. The server rule logic (applyRule/checkField) and the client runtime (VALIDATE_RUNTIME) mirror each other exactly, so a form validates identically in both places. Schemas are conventionally kept in app/schemas/.
bun add @wrnexus/validation
@@ -128,7 +141,46 @@ const head = `<script>${renderSchemasScript({ signup: signupSche
refine) run only server-side and are never serialized — client and server agree on every other rule because both interpret the same RuleDescriptor list.src/index.ts) executed directly by Bun.@wrnexus/core) for route handlers and the SSR layer that injects renderSchemasScript / VALIDATE_RUNTIME.Generated from the exact installed package declarations.
/**
+
+Helper and component kit
+The public helper API includes parseOrThrow, ValidationError, validationResponse, firstValidationError, validationSummary, and schemaFieldNames.
+Schema output is inferred automatically by ObjectSchema, parseOrThrow, parseBody, parseEnv, and asyncSchema. Use InferSchema<typeof schema> when a named output type is useful:
+const accountSchema = v.object({
+ email: v.string().email(),
+ attempts: v.number().integer(),
+});
+
+type AccountInput = InferSchema<typeof accountSchema>;
+const account = parseOrThrow(accountSchema, input);
+// account.email: string
+// account.attempts: number
+Enable validationPlugin() for:
+
+<ValidationSummary />
+<FieldError />
+
+The summary block composes Alert from @wrnexus/ui, while FieldError remains a lightweight accessible field-level primitive. Schemas can drive external contracts without maintaining a second definition:
+import {
+ localizeDescriptor,
+ openApiRequestBody,
+ parseDescriptor,
+ toJsonSchema,
+} from "@wrnexus/validation";
+
+const jsonSchema = toJsonSchema(contactSchema, {
+ id: "urn:example:contact",
+ title: "Contact request",
+});
+const requestBody = openApiRequestBody(contactSchema);
+
+const mr = localizeDescriptor(contactSchema, (key, params) =>
+ translations.t(`validation.${key}`, params),
+);
+const result = parseDescriptor(mr, input);
+JSON Schema output targets draft 2020-12, closes unknown object properties, and maps lengths/ranges/formats/enums/patterns/integer rules. OpenAPI request bodies reuse the same properties. Localized descriptors preserve explicit custom messages and fill default required, type-coercion, and rule messages; the same descriptor is consumable by server parsing and the eval-free browser runtime.
Generated from the exact installed package declarations.
export { ValidationPluginOptions, validationComponentsDir, default as validationPlugin } from './plugin.js';
+import '@wrnexus/plugin';
+
+/**
* Client-side validation. `renderSchemasScript` bakes the discovered schema
* descriptors into `window.__wireSchemas`; `VALIDATE_RUNTIME` is a generic,
* eval-free validator that reads them and validates every `form[data-schema]`
@@ -146,16 +198,16 @@ interface AsyncValidationContext<T> {
signal?: AbortSignal;
}
type AsyncRefinement<T> = (context: AsyncValidationContext<T>) => void | Promise<void>;
-declare class AsyncObjectSchema<T extends Record<string, unknown> = Record<string, unknown>> {
+declare class AsyncObjectSchema<T extends object = Record<string, unknown>> {
#private;
- readonly base: ObjectSchema;
- constructor(base: ObjectSchema);
+ readonly base: ObjectSchema<T>;
+ constructor(base: ObjectSchema<T>);
refine(refinement: AsyncRefinement<T>): this;
describe(): SchemaDescriptor;
parse(input: unknown, signal?: AbortSignal): Promise<ParseResult<T>>;
}
-declare function asyncSchema<T extends Record<string, unknown> = Record<string, unknown>>(schema: ObjectSchema): AsyncObjectSchema<T>;
-declare function parseBodyAsync<T extends Record<string, unknown>>(schema: AsyncObjectSchema<T>, request: Request, signal?: AbortSignal): Promise<{
+declare function asyncSchema<T extends object>(schema: ObjectSchema<T>): AsyncObjectSchema<T>;
+declare function parseBodyAsync<T extends object>(schema: AsyncObjectSchema<T>, request: Request, signal?: AbortSignal): Promise<{
ok: true;
value: T;
} | {
@@ -170,6 +222,99 @@ interface OpenApiSchema {
declare function schemaToOpenApi(schema: ObjectSchema | AsyncObjectSchema): OpenApiSchema;
declare function mergeValidationResults<T>(...results: ParseResult<T>[]): ParseResult<T>;
+declare class ValidationError<T = Record<string, unknown>> extends Error {
+ readonly result: ParseResult<T>;
+ constructor(result: ParseResult<T>);
+}
+declare function parseOrThrow<T extends object>(schema: ObjectSchema<T>, input: unknown): T;
+declare function validationResponse(result: ParseResult, options?: {
+ successStatus?: number;
+ failureStatus?: number;
+}): Response;
+declare function firstValidationError(errors: Record<string, string>): string | null;
+declare function validationSummary(errors: Record<string, string>): Array<{
+ field: string;
+ message: string;
+}>;
+declare function schemaFieldNames(schema: ObjectSchema | SchemaDescriptor): string[];
+
+interface JsonSchemaDocument {
+ $schema: "https://json-schema.org/draft/2020-12/schema";
+ $id?: string;
+ title?: string;
+ type: "object";
+ properties: Record<string, Record<string, unknown>>;
+ required?: string[];
+ additionalProperties: false;
+}
+declare function toJsonSchema(schema: ObjectSchema | SchemaDescriptor, options?: {
+ id?: string;
+ title?: string;
+}): JsonSchemaDocument;
+declare function openApiRequestBody(schema: ObjectSchema | SchemaDescriptor, options?: {
+ description?: string;
+ required?: boolean;
+ contentTypes?: string[];
+}): {
+ required: boolean;
+ content: {
+ [k: string]: {
+ schema: {
+ $id?: string;
+ title?: string;
+ type: "object";
+ properties: Record<string, Record<string, unknown>>;
+ required?: string[];
+ additionalProperties: false;
+ };
+ };
+ };
+ description?: string | undefined;
+};
+type ValidationMessageKey = "required" | "number" | `rule.${RuleDescriptor["kind"]}`;
+type ValidationMessageTranslator = (key: ValidationMessageKey, params: Record<string, unknown>) => string;
+declare function localizeDescriptor(schema: ObjectSchema | SchemaDescriptor, translate: ValidationMessageTranslator): SchemaDescriptor;
+declare function parseDescriptor<T = Record<string, unknown>>(descriptor: SchemaDescriptor, source: Record<string, unknown>): ParseResult<T>;
+
+type ContractKind = "api" | "action" | "webhook" | "realtime" | "queue" | "cron" | "pubsub" | "plugin" | "config" | "env";
+interface ContractDefinition<T extends object = Record<string, unknown>> {
+ kind: ContractKind;
+ name: string;
+ version: number;
+ payload: ObjectSchema<T> | SchemaDescriptor;
+ consumers?: string[];
+ description?: string;
+}
+interface ContractRecord {
+ kind: ContractKind;
+ name: string;
+ version: number;
+ payload: SchemaDescriptor;
+ consumers: string[];
+ description?: string;
+}
+interface ContractSnapshot {
+ format: 1;
+ contracts: ContractRecord[];
+}
+interface ContractIssue {
+ code: "WRN-CONTRACT-REMOVED" | "WRN-CONTRACT-FIELD-REMOVED" | "WRN-CONTRACT-FIELD-REQUIRED" | "WRN-CONTRACT-FIELD-TYPE" | "WRN-CONTRACT-RULE-TIGHTENED";
+ contract: string;
+ field?: string;
+ message: string;
+ consumers: string[];
+}
+declare function defineContract<T extends object>(definition: ContractDefinition<T>): ContractDefinition<T>;
+declare function defineEvent<T extends object>(definition: Omit<ContractDefinition<T>, "kind"> & {
+ kind?: "realtime" | "pubsub";
+}): ContractDefinition<T>;
+declare class ContractRegistry {
+ private readonly records;
+ register<T extends object>(definition: ContractDefinition<T>): this;
+ snapshot(): ContractSnapshot;
+}
+declare function checkContractCompatibility(previous: ContractSnapshot, current: ContractSnapshot): ContractIssue[];
+
/**
* @wrnexus/validation — one schema, validated on the server (API) and the browser
* (forms). A schema is a fluent builder; `.parse()` runs server-side and returns
@@ -218,6 +363,8 @@ interface FieldDescriptor {
optional?: boolean;
/** Message used when a required field is empty. Defaults to "Required". */
requiredMessage?: string;
+ /** Message used when coercion to the declared type fails. */
+ typeMessage?: string;
label?: string;
/** Trim string input before validating. */
trim?: boolean;
@@ -274,7 +421,9 @@ declare abstract class FieldSchema {
runRefinements(value: unknown): string | null;
describe(): FieldDescriptor;
}
-declare class StringSchema extends FieldSchema {
+declare class StringSchema<TValue extends string = string> extends FieldSchema {
+ /** Type-only marker used to preserve literal unions through schema inference. */
+ readonly __value: TValue;
readonly type: "string";
private _trim;
email(message?: string): this;
@@ -282,16 +431,18 @@ declare class StringSchema extends FieldSchema {
uuid(message?: string): this;
date(message?: string): this;
length(n: number, message?: string): this;
- oneOf(values: string[], message?: string): this;
+ oneOf<const TValues extends readonly string[]>(values: TValues, message?: string): StringSchema<TValues extends readonly [string, ...string[]] ? TValues[number] : TValue>;
trim(): this;
pattern(re: RegExp, message?: string): this;
describe(): FieldDescriptor;
}
-declare class NumberSchema extends FieldSchema {
+declare class NumberSchema<TValue extends number = number> extends FieldSchema {
+ /** Type-only marker used to preserve numeric literal unions through schema inference. */
+ readonly __value: TValue;
readonly type: "number";
integer(message?: string): this;
positive(message?: string): this;
- oneOf(values: number[], message?: string): this;
+ oneOf<const TValues extends readonly number[]>(values: TValues, message?: string): NumberSchema<TValues extends readonly [number, ...number[]] ? TValues[number] : TValue>;
}
declare class BooleanSchema extends FieldSchema {
readonly type: "boolean";
@@ -299,27 +450,37 @@ declare class BooleanSchema extends FieldSchema {
declare class UnknownSchema extends FieldSchema {
readonly type: "unknown";
}
-type AnyFieldSchema = StringSchema | NumberSchema | BooleanSchema | UnknownSchema;
-declare class ObjectSchema {
+type AnyFieldSchema = StringSchema<string> | NumberSchema<number> | BooleanSchema | UnknownSchema;
+/** Infer the runtime value produced by a field schema. */
+type InferFieldValue<TField extends FieldSchema> = TField extends StringSchema<infer TValue> ? TValue : TField extends NumberSchema<infer TValue> ? TValue : TField extends BooleanSchema ? boolean : unknown;
+/** Infer the validated object produced by a field map. */
+type InferObjectFields<TFields extends Record<string, FieldSchema>> = {
+ [K in keyof TFields]: InferFieldValue<TFields[K]>;
+};
+/** Infer the object value produced by an object schema. */
+type InferSchema<TSchema extends ObjectSchema> = TSchema extends ObjectSchema<infer TValue> ? TValue : never;
+declare class ObjectSchema<TValue extends object = Record<string, unknown>> {
private readonly fields;
+ /** Type-only marker used by helper functions to infer validated output. */
+ readonly __output: TValue;
constructor(fields: Record<string, FieldSchema>);
/** Return a defensive copy of the schema fields. */
getFields(): Readonly<Record<string, FieldSchema>>;
/** Create a new schema with fields added or replaced. The original is unchanged. */
- extend(fields: Record<string, FieldSchema>): ObjectSchema;
+ extend<TFields extends Record<string, FieldSchema>>(fields: TFields): ObjectSchema<Omit<TValue, keyof TFields> & InferObjectFields<TFields>>;
/** Create a new schema containing fields from both schemas. */
- merge(schema: ObjectSchema): ObjectSchema;
+ merge<TOther extends object>(schema: ObjectSchema<TOther>): ObjectSchema<TValue & TOther>;
/** Validate an input object; returns coerced values + per-field errors. */
- parse(input: unknown): ParseResult;
+ parse(input: unknown): ParseResult<TValue>;
describe(): SchemaDescriptor;
}
/** The fluent schema builder. */
declare const v: {
- string: () => StringSchema;
- number: () => NumberSchema;
+ string: () => StringSchema<string>;
+ number: () => NumberSchema<number>;
boolean: () => BooleanSchema;
unknown: () => UnknownSchema;
- object: (fields: Record<string, FieldSchema>) => ObjectSchema;
+ object: <TFields extends Record<string, FieldSchema>>(fields: TFields) => ObjectSchema<InferObjectFields<TFields>>;
};
/**
* Validate environment variables against a schema at startup. Values are read
@@ -333,14 +494,14 @@ declare const v: {
* PORT: v.number(),
* }));
*/
-declare function parseEnv<T = Record<string, unknown>>(schema: ObjectSchema, source?: Record<string, string | undefined>): T;
+declare function parseEnv<T extends object>(schema: ObjectSchema<T>, source?: Record<string, string | undefined>): T;
/** A 400 response carrying field errors, for API routes. */
declare function invalid(errors: Record<string, string>): Response;
/**
* Parse a request's JSON body against a schema. On failure returns
* `{ ok: false, response }` (a ready 400); on success `{ ok: true, value }`.
*/
-declare function parseBody<T = Record<string, unknown>>(schema: ObjectSchema, req: Request): Promise<{
+declare function parseBody<T extends object>(schema: ObjectSchema<T>, req: Request): Promise<{
ok: true;
value: T;
} | {
@@ -348,7 +509,7 @@ declare function parseBody<T = Record<string, unknown>>(schema: Obje
response: Response;
}>;
-export { type AnyFieldSchema, AsyncObjectSchema, type AsyncRefinement, type AsyncValidationContext, BooleanSchema, type FieldDescriptor, FieldSchema, NumberSchema, ObjectSchema, type OpenApiSchema, type ParseResult, type RuleDescriptor, type SchemaDescriptor, StringSchema, UnknownSchema, VALIDATE_RUNTIME, applyRule, asyncSchema, checkField, invalid, mergeValidationResults, parseBody, parseBodyAsync, parseEnv, renderSchemasScript, schemaToOpenApi, v };
+export { type AnyFieldSchema, AsyncObjectSchema, type AsyncRefinement, type AsyncValidationContext, BooleanSchema, type ContractDefinition, type ContractIssue, type ContractKind, type ContractRecord, ContractRegistry, type ContractSnapshot, type FieldDescriptor, FieldSchema, type InferFieldValue, type InferObjectFields, type InferSchema, type JsonSchemaDocument, NumberSchema, ObjectSchema, type OpenApiSchema, type ParseResult, type RuleDescriptor, type SchemaDescriptor, StringSchema, UnknownSchema, VALIDATE_RUNTIME, ValidationError, type ValidationMessageKey, type ValidationMessageTranslator, applyRule, asyncSchema, checkContractCompatibility, checkField, defineContract, defineEvent, firstValidationError, invalid, localizeDescriptor, mergeValidationResults, openApiRequestBody, parseBody, parseBodyAsync, parseDescriptor, parseEnv, parseOrThrow, renderSchemasScript, schemaFieldNames, schemaToOpenApi, toJsonSchema, v, validationResponse, validationSummary };
Copy-ready examples from the installed package documentation.
import { v, parseBody } from "@wrnexus/validation";
export const signupSchema = v.object({
@@ -382,9 +543,9 @@ import { signupSchema } from "./app/schemas/signup.ts";
const head = `<script>${renderSchemasScript({ signup: signupSchema.describe() })}</script>
<script>${VALIDATE_RUNTIME}</script>`;
// render a <form data-schema="signup"> with [data-error="email"] etc.Released 2026-07-12 in this documentation repository. Twenty-five installed packages are aligned to this version. See the changelog, upgrade guide, and package references.
Released 2026-07-12 in this documentation repository. Twenty-five installed packages are aligned to this version. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 26 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 27 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 29 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 30 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 30 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 31 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 33 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 33 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 38 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 38 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Released 2026-07-13. All 46 installed packages are aligned to this version. Highlights include the new helpers package, reliable workspace app addition, and browser SSO redirects through forward authentication. See the changelog, upgrade guide, and package references.
Roadmap items are direction, not delivery commitments. Dates require explicit owner approval.
This build-time index is local and sends no query to a third party. Use your browser’s find command to filter this compact index.
Get started · Packages · Components · Language · Architecture
Project structure · Routing · Pages and components · Server data · API routes · Middleware · Forms and validation · Authentication · Authorization · Application security · Database · Uploads · Realtime · Pub/sub · Queues · Testing · Workspaces and gateway · Deployment · Configuration and profiles · Internationalization and themes · Mobile · Observability · Upgrading · Troubleshooting
@wrnexus/ai · @wrnexus/authz · @wrnexus/compiler · @wrnexus/core · @wrnexus/csr · @wrnexus/db · @wrnexus/dev-server · @wrnexus/encryption · @wrnexus/helpers · @wrnexus/i18n · @wrnexus/jwt · @wrnexus/mobile · @wrnexus/native · @wrnexus/oauth · @wrnexus/pubsub · @wrnexus/queue · @wrnexus/reactive · @wrnexus/router · @wrnexus/ssr · @wrnexus/styles · @wrnexus/test · @wrnexus/tracking · @wrnexus/ui · @wrnexus/uploader · @wrnexus/validation · @wrnexus/dev-toolbar · @wrnexus/syntax · @wrnexus/plugin · @wrnexus/captcha · @wrnexus/auth · @wrnexus/store · @wrnexus/typecheck · @wrnexus/security · @wrnexus/cache · @wrnexus/image · @wrnexus/observability · @wrnexus/benchmark · @wrnexus/cli
This build-time index is local and sends no query to a third party. Use your browser’s find command to filter this compact index.
Get started · Packages · Components · Language · Architecture
Project structure · Routing · Pages and components · Server data · API routes · Middleware · Forms and validation · Authentication · Authorization · Application security · Database · Uploads · Realtime · Pub/sub · Queues · Testing · Workspaces and gateway · Deployment · Configuration and profiles · Internationalization and themes · Mobile · Observability · Upgrading · Troubleshooting
@wrnexus/ai · @wrnexus/authz · @wrnexus/compiler · @wrnexus/core · @wrnexus/csr · @wrnexus/db · @wrnexus/dev-server · @wrnexus/encryption · @wrnexus/helpers · @wrnexus/i18n · @wrnexus/jwt · @wrnexus/mobile · @wrnexus/native · @wrnexus/oauth · @wrnexus/pubsub · @wrnexus/queue · @wrnexus/reactive · @wrnexus/router · @wrnexus/ssr · @wrnexus/styles · @wrnexus/test · @wrnexus/tracking · @wrnexus/ui · @wrnexus/uploader · @wrnexus/validation · @wrnexus/dev-toolbar · @wrnexus/syntax · @wrnexus/plugin · @wrnexus/captcha · @wrnexus/auth · @wrnexus/store · @wrnexus/typecheck · @wrnexus/security · @wrnexus/cache · @wrnexus/image · @wrnexus/observability · @wrnexus/benchmark · @wrnexus/realtime · @wrnexus/content · @wrnexus/graphql · @wrnexus/identity · @wrnexus/language-server · @wrnexus/mcp · @wrnexus/playground · @wrnexus/pwa · @wrnexus/cli
WRNexusJS provides primitives for CSP, CSRF, Trusted Types, sessions, validation, authorization, encryption, upload restrictions, request limits, and WebSocket-origin checks. Applications remain responsible for correct configuration, business authorization, secrets, dependencies, data protection, and operations.
Only the current private-preview release 0.7.0 is documented here. A formal old-release support window is not yet published.
Use WorkRoot’s approved private contact path at workroot.in. Do not publish exploit details or secrets. Include affected version, impact, reproduction, and a safe contact method. Response targets, encryption key, bounty, audit, and certification are not currently claimed.
Use restrictive CSP and permissions policies, HSTS only on HTTPS production origins, MIME sniffing protection, restrictive referrers, explicit CORS, secure cookies, CSRF validation, request limits, and origin checks. See application security.
WRNexusJS provides primitives for CSP, CSRF, Trusted Types, sessions, validation, authorization, encryption, upload restrictions, request limits, and WebSocket-origin checks. Applications remain responsible for correct configuration, business authorization, secrets, dependencies, data protection, and operations.
Only the current private-preview release 0.8.0 is documented here. A formal old-release support window is not yet published.
Use WorkRoot’s approved private contact path at workroot.in. Do not publish exploit details or secrets. Include affected version, impact, reproduction, and a safe contact method. Response targets, encryption key, bounty, audit, and certification are not currently claimed.
Use restrictive CSP and permissions policies, HSTS only on HTTPS production origins, MIME sniffing protection, restrictive referrers, explicit CORS, secure cookies, CSRF validation, request limits, and origin checks. See application security.
Only confirmed public properties are listed; no customer or traffic claims are made.
Creator/company site demonstrating a public WRNexusJS deployment. Exact deployed version and infrastructure notes await owner confirmation.
This documentation portal, built and verified against WRNexusJS 0.7.0 on Bun.
Screenshots are intentionally deferred until approved assets and alt text are available.
Only confirmed public properties are listed; no customer or traffic claims are made.
Creator/company site demonstrating a public WRNexusJS deployment. Exact deployed version and infrastructure notes await owner confirmation.
This documentation portal, built and verified against WRNexusJS 0.8.0 on Bun.
Screenshots are intentionally deferred until approved assets and alt text are available.
WRNexusJS has no public Discord, public issue tracker, or guaranteed community support channel listed by this repository. Preview access and support begin through WorkRoot’s public contact path.
Include WRNexusJS version, Bun version, OS, a minimal reproduction, expected and actual behavior, and sanitized logs. Never include registry tokens, credentials, session cookies, or private data.
Support scope, service levels, and commercial terms require owner confirmation.
This tutorial connects the installed 0.7.0 APIs into one design. Snippets are limited to declarations and README patterns verified in the installed packages; a CI-compiled standalone fixture remains on the roadmap.
A .wrn page renders tasks from an SSR API binding. A shared validation schema protects mutations. Session middleware identifies users, authorization policies gate updates, and a realtime room broadcasts changes.
import { v, parseBody } from "@wrnexus/validation";
+ Preview · runnable-project extraction pendingSecure task board
This tutorial connects the installed 0.8.0 APIs into one design. Snippets are limited to declarations and README patterns verified in the installed packages; a CI-compiled standalone fixture remains on the roadmap.
Application shape
A .wrn page renders tasks from an SSR API binding. A shared validation schema protects mutations. Session middleware identifies users, authorization policies gate updates, and a realtime room broadcasts changes.
Schema and create route
import { v, parseBody } from "@wrnexus/validation";
const task = v.object({ title: v.string().trim().min(3).max(120) });
export const POST = async (ctx) => {
const parsed = await parseBody(task, ctx.req);
@@ -23,7 +23,7 @@ export const POST = async (ctx) => {
</ul></main>
}
}
Production checklist
- Choose SQLite for local development or configure the supported PostgreSQL driver.
- Run migrations before accepting traffic.
- Enable session authentication and enforce authorization on every mutation.
- Validate upload types and sizes; keep private objects behind authenticated routes.
- Use Redis pub/sub when realtime rooms span processes.
- Treat the default queue as non-durable until a production driver is selected.
Follow the focused database, authentication, authorization, realtime, and upload guides.
-
+
= P extends keyof RouteQueries
+ ? RouteQueries[P]
+ : Record (
path: P,
- ...args: Routes[P] extends Record