diff --git a/app/pages/404.wrn b/app/pages/404.wrn index 701c9c81..891e58d8 100644 --- a/app/pages/404.wrn +++ b/app/pages/404.wrn @@ -7,10 +7,10 @@ page Pagenotfound { view {
-
W WRNexusJS
+
W WRNexusJS
- +
} diff --git a/app/pages/access.wrn b/app/pages/access.wrn index 52519ce7..b4730aee 100644 --- a/app/pages/access.wrn +++ b/app/pages/access.wrn @@ -7,10 +7,10 @@ page Access { view {
-
W WRNexusJS
+
W WRNexusJS
-

Request preview access

WRNexusJS 0.3.6 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.

Request process

  1. Contact WorkRoot through the public contact path at workroot.in.
  2. Describe the application, team, expected deployment, and Bun environment.
  3. After approval, follow the registry instructions supplied privately.
  4. Use the canonical scaffold command below only after authentication.
bunx @wrnexus/cli@0.3.6 create my-app

Access approval, response time, licensing terms, and support level remain owner-controlled. This site does not collect access requests directly.

- +

Request preview access

WRNexusJS 0.4.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.

Request process

  1. Contact WorkRoot through the public contact path at workroot.in.
  2. Describe the application, team, expected deployment, and Bun environment.
  3. After approval, follow the registry instructions supplied privately.
  4. Use the canonical scaffold command below only after authentication.
bunx @wrnexus/cli@0.4.0 create my-app

Access approval, response time, licensing terms, and support level remain owner-controlled. This site does not collect access requests directly.

+
} diff --git a/app/pages/architecture.wrn b/app/pages/architecture.wrn index 6439d063..1a56ecda 100644 --- a/app/pages/architecture.wrn +++ b/app/pages/architecture.wrn @@ -7,10 +7,10 @@ page Architecture { view {
-
W WRNexusJS
+
W WRNexusJS
-
Framework architecture · 0.3.6

Architecture

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.

Request and build lifecycle

  1. DiscoverPages, APIs, middleware, components, layouts, schemas, rooms
  2. CompileParse .wrn, validate grammar, generate server code
  3. RequestLimits, security, locale, session, middleware
  4. MatchStatic and dynamic file route
  5. RenderSSR data, escaped interpolation, components, metadata
  6. EnhanceOnly required reactive/directive runtimes

Package boundaries

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.

Security and data flow

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.

Realtime and scale

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.

Workspaces and gateways

The gateway can dispatch multiple applications while preserving route, component, asset, config, and session boundaries. Validate host routing and isolation before production.

Build and deployment

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

Mobile compatibility bridges SSR-safe Capacitor capabilities; native route generation is experimental and is not general web portability. Test each target platform.

Generated files and limits

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.

- +
Framework architecture · 0.4.0

Architecture

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.

Request and build lifecycle

  1. DiscoverPages, APIs, middleware, components, layouts, schemas, rooms
  2. CompileParse .wrn, validate grammar, generate server code
  3. RequestLimits, security, locale, session, middleware
  4. MatchStatic and dynamic file route
  5. RenderSSR data, escaped interpolation, components, metadata
  6. EnhanceOnly required reactive/directive runtimes

Package boundaries

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.

Security and data flow

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.

Realtime and scale

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.

Workspaces and gateways

The gateway can dispatch multiple applications while preserving route, component, asset, config, and session boundaries. Validate host routing and isolation before production.

Build and deployment

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

Mobile compatibility bridges SSR-safe Capacitor capabilities; native route generation is experimental and is not general web portability. Test each target platform.

Generated files and limits

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.

+
} diff --git a/app/pages/benchmarks.wrn b/app/pages/benchmarks.wrn index d79ce35e..4ff0f1c5 100644 --- a/app/pages/benchmarks.wrn +++ b/app/pages/benchmarks.wrn @@ -7,10 +7,10 @@ page Benchmarks { view {
-
W WRNexusJS
+
W WRNexusJS

Benchmarks

No publishable benchmark dataset yet

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.

- +
} diff --git a/app/pages/changelog.wrn b/app/pages/changelog.wrn index bb2a115e..199c6662 100644 --- a/app/pages/changelog.wrn +++ b/app/pages/changelog.wrn @@ -7,10 +7,10 @@ page Changelog { view {
-
W WRNexusJS
+
W WRNexusJS
-

Changelog

0.3.6 2026-07-13

Documentation is aligned to all 29 installed packages. This release adds @wrnexus/helpers, original-request URL helpers, safe login redirects, working wrnexus workspace add, and forward-auth redirect propagation.

Migration notes

Run wrnexus update --latest and keep every @wrnexus/* package on 0.3.6. Existing applications must explicitly add @wrnexus/helpers before importing it; newly scaffolded applications include it automatically.

Versioning and support

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.

- +

Changelog

0.4.0 2026-07-13

Documentation is aligned to all 30 installed packages. This release adds @wrnexus/helpers, original-request URL helpers, safe login redirects, working wrnexus workspace add, and forward-auth redirect propagation.

Migration notes

Run wrnexus update --latest and keep every @wrnexus/* package on 0.4.0. Existing applications must explicitly add @wrnexus/helpers before importing it; newly scaffolded applications include it automatically.

Versioning and support

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.

+
} diff --git a/app/pages/components.wrn b/app/pages/components.wrn index 6f9eb105..3c08c765 100644 --- a/app/pages/components.wrn +++ b/app/pages/components.wrn @@ -12,7 +12,7 @@ page Components {
W WRNexusJS - +
@wrnexus/ui · 85 components

Component reference

Production-ready, server-rendered components documented directly from the installed .wrn sources.

Showing {category} components

base

Accordion

Theme-aware, responsive accordion component.

5 props1 slots0 events
View component →
@@ -57,7 +57,7 @@ page Components { layout

Image

Theme-aware, responsive image component.

9 props1 slots0 events
View component →
forms

Input

Theme-aware, responsive input component.

13 props0 slots0 events
View component →
forms

InputGroup

Theme-aware, responsive input group component.

13 props0 slots0 events
View component →
-advanced-forms

InputNumber

Theme-aware, responsive input number component.

13 props0 slots0 events
View component →
+advanced-forms

InputNumber

Theme-aware, responsive input number component.

40 props0 slots4 events
View component →
layout

Kbd

Theme-aware, responsive kbd component.

4 props1 slots0 events
View component →
layout

LayoutSplitter

Theme-aware, responsive layout splitter component.

6 props1 slots0 events
View component →
base

LegendIndicator

Theme-aware, responsive legend indicator component.

7 props1 slots0 events
View component →
@@ -100,7 +100,7 @@ page Components { base

TreeView

Theme-aware, responsive tree view component.

7 props1 slots0 events
View component →
layout

Typography

Theme-aware, responsive typography component.

6 props1 slots0 events
View component →
integrations

WysiwygEditor

Theme-aware, responsive wysiwyg editor component.

7 props1 slots0 events
View component →
- + } diff --git a/app/pages/components/accordion.wrn b/app/pages/components/accordion.wrn index c5cf6bfd..5fceb305 100644 --- a/app/pages/components/accordion.wrn +++ b/app/pages/components/accordion.wrn @@ -10,10 +10,10 @@ page Accordioncomponent {
W WRNexusJS - +
-
base component

Accordion

Theme-aware, responsive accordion component.

@wrnexus/ui 0.3.65 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Accordion
+      
base component

Accordion

Theme-aware, responsive accordion component.

@wrnexus/ui 0.4.05 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Accordion
   size="default"
   color="primary"
   items="[]"
@@ -37,7 +37,7 @@ page Accordioncomponent {
     }
 }
 
- + } diff --git a/app/pages/components/advanced-date-picker.wrn b/app/pages/components/advanced-date-picker.wrn index 69a3161a..2e08537e 100644 --- a/app/pages/components/advanced-date-picker.wrn +++ b/app/pages/components/advanced-date-picker.wrn @@ -10,10 +10,10 @@ page AdvancedDatePickercomponent {
W WRNexusJS - +
-
integrations component

AdvancedDatePicker

Theme-aware, responsive advanced date picker component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedDatePicker
+      
integrations component

AdvancedDatePicker

Theme-aware, responsive advanced date picker component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedDatePicker
   size="default"
   color="primary"
   title="Advanced Date Picker"
@@ -39,7 +39,7 @@ page AdvancedDatePickercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/advanced-range-slider.wrn b/app/pages/components/advanced-range-slider.wrn index a4432829..6a943ed7 100644 --- a/app/pages/components/advanced-range-slider.wrn +++ b/app/pages/components/advanced-range-slider.wrn @@ -10,10 +10,10 @@ page AdvancedRangeSlidercomponent {
W WRNexusJS - +
-
integrations component

AdvancedRangeSlider

Theme-aware, responsive advanced range slider component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedRangeSlider
+      
integrations component

AdvancedRangeSlider

Theme-aware, responsive advanced range slider component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedRangeSlider
   size="default"
   color="primary"
   title="Advanced Range Slider"
@@ -39,7 +39,7 @@ page AdvancedRangeSlidercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/advanced-select.wrn b/app/pages/components/advanced-select.wrn index 1d38feb3..1a03e5bb 100644 --- a/app/pages/components/advanced-select.wrn +++ b/app/pages/components/advanced-select.wrn @@ -10,10 +10,10 @@ page AdvancedSelectcomponent {
W WRNexusJS - +
-
advanced-forms component

AdvancedSelect

Theme-aware, responsive advanced select component.

@wrnexus/ui 0.3.651 props0 slots8 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedSelect
+      
advanced-forms component

AdvancedSelect

Theme-aware, responsive advanced select component.

@wrnexus/ui 0.4.051 props0 slots8 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AdvancedSelect
   size="default"
   color="primary"
   label="Advanced Select"
@@ -486,7 +486,7 @@ page AdvancedSelectcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/alert.wrn b/app/pages/components/alert.wrn index 4d338a6a..cd113258 100644 --- a/app/pages/components/alert.wrn +++ b/app/pages/components/alert.wrn @@ -10,16 +10,16 @@ page Alertcomponent {
W WRNexusJS - +
-
base component

Alert

Theme-aware, responsive alert component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Alert
+      
base component

Alert

Theme-aware, responsive alert component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Alert
   size="default"
   color="primary"
   title="Alert"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="Alert".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Alert"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Alert.wrn

component Alert {
+/>

Legacy mount name: data-component="Alert".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Alert"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/alert.wrn

component Alert {
   props {
     size = "default"
     color = "primary"
@@ -39,7 +39,7 @@ page Alertcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/avatar-group.wrn b/app/pages/components/avatar-group.wrn index cda247d4..e147b2de 100644 --- a/app/pages/components/avatar-group.wrn +++ b/app/pages/components/avatar-group.wrn @@ -10,10 +10,10 @@ page AvatarGroupcomponent {
W WRNexusJS - +
-
base component

AvatarGroup

Theme-aware, responsive avatar group component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AvatarGroup
+      
base component

AvatarGroup

Theme-aware, responsive avatar group component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<AvatarGroup
   size="default"
   color="primary"
   title="Avatar Group"
@@ -39,7 +39,7 @@ page AvatarGroupcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/avatar.wrn b/app/pages/components/avatar.wrn index ebcdf58a..04e528e5 100644 --- a/app/pages/components/avatar.wrn +++ b/app/pages/components/avatar.wrn @@ -10,16 +10,16 @@ page Avatarcomponent {
W WRNexusJS - +
-
base component

Avatar

Theme-aware, responsive avatar component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Avatar
+      
base component

Avatar

Theme-aware, responsive avatar component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Avatar
   size="default"
   color="primary"
   title="Avatar"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="Avatar".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Avatar"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Avatar.wrn

component Avatar {
+/>

Legacy mount name: data-component="Avatar".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Avatar"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/avatar.wrn

component Avatar {
   props {
     size = "default"
     color = "primary"
@@ -39,7 +39,7 @@ page Avatarcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/badge.wrn b/app/pages/components/badge.wrn index 95b99525..849cc6e5 100644 --- a/app/pages/components/badge.wrn +++ b/app/pages/components/badge.wrn @@ -10,16 +10,16 @@ page Badgecomponent {
W WRNexusJS - +
-
base component

Badge

Theme-aware, responsive badge component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Badge
+      
base component

Badge

Theme-aware, responsive badge component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Badge
   size="default"
   color="primary"
   title="Badge"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="Badge".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Badge"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Badge.wrn

component Badge {
+/>

Legacy mount name: data-component="Badge".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Badge"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/badge.wrn

component Badge {
   props {
     size = "default"
     color = "primary"
@@ -39,7 +39,7 @@ page Badgecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/blockquote.wrn b/app/pages/components/blockquote.wrn index 6e744b77..0a28876b 100644 --- a/app/pages/components/blockquote.wrn +++ b/app/pages/components/blockquote.wrn @@ -10,10 +10,10 @@ page Blockquotecomponent {
W WRNexusJS - +
-
base component

Blockquote

Theme-aware, responsive blockquote component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Blockquote
+      
base component

Blockquote

Theme-aware, responsive blockquote component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Blockquote
   size="default"
   color="primary"
   title="Blockquote"
@@ -39,7 +39,7 @@ page Blockquotecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/breadcrumb.wrn b/app/pages/components/breadcrumb.wrn index 935c61e9..0713fabc 100644 --- a/app/pages/components/breadcrumb.wrn +++ b/app/pages/components/breadcrumb.wrn @@ -10,10 +10,10 @@ page Breadcrumbcomponent {
W WRNexusJS - +
-
navigation component

Breadcrumb

Theme-aware, responsive breadcrumb component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Breadcrumb
+      
navigation component

Breadcrumb

Theme-aware, responsive breadcrumb component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Breadcrumb
   size="default"
   color="primary"
   label="Breadcrumb"
@@ -37,7 +37,7 @@ page Breadcrumbcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/button-group.wrn b/app/pages/components/button-group.wrn index 72ce5f76..cfbe786d 100644 --- a/app/pages/components/button-group.wrn +++ b/app/pages/components/button-group.wrn @@ -10,10 +10,10 @@ page ButtonGroupcomponent {
W WRNexusJS - +
-
base component

ButtonGroup

Theme-aware, responsive button group component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ButtonGroup
+      
base component

ButtonGroup

Theme-aware, responsive button group component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ButtonGroup
   size="default"
   color="primary"
   title="Button Group"
@@ -39,7 +39,7 @@ page ButtonGroupcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/button.wrn b/app/pages/components/button.wrn index a4c4d28c..f0e3443a 100644 --- a/app/pages/components/button.wrn +++ b/app/pages/components/button.wrn @@ -10,16 +10,16 @@ page Buttoncomponent {
W WRNexusJS - +
-
base component

Button

Theme-aware, responsive button component.

@wrnexus/ui 0.3.625 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Button
+      
base component

Button

Theme-aware, responsive button component.

@wrnexus/ui 0.4.025 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Button
   label="Button"
   loadingLabel="Loading…"
   description="description"
   as="as"
   href="href"
-/>

Legacy mount name: data-component="Button".

Props and attributes

PropTypeRequirementDefault
labelstringOptional"Button"
loadingLabelstringOptional"Loading…"
descriptionstringOptional""
asstringOptional""
hrefstringOptional""
targetstringOptional""
relstringOptional""
typestringOptional"button"
variantstringOptional"default"
colorstringOptional"primary"
sizestringOptional"default"
disabledbooleanOptionalfalse
loadingbooleanOptionalfalse
pillbooleanOptionalfalse
fullWidthbooleanOptionalfalse
iconstringOptional""
iconPositionstringOptional"start"
ariaLabelstringOptional""
ariaPressedstringOptional""
ariaExpandedstringOptional""
ariaControlsstringOptional""
titlestringOptional""
autofocusbooleanOptionalfalse
controlClassstringOptional""
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Button.wrn

component Button {
+/>

Legacy mount name: data-component="Button".

Props and attributes

PropTypeRequirementDefault
labelstringOptional"Button"
loadingLabelstringOptional"Loading…"
descriptionstringOptional""
asstringOptional""
hrefstringOptional""
targetstringOptional""
relstringOptional""
typestringOptional"button"
variantstringOptional"default"
colorstringOptional"primary"
sizestringOptional"default"
disabledbooleanOptionalfalse
loadingbooleanOptionalfalse
pillbooleanOptionalfalse
fullWidthbooleanOptionalfalse
iconstringOptional""
iconPositionstringOptional"start"
ariaLabelstringOptional""
ariaPressedstringOptional""
ariaExpandedstringOptional""
ariaControlsstringOptional""
titlestringOptional""
autofocusbooleanOptionalfalse
controlClassstringOptional""
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/button.wrn

component Button {
   props {
     label = "Button"
     loadingLabel = "Loading…"
@@ -181,7 +181,7 @@ page Buttoncomponent {
     }
 }
 
- + } diff --git a/app/pages/components/card.wrn b/app/pages/components/card.wrn index 50d6a9da..a8055fb8 100644 --- a/app/pages/components/card.wrn +++ b/app/pages/components/card.wrn @@ -10,16 +10,16 @@ page Cardcomponent {
W WRNexusJS - +
-
base component

Card

Theme-aware, responsive card component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Card
+      
base component

Card

Theme-aware, responsive card component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Card
   size="default"
   color="primary"
   title="Card"
   description="description"
   items="[]"
-/>

Legacy mount name: data-component="Card".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Card"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Card.wrn

component Card {
+/>

Legacy mount name: data-component="Card".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Card"
descriptionstringOptional""
itemsstringOptional[]
variantstringOptional"default"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/card.wrn

component Card {
   props {
     size = "default"
     color = "primary"
@@ -39,7 +39,7 @@ page Cardcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/carousel.wrn b/app/pages/components/carousel.wrn index d4cb0f06..51a4829c 100644 --- a/app/pages/components/carousel.wrn +++ b/app/pages/components/carousel.wrn @@ -10,10 +10,10 @@ page Carouselcomponent {
W WRNexusJS - +
-
base component

Carousel

Theme-aware, responsive carousel component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Carousel
+      
base component

Carousel

Theme-aware, responsive carousel component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Carousel
   size="default"
   color="primary"
   title="Carousel"
@@ -39,7 +39,7 @@ page Carouselcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/chart.wrn b/app/pages/components/chart.wrn index 2365c6c3..22f3eb91 100644 --- a/app/pages/components/chart.wrn +++ b/app/pages/components/chart.wrn @@ -10,10 +10,10 @@ page Chartcomponent {
W WRNexusJS - +
-
integrations component

Chart

Theme-aware, responsive chart component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Chart
+      
integrations component

Chart

Theme-aware, responsive chart component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Chart
   size="default"
   color="primary"
   title="Chart"
@@ -39,7 +39,7 @@ page Chartcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/chat-bubble.wrn b/app/pages/components/chat-bubble.wrn index b3631a4b..15a6f826 100644 --- a/app/pages/components/chat-bubble.wrn +++ b/app/pages/components/chat-bubble.wrn @@ -10,10 +10,10 @@ page ChatBubblecomponent {
W WRNexusJS - +
-
base component

ChatBubble

Theme-aware, responsive chat bubble component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ChatBubble
+      
base component

ChatBubble

Theme-aware, responsive chat bubble component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ChatBubble
   size="default"
   color="primary"
   title="Chat Bubble"
@@ -39,7 +39,7 @@ page ChatBubblecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/checkbox.wrn b/app/pages/components/checkbox.wrn index aba96139..337bf39e 100644 --- a/app/pages/components/checkbox.wrn +++ b/app/pages/components/checkbox.wrn @@ -10,16 +10,16 @@ page Checkboxcomponent {
W WRNexusJS - +
-
forms component

Checkbox

Theme-aware, responsive checkbox component.

@wrnexus/ui 0.3.68 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Checkbox
+      
forms component

Checkbox

Theme-aware, responsive checkbox component.

@wrnexus/ui 0.4.08 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Checkbox
   size="default"
   color="primary"
   label="Checkbox"
   name="name"
   value="on"
-/>

Legacy mount name: data-component="Checkbox".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Checkbox"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Checkbox.wrn

component Checkbox {
+/>

Legacy mount name: data-component="Checkbox".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Checkbox"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/checkbox.wrn

component Checkbox {
   props {
     size = "default"
     color = "primary"
@@ -38,7 +38,7 @@ page Checkboxcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/clipboard.wrn b/app/pages/components/clipboard.wrn index 2b2343dd..bf343d72 100644 --- a/app/pages/components/clipboard.wrn +++ b/app/pages/components/clipboard.wrn @@ -10,10 +10,10 @@ page Clipboardcomponent {
W WRNexusJS - +
-
integrations component

Clipboard

Theme-aware, responsive clipboard component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Clipboard
+      
integrations component

Clipboard

Theme-aware, responsive clipboard component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Clipboard
   size="default"
   color="primary"
   title="Clipboard"
@@ -39,7 +39,7 @@ page Clipboardcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/collapse.wrn b/app/pages/components/collapse.wrn index 33737541..2981db33 100644 --- a/app/pages/components/collapse.wrn +++ b/app/pages/components/collapse.wrn @@ -10,10 +10,10 @@ page Collapsecomponent {
W WRNexusJS - +
-
base component

Collapse

Theme-aware, responsive collapse component.

@wrnexus/ui 0.3.65 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Collapse
+      
base component

Collapse

Theme-aware, responsive collapse component.

@wrnexus/ui 0.4.05 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Collapse
   size="default"
   color="primary"
   items="[]"
@@ -37,7 +37,7 @@ page Collapsecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/color-picker.wrn b/app/pages/components/color-picker.wrn index 157dcda0..cfcf5981 100644 --- a/app/pages/components/color-picker.wrn +++ b/app/pages/components/color-picker.wrn @@ -10,10 +10,10 @@ page ColorPickercomponent {
W WRNexusJS - +
-
forms component

ColorPicker

Theme-aware, responsive color picker component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ColorPicker
+      
forms component

ColorPicker

Theme-aware, responsive color picker component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ColorPicker
   size="default"
   color="primary"
   label="Color Picker"
@@ -43,7 +43,7 @@ page ColorPickercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/columns.wrn b/app/pages/components/columns.wrn index fe532a6b..93a8959e 100644 --- a/app/pages/components/columns.wrn +++ b/app/pages/components/columns.wrn @@ -10,10 +10,10 @@ page Columnscomponent {
W WRNexusJS - +
-
layout component

Columns

Theme-aware, responsive columns component.

@wrnexus/ui 0.3.66 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Columns
+      
layout component

Columns

Theme-aware, responsive columns component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Columns
   size="default"
   color="primary"
   columns="2"
@@ -35,7 +35,7 @@ page Columnscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/combo-box.wrn b/app/pages/components/combo-box.wrn index 1781cc4d..7e3f9467 100644 --- a/app/pages/components/combo-box.wrn +++ b/app/pages/components/combo-box.wrn @@ -10,16 +10,16 @@ page ComboBoxcomponent {
W WRNexusJS - +
-
advanced-forms component

ComboBox

Editable autocomplete combobox with local and remote suggestions.

@wrnexus/ui 0.3.641 props0 slots8 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ComboBox
+      
advanced-forms component

ComboBox

Editable autocomplete combobox with local and remote suggestions.

@wrnexus/ui 0.4.041 props0 slots8 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ComboBox
   size="default"
   color="primary"
   label="ComboBox"
   name="name"
   value="value"
-/>

Legacy mount name: data-component="ComboBox".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"ComboBox"
namestringOptional""
valuestringOptional""
optionsstringOptional[]
groupsstringOptional[]
placeholderstringOptional"Search or select an option"
searchPlaceholderstringOptional"Start typing…"
clearablebooleanOptionaltrue
allowCustomValuebooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
invalidbooleanOptionalfalse
validationMessagestringOptional""
helpTextstringOptional""
loadingbooleanOptionalfalse
loadingLabelstringOptional"Loading suggestions…"
emptyLabelstringOptional"No matching options"
clearLabelstringOptional"Clear value"
toggleLabelstringOptional"Toggle suggestions"
searchModestringOptional"contains"
searchFieldsstringOptional"label,description"
minSearchLengthnumberOptional0
searchResultLimitnumberOptional0
optionTemplatestringOptional"default"
defaultOpenbooleanOptionalfalse
closeOnSelectbooleanOptionaltrue
fixedbooleanOptionalfalse
placementstringOptional"bottom"
autocompletestringOptional"off"
remotebooleanOptionalfalse
remoteUrlstringOptional""
remoteQueryParamstringOptional"q"
remoteDebouncenumberOptional250
remoteAutoLoadbooleanOptionaltrue
infinitebooleanOptionalfalse
hasMorebooleanOptionalfalse
pagenumberOptional1
loadMoreLabelstringOptional"Load more"
classstringOptional""

Slots

This component does not declare a slot.

Events

  • search
  • select
  • change
  • clear
  • open
  • close
  • load
  • error

Source contract

Installed source: components/ComboBox.wrn

component ComboBox {
+/>

Legacy mount name: data-component="ComboBox".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"ComboBox"
namestringOptional""
valuestringOptional""
optionsstringOptional[]
groupsstringOptional[]
placeholderstringOptional"Search or select an option"
searchPlaceholderstringOptional"Start typing…"
clearablebooleanOptionaltrue
allowCustomValuebooleanOptionalfalse
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
invalidbooleanOptionalfalse
validationMessagestringOptional""
helpTextstringOptional""
loadingbooleanOptionalfalse
loadingLabelstringOptional"Loading suggestions…"
emptyLabelstringOptional"No matching options"
clearLabelstringOptional"Clear value"
toggleLabelstringOptional"Toggle suggestions"
searchModestringOptional"contains"
searchFieldsstringOptional"label,description"
minSearchLengthnumberOptional0
searchResultLimitnumberOptional0
optionTemplatestringOptional"default"
defaultOpenbooleanOptionalfalse
closeOnSelectbooleanOptionaltrue
fixedbooleanOptionalfalse
placementstringOptional"bottom"
autocompletestringOptional"off"
remotebooleanOptionalfalse
remoteUrlstringOptional""
remoteQueryParamstringOptional"q"
remoteDebouncenumberOptional250
remoteAutoLoadbooleanOptionaltrue
infinitebooleanOptionalfalse
hasMorebooleanOptionalfalse
pagenumberOptional1
loadMoreLabelstringOptional"Load more"
classstringOptional""

Slots

This component does not declare a slot.

Events

  • search
  • select
  • change
  • clear
  • open
  • close
  • load
  • error

Source contract

Installed source: components/Combobox.wrn

component ComboBox {
   props {
     size = "default"
     color = "primary"
@@ -413,7 +413,7 @@ page ComboBoxcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/confetti.wrn b/app/pages/components/confetti.wrn index 905b8521..d863171e 100644 --- a/app/pages/components/confetti.wrn +++ b/app/pages/components/confetti.wrn @@ -10,10 +10,10 @@ page Confetticomponent {
W WRNexusJS - +
-
integrations component

Confetti

Theme-aware, responsive confetti component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Confetti
+      
integrations component

Confetti

Theme-aware, responsive confetti component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Confetti
   size="default"
   color="primary"
   title="Confetti"
@@ -39,7 +39,7 @@ page Confetticomponent {
     }
 }
 
- + } diff --git a/app/pages/components/container.wrn b/app/pages/components/container.wrn index b73f0f5a..b43d6910 100644 --- a/app/pages/components/container.wrn +++ b/app/pages/components/container.wrn @@ -10,16 +10,16 @@ page Containercomponent {
W WRNexusJS - +
-
layout component

Container

Theme-aware, responsive container component.

@wrnexus/ui 0.3.66 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Container
+      
layout component

Container

Theme-aware, responsive container component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Container
   size="default"
   color="primary"
   columns="2"
   gap="md"
   maxWidth="xl"
-/>

Legacy mount name: data-component="Container".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
columnsnumberOptional2
gapstringOptional"md"
maxWidthstringOptional"xl"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Container.wrn

component Container {
+/>

Legacy mount name: data-component="Container".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
columnsnumberOptional2
gapstringOptional"md"
maxWidthstringOptional"xl"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/container.wrn

component Container {
   props {
     size = "default"
     color = "primary"
@@ -35,7 +35,7 @@ page Containercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/context-menu.wrn b/app/pages/components/context-menu.wrn index 5c778e8e..f7a8877a 100644 --- a/app/pages/components/context-menu.wrn +++ b/app/pages/components/context-menu.wrn @@ -10,10 +10,10 @@ page ContextMenucomponent {
W WRNexusJS - +
-
overlays component

ContextMenu

Theme-aware, responsive context menu component.

@wrnexus/ui 0.3.68 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ContextMenu
+      
overlays component

ContextMenu

Theme-aware, responsive context menu component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ContextMenu
   size="default"
   color="primary"
   title="Context Menu"
@@ -42,7 +42,7 @@ page ContextMenucomponent {
     }
 }
 
- + } diff --git a/app/pages/components/copy-markup.wrn b/app/pages/components/copy-markup.wrn index aee4f927..bebe8cc1 100644 --- a/app/pages/components/copy-markup.wrn +++ b/app/pages/components/copy-markup.wrn @@ -10,10 +10,10 @@ page CopyMarkupcomponent {
W WRNexusJS - +
-
advanced-forms component

CopyMarkup

Theme-aware, responsive copy markup component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<CopyMarkup
+      
advanced-forms component

CopyMarkup

Theme-aware, responsive copy markup component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<CopyMarkup
   size="default"
   color="primary"
   label="Copy Markup"
@@ -43,7 +43,7 @@ page CopyMarkupcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/custom-scrollbar.wrn b/app/pages/components/custom-scrollbar.wrn index 68dbd2f6..e39ad967 100644 --- a/app/pages/components/custom-scrollbar.wrn +++ b/app/pages/components/custom-scrollbar.wrn @@ -10,10 +10,10 @@ page CustomScrollbarcomponent {
W WRNexusJS - +
-
layout component

CustomScrollbar

Theme-aware, responsive custom scrollbar component.

@wrnexus/ui 0.3.66 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<CustomScrollbar
+      
layout component

CustomScrollbar

Theme-aware, responsive custom scrollbar component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<CustomScrollbar
   size="default"
   color="primary"
   columns="2"
@@ -35,7 +35,7 @@ page CustomScrollbarcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/data-map.wrn b/app/pages/components/data-map.wrn index 71320a06..e0cbb612 100644 --- a/app/pages/components/data-map.wrn +++ b/app/pages/components/data-map.wrn @@ -10,10 +10,10 @@ page DataMapcomponent {
W WRNexusJS - +
-
integrations component

DataMap

Theme-aware, responsive data map component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DataMap
+      
integrations component

DataMap

Theme-aware, responsive data map component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DataMap
   size="default"
   color="primary"
   title="Data Map"
@@ -39,7 +39,7 @@ page DataMapcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/data-table.wrn b/app/pages/components/data-table.wrn index 4acfcc4d..e1f8c32c 100644 --- a/app/pages/components/data-table.wrn +++ b/app/pages/components/data-table.wrn @@ -10,10 +10,10 @@ page DataTablecomponent {
W WRNexusJS - +
-
integrations component

DataTable

Theme-aware, responsive data table component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DataTable
+      
integrations component

DataTable

Theme-aware, responsive data table component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DataTable
   size="default"
   color="primary"
   caption="Data Table"
@@ -43,7 +43,7 @@ page DataTablecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/date-picker.wrn b/app/pages/components/date-picker.wrn index add579db..0c877b10 100644 --- a/app/pages/components/date-picker.wrn +++ b/app/pages/components/date-picker.wrn @@ -10,10 +10,10 @@ page DatePickercomponent {
W WRNexusJS - +
-
base component

DatePicker

Theme-aware, responsive date picker component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DatePicker
+      
base component

DatePicker

Theme-aware, responsive date picker component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DatePicker
   size="default"
   color="primary"
   label="Date Picker"
@@ -43,7 +43,7 @@ page DatePickercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/device-frame.wrn b/app/pages/components/device-frame.wrn index 641a28dc..ed07b0c9 100644 --- a/app/pages/components/device-frame.wrn +++ b/app/pages/components/device-frame.wrn @@ -10,10 +10,10 @@ page DeviceFramecomponent {
W WRNexusJS - +
-
base component

DeviceFrame

Theme-aware, responsive device frame component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DeviceFrame
+      
base component

DeviceFrame

Theme-aware, responsive device frame component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DeviceFrame
   size="default"
   color="primary"
   title="Device Frame"
@@ -39,7 +39,7 @@ page DeviceFramecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/divider.wrn b/app/pages/components/divider.wrn index 03c3212d..2445d3a6 100644 --- a/app/pages/components/divider.wrn +++ b/app/pages/components/divider.wrn @@ -10,15 +10,15 @@ page Dividercomponent {
W WRNexusJS - +
-
layout component

Divider

Theme-aware, responsive divider component.

@wrnexus/ui 0.3.65 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Divider
+      
layout component

Divider

Theme-aware, responsive divider component.

@wrnexus/ui 0.4.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Divider
   size="default"
   color="primary"
   label="label"
   orientation="horizontal"
-/>

Legacy mount name: data-component="Divider".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Divider.wrn

component Divider {
+/>

Legacy mount name: data-component="Divider".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional""
orientationstringOptional"horizontal"
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/divider.wrn

component Divider {
   props {
     size = "default"
     color = "primary"
@@ -31,7 +31,7 @@ page Dividercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/drag-and-drop.wrn b/app/pages/components/drag-and-drop.wrn index a867e41d..1e8c8af7 100644 --- a/app/pages/components/drag-and-drop.wrn +++ b/app/pages/components/drag-and-drop.wrn @@ -10,10 +10,10 @@ page DragAndDropcomponent {
W WRNexusJS - +
-
integrations component

DragAndDrop

Theme-aware, responsive drag and drop component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DragAndDrop
+      
integrations component

DragAndDrop

Theme-aware, responsive drag and drop component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<DragAndDrop
   size="default"
   color="primary"
   title="Drag And Drop"
@@ -39,7 +39,7 @@ page DragAndDropcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/drawer.wrn b/app/pages/components/drawer.wrn index 67214de2..52187f5a 100644 --- a/app/pages/components/drawer.wrn +++ b/app/pages/components/drawer.wrn @@ -10,10 +10,10 @@ page Drawercomponent {
W WRNexusJS - +
-
overlays component

Drawer

Theme-aware, responsive drawer component.

@wrnexus/ui 0.3.68 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Drawer
+      
overlays component

Drawer

Theme-aware, responsive drawer component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Drawer
   size="default"
   color="primary"
   title="Drawer"
@@ -42,7 +42,7 @@ page Drawercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/dropdown.wrn b/app/pages/components/dropdown.wrn index 01f78e0b..168cfb1b 100644 --- a/app/pages/components/dropdown.wrn +++ b/app/pages/components/dropdown.wrn @@ -10,10 +10,10 @@ page Dropdowncomponent {
W WRNexusJS - +
-
overlays component

Dropdown

Theme-aware, responsive dropdown component.

@wrnexus/ui 0.3.68 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Dropdown
+      
overlays component

Dropdown

Theme-aware, responsive dropdown component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Dropdown
   size="default"
   color="primary"
   title="Dropdown"
@@ -42,7 +42,7 @@ page Dropdowncomponent {
     }
 }
 
- + } diff --git a/app/pages/components/file-input.wrn b/app/pages/components/file-input.wrn index ff4d85f7..7e60809a 100644 --- a/app/pages/components/file-input.wrn +++ b/app/pages/components/file-input.wrn @@ -10,10 +10,10 @@ page FileInputcomponent {
W WRNexusJS - +
-
forms component

FileInput

Theme-aware, responsive file input component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileInput
+      
forms component

FileInput

Theme-aware, responsive file input component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileInput
   size="default"
   color="primary"
   label="File Input"
@@ -43,7 +43,7 @@ page FileInputcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/file-upload-progress.wrn b/app/pages/components/file-upload-progress.wrn index 378eb926..2bea4ee2 100644 --- a/app/pages/components/file-upload-progress.wrn +++ b/app/pages/components/file-upload-progress.wrn @@ -10,10 +10,10 @@ page FileUploadProgresscomponent {
W WRNexusJS - +
-
base component

FileUploadProgress

Theme-aware, responsive file upload progress component.

@wrnexus/ui 0.3.67 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileUploadProgress
+      
base component

FileUploadProgress

Theme-aware, responsive file upload progress component.

@wrnexus/ui 0.4.07 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileUploadProgress
   size="default"
   color="primary"
   label="Progress"
@@ -39,7 +39,7 @@ page FileUploadProgresscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/file-upload.wrn b/app/pages/components/file-upload.wrn index 8be73a2c..ac536388 100644 --- a/app/pages/components/file-upload.wrn +++ b/app/pages/components/file-upload.wrn @@ -10,10 +10,10 @@ page FileUploadcomponent {
W WRNexusJS - +
-
integrations component

FileUpload

Theme-aware, responsive file upload component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileUpload
+      
integrations component

FileUpload

Theme-aware, responsive file upload component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<FileUpload
   size="default"
   color="primary"
   title="File Upload"
@@ -39,7 +39,7 @@ page FileUploadcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/grid.wrn b/app/pages/components/grid.wrn index 1ef21092..1613a7e7 100644 --- a/app/pages/components/grid.wrn +++ b/app/pages/components/grid.wrn @@ -10,16 +10,16 @@ page Gridcomponent {
W WRNexusJS - +
-
layout component

Grid

Theme-aware, responsive grid component.

@wrnexus/ui 0.3.66 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Grid
+      
layout component

Grid

Theme-aware, responsive grid component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Grid
   size="default"
   color="primary"
   columns="2"
   gap="md"
   maxWidth="xl"
-/>

Legacy mount name: data-component="Grid".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
columnsnumberOptional2
gapstringOptional"md"
maxWidthstringOptional"xl"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Grid.wrn

component Grid {
+/>

Legacy mount name: data-component="Grid".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
columnsnumberOptional2
gapstringOptional"md"
maxWidthstringOptional"xl"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/grid.wrn

component Grid {
   props {
     size = "default"
     color = "primary"
@@ -35,7 +35,7 @@ page Gridcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/image.wrn b/app/pages/components/image.wrn index 0e86f6c8..1f2f2595 100644 --- a/app/pages/components/image.wrn +++ b/app/pages/components/image.wrn @@ -10,10 +10,10 @@ page Imagecomponent {
W WRNexusJS - +
-
layout component

Image

Theme-aware, responsive image component.

@wrnexus/ui 0.3.69 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Image
+      
layout component

Image

Theme-aware, responsive image component.

@wrnexus/ui 0.4.09 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Image
   size="default"
   color="primary"
   src="src"
@@ -39,7 +39,7 @@ page Imagecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/input-group.wrn b/app/pages/components/input-group.wrn index 6dec2903..b3ed520d 100644 --- a/app/pages/components/input-group.wrn +++ b/app/pages/components/input-group.wrn @@ -10,10 +10,10 @@ page InputGroupcomponent {
W WRNexusJS - +
-
forms component

InputGroup

Theme-aware, responsive input group component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<InputGroup
+      
forms component

InputGroup

Theme-aware, responsive input group component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<InputGroup
   size="default"
   color="primary"
   label="Input Group"
@@ -43,7 +43,7 @@ page InputGroupcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/input-number.wrn b/app/pages/components/input-number.wrn index a93d6d31..b5a87e69 100644 --- a/app/pages/components/input-number.wrn +++ b/app/pages/components/input-number.wrn @@ -10,40 +10,644 @@ page InputNumbercomponent {
W WRNexusJS - +
-
advanced-forms component

InputNumber

Theme-aware, responsive input number component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<InputNumber
+      
advanced-forms component

InputNumber

Theme-aware, responsive input number component.

@wrnexus/ui 0.4.040 props0 slots4 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<InputNumber
   size="default"
   color="primary"
-  label="Input Number"
-  name="name"
-  value="value"
-/>

Legacy mount name: data-component="InputNumber".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Input Number"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"number"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/InputNumber.wrn

component InputNumber {
-  props {
-    size = "default"
-    color = "primary"
-    label = "Input Number"
-    name = ""
-    value = ""
-    placeholder = ""
-    type = "number"
-    min = ""
-    max = ""
-    step = ""
-    disabled = false
-    required = false
-    class = ""
-  }
-  view {
-        <label class="wire-next wire-next--color-{color} wire-next--size-{size} wire-next--field wire-next--input-number {class}">
+  variant="default"
+  id="id"
+  name="quantity"
+/>

Legacy mount name: data-component="InputNumber".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
variantstringOptional"default"
classstringOptional""
idstringOptional""
namestringOptional"quantity"
valuenumberOptional0
minstringOptional""
maxstringOptional""
stepnumberOptional1
precisionstringOptional"auto"
labelstringOptional""
descriptionstringOptional""
helpTextstringOptional""
errorstringOptional""
invalidbooleanOptionalfalse
prefixstringOptional""
suffixstringOptional""
placeholderstringOptional""
autocompletestringOptional"off"
inputModestringOptional"decimal"
ariaLabelstringOptional""
requiredbooleanOptionalfalse
disabledbooleanOptionalfalse
inputDisabledbooleanOptionalfalse
buttonsDisabledbooleanOptionalfalse
readonlybooleanOptionalfalse
allowInputbooleanOptionaltrue
keyboardbooleanOptionaltrue
wheelbooleanOptionalfalse
clampbooleanOptionaltrue
fullWidthbooleanOptionalfalse
showButtonsbooleanOptionaltrue
showValidationMessagebooleanOptionaltrue
decrementLabelstringOptional"Decrease value"
incrementLabelstringOptional"Increase value"
controlsLabelstringOptional"Quantity controls"
requiredMessagestringOptional"A value is required."
minMessagestringOptional"Value is below the minimum."
maxMessagestringOptional"Value is above the maximum."

Slots

This component does not declare a slot.

Events

  • input
  • change
  • increment
  • decrement

Source contract

Installed source: components/InputNumber.wrn

component InputNumber {
+    props {
+        size = "default"
+        color = "primary"
+        variant = "default"
+        class = ""
+
+        id = ""
+        name = "quantity"
+        value = 0
+        min = ""
+        max = ""
+        step = 1
+        precision = "auto"
+
+        label = ""
+        description = ""
+        helpText = ""
+        error = ""
+        invalid = false
+
+        prefix = ""
+        suffix = ""
+        placeholder = ""
+        autocomplete = "off"
+        inputMode = "decimal"
+        ariaLabel = ""
+
+        required = false
+        disabled = false
+        inputDisabled = false
+        buttonsDisabled = false
+        readonly = false
+        allowInput = true
+        keyboard = true
+        wheel = false
+        clamp = true
+        fullWidth = false
+        showButtons = true
+        showValidationMessage = true
+
+        decrementLabel = "Decrease value"
+        incrementLabel = "Increase value"
+        controlsLabel = "Quantity controls"
+        requiredMessage = "A value is required."
+        minMessage = "Value is below the minimum."
+        maxMessage = "Value is above the maximum."
+
+        @event input = function
+        @event change = function
+        @event increment = function
+        @event decrement = function
+    }
+
+    state currentValue = value
+    state committedValue = value
+
+    functions {
+        function inputId() {
+            if (id !== "") {
+                return id
+            }
+
+            if (name !== "") {
+                return name
+            }
+
+            return "input-number"
+        }
+
+        function descriptionId() {
+            return inputId() + "-description"
+        }
+
+        function messageId() {
+            return inputId() + "-message"
+        }
+
+        function componentColor() {
+            if (color === "secondary") {
+                return "var(--wire-color-secondary)"
+            }
+
+            if (color === "success") {
+                return "var(--wire-color-success)"
+            }
+
+            if (color === "warning") {
+                return "var(--wire-color-warning)"
+            }
+
+            if (color === "danger") {
+                return "var(--wire-color-danger)"
+            }
+
+            if (color === "info") {
+                return "var(--wire-color-info)"
+            }
+
+            return "var(--wire-color-primary)"
+        }
+
+        function hasMin() {
+            return min !== "" && min !== null && min !== undefined
+        }
+
+        function hasMax() {
+            return max !== "" && max !== null && max !== undefined
+        }
+
+        function isBlank() {
+            return currentValue === "" || currentValue === null || currentValue === undefined
+        }
+
+        function normalizedStep() {
+            return Number(step) > 0 ? Number(step) : 1
+        }
+
+        function inferredPrecision() {
+            if (precision !== "auto" && precision !== "") {
+                return Math.max(0, Number(precision) || 0)
+            }
+
+            if (String(normalizedStep()).includes(".")) {
+                return String(normalizedStep()).split(".")[1].length
+            }
+
+            return 0
+        }
+
+        function precisionFactor() {
+            return Math.pow(10, inferredPrecision())
+        }
+
+        function roundValue(nextValue) {
+            return Math.round(Number(nextValue) * precisionFactor()) / precisionFactor()
+        }
+
+        function clampValue(nextValue) {
+            nextValue = Number(nextValue)
+
+            if (hasMin() && nextValue < Number(min)) {
+                nextValue = Number(min)
+            }
+
+            if (hasMax() && nextValue > Number(max)) {
+                nextValue = Number(max)
+            }
+
+            return roundValue(nextValue)
+        }
+
+        function isBelowMin() {
+            return !isBlank() && hasMin() && Number(currentValue) < Number(min)
+        }
+
+        function isAboveMax() {
+            return !isBlank() && hasMax() && Number(currentValue) > Number(max)
+        }
+
+        function isInvalid() {
+            return (
+                invalid ||
+                error !== "" ||
+                (required && isBlank()) ||
+                isBelowMin() ||
+                isAboveMax()
+            )
+        }
+
+        function validationMessage() {
+            if (error !== "") {
+                return error
+            }
+
+            if (required && isBlank()) {
+                return requiredMessage
+            }
+
+            if (isBelowMin()) {
+                return minMessage
+            }
+
+            if (isAboveMax()) {
+                return maxMessage
+            }
+
+            return ""
+        }
+
+        function hasMessage() {
+            return (
+                helpText !== "" ||
+                (showValidationMessage && isInvalid() && validationMessage() !== "")
+            )
+        }
+
+        function describedBy() {
+            if (description !== "" && hasMessage()) {
+                return descriptionId() + " " + messageId()
+            }
+
+            if (description !== "") {
+                return descriptionId()
+            }
+
+            if (hasMessage()) {
+                return messageId()
+            }
+
+            return ""
+        }
+
+        function decrementDisabled() {
+            return (
+                disabled ||
+                readonly ||
+                buttonsDisabled ||
+                (hasMin() && !isBlank() && Number(currentValue) <= Number(min))
+            )
+        }
+
+        function incrementDisabled() {
+            return (
+                disabled ||
+                readonly ||
+                buttonsDisabled ||
+                (hasMax() && !isBlank() && Number(currentValue) >= Number(max))
+            )
+        }
+
+        function dispatchInputNumberEvent(
+            sourceEvent,
+            eventName,
+            action,
+            previousValue,
+            root,
+            customEvent
+        ) {
+            root = sourceEvent.currentTarget.closest("[data-wrn-input-number]")
+
+            if (!root && sourceEvent.target) {
+                root = sourceEvent.target.closest("[data-wrn-input-number]")
+            }
+
+            if (!root) {
+                return
+            }
+
+            customEvent = document.createEvent("CustomEvent")
+            customEvent.initCustomEvent(eventName, true, false, {
+                component: "InputNumber",
+                name: name,
+                value: currentValue,
+                previousValue: previousValue,
+                action: action,
+                min: hasMin() ? Number(min) : null,
+                max: hasMax() ? Number(max) : null,
+                step: normalizedStep(),
+                valid: !isInvalid()
+            })
+            root.dispatchEvent(customEvent)
+        }
+
+        function applyControlValue(nextValue, action, sourceEvent, previousValue) {
+            previousValue = currentValue
+            currentValue = clampValue(nextValue)
+            committedValue = currentValue
+
+            dispatchInputNumberEvent(
+                sourceEvent,
+                "input",
+                action,
+                previousValue
+            )
+            dispatchInputNumberEvent(
+                sourceEvent,
+                "change",
+                action,
+                previousValue
+            )
+            dispatchInputNumberEvent(
+                sourceEvent,
+                action,
+                action,
+                previousValue
+            )
+        }
+
+        function incrementValue(sourceEvent, nextValue) {
+            if (incrementDisabled()) {
+                return
+            }
+
+            if (isBlank()) {
+                nextValue = hasMin() ? Number(min) : normalizedStep()
+            } else {
+                nextValue =
+                    Number(currentValue) +
+                    normalizedStep() * (sourceEvent.shiftKey ? 10 : 1)
+            }
+
+            applyControlValue(nextValue, "increment", sourceEvent)
+        }
+
+        function decrementValue(sourceEvent, nextValue) {
+            if (decrementDisabled()) {
+                return
+            }
+
+            if (isBlank()) {
+                nextValue = hasMax() ? Number(max) : -normalizedStep()
+            } else {
+                nextValue =
+                    Number(currentValue) -
+                    normalizedStep() * (sourceEvent.shiftKey ? 10 : 1)
+            }
+
+            applyControlValue(nextValue, "decrement", sourceEvent)
+        }
+
+        function handleInput(sourceEvent, previousValue, nextValue) {
+            sourceEvent.stopPropagation()
+            previousValue = currentValue
+            nextValue = sourceEvent.target.value
+
+            if (nextValue === "") {
+                currentValue = ""
+            } else if (!Number.isNaN(Number(nextValue))) {
+                currentValue = roundValue(Number(nextValue))
+            }
+
+            dispatchInputNumberEvent(
+                sourceEvent,
+                "input",
+                "input",
+                previousValue
+            )
+        }
+
+        function handleChange(sourceEvent, previousValue) {
+            sourceEvent.stopPropagation()
+            previousValue = committedValue
+
+            if (!isBlank()) {
+                currentValue = clamp
+                    ? clampValue(currentValue)
+                    : roundValue(currentValue)
+            }
+
+            committedValue = currentValue
+
+            dispatchInputNumberEvent(
+                sourceEvent,
+                "change",
+                "change",
+                previousValue
+            )
+        }
+
+        function handleKeydown(sourceEvent) {
+            if (
+                !keyboard ||
+                disabled ||
+                readonly ||
+                inputDisabled ||
+                !allowInput
+            ) {
+                return
+            }
+
+            if (sourceEvent.key === "ArrowUp") {
+                sourceEvent.preventDefault()
+                incrementValue(sourceEvent)
+            } else if (sourceEvent.key === "ArrowDown") {
+                sourceEvent.preventDefault()
+                decrementValue(sourceEvent)
+            } else if (sourceEvent.key === "Home" && hasMin()) {
+                sourceEvent.preventDefault()
+                applyControlValue(Number(min), "decrement", sourceEvent)
+            } else if (sourceEvent.key === "End" && hasMax()) {
+                sourceEvent.preventDefault()
+                applyControlValue(Number(max), "increment", sourceEvent)
+            }
+        }
+
+        function handleWheel(sourceEvent) {
+            if (
+                !wheel ||
+                disabled ||
+                readonly ||
+                inputDisabled ||
+                !allowInput
+            ) {
+                return
+            }
+
+            sourceEvent.preventDefault()
+
+            if (sourceEvent.deltaY < 0) {
+                incrementValue(sourceEvent)
+            } else if (sourceEvent.deltaY > 0) {
+                decrementValue(sourceEvent)
+            }
+        }
+    }
+
+    view {
+        <div
+            {...attrs}
+            data-wrn-input-number
+            data-variant='{variant}'
+            data-size='{size}'
+            data-color='{color}'
+            data-value='{currentValue}'
+            data-invalid='{isInvalid() ? "true" : "false"}'
+            data-disabled='{disabled ? "true" : "false"}'
+            style='--input-number-accent: {componentColor()};'
+            class='relative flex flex-col gap-1.5 text-[var(--wire-color-text)] {fullWidth ? "w-full" : variant === "compact" ? "w-fit max-w-full" : "w-full max-w-sm"} {disabled ? "opacity-60" : ""} {class}'
+        >
+            {#if label !== "" && variant !== "labeled" && variant !== "seat"}
+            <label
+                for='{inputId()}'
+                class='inline-flex items-center gap-1 text-sm font-semibold leading-5 text-[var(--wire-color-text)]'
+            >
         <span>{label}</span>
-        <input {...attrs} type="{type}" name="{name}" value="{value}" placeholder="{placeholder}" min="{min}" max="{max}" step="{step}" disabled="{disabled}" required="{required}" />
-        </label>
+                {#if required}
+                <span
+                    aria-hidden="true"
+                    class='text-[var(--wire-color-danger)]'
+                >*</span>
+                {/if}
+            </label>
+            {/if}
+
+            {#if description !== "" && variant !== "labeled" && variant !== "seat"}
+            <p
+                id='{descriptionId()}'
+                class='m-0 text-xs leading-5 text-[var(--wire-color-muted)]'
+            >
+                {description}
+            </p>
+            {/if}
+
+            <div
+                class='group flex min-w-0 overflow-hidden border bg-[var(--wire-color-surface)] text-[var(--wire-color-text)] shadow-[var(--wire-shadow-1)] transition-[border-color,box-shadow,background-color] duration-[var(--wire-motion-base)] ease-[var(--wire-ease-standard)] focus-within:border-[var(--input-number-accent)] focus-within:shadow-[0_0_0_3px_color-mix(in_srgb,var(--input-number-accent)_18%,transparent)] {variant === "compact" ? "rounded-full" : "rounded-[var(--wire-radius-sm)]"} {size === "xs" ? "min-h-8 text-xs" : size === "sm" ? "min-h-9 text-sm" : size === "lg" ? "min-h-12 text-base" : size === "xl" ? "min-h-14 text-lg" : "min-h-10 text-sm"} {isInvalid() ? "border-[var(--wire-color-danger)] focus-within:border-[var(--wire-color-danger)] focus-within:shadow-[0_0_0_3px_color-mix(in_srgb,var(--wire-color-danger)_18%,transparent)]" : "border-[var(--wire-color-border)]"} {disabled ? "cursor-not-allowed bg-[var(--wire-color-surface-2)]" : ""}'
+            >
+                {#if variant === "horizontal" && showButtons}
+                <button
+                    type="button"
+                    aria-label='{decrementLabel}'
+                    aria-controls='{inputId()}'
+                    disabled='{decrementDisabled()}'
+                    @click='decrementValue(event)'
+                    class='inline-flex shrink-0 items-center justify-center border-r border-[var(--wire-color-border)] bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 {size === "xs" ? "w-8" : size === "sm" ? "w-9" : size === "lg" ? "w-12" : size === "xl" ? "w-14" : "w-10"}'
+                >
+        <span
+                        aria-hidden="true"
+                        class='icon-[lucide--minus] size-4'
+                    >
+        </span>
+        </button>
+                {/if}
+
+                <div
+                    class='flex min-w-0 flex-1 {variant === "labeled" ? "flex-col items-stretch justify-center gap-0.5" : variant === "seat" ? "items-center justify-between gap-3" : "items-center"} {size === "xs" ? "px-2" : size === "sm" ? "px-2.5" : size === "lg" ? "px-4" : size === "xl" ? "px-5" : "px-3"}'
+                >
+                    {#if variant === "labeled" || variant === "seat"}
+                    <div class='min-w-0 flex-1'>
+                        {#if label !== ""}
+                        <label
+                            for='{inputId()}'
+                            class='block truncate font-semibold leading-4 text-[var(--wire-color-text)] {variant === "labeled" ? "text-xs font-medium text-[var(--wire-color-muted)]" : "text-sm"}'
+                        >
+                            {label}
+                            {#if required}
+                            <span
+                                aria-hidden="true"
+                                class='ml-0.5 text-[var(--wire-color-danger)]'
+                            >*</span>
+                            {/if}
+                        </label>
+                        {/if}
+
+                        {#if description !== ""}
+                        <span
+                            id='{descriptionId()}'
+                            class='block truncate text-xs leading-4 text-[var(--wire-color-muted)]'
+                        >
+                            {description}
+                        </span>
+                        {/if}
+                    </div>
+                    {/if}
+
+                    <div
+                        class='flex min-w-0 items-center {variant === "seat" ? "w-auto shrink-0" : "w-full"}'
+                    >
+                        {#if prefix !== ""}
+                        <span
+                            aria-hidden="true"
+                            class='shrink-0 pr-1.5 text-[var(--wire-color-muted)]'
+                        >
+                            {prefix}
+                        </span>
+                        {/if}
+
+                        <input
+                            id='{inputId()}'
+                            name='{name}'
+                            type="number"
+                            value='{currentValue}'
+                            min='{min}'
+                            max='{max}'
+                            step='{normalizedStep()}'
+                            placeholder='{placeholder}'
+                            autocomplete='{autocomplete}'
+                            inputmode='{inputMode}'
+                            aria-label='{ariaLabel !== "" ? ariaLabel : label !== "" ? label : name}'
+                            aria-describedby='{describedBy()}'
+                            aria-invalid='{isInvalid() ? "true" : "false"}'
+                            aria-required='{required ? "true" : "false"}'
+                            aria-disabled='{disabled || inputDisabled ? "true" : "false"}'
+                            required='{required}'
+                            disabled='{disabled}'
+                            readonly='{readonly || inputDisabled || !allowInput}'
+                            tabindex='{inputDisabled ? "-1" : "0"}'
+                            @input='handleInput(event)'
+                            @change='handleChange(event)'
+                            @keydown='handleKeydown(event)'
+                            @wheel='handleWheel(event)'
+                            class='min-w-0 flex-1 appearance-none border-0 bg-transparent p-0 font-medium leading-none text-[var(--wire-color-text)] outline-none placeholder:text-[var(--wire-color-muted)] read-only:cursor-default disabled:cursor-not-allowed [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none {variant === "horizontal" || variant === "compact" || variant === "seat" ? "text-center" : "text-left"} {variant === "seat" ? "w-10 flex-none" : "w-full"}'
+                        />
+
+                        {#if suffix !== ""}
+                        <span
+                            aria-hidden="true"
+                            class='shrink-0 pl-1.5 text-[var(--wire-color-muted)]'
+                        >
+                            {suffix}
+                        </span>
+                        {/if}
+                    </div>
+        </div>
+
+                {#if variant === "horizontal" && showButtons}
+                <button
+                    type="button"
+                    aria-label='{incrementLabel}'
+                    aria-controls='{inputId()}'
+                    disabled='{incrementDisabled()}'
+                    @click='incrementValue(event)'
+                    class='inline-flex shrink-0 items-center justify-center border-l border-[var(--wire-color-border)] bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 {size === "xs" ? "w-8" : size === "sm" ? "w-9" : size === "lg" ? "w-12" : size === "xl" ? "w-14" : "w-10"}'
+                >
+        <span
+                        aria-hidden="true"
+                        class='icon-[lucide--plus] size-4'
+                    >
+        </span>
+        </button>
+                {:else}
+                {#if showButtons}
+                <div
+                    role="group"
+                    aria-label='{controlsLabel}'
+                    class='flex shrink-0 border-l border-[var(--wire-color-border)] {variant === "vertical" ? "flex-col" : "flex-row"}'
+                >
+        <button
+                        type="button"
+                        aria-label='{decrementLabel}'
+                        aria-controls='{inputId()}'
+                        disabled='{decrementDisabled()}'
+                        @click='decrementValue(event)'
+                        class='inline-flex items-center justify-center bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 {variant === "vertical" ? "flex-1 border-b border-[var(--wire-color-border)]" : "border-r border-[var(--wire-color-border)]"} {size === "xs" ? "w-8" : size === "sm" ? "w-9" : size === "lg" ? "w-12" : size === "xl" ? "w-14" : "w-10"}'
+                    >
+        <span
+                            aria-hidden="true"
+                            class='icon-[lucide--minus] size-4'
+                        >
+        </span>
+        </button>
+        <button
+                        type="button"
+                        aria-label='{incrementLabel}'
+                        aria-controls='{inputId()}'
+                        disabled='{incrementDisabled()}'
+                        @click='incrementValue(event)'
+                        class='inline-flex items-center justify-center bg-transparent text-[var(--wire-color-muted)] transition-[color,background-color] duration-[var(--wire-motion-fast)] hover:bg-[var(--wire-color-surface-2)] hover:text-[var(--input-number-accent)] focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--input-number-accent)] disabled:cursor-not-allowed disabled:opacity-40 {variant === "vertical" ? "flex-1" : ""} {size === "xs" ? "w-8" : size === "sm" ? "w-9" : size === "lg" ? "w-12" : size === "xl" ? "w-14" : "w-10"}'
+                    >
+        <span
+                            aria-hidden="true"
+                            class='icon-[lucide--plus] size-4'
+                        >
+        </span>
+        </button>
+        </div>
+                {/if}
+                {/if}
+            </div>
+
+            {#if showValidationMessage && isInvalid() && validationMessage() !== ""}
+            <p
+                id='{messageId()}'
+                role="alert"
+                aria-live="polite"
+                class='m-0 flex items-center gap-1.5 text-xs leading-5 text-[var(--wire-color-danger)]'
+            >
+        <span
+                    aria-hidden="true"
+                    class='icon-[lucide--circle-alert] size-3.5 shrink-0'
+                >
+        </span>
+        <span>{validationMessage()}</span>
+        </p>
+            {/if}
+
+            {#if (!showValidationMessage || !isInvalid() || validationMessage() === "") && helpText !== ""}
+            <p
+                id='{messageId()}'
+                class='m-0 text-xs leading-5 text-[var(--wire-color-muted)]'
+            >
+                {helpText}
+            </p>
+            {/if}
+        </div>
     }
 }
 
- + } diff --git a/app/pages/components/input.wrn b/app/pages/components/input.wrn index 93f78dd6..10bbfeb4 100644 --- a/app/pages/components/input.wrn +++ b/app/pages/components/input.wrn @@ -10,16 +10,16 @@ page Inputcomponent {
W WRNexusJS - +
-
forms component

Input

Theme-aware, responsive input component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Input
+      
forms component

Input

Theme-aware, responsive input component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Input
   size="default"
   color="primary"
   label="Input"
   name="name"
   value="value"
-/>

Legacy mount name: data-component="Input".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Input"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"text"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Input.wrn

component Input {
+/>

Legacy mount name: data-component="Input".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Input"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
typestringOptional"text"
minstringOptional""
maxstringOptional""
stepstringOptional""
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/input.wrn

component Input {
   props {
     size = "default"
     color = "primary"
@@ -43,7 +43,7 @@ page Inputcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/kbd.wrn b/app/pages/components/kbd.wrn index 46697d45..ed78e796 100644 --- a/app/pages/components/kbd.wrn +++ b/app/pages/components/kbd.wrn @@ -10,10 +10,10 @@ page Kbdcomponent {
W WRNexusJS - +
-
layout component

Kbd

Theme-aware, responsive kbd component.

@wrnexus/ui 0.3.64 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Kbd
+      
layout component

Kbd

Theme-aware, responsive kbd component.

@wrnexus/ui 0.4.04 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Kbd
   size="default"
   color="primary"
   label="⌘ K"
@@ -31,7 +31,7 @@ page Kbdcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/layout-splitter.wrn b/app/pages/components/layout-splitter.wrn index ea163380..84e44469 100644 --- a/app/pages/components/layout-splitter.wrn +++ b/app/pages/components/layout-splitter.wrn @@ -10,10 +10,10 @@ page LayoutSplittercomponent {
W WRNexusJS - +
-
layout component

LayoutSplitter

Theme-aware, responsive layout splitter component.

@wrnexus/ui 0.3.66 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<LayoutSplitter
+      
layout component

LayoutSplitter

Theme-aware, responsive layout splitter component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<LayoutSplitter
   size="default"
   color="primary"
   columns="2"
@@ -35,7 +35,7 @@ page LayoutSplittercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/legend-indicator.wrn b/app/pages/components/legend-indicator.wrn index ab701f6e..b0896c3e 100644 --- a/app/pages/components/legend-indicator.wrn +++ b/app/pages/components/legend-indicator.wrn @@ -10,10 +10,10 @@ page LegendIndicatorcomponent {
W WRNexusJS - +
-
base component

LegendIndicator

Theme-aware, responsive legend indicator component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<LegendIndicator
+      
base component

LegendIndicator

Theme-aware, responsive legend indicator component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<LegendIndicator
   size="default"
   color="primary"
   title="Legend Indicator"
@@ -39,7 +39,7 @@ page LegendIndicatorcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/link.wrn b/app/pages/components/link.wrn index acff62f0..9f775e18 100644 --- a/app/pages/components/link.wrn +++ b/app/pages/components/link.wrn @@ -10,10 +10,10 @@ page Linkcomponent {
W WRNexusJS - +
-
layout component

Link

Theme-aware, responsive link component.

@wrnexus/ui 0.3.68 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Link
+      
layout component

Link

Theme-aware, responsive link component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Link
   size="default"
   color="primary"
   label="Link"
@@ -36,7 +36,7 @@ page Linkcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/list-group.wrn b/app/pages/components/list-group.wrn index 943b9331..3a331344 100644 --- a/app/pages/components/list-group.wrn +++ b/app/pages/components/list-group.wrn @@ -10,10 +10,10 @@ page ListGroupcomponent {
W WRNexusJS - +
-
base component

ListGroup

Theme-aware, responsive list group component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ListGroup
+      
base component

ListGroup

Theme-aware, responsive list group component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ListGroup
   size="default"
   color="primary"
   title="List Group"
@@ -39,7 +39,7 @@ page ListGroupcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/list.wrn b/app/pages/components/list.wrn index 1a8c8671..1c9eb3e5 100644 --- a/app/pages/components/list.wrn +++ b/app/pages/components/list.wrn @@ -10,10 +10,10 @@ page Listcomponent {
W WRNexusJS - +
-
base component

List

Theme-aware, responsive list component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<List
+      
base component

List

Theme-aware, responsive list component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<List
   size="default"
   color="primary"
   title="List"
@@ -39,7 +39,7 @@ page Listcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/map.wrn b/app/pages/components/map.wrn index 2a4975f7..6521bc10 100644 --- a/app/pages/components/map.wrn +++ b/app/pages/components/map.wrn @@ -10,10 +10,10 @@ page Mapcomponent {
W WRNexusJS - +
-
integrations component

Map

Theme-aware, responsive map component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Map
+      
integrations component

Map

Theme-aware, responsive map component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Map
   size="default"
   color="primary"
   title="Map"
@@ -39,7 +39,7 @@ page Mapcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/marquee.wrn b/app/pages/components/marquee.wrn index 365cd2f4..8bc19776 100644 --- a/app/pages/components/marquee.wrn +++ b/app/pages/components/marquee.wrn @@ -10,10 +10,10 @@ page Marqueecomponent {
W WRNexusJS - +
-
base component

Marquee

Theme-aware, responsive marquee component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Marquee
+      
base component

Marquee

Theme-aware, responsive marquee component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Marquee
   size="default"
   color="primary"
   title="Marquee"
@@ -39,7 +39,7 @@ page Marqueecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/mega-menu.wrn b/app/pages/components/mega-menu.wrn index 5207bee4..fee67207 100644 --- a/app/pages/components/mega-menu.wrn +++ b/app/pages/components/mega-menu.wrn @@ -10,10 +10,10 @@ page MegaMenucomponent {
W WRNexusJS - +
-
navigation component

MegaMenu

Theme-aware, responsive mega menu component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<MegaMenu
+      
navigation component

MegaMenu

Theme-aware, responsive mega menu component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<MegaMenu
   size="default"
   color="primary"
   label="Mega Menu"
@@ -37,7 +37,7 @@ page MegaMenucomponent {
     }
 }
 
- + } diff --git a/app/pages/components/modal.wrn b/app/pages/components/modal.wrn index 1b6e5af8..98d67146 100644 --- a/app/pages/components/modal.wrn +++ b/app/pages/components/modal.wrn @@ -10,10 +10,10 @@ page Modalcomponent {
W WRNexusJS - +
-
overlays component

Modal

Theme-aware, responsive modal component.

@wrnexus/ui 0.3.68 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Modal
+      
overlays component

Modal

Theme-aware, responsive modal component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Modal
   size="default"
   color="primary"
   title="Modal"
@@ -42,7 +42,7 @@ page Modalcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/nav.wrn b/app/pages/components/nav.wrn index 2f8b7842..1789491c 100644 --- a/app/pages/components/nav.wrn +++ b/app/pages/components/nav.wrn @@ -10,10 +10,10 @@ page Navcomponent {
W WRNexusJS - +
-
navigation component

Nav

Theme-aware, responsive nav component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Nav
+      
navigation component

Nav

Theme-aware, responsive nav component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Nav
   size="default"
   color="primary"
   label="Nav"
@@ -37,7 +37,7 @@ page Navcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/navbar.wrn b/app/pages/components/navbar.wrn index 5f70397d..117b9eb6 100644 --- a/app/pages/components/navbar.wrn +++ b/app/pages/components/navbar.wrn @@ -10,10 +10,10 @@ page Navbarcomponent {
W WRNexusJS - +
-
navigation component

Navbar

Theme-aware, responsive navbar component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Navbar
+      
navigation component

Navbar

Theme-aware, responsive navbar component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Navbar
   size="default"
   color="primary"
   label="Navbar"
@@ -37,7 +37,7 @@ page Navbarcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/pagination.wrn b/app/pages/components/pagination.wrn index 2af5ca1d..620083d3 100644 --- a/app/pages/components/pagination.wrn +++ b/app/pages/components/pagination.wrn @@ -10,10 +10,10 @@ page Paginationcomponent {
W WRNexusJS - +
-
navigation component

Pagination

Theme-aware, responsive pagination component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Pagination
+      
navigation component

Pagination

Theme-aware, responsive pagination component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Pagination
   size="default"
   color="primary"
   label="Pagination"
@@ -37,7 +37,7 @@ page Paginationcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/pin-input.wrn b/app/pages/components/pin-input.wrn index b4705d9c..a4432098 100644 --- a/app/pages/components/pin-input.wrn +++ b/app/pages/components/pin-input.wrn @@ -10,10 +10,10 @@ page PinInputcomponent {
W WRNexusJS - +
-
advanced-forms component

PinInput

Secure multi-cell PIN and verification-code input with regex and paste support.

@wrnexus/ui 0.3.626 props0 slots6 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<PinInput
+      
advanced-forms component

PinInput

Secure multi-cell PIN and verification-code input with regex and paste support.

@wrnexus/ui 0.4.026 props0 slots6 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<PinInput
   size="default"
   color="primary"
   label="Verification code"
@@ -133,7 +133,7 @@ page PinInputcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/popover.wrn b/app/pages/components/popover.wrn index f919d4aa..70fa9f09 100644 --- a/app/pages/components/popover.wrn +++ b/app/pages/components/popover.wrn @@ -10,10 +10,10 @@ page Popovercomponent {
W WRNexusJS - +
-
overlays component

Popover

Theme-aware, responsive popover component.

@wrnexus/ui 0.3.68 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Popover
+      
overlays component

Popover

Theme-aware, responsive popover component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Popover
   size="default"
   color="primary"
   title="Popover"
@@ -42,7 +42,7 @@ page Popovercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/progress.wrn b/app/pages/components/progress.wrn index d5283c9d..6dfca1a4 100644 --- a/app/pages/components/progress.wrn +++ b/app/pages/components/progress.wrn @@ -10,16 +10,16 @@ page Progresscomponent {
W WRNexusJS - +
-
base component

Progress

Theme-aware, responsive progress component.

@wrnexus/ui 0.3.67 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Progress
+      
base component

Progress

Theme-aware, responsive progress component.

@wrnexus/ui 0.4.07 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Progress
   size="default"
   color="primary"
   label="Progress"
   value="50"
   max="100"
-/>

Legacy mount name: data-component="Progress".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Progress"
valuenumberOptional50
maxnumberOptional100
showValuebooleanOptionaltrue
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Progress.wrn

component Progress {
+/>

Legacy mount name: data-component="Progress".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Progress"
valuenumberOptional50
maxnumberOptional100
showValuebooleanOptionaltrue
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/progress.wrn

component Progress {
   props {
     size = "default"
     color = "primary"
@@ -39,7 +39,7 @@ page Progresscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/radio.wrn b/app/pages/components/radio.wrn index 8b510d44..90904e4d 100644 --- a/app/pages/components/radio.wrn +++ b/app/pages/components/radio.wrn @@ -10,16 +10,16 @@ page Radiocomponent {
W WRNexusJS - +
-
forms component

Radio

Theme-aware, responsive radio component.

@wrnexus/ui 0.3.68 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Radio
+      
forms component

Radio

Theme-aware, responsive radio component.

@wrnexus/ui 0.4.08 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Radio
   size="default"
   color="primary"
   label="Radio"
   name="name"
   value="on"
-/>

Legacy mount name: data-component="Radio".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Radio"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Radio.wrn

component Radio {
+/>

Legacy mount name: data-component="Radio".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Radio"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/radio.wrn

component Radio {
   props {
     size = "default"
     color = "primary"
@@ -38,7 +38,7 @@ page Radiocomponent {
     }
 }
 
- + } diff --git a/app/pages/components/range-slider.wrn b/app/pages/components/range-slider.wrn index c450fbb7..19852abd 100644 --- a/app/pages/components/range-slider.wrn +++ b/app/pages/components/range-slider.wrn @@ -10,10 +10,10 @@ page RangeSlidercomponent {
W WRNexusJS - +
-
forms component

RangeSlider

Theme-aware, responsive range slider component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<RangeSlider
+      
forms component

RangeSlider

Theme-aware, responsive range slider component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<RangeSlider
   size="default"
   color="primary"
   label="Range Slider"
@@ -43,7 +43,7 @@ page RangeSlidercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/rating.wrn b/app/pages/components/rating.wrn index 5123ad4a..12fc0922 100644 --- a/app/pages/components/rating.wrn +++ b/app/pages/components/rating.wrn @@ -10,10 +10,10 @@ page Ratingcomponent {
W WRNexusJS - +
-
base component

Rating

Theme-aware, responsive rating component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Rating
+      
base component

Rating

Theme-aware, responsive rating component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Rating
   size="default"
   color="primary"
   title="Rating"
@@ -39,7 +39,7 @@ page Ratingcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/scrollspy.wrn b/app/pages/components/scrollspy.wrn index af889f5c..9e6fa28d 100644 --- a/app/pages/components/scrollspy.wrn +++ b/app/pages/components/scrollspy.wrn @@ -10,10 +10,10 @@ page Scrollspycomponent {
W WRNexusJS - +
-
navigation component

Scrollspy

Theme-aware, responsive scrollspy component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Scrollspy
+      
navigation component

Scrollspy

Theme-aware, responsive scrollspy component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Scrollspy
   size="default"
   color="primary"
   label="Scrollspy"
@@ -37,7 +37,7 @@ page Scrollspycomponent {
     }
 }
 
- + } diff --git a/app/pages/components/search-box.wrn b/app/pages/components/search-box.wrn index 8997de13..876a46f8 100644 --- a/app/pages/components/search-box.wrn +++ b/app/pages/components/search-box.wrn @@ -10,10 +10,10 @@ page SearchBoxcomponent {
W WRNexusJS - +
-
advanced-forms component

SearchBox

Theme-aware, responsive search box component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<SearchBox
+      
advanced-forms component

SearchBox

Theme-aware, responsive search box component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<SearchBox
   size="default"
   color="primary"
   label="Search Box"
@@ -43,7 +43,7 @@ page SearchBoxcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/select.wrn b/app/pages/components/select.wrn index a80fb1a0..80f2cb92 100644 --- a/app/pages/components/select.wrn +++ b/app/pages/components/select.wrn @@ -10,16 +10,16 @@ page Selectcomponent {
W WRNexusJS - +
-
forms component

Select

Theme-aware, responsive select component.

@wrnexus/ui 0.3.610 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Select
+      
forms component

Select

Theme-aware, responsive select component.

@wrnexus/ui 0.4.010 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Select
   size="default"
   color="primary"
   label="Select"
   name="name"
   value="value"
-/>

Legacy mount name: data-component="Select".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Select"
namestringOptional""
valuestringOptional""
optionsstringOptional[]
placeholderstringOptional"Select an option"
multiplebooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Select.wrn

component Select {
+/>

Legacy mount name: data-component="Select".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Select"
namestringOptional""
valuestringOptional""
optionsstringOptional[]
placeholderstringOptional"Select an option"
multiplebooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/select.wrn

component Select {
   props {
     size = "default"
     color = "primary"
@@ -41,7 +41,7 @@ page Selectcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/sidebar.wrn b/app/pages/components/sidebar.wrn index 277f1d4a..da14d575 100644 --- a/app/pages/components/sidebar.wrn +++ b/app/pages/components/sidebar.wrn @@ -10,10 +10,10 @@ page Sidebarcomponent {
W WRNexusJS - +
-
navigation component

Sidebar

Theme-aware, responsive sidebar component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Sidebar
+      
navigation component

Sidebar

Theme-aware, responsive sidebar component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Sidebar
   size="default"
   color="primary"
   label="Sidebar"
@@ -37,7 +37,7 @@ page Sidebarcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/skeleton.wrn b/app/pages/components/skeleton.wrn index 2850f965..058a742f 100644 --- a/app/pages/components/skeleton.wrn +++ b/app/pages/components/skeleton.wrn @@ -10,15 +10,15 @@ page Skeletoncomponent {
W WRNexusJS - +
-
base component

Skeleton

Theme-aware, responsive skeleton component.

@wrnexus/ui 0.3.65 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Skeleton
+      
base component

Skeleton

Theme-aware, responsive skeleton component.

@wrnexus/ui 0.4.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Skeleton
   color="primary"
   label="Loading"
   size="md"
   lines="3"
-/>

Legacy mount name: data-component="Skeleton".

Props and attributes

PropTypeRequirementDefault
colorstringOptional"primary"
labelstringOptional"Loading"
sizestringOptional"md"
linesnumberOptional3
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Skeleton.wrn

component Skeleton {
+/>

Legacy mount name: data-component="Skeleton".

Props and attributes

PropTypeRequirementDefault
colorstringOptional"primary"
labelstringOptional"Loading"
sizestringOptional"md"
linesnumberOptional3
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/skeleton.wrn

component Skeleton {
   props {
     color = "primary"
     label = "Loading"
@@ -35,7 +35,7 @@ page Skeletoncomponent {
     }
 }
 
- + } diff --git a/app/pages/components/spinner.wrn b/app/pages/components/spinner.wrn index d5d10531..f81843e2 100644 --- a/app/pages/components/spinner.wrn +++ b/app/pages/components/spinner.wrn @@ -10,15 +10,15 @@ page Spinnercomponent {
W WRNexusJS - +
-
base component

Spinner

Theme-aware, responsive spinner component.

@wrnexus/ui 0.3.65 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Spinner
+      
base component

Spinner

Theme-aware, responsive spinner component.

@wrnexus/ui 0.4.05 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Spinner
   color="primary"
   label="Loading"
   size="md"
   lines="3"
-/>

Legacy mount name: data-component="Spinner".

Props and attributes

PropTypeRequirementDefault
colorstringOptional"primary"
labelstringOptional"Loading"
sizestringOptional"md"
linesnumberOptional3
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Spinner.wrn

component Spinner {
+/>

Legacy mount name: data-component="Spinner".

Props and attributes

PropTypeRequirementDefault
colorstringOptional"primary"
labelstringOptional"Loading"
sizestringOptional"md"
linesnumberOptional3
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/spinner.wrn

component Spinner {
   props {
     color = "primary"
     label = "Loading"
@@ -35,7 +35,7 @@ page Spinnercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/stepper.wrn b/app/pages/components/stepper.wrn index bd1fadfe..7c738104 100644 --- a/app/pages/components/stepper.wrn +++ b/app/pages/components/stepper.wrn @@ -10,10 +10,10 @@ page Steppercomponent {
W WRNexusJS - +
-
navigation component

Stepper

Theme-aware, responsive stepper component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Stepper
+      
navigation component

Stepper

Theme-aware, responsive stepper component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Stepper
   size="default"
   color="primary"
   label="Stepper"
@@ -37,7 +37,7 @@ page Steppercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/strong-password.wrn b/app/pages/components/strong-password.wrn index e2ffa346..fcc54a01 100644 --- a/app/pages/components/strong-password.wrn +++ b/app/pages/components/strong-password.wrn @@ -10,10 +10,10 @@ page StrongPasswordcomponent {
W WRNexusJS - +
-
advanced-forms component

StrongPassword

Theme-aware, responsive strong password component.

@wrnexus/ui 0.3.627 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<StrongPassword
+      
advanced-forms component

StrongPassword

Theme-aware, responsive strong password component.

@wrnexus/ui 0.4.027 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<StrongPassword
   size="default"
   color="primary"
   label="Password"
@@ -257,7 +257,7 @@ page StrongPasswordcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/styled-icon.wrn b/app/pages/components/styled-icon.wrn index 5e74340b..731c3c26 100644 --- a/app/pages/components/styled-icon.wrn +++ b/app/pages/components/styled-icon.wrn @@ -10,10 +10,10 @@ page StyledIconcomponent {
W WRNexusJS - +
-
base component

StyledIcon

Theme-aware, responsive styled icon component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<StyledIcon
+      
base component

StyledIcon

Theme-aware, responsive styled icon component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<StyledIcon
   size="default"
   color="primary"
   title="Styled Icon"
@@ -39,7 +39,7 @@ page StyledIconcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/switch.wrn b/app/pages/components/switch.wrn index 5185a8c2..773e4a85 100644 --- a/app/pages/components/switch.wrn +++ b/app/pages/components/switch.wrn @@ -10,16 +10,16 @@ page Switchcomponent {
W WRNexusJS - +
-
forms component

Switch

Theme-aware, responsive switch component.

@wrnexus/ui 0.3.68 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Switch
+      
forms component

Switch

Theme-aware, responsive switch component.

@wrnexus/ui 0.4.08 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Switch
   size="default"
   color="primary"
   label="Switch"
   name="name"
   value="on"
-/>

Legacy mount name: data-component="Switch".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Switch"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Switch.wrn

component Switch {
+/>

Legacy mount name: data-component="Switch".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Switch"
namestringOptional""
valuestringOptional"on"
checkedbooleanOptionalfalse
disabledbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/switch.wrn

component Switch {
   props {
     size = "default"
     color = "primary"
@@ -38,7 +38,7 @@ page Switchcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/table.wrn b/app/pages/components/table.wrn index 85309e9d..d4777bc7 100644 --- a/app/pages/components/table.wrn +++ b/app/pages/components/table.wrn @@ -10,16 +10,16 @@ page Tablecomponent {
W WRNexusJS - +
-
tables component

Table

Theme-aware, responsive table component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Table
+      
tables component

Table

Theme-aware, responsive table component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Table
   size="default"
   color="primary"
   caption="Table"
   columns="[]"
   rows="[]"
-/>

Legacy mount name: data-component="Table".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
captionstringOptional"Table"
columnsstringOptional[]
rowsstringOptional[]
stripedbooleanOptionaltrue
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Table.wrn

component Table {
+/>

Legacy mount name: data-component="Table".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
captionstringOptional"Table"
columnsstringOptional[]
rowsstringOptional[]
stripedbooleanOptionaltrue
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/table.wrn

component Table {
   props {
     size = "default"
     color = "primary"
@@ -43,7 +43,7 @@ page Tablecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/tabs.wrn b/app/pages/components/tabs.wrn index 0d2dd312..49178ba2 100644 --- a/app/pages/components/tabs.wrn +++ b/app/pages/components/tabs.wrn @@ -10,10 +10,10 @@ page Tabscomponent {
W WRNexusJS - +
-
navigation component

Tabs

Theme-aware, responsive tabs component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Tabs
+      
navigation component

Tabs

Theme-aware, responsive tabs component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Tabs
   size="default"
   color="primary"
   label="Tabs"
@@ -37,7 +37,7 @@ page Tabscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/textarea.wrn b/app/pages/components/textarea.wrn index e066fe18..166a0aec 100644 --- a/app/pages/components/textarea.wrn +++ b/app/pages/components/textarea.wrn @@ -10,16 +10,16 @@ page Textareacomponent {
W WRNexusJS - +
-
forms component

Textarea

Theme-aware, responsive textarea component.

@wrnexus/ui 0.3.610 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Textarea
+      
forms component

Textarea

Theme-aware, responsive textarea component.

@wrnexus/ui 0.4.010 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Textarea
   size="default"
   color="primary"
   label="Textarea"
   name="name"
   value="value"
-/>

Legacy mount name: data-component="Textarea".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Textarea"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
rowsnumberOptional5
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/Textarea.wrn

component Textarea {
+/>

Legacy mount name: data-component="Textarea".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
labelstringOptional"Textarea"
namestringOptional""
valuestringOptional""
placeholderstringOptional""
rowsnumberOptional5
disabledbooleanOptionalfalse
requiredbooleanOptionalfalse
classstringOptional""

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/textarea.wrn

component Textarea {
   props {
     size = "default"
     color = "primary"
@@ -40,7 +40,7 @@ page Textareacomponent {
     }
 }
 
- + } diff --git a/app/pages/components/time-picker.wrn b/app/pages/components/time-picker.wrn index dd689eeb..8244e7e1 100644 --- a/app/pages/components/time-picker.wrn +++ b/app/pages/components/time-picker.wrn @@ -10,10 +10,10 @@ page TimePickercomponent {
W WRNexusJS - +
-
forms component

TimePicker

Theme-aware, responsive time picker component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TimePicker
+      
forms component

TimePicker

Theme-aware, responsive time picker component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TimePicker
   size="default"
   color="primary"
   label="Time Picker"
@@ -43,7 +43,7 @@ page TimePickercomponent {
     }
 }
 
- + } diff --git a/app/pages/components/timeline.wrn b/app/pages/components/timeline.wrn index a9b0c283..1851bb7b 100644 --- a/app/pages/components/timeline.wrn +++ b/app/pages/components/timeline.wrn @@ -10,10 +10,10 @@ page Timelinecomponent {
W WRNexusJS - +
-
base component

Timeline

Theme-aware, responsive timeline component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Timeline
+      
base component

Timeline

Theme-aware, responsive timeline component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Timeline
   size="default"
   color="primary"
   title="Timeline"
@@ -39,7 +39,7 @@ page Timelinecomponent {
     }
 }
 
- + } diff --git a/app/pages/components/toast-notifications.wrn b/app/pages/components/toast-notifications.wrn index a0f8c731..caa2e15f 100644 --- a/app/pages/components/toast-notifications.wrn +++ b/app/pages/components/toast-notifications.wrn @@ -10,10 +10,10 @@ page ToastNotificationscomponent {
W WRNexusJS - +
-
integrations component

ToastNotifications

Theme-aware, responsive toast notifications component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ToastNotifications
+      
integrations component

ToastNotifications

Theme-aware, responsive toast notifications component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ToastNotifications
   size="default"
   color="primary"
   title="Toast Notifications"
@@ -39,7 +39,7 @@ page ToastNotificationscomponent {
     }
 }
 
- + } diff --git a/app/pages/components/toast.wrn b/app/pages/components/toast.wrn index 440d2aca..3258ddc4 100644 --- a/app/pages/components/toast.wrn +++ b/app/pages/components/toast.wrn @@ -10,10 +10,10 @@ page Toastcomponent {
W WRNexusJS - +
-
base component

Toast

Theme-aware, responsive toast component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Toast
+      
base component

Toast

Theme-aware, responsive toast component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Toast
   size="default"
   color="primary"
   title="Toast"
@@ -39,7 +39,7 @@ page Toastcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/toggle-count.wrn b/app/pages/components/toggle-count.wrn index d3205f92..9ba6563b 100644 --- a/app/pages/components/toggle-count.wrn +++ b/app/pages/components/toggle-count.wrn @@ -10,10 +10,10 @@ page ToggleCountcomponent {
W WRNexusJS - +
-
advanced-forms component

ToggleCount

Theme-aware, responsive toggle count component.

@wrnexus/ui 0.3.613 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ToggleCount
+      
advanced-forms component

ToggleCount

Theme-aware, responsive toggle count component.

@wrnexus/ui 0.4.013 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<ToggleCount
   size="default"
   color="primary"
   label="Toggle Count"
@@ -43,7 +43,7 @@ page ToggleCountcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/toggle-password.wrn b/app/pages/components/toggle-password.wrn index d71e7509..d429adbe 100644 --- a/app/pages/components/toggle-password.wrn +++ b/app/pages/components/toggle-password.wrn @@ -10,10 +10,10 @@ page TogglePasswordcomponent {
W WRNexusJS - +
-
advanced-forms component

TogglePassword

Accessible password field with optional show and hide controls.

@wrnexus/ui 0.3.624 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TogglePassword
+      
advanced-forms component

TogglePassword

Accessible password field with optional show and hide controls.

@wrnexus/ui 0.4.024 props0 slots3 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TogglePassword
   size="default"
   color="primary"
   label="Password"
@@ -175,7 +175,7 @@ page TogglePasswordcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/tooltip.wrn b/app/pages/components/tooltip.wrn index 56ac6955..2a020e6b 100644 --- a/app/pages/components/tooltip.wrn +++ b/app/pages/components/tooltip.wrn @@ -10,16 +10,16 @@ page Tooltipcomponent {
W WRNexusJS - +
-
overlays component

Tooltip

Theme-aware, responsive tooltip component.

@wrnexus/ui 0.3.68 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Tooltip
+      
overlays component

Tooltip

Theme-aware, responsive tooltip component.

@wrnexus/ui 0.4.08 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Tooltip
   size="default"
   color="primary"
   title="Tooltip"
   description="description"
   open="false"
-/>

Legacy mount name: data-component="Tooltip".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Tooltip"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/Tooltip.wrn

component Tooltip {
+/>

Legacy mount name: data-component="Tooltip".

Props and attributes

PropTypeRequirementDefault
sizestringOptional"default"
colorstringOptional"primary"
titlestringOptional"Tooltip"
descriptionstringOptional""
openbooleanOptionalfalse
placementstringOptional"bottom"
closeLabelstringOptional"Close"
classstringOptional""

Slots

  • default

Events

This component does not declare a custom event.

Source contract

Installed source: components/tooltip.wrn

component Tooltip {
   props {
     size = "default"
     color = "primary"
@@ -42,7 +42,7 @@ page Tooltipcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/tree-view.wrn b/app/pages/components/tree-view.wrn index 77225c5f..b5499209 100644 --- a/app/pages/components/tree-view.wrn +++ b/app/pages/components/tree-view.wrn @@ -10,10 +10,10 @@ page TreeViewcomponent {
W WRNexusJS - +
-
base component

TreeView

Theme-aware, responsive tree view component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TreeView
+      
base component

TreeView

Theme-aware, responsive tree view component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<TreeView
   size="default"
   color="primary"
   title="Tree View"
@@ -39,7 +39,7 @@ page TreeViewcomponent {
     }
 }
 
- + } diff --git a/app/pages/components/typography.wrn b/app/pages/components/typography.wrn index 008906ed..3e6f1bfd 100644 --- a/app/pages/components/typography.wrn +++ b/app/pages/components/typography.wrn @@ -10,10 +10,10 @@ page Typographycomponent {
W WRNexusJS - +
-
layout component

Typography

Theme-aware, responsive typography component.

@wrnexus/ui 0.3.66 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Typography
+      
layout component

Typography

Theme-aware, responsive typography component.

@wrnexus/ui 0.4.06 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<Typography
   size="default"
   color="primary"
   columns="2"
@@ -35,7 +35,7 @@ page Typographycomponent {
     }
 }
 
- + } diff --git a/app/pages/components/wysiwyg-editor.wrn b/app/pages/components/wysiwyg-editor.wrn index 93bc3e0d..508d3b38 100644 --- a/app/pages/components/wysiwyg-editor.wrn +++ b/app/pages/components/wysiwyg-editor.wrn @@ -10,10 +10,10 @@ page WysiwygEditorcomponent {
W WRNexusJS - +
-
integrations component

WysiwygEditor

Theme-aware, responsive wysiwyg editor component.

@wrnexus/ui 0.3.67 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<WysiwygEditor
+      
integrations component

WysiwygEditor

Theme-aware, responsive wysiwyg editor component.

@wrnexus/ui 0.4.07 props1 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<WysiwygEditor
   size="default"
   color="primary"
   title="Wysiwyg Editor"
@@ -39,7 +39,7 @@ page WysiwygEditorcomponent {
     }
 }
 
- + } diff --git a/app/pages/examples.wrn b/app/pages/examples.wrn index b8bdf3ab..8e5963e0 100644 --- a/app/pages/examples.wrn +++ b/app/pages/examples.wrn @@ -7,10 +7,10 @@ page Examples { view {
-
W WRNexusJS
+
W WRNexusJS
-

Examples

Examples are tied to installed 0.3.6 package documentation. The focused snippets in guides are source-verified; standalone runnable projects and CI compilation are tracked as remaining work.

Minimal .wrn page

Documented

Database CRUD

Planned fixture

Authentication and protected route

Planned fixture

Permissions

Planned fixture

Forms and validation

Documented

Realtime dashboard

Planned fixture

File upload

Planned fixture

Background queue

Planned fixture

Redis pub/sub

Planned fixture

Workspace gateway

Planned fixture

Deployment

Planned fixture

Experimental mobile mode

Planned fixture
- +

Examples

Examples are tied to installed 0.4.0 package documentation. The focused snippets in guides are source-verified; standalone runnable projects and CI compilation are tracked as remaining work.

Minimal .wrn page

Documented

Database CRUD

Planned fixture

Authentication and protected route

Planned fixture

Permissions

Planned fixture

Forms and validation

Documented

Realtime dashboard

Planned fixture

File upload

Planned fixture

Background queue

Planned fixture

Redis pub/sub

Planned fixture

Workspace gateway

Planned fixture

Deployment

Planned fixture

Experimental mobile mode

Planned fixture
+
} diff --git a/app/pages/getting-started.wrn b/app/pages/getting-started.wrn index 46b37a8d..6e75886a 100644 --- a/app/pages/getting-started.wrn +++ b/app/pages/getting-started.wrn @@ -7,9 +7,9 @@ page Gettingstarted { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · v0.3.6

Build 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.3.6 create my-app
+      
Preview guide · v0.4.0

Build 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.4.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.

- +
} diff --git a/app/pages/guides/api-routes.wrn b/app/pages/guides/api-routes.wrn index bdd964b8..388ea19d 100644 --- a/app/pages/guides/api-routes.wrn +++ b/app/pages/guides/api-routes.wrn @@ -7,10 +7,10 @@ page APIroutes { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

API routes

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

API routes

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/authentication.wrn b/app/pages/guides/authentication.wrn index cfd9141f..950eb7c7 100644 --- a/app/pages/guides/authentication.wrn +++ b/app/pages/guides/authentication.wrn @@ -7,10 +7,10 @@ page Authentication { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Authentication

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Authentication

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/authorization.wrn b/app/pages/guides/authorization.wrn index 61367522..eb3c5f82 100644 --- a/app/pages/guides/authorization.wrn +++ b/app/pages/guides/authorization.wrn @@ -7,10 +7,10 @@ page Authorization { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Authorization

Authentication identifies; authorization decides. Enforce permissions in server routes and policies, including object ownership. UI hiding is never an authorization boundary.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Authorization

Authentication identifies; authorization decides. Enforce permissions in server routes and policies, including object ownership. UI hiding is never an authorization boundary.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/configuration-and-profiles.wrn b/app/pages/guides/configuration-and-profiles.wrn index 5390b31a..8beebe5a 100644 --- a/app/pages/guides/configuration-and-profiles.wrn +++ b/app/pages/guides/configuration-and-profiles.wrn @@ -7,10 +7,10 @@ page Configurationandprofiles { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Configuration and profiles

wrnexus.config.ts owns styles, SEO, security, data, mobile, fonts, and profiles. Keep secrets in validated environment variables and review merged production configuration.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Configuration and profiles

wrnexus.config.ts owns styles, SEO, security, data, mobile, fonts, and profiles. Keep secrets in validated environment variables and review merged production configuration.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/database.wrn b/app/pages/guides/database.wrn index e1af0925..27c30744 100644 --- a/app/pages/guides/database.wrn +++ b/app/pages/guides/database.wrn @@ -7,10 +7,10 @@ page Database { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Database

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Database

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/deployment.wrn b/app/pages/guides/deployment.wrn index af289e82..05022715 100644 --- a/app/pages/guides/deployment.wrn +++ b/app/pages/guides/deployment.wrn @@ -7,10 +7,10 @@ page Deployment { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Deployment

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Deployment

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/forms-and-validation.wrn b/app/pages/guides/forms-and-validation.wrn index 2fb191e6..fa08b4b7 100644 --- a/app/pages/guides/forms-and-validation.wrn +++ b/app/pages/guides/forms-and-validation.wrn @@ -7,10 +7,10 @@ page Formsandvalidation { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Forms and validation

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Forms and validation

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/i18n-and-themes.wrn b/app/pages/guides/i18n-and-themes.wrn index d98e9d53..3bcf67f5 100644 --- a/app/pages/guides/i18n-and-themes.wrn +++ b/app/pages/guides/i18n-and-themes.wrn @@ -7,10 +7,10 @@ page Internationalizationandthemes { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Internationalization and themes

Store locale JSON under app/locales and use translation directives. Themes resolve CSS tokens; ensure contrast, system preference behavior, persistence, and non-color cues.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Internationalization and themes

Store locale JSON under app/locales and use translation directives. Themes resolve CSS tokens; ensure contrast, system preference behavior, persistence, and non-color cues.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/middleware.wrn b/app/pages/guides/middleware.wrn index 8c34bdb4..b47e3e3a 100644 --- a/app/pages/guides/middleware.wrn +++ b/app/pages/guides/middleware.wrn @@ -7,10 +7,10 @@ page Middleware { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Middleware

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Middleware

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/mobile.wrn b/app/pages/guides/mobile.wrn index 9e204aec..10fbe350 100644 --- a/app/pages/guides/mobile.wrn +++ b/app/pages/guides/mobile.wrn @@ -7,10 +7,10 @@ page Mobile { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Mobile

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Mobile

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/observability.wrn b/app/pages/guides/observability.wrn index 72f28347..5a0afe31 100644 --- a/app/pages/guides/observability.wrn +++ b/app/pages/guides/observability.wrn @@ -7,10 +7,10 @@ page Observability { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Observability

Use tracking middleware and sinks with redaction, sampling, stable request identifiers, alert ownership, and retention limits. Never capture registry tokens or session secrets.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Observability

Use tracking middleware and sinks with redaction, sampling, stable request identifiers, alert ownership, and retention limits. Never capture registry tokens or session secrets.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/pages-and-components.wrn b/app/pages/guides/pages-and-components.wrn index 4bcb85bd..8c1817c1 100644 --- a/app/pages/guides/pages-and-components.wrn +++ b/app/pages/guides/pages-and-components.wrn @@ -7,10 +7,10 @@ page Pagesandcomponents { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Pages and components

Pages are routable, components are reusable, and layouts provide shared slots. Mount a component with data-component and keep browser state scoped and minimal.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Pages and components

Pages are routable, components are reusable, and layouts provide shared slots. Mount a component with data-component and keep browser state scoped and minimal.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/project-structure.wrn b/app/pages/guides/project-structure.wrn index 923618b7..98862da9 100644 --- a/app/pages/guides/project-structure.wrn +++ b/app/pages/guides/project-structure.wrn @@ -7,10 +7,10 @@ page Projectstructure { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Project structure

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Project structure

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/pubsub.wrn b/app/pages/guides/pubsub.wrn index 4fa9909a..9c6cb2c3 100644 --- a/app/pages/guides/pubsub.wrn +++ b/app/pages/guides/pubsub.wrn @@ -7,10 +7,10 @@ page Pubsub { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Pub/sub

The in-process driver cannot cross processes. Use Redis where instances must share events, define channel ownership, and design for reconnects and duplicate delivery.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Pub/sub

The in-process driver cannot cross processes. Use Redis where instances must share events, define channel ownership, and design for reconnects and duplicate delivery.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/queues.wrn b/app/pages/guides/queues.wrn index a98acb22..47ab7783 100644 --- a/app/pages/guides/queues.wrn +++ b/app/pages/guides/queues.wrn @@ -7,10 +7,10 @@ page Queues { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Queues

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Queues

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/realtime.wrn b/app/pages/guides/realtime.wrn index ff4ae9d6..5fd3e006 100644 --- a/app/pages/guides/realtime.wrn +++ b/app/pages/guides/realtime.wrn @@ -7,10 +7,10 @@ page Realtime { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Realtime

defineRoom handles connection and messages. Validate message shapes, authorize subscriptions, restrict origins, bound payloads, and use pub/sub to scale across processes.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Realtime

defineRoom handles connection and messages. Validate message shapes, authorize subscriptions, restrict origins, bound payloads, and use pub/sub to scale across processes.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/routing.wrn b/app/pages/guides/routing.wrn index f977d9ce..11fae245 100644 --- a/app/pages/guides/routing.wrn +++ b/app/pages/guides/routing.wrn @@ -7,10 +7,10 @@ page Routing { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Routing

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Routing

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/security.wrn b/app/pages/guides/security.wrn index f30136e9..064dd01f 100644 --- a/app/pages/guides/security.wrn +++ b/app/pages/guides/security.wrn @@ -7,10 +7,10 @@ page Applicationsecurity { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Application security

Use CSP, CSRF, Trusted Types, session hardening, validation, origin checks, upload restrictions, encryption, request limits, and explicit CORS. See the security policy for reporting.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Application security

Use CSP, CSRF, Trusted Types, session hardening, validation, origin checks, upload restrictions, encryption, request limits, and explicit CORS. See the security policy for reporting.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/server-data.wrn b/app/pages/guides/server-data.wrn index 3b0bd117..3be0e194 100644 --- a/app/pages/guides/server-data.wrn +++ b/app/pages/guides/server-data.wrn @@ -7,10 +7,10 @@ page Serverdata { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Server data

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Server data

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/testing.wrn b/app/pages/guides/testing.wrn index cdf8451c..a8b4a4d2 100644 --- a/app/pages/guides/testing.wrn +++ b/app/pages/guides/testing.wrn @@ -7,10 +7,10 @@ page Testing { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Testing

Use Bun tests and @wrnexus/test helpers. Cover server HTML, API status and validation, authorization failures, reactive behavior, and a production startup smoke test.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Testing

Use Bun tests and @wrnexus/test helpers. Cover server HTML, API status and validation, authorization failures, reactive behavior, and a production startup smoke test.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/troubleshooting.wrn b/app/pages/guides/troubleshooting.wrn index 4edd4344..c0218f36 100644 --- a/app/pages/guides/troubleshooting.wrn +++ b/app/pages/guides/troubleshooting.wrn @@ -7,10 +7,10 @@ page Troubleshooting { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Troubleshooting

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Troubleshooting

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/upgrading.wrn b/app/pages/guides/upgrading.wrn index 8fa25048..e1e7dab3 100644 --- a/app/pages/guides/upgrading.wrn +++ b/app/pages/guides/upgrading.wrn @@ -7,10 +7,10 @@ page Upgrading { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Upgrading

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.3.6.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Upgrading

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.4.0.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/uploads.wrn b/app/pages/guides/uploads.wrn index 9194ca28..7202765d 100644 --- a/app/pages/guides/uploads.wrn +++ b/app/pages/guides/uploads.wrn @@ -7,10 +7,10 @@ page Uploads { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Uploads

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.

Release scope

This guide describes installed 0.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +
Preview guide · 0.4.0

Uploads

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.

Release scope

This guide describes installed 0.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/guides/workspaces-and-gateway.wrn b/app/pages/guides/workspaces-and-gateway.wrn index 6b97d092..21c23de8 100644 --- a/app/pages/guides/workspaces-and-gateway.wrn +++ b/app/pages/guides/workspaces-and-gateway.wrn @@ -7,9 +7,9 @@ page Workspacesandgateway { view {
-
W WRNexusJS
+
W WRNexusJS
-
Preview guide · 0.3.6

Workspaces 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
+      
Preview guide · 0.4.0

Workspaces 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.3.6 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

- +};

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.4.0 capabilities. Follow linked package declarations for exact signatures; undocumented behavior is not guaranteed.

Browse package APIs · Troubleshooting · Support

+
} diff --git a/app/pages/index.wrn b/app/pages/index.wrn index 883ad801..d64de96e 100644 --- a/app/pages/index.wrn +++ b/app/pages/index.wrn @@ -7,9 +7,9 @@ page Home { view {
-
W WRNexusJS
+
W WRNexusJS
-

WRNexusJS v0.3.6

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.wrn
page Dashboard {
+      

WRNexusJS v0.4.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.wrn
page 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

  1. RequestSecurity headers and request limits
  2. MiddlewareAuthentication, policy, and context
  3. File routePage or API handler
  4. Compiler + SSRSafe HTML and scoped runtime
  5. 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.3.6.

View deployment notes and showcase status →

-

Capability status

CapabilityStatusDetails
SSR, routing, compiler, APIsPreviewInstalled in 0.3.6; public support policy pending.
Mobile/nativeExperimentalCapacitor compatibility and native generation have platform limitations.
Durable queuesExperimentalProduction 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.4.0.

View deployment notes and showcase status →

+

Capability status

CapabilityStatusDetails
SSR, routing, compiler, APIsPreviewInstalled in 0.4.0; public support policy pending.
Mobile/nativeExperimentalCapacitor compatibility and native generation have platform limitations.
Durable queuesExperimentalProduction durability requires an appropriate driver strategy.
+

Continue exploring

+
} diff --git a/app/pages/language.wrn b/app/pages/language.wrn index ef2b5fc2..4e27f5c3 100644 --- a/app/pages/language.wrn +++ b/app/pages/language.wrn @@ -7,15 +7,15 @@ page Thewrnlanguage { view {
-
W WRNexusJS
+
W WRNexusJS
-
Language reference · 0.3.6

The .wrn language

File anatomy

page Account {
+      
Language reference · 0.4.0

The .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 84d2284a..7f49c316 100644 --- a/app/pages/license.wrn +++ b/app/pages/license.wrn @@ -7,10 +7,10 @@ page License { view {
-
W WRNexusJS
+
W WRNexusJS

License

Owner decision required

This 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 42134145..17b31e69 100644 --- a/app/pages/packages.wrn +++ b/app/pages/packages.wrn @@ -12,10 +12,10 @@ page Packages {
W WRNexusJS - +
-
26 focused packages

Package reference

Everything in the framework, organized by responsibility and documented from the published 0.3.6 APIs.

Showing {category} packages

+
26 focused packages

Package reference

Everything in the framework, organized by responsibility and documented from the published 0.4.0 APIs.

Showing {category} packages

AI

@wrnexus/ai

Server-side Anthropic client with generation and streaming.

Open documentation →
@@ -93,7 +93,7 @@ page Packages { Security

@wrnexus/validation

Typed schemas, coercion, validation, and browser descriptors.

Open documentation →
- + } diff --git a/app/pages/packages/ai.wrn b/app/pages/packages/ai.wrn index 10ea9445..4da1fb08 100644 --- a/app/pages/packages/ai.wrn +++ b/app/pages/packages/ai.wrn @@ -10,11 +10,11 @@ page wrnexusai {
W WRNexusJS - +
-
AI · Package reference

@wrnexus/ai

Server-side Anthropic client with generation and streaming.

v0.3.6Private registryAI

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/ai@0.3.6

Request 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.
+
AI · Package reference

@wrnexus/ai

Server-side Anthropic client with generation and streaming.

v0.4.0Private registryAI

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/ai@0.4.0

Request 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.

Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.

Overview

@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.

@@ -109,7 +109,46 @@ 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).

    -

    Complete TypeScript API

    Generated from the exact installed package declarations.

    /**
    +

    Complete TypeScript API

    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.
    @@ -175,7 +214,7 @@ interface AI {
     /** Create a Claude client. Reads `ANTHROPIC_API_KEY` from the environment by default. */
     declare function createAI(config?: AIConfig): AI;
     
    -export { type AI, type AIConfig, AIError, type Effort, type GenerateOptions, type Message, type Role, createAI };
    +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 };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Return generated JSON from an API route

    // app/api/summarize.ts — summarize posted text
     import { createAI } from "@wrnexus/ai";
     const ai = createAI();
    @@ -201,7 +240,7 @@ export const POST = async (ctx) => {
     };
    - + } diff --git a/app/pages/packages/authz.wrn b/app/pages/packages/authz.wrn index febae96c..0bfd58c2 100644 --- a/app/pages/packages/authz.wrn +++ b/app/pages/packages/authz.wrn @@ -10,11 +10,11 @@ page wrnexusauthz {
    W WRNexusJS - +
    -
    Security · Package reference

    @wrnexus/authz

    Role, permission, policy, and authorization guards.

    v0.3.6Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/authz@0.3.6

    Request 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.
    +
    Security · Package reference

    @wrnexus/authz

    Role, permission, policy, and authorization guards.

    v0.4.0Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/authz@0.4.0

    Request 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.

    Overview

    @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.

    @@ -124,6 +124,22 @@ app.put(
  • Policy combinators (any, all) and authorize are async-aware, so policies may return a Promise<boolean> (e.g. for a database ownership check).
  • Complete TypeScript API

    Generated from the exact installed package declarations.

    import { Context, Middleware } from '@wrnexus/core';
     
    +interface AuthorizationDecision {
    +    allowed: boolean;
    +    reason?: string;
    +    policy?: string;
    +    metadata?: Record<string, unknown>;
    +}
    +type DecisionPolicy<S = Subject, R = unknown> = (subject: S, resource?: R) => AuthorizationDecision | Promise<AuthorizationDecision>;
    +declare function allow(reason?: string, metadata?: Record<string, unknown>): AuthorizationDecision;
    +declare function deny(reason?: string, metadata?: Record<string, unknown>): AuthorizationDecision;
    +declare function decision<S, R>(name: string, policy: Policy<S, R>, denial?: string): DecisionPolicy<S, R>;
    +declare function owner<SubjectType extends Subject, Resource extends Record<string, unknown>>(subjectKey?: keyof SubjectType, resourceKey?: keyof Resource | string): DecisionPolicy<SubjectType, Resource>;
    +declare function anyDecision<S, R>(...policies: DecisionPolicy<S, R>[]): DecisionPolicy<S, R>;
    +declare function allDecisions<S, R>(...policies: DecisionPolicy<S, R>[]): DecisionPolicy<S, R>;
    +declare function authorizeDecision(evaluate: (ctx: Context) => AuthorizationDecision | Promise<AuthorizationDecision>): Middleware;
    +declare function filterAuthorized<S, R>(subject: S, values: readonly R[], policy: Policy<S, R>): Promise<R[]>;
    +
     /**
      * @wrnexus/authz — authorization: role-based (RBAC), policy-based (PBAC), and
      * attribute-based (ABAC). Compose freely; all three reduce to a boolean check
    @@ -167,7 +183,7 @@ declare function requireRole(...roles: string[]): Middleware;
     /** Guard requiring an RBAC permission. */
     declare function requirePermission(rbac: Rbac, permission: string): Middleware;
     
    -export { type Policy, type Rbac, type Subject, all, any, attr, authorize, defineRbac, hasRole, requirePermission, requireRole };
    +export { type AuthorizationDecision, type DecisionPolicy, type Policy, type Rbac, type Subject, all, allDecisions, allow, any, anyDecision, attr, authorize, authorizeDecision, decision, defineRbac, deny, filterAuthorized, hasRole, owner, requirePermission, requireRole };
     

    Examples

    Copy-ready examples from the installed package documentation.

    RBAC

    import { defineRbac, hasRole } from "@wrnexus/authz";
     
     const rbac = defineRbac({
    @@ -226,7 +242,7 @@ app.put(
     );
    - + } diff --git a/app/pages/packages/cli.wrn b/app/pages/packages/cli.wrn index 7ff91159..f8c657df 100644 --- a/app/pages/packages/cli.wrn +++ b/app/pages/packages/cli.wrn @@ -10,11 +10,11 @@ page wrnexuscli {
    W WRNexusJS - +
    -
    Tooling · Package reference

    @wrnexus/cli

    Create, develop, build, generate, test, and maintain WRNexusJS apps.

    v0.3.6Private registryTooling

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/cli@0.3.6

    Request preview access. Never put registry tokens in source control.

    The wrnexus command-line tool that scaffolds, runs, builds, tests, and manages WRNexusJS apps.
    +
    Tooling · Package reference

    @wrnexus/cli

    Create, develop, build, generate, test, and maintain WRNexusJS apps.

    v0.4.0Private registryTooling

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/cli@0.4.0

    Request preview access. Never put registry tokens in source control.

    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.

    Overview

    @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.

    @@ -153,7 +153,7 @@ wrnexus update --latest wrnexus doctor
    - + } diff --git a/app/pages/packages/compiler.wrn b/app/pages/packages/compiler.wrn index 9b49d32d..663aa9c8 100644 --- a/app/pages/packages/compiler.wrn +++ b/app/pages/packages/compiler.wrn @@ -10,11 +10,11 @@ page wrnexuscompiler {
    W WRNexusJS - +
    -
    Core · Package reference

    @wrnexus/compiler

    Parser and code generators for the .wrn language.

    v0.3.6Private registryCore

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/compiler@0.3.6

    Request preview access. Never put registry tokens in source control.

    Compiler for the .wrn language — tokenizes, parses, and lowers .wrn page and component files to TypeScript.
    +
    Core · Package reference

    @wrnexus/compiler

    Parser and code generators for the .wrn language.

    v0.4.0Private registryCore

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/compiler@0.4.0

    Request preview access. Never put registry tokens in source control.

    Compiler for the .wrn language — tokenizes, parses, and lowers .wrn page and component files to TypeScript.

    Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.

    Overview

    @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.

    @@ -152,6 +152,39 @@ declare class NativeCompileError extends Error { /** Compile a parsed `.wrn` page to an Expo Router React Native screen. */ declare function generateNative(ast: PageAst): string; +interface CompilationCacheEntry extends CompileResult { + key: string; + file: string; + sourceHash: string; + createdAt: number; +} +interface CompilationCacheOptions { + maxEntries?: number; + now?: () => number; +} +interface CompilationCache { + compile(source: string, file?: string, salt?: string): CompilationCacheEntry; + get(key: string): CompilationCacheEntry | undefined; + invalidate(file?: string): number; + clear(): void; + size(): number; + stats(): { + hits: number; + misses: number; + entries: number; + }; +} +declare function compilationKey(source: string, file?: string, salt?: string): string; +declare function createCompilationCache(options?: CompilationCacheOptions): CompilationCache; +declare class DependencyGraph { + #private; + set(file: string, dependencies: Iterable<string>): void; + remove(file: string): void; + dependencies(file: string): string[]; + dependents(file: string): string[]; + affected(file: string): string[]; +} + /** * @wrnexus/compiler — the `.wrn` language compiler. * @@ -177,7 +210,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 CompileResult, NativeCompileError, compile, compileNativeWireFile, compileWireFile, generate, generateNative }; +export { type CompilationCache, type CompilationCacheEntry, type CompilationCacheOptions, type CompileResult, DependencyGraph, NativeCompileError, compilationKey, compile, compileNativeWireFile, compileWireFile, createCompilationCache, generate, generateNative };

    Examples

    Copy-ready examples from the installed package documentation.

    Compile a page

    import { compileWireFile } from "@wrnexus/compiler";
     
     const ts = compileWireFile(`
    @@ -208,7 +241,7 @@ lx.next(); // { type: "ident", value: "Home", pos: 5 &#
     lx.next(); // { type: "lbrace", value: "{", pos: 10 }
    - + } diff --git a/app/pages/packages/core.wrn b/app/pages/packages/core.wrn index 48a570ee..7e0bf743 100644 --- a/app/pages/packages/core.wrn +++ b/app/pages/packages/core.wrn @@ -10,11 +10,11 @@ page wrnexuscore {
    W WRNexusJS - +
    -
    Core · Package reference

    @wrnexus/core

    Contexts, middleware, security, sessions, caching, JSX, and realtime.

    v0.3.6Private registryCore

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/core@0.3.6

    Request 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.
    +
    Core · Package reference

    @wrnexus/core

    Contexts, middleware, security, sessions, caching, JSX, and realtime.

    v0.4.0Private registryCore

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/core@0.4.0

    Request 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.

    Overview

    @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.

    @@ -1072,7 +1072,81 @@ interface BudgetViolation { } declare function checkPerformanceBudgets(budgets: PerformanceBudgets, measurement: PerformanceMeasurement): BudgetViolation[]; -export { type ActionDefinition, type AsyncSessionBackend, type Bucket, type BudgetViolation, CSRF_COOKIE, CSRF_HEADER, type CacheControlOptions, type CachePolicy, type ContentSecurityPolicyConfig, type Context, type CookieOptions, type CookieStore, type CorsConfig, type CorsOrigin, type CspDirectiveValue, type DefinedAction, type DefinedEndpoint, type DefinedLoader, type EndpointDefinition, EndpointError, type EndpointErrorBody, type FeatureFlags, type FeatureRule, type FeatureValue, type HstsConfig, type LoaderDefinition, type LocalStorageSnapshot, type Middleware, type Mode, type Next, type PageComponent, type PageMeta, type PerformanceBudgets, type PerformanceMeasurement, type PermissionsPolicyConfig, type RateLimitOptions, type RateLimitStore, type RawSocket, type RealtimeBridge, type RealtimeBus, type RealtimeConnectMeta, type RealtimeEnvelope, type RealtimeHandler, type RealtimeRegistry, type RealtimeSocket, type RequestLoggerOptions, type RequestRecord, type RequireAuthOptions, type Room, type RoomAuthInfo, type RoomClient, type RoomDefinition, type RoomHandlers, type RpcClientOptions, SESSION_USER_KEY, type SaveUploadOptions, type SavedUpload, type SchemaLike, type SecurityConfig, type SeoConfig, type ServerSentEvent, type SessionBackend, type SessionEntry, type SessionStore, type Span, type SpanRecord, type StreamResponseInit, type TFunction, TTLCache, type Target, type Tenant, type TenantMiddlewareOptions, type TenantResolver, type Tracer, type TrustedTypesConfig, UploadError, bridgeRealtime, cacheControl, checkPerformanceBudgets, collectUploads, createContext, createCorsPreflightResponse, createRealtimeRegistry, createRpcClient, createTracer, csrfProtection, csrfToken, dedupe, defaultKey, defineAction, defineEndpoint, defineFeatureFlags, defineLoader, defineRoom, escapeHtml, etag, getUser, hashPassword, isRoomDefinition, isSafeIslandName, isSafeRequestPath, isWebSocketOriginAllowed, loadSession, logIn, logOut, notModified, peerKey, proxyKey, rateLimit, renderDevError, renderError, renderNotFound, renderProdError, renderStatusPage, requestLogger, requireAuth, requireTenant, resolveRequestUrl, sanitizeFilename, saveUpload, sessionAuth, setSessionBackend, sse, streamResponse, tenantFromSubdomain, tenantMiddleware, tenantScope, tracingMiddleware, verifyCsrf, verifyPassword, withCacheControl, withContextHeaders, withSecurityHeaders, withSpan }; +interface ProblemDetails { + type: string; + title: string; + status: number; + detail?: string; + instance?: string; + code?: string; + [key: string]: unknown; +} +interface ProblemDetailsInput { + type?: string; + title: string; + status: number; + detail?: string; + instance?: string; + code?: string; + [key: string]: unknown; +} +declare function problem(details: ProblemDetailsInput, headers?: HeadersInit): Response; +type ServiceToken<T> = string | symbol | { + readonly key: symbol; + readonly __type?: T; +}; +declare function serviceToken<T>(description: string): ServiceToken<T>; +declare class ServiceContainer { + #private; + private readonly parent?; + constructor(parent?: ServiceContainer | undefined); + set<T>(token: ServiceToken<T>, value: T): this; + has<T>(token: ServiceToken<T>): boolean; + get<T>(token: ServiceToken<T>): T; + tryGet<T>(token: ServiceToken<T>): T | undefined; + scope(): ServiceContainer; +} +type LifecyclePhase = "starting" | "started" | "stopping" | "stopped"; +type LifecycleHandler = (signal: AbortSignal) => void | Promise<void>; +declare class ApplicationLifecycle { + #private; + on(phase: LifecyclePhase, handler: LifecycleHandler): () => void; + run(phase: LifecyclePhase): Promise<void>; + get signal(): AbortSignal; +} +interface HealthCheckResult { + status: "up" | "down" | "degraded"; + message?: string; + details?: unknown; + durationMs?: number; +} +type HealthCheck = () => HealthCheckResult | Promise<HealthCheckResult>; +declare class HealthRegistry { + #private; + register(name: string, check: HealthCheck): () => void; + check(): Promise<{ + status: "up" | "down" | "degraded"; + checks: Record<string, HealthCheckResult>; + }>; +} +declare function requestId(headers: Headers, preferred?: string): string; +interface IdempotencyRecord<T = unknown> { + key: string; + value: T; + expiresAt: number; +} +interface IdempotencyStore<T = unknown> { + get(key: string): Promise<IdempotencyRecord<T> | null>; + set(record: IdempotencyRecord<T>): Promise<void>; + delete(key: string): Promise<void>; +} +declare function memoryIdempotencyStore<T = unknown>(now?: () => number): IdempotencyStore<T>; +declare function withIdempotency<T>(store: IdempotencyStore<T>, key: string, execute: () => Promise<T>, ttlMs?: number): Promise<{ + value: T; + replayed: boolean; +}>; + +export { type ActionDefinition, ApplicationLifecycle, type AsyncSessionBackend, type Bucket, type BudgetViolation, CSRF_COOKIE, CSRF_HEADER, type CacheControlOptions, type CachePolicy, type ContentSecurityPolicyConfig, type Context, type CookieOptions, type CookieStore, type CorsConfig, type CorsOrigin, type CspDirectiveValue, type DefinedAction, type DefinedEndpoint, type DefinedLoader, type EndpointDefinition, EndpointError, type EndpointErrorBody, type FeatureFlags, type FeatureRule, type FeatureValue, type HealthCheck, type HealthCheckResult, HealthRegistry, type HstsConfig, type IdempotencyRecord, type IdempotencyStore, type LifecycleHandler, type LifecyclePhase, type LoaderDefinition, type LocalStorageSnapshot, type Middleware, type Mode, type Next, type PageComponent, type PageMeta, type PerformanceBudgets, type PerformanceMeasurement, type PermissionsPolicyConfig, type ProblemDetails, type ProblemDetailsInput, type RateLimitOptions, type RateLimitStore, type RawSocket, type RealtimeBridge, type RealtimeBus, type RealtimeConnectMeta, type RealtimeEnvelope, type RealtimeHandler, type RealtimeRegistry, type RealtimeSocket, type RequestLoggerOptions, type RequestRecord, type RequireAuthOptions, type Room, type RoomAuthInfo, type RoomClient, type RoomDefinition, type RoomHandlers, type RpcClientOptions, SESSION_USER_KEY, type SaveUploadOptions, type SavedUpload, type SchemaLike, type SecurityConfig, type SeoConfig, type ServerSentEvent, ServiceContainer, type ServiceToken, type SessionBackend, type SessionEntry, type SessionStore, type Span, type SpanRecord, type StreamResponseInit, type TFunction, TTLCache, type Target, type Tenant, type TenantMiddlewareOptions, type TenantResolver, type Tracer, type TrustedTypesConfig, UploadError, bridgeRealtime, cacheControl, checkPerformanceBudgets, collectUploads, createContext, createCorsPreflightResponse, createRealtimeRegistry, createRpcClient, createTracer, csrfProtection, csrfToken, dedupe, defaultKey, defineAction, defineEndpoint, defineFeatureFlags, defineLoader, defineRoom, escapeHtml, etag, getUser, hashPassword, isRoomDefinition, isSafeIslandName, isSafeRequestPath, isWebSocketOriginAllowed, loadSession, logIn, logOut, memoryIdempotencyStore, notModified, peerKey, problem, proxyKey, rateLimit, renderDevError, renderError, renderNotFound, renderProdError, renderStatusPage, requestId, requestLogger, requireAuth, requireTenant, resolveRequestUrl, sanitizeFilename, saveUpload, serviceToken, sessionAuth, setSessionBackend, sse, streamResponse, tenantFromSubdomain, tenantMiddleware, tenantScope, tracingMiddleware, verifyCsrf, verifyPassword, withCacheControl, withContextHeaders, withIdempotency, withSecurityHeaders, withSpan };

    Examples

    Copy-ready examples from the installed package documentation.

    A minimal middleware chain

    import {
       createContext,
       withContextHeaders,
    @@ -1136,7 +1210,7 @@ const registry = createRealtimeRegistry();
     bridgeRealtime(registry, createPubSub(redisDriver(process.env.REDIS_URL)));
    - + } diff --git a/app/pages/packages/csr.wrn b/app/pages/packages/csr.wrn index a05b94db..86951d75 100644 --- a/app/pages/packages/csr.wrn +++ b/app/pages/packages/csr.wrn @@ -10,11 +10,11 @@ page wrnexuscsr {
    W WRNexusJS - +
    -
    Frontend · Package reference

    @wrnexus/csr

    Reactive, navigation, and realtime browser runtimes.

    v0.3.6Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/csr@0.3.6

    Request preview access. Never put registry tokens in source control.

    The browser-side client runtime for WRNexusJS — generic, self-contained JS that hydrates server-rendered pages with reactivity, client-side navigation, and realtime rooms.
    +
    Frontend · Package reference

    @wrnexus/csr

    Reactive, navigation, and realtime browser runtimes.

    v0.4.0Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/csr@0.4.0

    Request preview access. Never put registry tokens in source control.

    The browser-side client runtime for WRNexusJS — generic, self-contained JS that hydrates server-rendered pages with reactivity, client-side navigation, and realtime rooms.

    Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.

    Overview

    @wrnexus/csr holds the three client runtimes that WRNexusJS serves to the browser. Components are authored as .wrn files and rendered on the server; this package provides the single, generic runtime that hydrates that HTML in the browser — there are no per-component browser bundles. Each runtime is exported as a plain-JS string (no build step, no imports) intended to be served verbatim from a well-known URL:

    @@ -251,7 +251,7 @@ room.on("chat", (msg) => console.log(msg.user, msg.text)); room.send({ type: "chat", user: "ada", text: "hi" });
    - + } diff --git a/app/pages/packages/db.wrn b/app/pages/packages/db.wrn index 7bed4fe4..0dd72424 100644 --- a/app/pages/packages/db.wrn +++ b/app/pages/packages/db.wrn @@ -10,11 +10,11 @@ page wrnexusdb {
    W WRNexusJS - +
    -
    Data · Package reference

    @wrnexus/db

    Database adapters, typed queries, models, migrations, and sessions.

    v0.3.6Private registryData

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/db@0.3.6

    Request 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.
    +
    Data · Package reference

    @wrnexus/db

    Database adapters, typed queries, models, migrations, and sessions.

    v0.4.0Private registryData

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/db@0.4.0

    Request 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.

    Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.

    Overview

    @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.

    @@ -200,7 +200,9 @@ declare function parseMigration(name: string, content: string): Migration; declare function loadMigrations(dir: string): Migration[]; /** Names of already-applied migrations, oldest first. */ declare function appliedMigrations(db: Db): Promise<string[]>; -/** Apply all pending migrations (each in a transaction). Returns applied names. */ +/** Apply an ordered migration list (each in a transaction). Returns applied names. */ +declare function applyMigrations(db: Db, migrations: readonly Migration[]): Promise<string[]>; +/** Apply all pending migrations from a directory. */ declare function migrate(db: Db, dir: string): Promise<string[]>; /** Roll back the most recently applied migration. Returns its name, or null. */ declare function rollback(db: Db, dir: string): Promise<string | null>; @@ -301,7 +303,40 @@ interface RelationOptions<C> { */ declare function loadRelated<P extends Row, C extends Row = Row>(db: Db, parents: P[], opts: RelationOptions<C>): Promise<(P & Record<string, C | C[] | null>)[]>; -export { Db, Dialect, type Migration, Model, type ModelRef, type PageOptions, type Paginated, type QueryDef, type QueryKind, type RelationOptions, Row, appliedMigrations, closeDatabases, databaseNames, generateQueriesFile, getDb, hasDb, loadMigrations, loadRelated, migrate, paginate, parseMigration, parseQueries, registerDb, rollback, scaffoldMigration, setDb, status }; +interface CursorPageOptions { + limit?: number; + after?: string; + before?: string; + column?: string; + direction?: "asc" | "desc"; + maxLimit?: number; +} +interface CursorPage<T> { + items: T[]; + nextCursor?: string; + previousCursor?: string; + hasMore: boolean; +} +declare function cursorPaginate<T extends Row = Row>(db: Db, query: { + sql: string; + params?: unknown[]; + model?: Model<T>; +}, options?: CursorPageOptions): Promise<CursorPage<T>>; +declare function optimisticUpdate(db: Db, input: { + table: string; + idColumn?: string; + id: unknown; + versionColumn?: string; + version: number; + values: Record<string, unknown>; +}): Promise<number>; +declare function tenantScope(sql: string, tenantId: unknown, dialect: Dialect, existingParams?: number, column?: string): { + sql: string; + params: unknown[]; +}; +declare function softDeleteClause(column?: string): string; + +export { type CursorPage, type CursorPageOptions, Db, Dialect, type Migration, Model, type ModelRef, type PageOptions, type Paginated, type QueryDef, type QueryKind, type RelationOptions, Row, appliedMigrations, applyMigrations, closeDatabases, cursorPaginate, databaseNames, generateQueriesFile, getDb, hasDb, loadMigrations, loadRelated, migrate, optimisticUpdate, paginate, parseMigration, parseQueries, registerDb, rollback, scaffoldMigration, setDb, softDeleteClause, status, tenantScope };

    Examples

    Copy-ready examples from the installed package documentation.

    Define models, connect, create tables, and query with typed results

    import { v, table, createDb } from "@wrnexus/db";
     import { sqlite } from "@wrnexus/db/sqlite";
     
    @@ -340,7 +375,7 @@ await repo.insert({ email: "a@b.com" });
     const active = await repo.find({ active: true });
    - + } diff --git a/app/pages/packages/dev-server.wrn b/app/pages/packages/dev-server.wrn index e8fc2271..a114fe11 100644 --- a/app/pages/packages/dev-server.wrn +++ b/app/pages/packages/dev-server.wrn @@ -10,11 +10,11 @@ page wrnexusdevserver {
    W WRNexusJS - +
    -
    Runtime · Package reference

    @wrnexus/dev-server

    Development and production servers, HMR, assets, and gateways.

    v0.3.6Private registryRuntime

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/dev-server@0.3.6

    Request 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.
    +
    Runtime · Package reference

    @wrnexus/dev-server

    Development and production servers, HMR, assets, and gateways.

    v0.4.0Private registryRuntime

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/dev-server@0.4.0

    Request 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.

    Overview

    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).

    @@ -231,8 +231,8 @@ import { Router } from '@wrnexus/router'; import { ResolvedTheme, MobileConfig, PwaConfig, ObservabilityConfig, TenancyConfig, StylesConfig, ThemeConfig } from '@wrnexus/styles'; import { ResolvedI18n, I18nConfig } from '@wrnexus/i18n'; import { StorageConfig } from '@wrnexus/uploader'; -import { DevToolbarConfig } from '@wrnexus/dev-toolbar/types'; -import { PluginInput } from '@wrnexus/plugin'; +import { DevToolbarConfig, DevToolbarPlatformSnapshot, DevToolbarPanel } from '@wrnexus/dev-toolbar/types'; +import { ClientRuntimeDefinition, PluginInput } from '@wrnexus/plugin'; import { DevToolbarCollector } from '@wrnexus/dev-toolbar/server'; import { IncomingMessage, ServerResponse, Server } from 'node:http'; @@ -333,6 +333,8 @@ interface RuntimeDeps { inlineStyles?: string; /** Production cache-busting version appended to framework asset URLs. */ assetVersion?: string; + /** Package browser runtimes resolved by the plugin system. */ + clientRuntimes?: ClientRuntimeDefinition[]; /** Raw HTML appended to every page head (e.g. CDN framework links). */ head?: string; /** Global SEO defaults. */ @@ -359,6 +361,8 @@ interface RuntimeDeps { config: DevToolbarConfig; collector: DevToolbarCollector; root: string; + platform?: DevToolbarPlatformSnapshot; + panels?: DevToolbarPanel[]; }; } interface UpgradeServer { @@ -499,6 +503,11 @@ interface ProdManifest { mod: RouteModule; }[]; } +interface ProductionPluginAsset { + path: string; + contentType: string; + immutable?: boolean; +} interface ProdOptions { /** Absolute path to the pre-built global stylesheet, if any. */ stylesPath?: string; @@ -554,6 +563,10 @@ interface ProdOptions { storage?: StorageConfig; /** Cache-busting version appended to framework asset URLs. */ assetVersion?: string; + /** Package browser runtimes already emitted by the production build. */ + clientRuntimes?: ClientRuntimeDefinition[]; + /** Public URL to emitted package asset metadata. */ + pluginAssets?: Record<string, ProductionPluginAsset>; /** Absolute path to copied public assets, if any. */ publicDir?: string; /** Raw HTML appended to every page head. */ @@ -716,7 +729,7 @@ await startGateway({ });
    - + } diff --git a/app/pages/packages/encryption.wrn b/app/pages/packages/encryption.wrn index ed03d884..baed096f 100644 --- a/app/pages/packages/encryption.wrn +++ b/app/pages/packages/encryption.wrn @@ -10,11 +10,11 @@ page wrnexusencryption {
    W WRNexusJS - +
    -
    Security · Package reference

    @wrnexus/encryption

    Hashing, HMAC, authenticated encryption, and key derivation.

    v0.3.6Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/encryption@0.3.6

    Request 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.
    +
    Security · Package reference

    @wrnexus/encryption

    Hashing, HMAC, authenticated encryption, and key derivation.

    v0.4.0Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/encryption@0.4.0

    Request 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.

    Overview

    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).

    @@ -60,7 +60,27 @@ if (!ok) throw new Error("Invalid webhook signature");
  • No dependencies. The package has an empty dependency set; nothing is bundled beyond standard runtime APIs.
  • Algorithms: AES-256-GCM (encryption), PBKDF2 with 100k SHA-256 iterations (key derivation), SHA-256 (digest), HMAC-SHA256 (signing).
  • Keep generated/derived keys and HMAC secrets out of source control; treat them as first-class secrets.
  • -

    Complete TypeScript API

    Generated from the exact installed package declarations.

    /**
    +

    Complete TypeScript API

    Generated from the exact installed package declarations.

    interface EncryptionKey {
    +    id: string;
    +    secret: string;
    +    active?: boolean;
    +    createdAt?: number;
    +}
    +interface EncryptionKeyring {
    +    active(): EncryptionKey;
    +    get(id: string): EncryptionKey | undefined;
    +    keys(): EncryptionKey[];
    +    rotate(key?: EncryptionKey): Promise<EncryptionKey>;
    +    remove(id: string): boolean;
    +}
    +declare function createKeyring(initial: EncryptionKey[]): EncryptionKeyring;
    +/** Versioned payload: `wrn1.<key-id>.<aes-gcm-payload>`. */
    +declare function seal(plaintext: string, keyring: EncryptionKeyring): Promise<string>;
    +declare function open(sealed: string, keyring: EncryptionKeyring): Promise<string>;
    +declare function sealedKeyId(sealed: string): string | null;
    +declare function needsRotation(sealed: string, keyring: EncryptionKeyring): boolean;
    +
    +/**
      * @wrnexus/encryption — authenticated symmetric encryption (AES-256-GCM) via
      * WebCrypto, dependency-free. Use it to encrypt secrets, tokens, or database
      * fields at rest.
    @@ -89,7 +109,7 @@ 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 { decrypt, deriveKey, encrypt, generateKey, hmacSign, hmacVerify, sha256 };
    +export { type EncryptionKey, type EncryptionKeyring, createKeyring, decrypt, deriveKey, encrypt, generateKey, hmacSign, hmacVerify, needsRotation, open, seal, sealedKeyId, sha256 };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Symmetric encryption of a secret at rest

    import { generateKey, encrypt, decrypt } from "@wrnexus/encryption";
     
     const key = await generateKey(); // store this safely (env/secret manager)
    @@ -107,7 +127,7 @@ const ok = await hmacVerify(rawBody, webhookSecret, incomingSignatureHeader);
     if (!ok) throw new Error("Invalid webhook signature");
    - + } diff --git a/app/pages/packages/helpers.wrn b/app/pages/packages/helpers.wrn index 11e553a0..4ba2f760 100644 --- a/app/pages/packages/helpers.wrn +++ b/app/pages/packages/helpers.wrn @@ -10,11 +10,11 @@ page wrnexushelpers {
    W WRNexusJS - +
    -
    Tooling · Package reference

    @wrnexus/helpers

    Safe Context URL helpers and forward-auth login redirects.

    v0.3.6Private registryTooling

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/helpers@0.3.6

    Request 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.

    +
    Tooling · Package reference

    @wrnexus/helpers

    Safe Context URL helpers and forward-auth login redirects.

    v0.4.0Private registryTooling

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/helpers@0.4.0

    Request 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.

    Usage

    @@ -67,6 +67,25 @@ declare function currentAppName(): string | undefined; declare function currentAppOrigin(): string | undefined; declare function workspaceAppOrigins(): Readonly<Record<string, string>>; +interface RetryOptions { + attempts?: number; + minDelayMs?: number; + maxDelayMs?: number; + factor?: number; + jitter?: number; + signal?: AbortSignal; + retryIf?: (error: unknown, attempt: number) => boolean | Promise<boolean>; + onRetry?: (error: unknown, attempt: number, delayMs: number) => void | Promise<void>; +} +declare function backoffDelay(attempt: number, options?: Pick<RetryOptions, "minDelayMs" | "maxDelayMs" | "factor" | "jitter">): number; +declare function sleep(ms: number, signal?: AbortSignal): Promise<void>; +declare function retry<T>(operation: (attempt: number, signal?: AbortSignal) => Promise<T>, options?: RetryOptions): Promise<T>; +declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, message?: string, signal?: AbortSignal): Promise<T>; +declare function stableStringify(value: unknown): string; +declare function safeJsonParse<T>(value: string, fallback: T): T; +declare function clamp(value: number, min: number, max: number): number; +declare function once<T extends (...args: any[]) => any>(fn: T): T; + /** * @wrnexus/helpers — safe conveniences for common WRNexusJS application flows. * @@ -108,7 +127,7 @@ declare function getOriginalRequestOrigin(ctx: RequestContext, options?: Origina */ declare function redirectToLogin(ctx: RequestContext, loginUrl: string | URL, options?: LoginRedirectOptions): Response; -export { type AllowedHosts, type LoginRedirectOptions, type OriginalRequestOptions, type RequestContext, appOrigin, appUrl, currentAppName, currentAppOrigin, getOriginalRequestMethod, getOriginalRequestOrigin, getOriginalRequestPath, getOriginalRequestUrl, redirectToLogin, workspaceAppOrigins }; +export { type AllowedHosts, type LoginRedirectOptions, type OriginalRequestOptions, type RequestContext, type RetryOptions, appOrigin, appUrl, backoffDelay, clamp, currentAppName, currentAppOrigin, getOriginalRequestMethod, getOriginalRequestOrigin, getOriginalRequestPath, getOriginalRequestUrl, once, redirectToLogin, retry, safeJsonParse, sleep, stableStringify, withTimeout, workspaceAppOrigins };

    Examples

    Copy-ready examples from the installed package documentation.

    Redirect an unauthenticated forward-auth request

    import type { Context } from "@wrnexus/core";
     import { redirectToLogin } from "@wrnexus/helpers";
     
    @@ -135,7 +154,7 @@ export const GET = async (ctx: Context) => {
     };
    - + } diff --git a/app/pages/packages/i18n.wrn b/app/pages/packages/i18n.wrn index 226a321f..42dfdf56 100644 --- a/app/pages/packages/i18n.wrn +++ b/app/pages/packages/i18n.wrn @@ -10,11 +10,11 @@ page wrnexusi18n {
    W WRNexusJS - +
    -
    Frontend · Package reference

    @wrnexus/i18n

    Translation loading, locale resolution, and Intl formatting.

    v0.3.6Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/i18n@0.3.6

    Request preview access. Never put registry tokens in source control.

    Per-request translations plus locale-aware number, date, and currency formatting for WRNexusJS apps.
    +
    Frontend · Package reference

    @wrnexus/i18n

    Translation loading, locale resolution, and Intl formatting.

    v0.4.0Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/i18n@0.4.0

    Request 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.

    Overview

    @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.

    @@ -134,6 +134,26 @@ declare function formatRelativeTime(value: number, unit: Intl.RelativeTimeFormat */ declare function plural(count: number, forms: Partial<Record<Intl.LDMLPluralRule, string>>, lang: string): string; +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, { + translated: number; + total: number; + percentage: number; + missing: string[]; + extra: string[]; +}>; +interface LocaleFormatter { + number(value: number, options?: Intl.NumberFormatOptions): string; + currency(value: number, currency: string, options?: Omit<Intl.NumberFormatOptions, "style" | "currency">): string; + date(value: Date | number | string, options?: Intl.DateTimeFormatOptions): string; + 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 formatMessage(template: string, params: Record<string, string | number>, locale: string): string; + /** * @wrnexus/i18n — translations for pages and API responses. * @@ -180,7 +200,7 @@ declare function renderI18nData(i18n: ResolvedI18n, lang: string): string; */ declare const I18N_RUNTIME: string; -export { I18N_JS_HREF, I18N_RUNTIME, type I18nConfig, LANG_COOKIE, type Messages, type ResolvedI18n, formatCurrency, formatDate, formatNumber, formatRelativeTime, loadLocales, makeT, plural, renderI18nData, resolveI18n, resolveLang, translateHtml }; +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,
    @@ -231,7 +251,7 @@ formatRelativeTime(-3, "day", lang); // "3 days ago"
     plural(2, { one: "# item", other: "# items" }, lang); // "2 items"
    - + } diff --git a/app/pages/packages/jwt.wrn b/app/pages/packages/jwt.wrn index f612ec8d..b59301af 100644 --- a/app/pages/packages/jwt.wrn +++ b/app/pages/packages/jwt.wrn @@ -10,11 +10,11 @@ page wrnexusjwt {
    W WRNexusJS - +
    -
    Security · Package reference

    @wrnexus/jwt

    HS256 JWT signing, verification, and bearer authentication.

    v0.3.6Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/jwt@0.3.6

    Request 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.
    +
    Security · Package reference

    @wrnexus/jwt

    HS256 JWT signing, verification, and bearer authentication.

    v0.4.0Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/jwt@0.4.0

    Request 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.

    Overview

    @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.

    @@ -89,6 +89,24 @@ app.use(jwtAuth({ secret: process.env.JWT_SECRET!, required: false }))

    ctx.user; it complements the framework's cookie/session auth with a stateless bearer-token flow for API and mobile clients.

    Complete TypeScript API

    Generated from the exact installed package declarations.

    import { Context, Middleware } from '@wrnexus/core';
     
    +interface JwtKey {
    +    id: string;
    +    secret: string;
    +    active?: boolean;
    +}
    +interface JwtKeyring {
    +    active(): JwtKey;
    +    resolve(id: string): JwtKey | undefined;
    +    keys(): JwtKey[];
    +}
    +declare function decodeJwt(token: string): {
    +    header: Record<string, unknown>;
    +    claims: JwtClaims;
    +};
    +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>;
    +
     /**
      * @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
    @@ -117,13 +135,23 @@ interface SignOptions {
         expiresIn?: number;
         /** Override issued-at (seconds). */
         now?: number;
    +    issuer?: string;
    +    audience?: string | string[];
    +    jwtId?: string;
    +    /** Key identifier placed in the protected header. */
    +    keyId?: string;
    +}
    +interface VerifyOptions {
    +    now?: number;
    +    clockTolerance?: number;
    +    issuer?: string;
    +    audience?: string | string[];
    +    maxAge?: number;
     }
     /** Sign a payload into a JWT (HS256). */
     declare function signJwt(payload: JwtClaims, secret: string, options?: SignOptions): Promise<string>;
     /** Verify a JWT and return its claims. Throws `JwtError` on any failure. */
    -declare function verifyJwt<T extends JwtClaims = JwtClaims>(token: string, secret: string, options?: {
    -    now?: number;
    -}): Promise<T>;
    +declare function verifyJwt<T extends JwtClaims = JwtClaims>(token: string, secret: string, options?: VerifyOptions): Promise<T>;
     interface JwtAuthOptions {
         secret: string;
         /** Where to read the token. Default: `Authorization: Bearer <token>`. */
    @@ -137,7 +165,7 @@ interface JwtAuthOptions {
      */
     declare function jwtAuth(options: JwtAuthOptions): Middleware;
     
    -export { type JwtAuthOptions, type JwtClaims, JwtError, type SignOptions, jwtAuth, signJwt, verifyJwt };
    +export { type JwtAuthOptions, type JwtClaims, JwtError, type JwtKey, type JwtKeyring, type SignOptions, type VerifyOptions, createJwtKeyring, decodeJwt, jwtAuth, signJwt, signWithKeyring, verifyJwt, verifyWithKeyring };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Typical usage

    import { signJwt, verifyJwt, jwtAuth, JwtError } from "@wrnexus/jwt";
     
     const secret = process.env.JWT_SECRET!;
    @@ -164,7 +192,7 @@ app.use(jwtAuth({ secret: process.env.JWT_SECRET! }));
     app.use(jwtAuth({ secret: process.env.JWT_SECRET!, required: false }));
    - + } diff --git a/app/pages/packages/mobile.wrn b/app/pages/packages/mobile.wrn index e73e9f1e..03541915 100644 --- a/app/pages/packages/mobile.wrn +++ b/app/pages/packages/mobile.wrn @@ -10,11 +10,11 @@ page wrnexusmobile {
    W WRNexusJS - +
    -
    Native · Package reference

    @wrnexus/mobile

    SSR-safe compatibility access to Capacitor plugins.

    v0.3.6Private registryNative

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/mobile@0.3.6

    Request preview access. Never put registry tokens in source control.

    SSR-safe access to Capacitor plugins from WRNexusJS browser code.
    +
    Native · Package reference

    @wrnexus/mobile

    SSR-safe compatibility access to Capacitor plugins.

    v0.4.0Private registryNative

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/mobile@0.4.0

    Request preview access. Never put registry tokens in source control.

    SSR-safe access to Capacitor plugins from WRNexusJS browser code.

    Overview

    @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:

    @@ -68,6 +68,44 @@ const status = network ? await network.getStatus() : { connected: true, con

    prefer the higher-level cross-platform capability API.

    Complete TypeScript API

    Generated from the exact installed package declarations.

    export { native } from '@wrnexus/native';
     
    +interface DeepLink {
    +    url: URL;
    +    path: string;
    +    query: URLSearchParams;
    +}
    +declare function parseDeepLink(value: string, schemes?: string[]): DeepLink | null;
    +interface OfflineTask<T = unknown> {
    +    id: string;
    +    type: string;
    +    payload: T;
    +    createdAt: number;
    +    attempts: number;
    +}
    +interface OfflineTaskStore {
    +    load(): Promise<OfflineTask[]>;
    +    save(tasks: OfflineTask[]): Promise<void>;
    +}
    +declare function memoryOfflineTaskStore(): OfflineTaskStore;
    +declare class OfflineQueue {
    +    #private;
    +    private readonly store;
    +    constructor(store?: OfflineTaskStore);
    +    process<T>(type: string, handler: (payload: T) => Promise<void>): void;
    +    add<T>(type: string, payload: T): Promise<OfflineTask<T>>;
    +    sync(limit?: number): Promise<{
    +        completed: number;
    +        failed: number;
    +    }>;
    +    size(): Promise<number>;
    +}
    +interface MobileEnvironment {
    +    platform: string;
    +    native: boolean;
    +    online: boolean;
    +    userAgent?: string;
    +}
    +declare function mobileEnvironment(): MobileEnvironment;
    +
     /** @wrnexus/mobile — SSR-safe access to Capacitor's native bridge. */
     
     type MobilePlatform = "ios" | "android" | "web" | string;
    @@ -103,7 +141,7 @@ declare const mobile: {
         whenNative: typeof whenNative;
     };
     
    -export { type CapacitorBridge, type MobilePlatform, MobileUnavailableError, invoke, isNative, mobile, platform, plugin, registerPlugin, requirePlugin, whenNative };
    +export { type CapacitorBridge, type DeepLink, type MobileEnvironment, type MobilePlatform, MobileUnavailableError, OfflineQueue, type OfflineTask, type OfflineTaskStore, invoke, isNative, memoryOfflineTaskStore, mobile, mobileEnvironment, parseDeepLink, platform, plugin, registerPlugin, requirePlugin, whenNative };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Register and invoke a Capacitor plugin

    import { Camera, CameraResultType } from "@capacitor/camera";
     import { mobile } from "@wrnexus/mobile";
     
    @@ -131,7 +169,7 @@ const network = mobile.plugin<NetworkPlugin>("Network");
     const status = network ? await network.getStatus() : { connected: true, connectionType: "unknown" };
    - + } diff --git a/app/pages/packages/native.wrn b/app/pages/packages/native.wrn index 73db3ed5..606b4fa9 100644 --- a/app/pages/packages/native.wrn +++ b/app/pages/packages/native.wrn @@ -10,11 +10,11 @@ page wrnexusnative {
    W WRNexusJS - +
    -
    Native · Package reference

    @wrnexus/native

    Cross-platform browser and Capacitor capability registry.

    v0.3.6Private registryNative

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/native@0.3.6

    Request preview access. Never put registry tokens in source control.

    Cross-platform capabilities for browsers, Capacitor WebViews, and compiled native apps.
    +
    Native · Package reference

    @wrnexus/native

    Cross-platform browser and Capacitor capability registry.

    v0.4.0Private registryNative

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/native@0.4.0

    Request preview access. Never put registry tokens in source control.

    Cross-platform capabilities for browsers, Capacitor WebViews, and compiled native apps.

    Overview

    @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
    @@ -81,6 +81,35 @@ 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; +interface NativeCapabilityManifestEntry { + name: string; + description?: string; + permissions?: string[]; + targets?: NativeTarget[]; + optional?: boolean; +} +interface NativeCapabilityManifest { + name: string; + version?: string; + capabilities: NativeCapabilityManifestEntry[]; +} +declare function defineNativeManifest<T extends NativeCapabilityManifest>(manifest: T): T; +declare function inspectNativeCapabilities(target?: NativeTarget): Array<{ + name: string; + supported: boolean; +}>; +declare function missingNativeCapabilities(manifest: NativeCapabilityManifest, target?: NativeTarget): NativeCapabilityManifestEntry[]; +interface PermissionAdapter { + query(name: string): Promise<"granted" | "denied" | "prompt" | "unavailable">; + request?(name: string): 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>; +} + declare const native: { isMobile: typeof isMobile; platform: typeof platform; @@ -90,7 +119,7 @@ declare const native: { supports: typeof supports; }; -export { NativeCapability, NativePlatform, NativeRunOptions, NativeTarget, NativeUnavailableError, clearRegistry, isMobile, native, platform, register, registered, run, 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 };

    Examples

    Copy-ready examples from the installed package documentation.

    Share a page when the platform supports it

    import { native } from "@wrnexus/native";
     
     export async function shareCurrentPage() {
    @@ -123,7 +152,7 @@ const position = await native.run(
     );
    - + } diff --git a/app/pages/packages/oauth.wrn b/app/pages/packages/oauth.wrn index fcfbf032..095879c8 100644 --- a/app/pages/packages/oauth.wrn +++ b/app/pages/packages/oauth.wrn @@ -10,11 +10,11 @@ page wrnexusoauth {
    W WRNexusJS - +
    -
    Security · Package reference

    @wrnexus/oauth

    OAuth 2.0, PKCE, provider presets, and profile mapping.

    v0.3.6Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/oauth@0.3.6

    Request 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.
    +
    Security · Package reference

    @wrnexus/oauth

    OAuth 2.0, PKCE, provider presets, and profile mapping.

    v0.4.0Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/oauth@0.4.0

    Request 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.

    Overview

    @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.

    @@ -146,7 +146,34 @@ const gitlab = defineProvider({

    verifier between startAuth and completeAuth (session or signed cookie).

  • Pairs with [@wrnexus/core](../core) — feed the normalized OAuthProfile into
  • logIn to establish a session.

    -

    Complete TypeScript API

    Generated from the exact installed package declarations.

    /**
    +

    Complete TypeScript API

    Generated from the exact installed package declarations.

    interface OAuthStateRecord {
    +    state: string;
    +    verifier: string;
    +    redirectUri: string;
    +    returnTo?: string;
    +    expiresAt: number;
    +}
    +interface OAuthStateStore {
    +    set(record: OAuthStateRecord): Promise<void>;
    +    consume(state: string): Promise<OAuthStateRecord | null>;
    +}
    +declare function memoryOAuthStateStore(now?: () => number): OAuthStateStore;
    +declare function createOAuthState(store: OAuthStateStore, input: Omit<OAuthStateRecord, "state" | "expiresAt"> & {
    +    ttlMs?: number;
    +}): Promise<OAuthStateRecord>;
    +declare function refreshOAuthTokens(provider: OAuthProvider, refreshToken: string, fetchImpl?: typeof fetch): Promise<OAuthTokens>;
    +interface OidcDiscovery {
    +    issuer: string;
    +    authorization_endpoint: string;
    +    token_endpoint: string;
    +    userinfo_endpoint?: string;
    +    jwks_uri: string;
    +    revocation_endpoint?: string;
    +}
    +declare function discoverOidc(issuer: string, fetchImpl?: typeof fetch): Promise<OidcDiscovery>;
    +declare function validateOAuthReturnTo(value: string | undefined, origin: string, fallback?: string): string;
    +
    +/**
      * @wrnexus/oauth — OAuth 2.0 sign-in with any provider. Ships presets for Google,
      * GitHub, and Discord, and `defineProvider` for a custom one. Dependency-free
      * (uses `fetch` + WebCrypto for PKCE). Pairs with @wrnexus/core's `logIn`.
    @@ -235,7 +262,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 OAuthTokens, type ProviderCredentials, type StartAuthOptions, type StartAuthResult, completeAuth, defineProvider, discord, exchangeCode, fetchProfile, github, google, randomToken, startAuth };
    +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 };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Typical usage

    import { google, startAuth, completeAuth } from "@wrnexus/oauth";
     import { logIn } from "@wrnexus/core";
     
    @@ -286,7 +313,7 @@ const gitlab = defineProvider({
     });
    - + } diff --git a/app/pages/packages/pubsub.wrn b/app/pages/packages/pubsub.wrn index 68efebd7..0bd181d4 100644 --- a/app/pages/packages/pubsub.wrn +++ b/app/pages/packages/pubsub.wrn @@ -10,11 +10,11 @@ page wrnexuspubsub {
    W WRNexusJS - +
    -
    Realtime · Package reference

    @wrnexus/pubsub

    In-process and Redis-backed publish/subscribe.

    v0.3.6Private registryRealtime

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/pubsub@0.3.6

    Request 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.
    +
    Realtime · Package reference

    @wrnexus/pubsub

    In-process and Redis-backed publish/subscribe.

    v0.4.0Private registryRealtime

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/pubsub@0.4.0

    Request 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.

    Overview

    @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.

    @@ -94,7 +94,37 @@ driver.close();
  • The Redis driver reads REDIS_URL from the environment when no url is passed.
  • Backs [@wrnexus/core](../core)'s realtime bridge for horizontal scaling.
  • No external npm dependencies — the Redis client is a self-contained RESP codec.
  • -

    Complete TypeScript API

    Generated from the exact installed package declarations.

    /**
    +

    Complete TypeScript API

    Generated from the exact installed package declarations.

    interface MessageEnvelope<T = unknown> {
    +    id: string;
    +    topic: string;
    +    data: T;
    +    timestamp: number;
    +    attempts: number;
    +}
    +interface ResilientPubSubOptions {
    +    retries?: number;
    +    retryDelayMs?: number;
    +    onError?: (error: unknown, envelope: MessageEnvelope) => void;
    +}
    +declare function createResilientPubSub(driver: PubSubDriver, options?: ResilientPubSubOptions): PubSub;
    +interface PresenceMember {
    +    id: string;
    +    metadata?: Record<string, unknown>;
    +    joinedAt: number;
    +    expiresAt: number;
    +}
    +declare class PresenceChannel {
    +    #private;
    +    private readonly ttlMs;
    +    private readonly now;
    +    constructor(ttlMs?: number, now?: () => number);
    +    touch(id: string, metadata?: Record<string, unknown>): PresenceMember;
    +    leave(id: string): boolean;
    +    list(): PresenceMember[];
    +    prune(): number;
    +}
    +
    +/**
      * @wrnexus/pubsub — topic-based publish/subscribe with a pluggable driver.
      * The default is in-process; swap in a Redis/NATS driver for cross-instance
      * messaging (it also backs @wrnexus/core's realtime bridge).
    @@ -119,7 +149,7 @@ declare function memoryDriver(): PubSubDriver;
     /** Create a pub/sub bus over a driver (in-memory by default). */
     declare function createPubSub(driver?: PubSubDriver): PubSub;
     
    -export { type Handler, type PubSub, type PubSubDriver, createPubSub, memoryDriver };
    +export { type Handler, type MessageEnvelope, PresenceChannel, type PresenceMember, type PubSub, type PubSubDriver, type ResilientPubSubOptions, createPubSub, createResilientPubSub, memoryDriver };
     

    Examples

    Copy-ready examples from the installed package documentation.

    In-process (default)

    import { createPubSub } from "@wrnexus/pubsub";
     
     const bus = createPubSub();
    @@ -146,7 +176,7 @@ await bus.publish("order:created", { id: 7 });
     driver.close();
    - + } diff --git a/app/pages/packages/queue.wrn b/app/pages/packages/queue.wrn index f43a6ab1..0cbaf78f 100644 --- a/app/pages/packages/queue.wrn +++ b/app/pages/packages/queue.wrn @@ -10,11 +10,11 @@ page wrnexusqueue {
    W WRNexusJS - +
    -
    Data · Package reference

    @wrnexus/queue

    Background jobs with delay, concurrency, retry, and repetition.

    v0.3.6Private registryData

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/queue@0.3.6

    Request preview access. Never put registry tokens in source control.

    A background job queue with delays, retries + exponential backoff, recurring jobs, and concurrent workers.
    +
    Data · Package reference

    @wrnexus/queue

    Background jobs with delay, concurrency, retry, and repetition.

    v0.4.0Private registryData

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/queue@0.4.0

    Request 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.

    Overview

    @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().

    @@ -106,6 +106,41 @@ const ran = await queue.drain(); // => 1

    pluggable driver is intended for backing it with Redis/SQL for durability.

  • Works alongside @wrnexus/core for offloading work from the request path.
  • Complete TypeScript API

    Generated from the exact installed package declarations.

    /**
    + * Persistence contract for the durable queue.
    + *
    + * Distributed drivers should implement `claim()` atomically and exclude leased
    + * jobs from `due()` until their lease expires. Calling `put()` must replace the
    + * stored record and release any previous lease for that job.
    + */
    +interface QueueStore {
    +    put(job: Job): Promise<void>;
    +    get(id: string): Promise<Job | null>;
    +    remove(id: string): Promise<void>;
    +    due(now: number, limit: number): Promise<Job[]>;
    +    list(name?: string): Promise<Job[]>;
    +    claim?(id: string, worker: string, leaseUntil: number): Promise<boolean>;
    +}
    +declare function memoryQueueStore(): QueueStore;
    +interface DurableQueueOptions {
    +    store?: QueueStore;
    +    workerId?: string;
    +    maxAttempts?: number;
    +    concurrency?: number;
    +    leaseMs?: number;
    +    backoff?: (attempt: number) => number;
    +    now?: () => number;
    +    onDeadLetter?: (job: Job, error: unknown) => void | Promise<void>;
    +}
    +interface DurableQueue {
    +    add<T>(name: string, data: T, options?: AddOptions): Promise<Job<T>>;
    +    process<T>(name: string, handler: JobHandler<T>): void;
    +    drain(): Promise<number>;
    +    failed(): Job[];
    +    retry(id: string): Promise<boolean>;
    +}
    +declare function createDurableQueue(options?: DurableQueueOptions): DurableQueue;
    +
    +/**
      * @wrnexus/queue — a background job queue with delays, retries + backoff, and
      * concurrent workers. The default store is in-process; a pluggable driver lets
      * you back it with Redis/SQL for durability across restarts.
    @@ -187,7 +222,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 Job, type JobDefinition, type JobHandler, type Queue, type QueueOptions, type WorkflowStep, createQueue, cronToInterval, defineJob, defineWorkflow };
    +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 };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Register workers, enqueue jobs, then start the poller

    import { createQueue } from "@wrnexus/queue";
     
     const queue = createQueue({ maxAttempts: 3, backoffMs: 1000 });
    @@ -217,7 +252,7 @@ clock = 5000;
     const ran = await queue.drain(); // => 1
    - + } diff --git a/app/pages/packages/reactive.wrn b/app/pages/packages/reactive.wrn index 5e2da42d..acd71854 100644 --- a/app/pages/packages/reactive.wrn +++ b/app/pages/packages/reactive.wrn @@ -10,11 +10,11 @@ page wrnexusreactive {
    W WRNexusJS - +
    -
    Frontend · Package reference

    @wrnexus/reactive

    Small type-safe reactive signal primitives.

    v0.3.6Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/reactive@0.3.6

    Request preview access. Never put registry tokens in source control.

    Tiny, type-safe reactive primitives (signals) with zero dependencies.
    +
    Frontend · Package reference

    @wrnexus/reactive

    Small type-safe reactive signal primitives.

    v0.4.0Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/reactive@0.4.0

    Request 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.

    Overview

    @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.

    @@ -105,7 +105,35 @@ declare function effect(run: () => void | Cleanup): Cleanup; /** Create a lazily readable derived signal with automatic dependency tracking. */ declare function computed<T>(read: () => T): ReadonlySignal<T>; -export { type Cleanup, type ReadonlySignal, type Signal, type Subscriber, type Unsubscribe, batch, computed, effect, signal, untrack }; +interface WatchOptions<T> { + immediate?: boolean; + equals?: (left: T, right: T) => boolean; +} +declare function watch<T>(read: () => T, listener: (value: T, previous: T | undefined) => void | Cleanup, options?: WatchOptions<T>): Cleanup; +type ResourceStatus = "idle" | "pending" | "success" | "error"; +interface Resource<T> { + data: ReadonlySignal<T | undefined>; + error: ReadonlySignal<unknown>; + status: ReadonlySignal<ResourceStatus>; + loading: ReadonlySignal<boolean>; + run(): Promise<T | undefined>; + abort(reason?: unknown): void; + reset(): void; +} +interface ResourceOptions<T> { + initial?: T; + immediate?: boolean; + keepPrevious?: boolean; +} +declare function resource<T>(loader: (signal: AbortSignal) => Promise<T>, options?: ResourceOptions<T>): Resource<T>; +interface ReactiveScope { + add(cleanup: Cleanup): Cleanup; + dispose(): void; + readonly disposed: boolean; +} +declare function createScope(): ReactiveScope; + +export { type Cleanup, type ReactiveScope, type ReadonlySignal, type Resource, type ResourceOptions, type ResourceStatus, type Signal, type Subscriber, type Unsubscribe, type WatchOptions, batch, computed, createScope, effect, resource, signal, untrack, watch };

    Examples

    Copy-ready examples from the installed package documentation.

    Typical usage

    import { signal } from "@wrnexus/reactive";
     
     const count = signal(0);
    @@ -128,7 +156,7 @@ const user: Signal<{ name: string } | null> = signal(null);
     user.set({ name: "Ada" });
    - + } diff --git a/app/pages/packages/router.wrn b/app/pages/packages/router.wrn index 1d610657..ef85a5d6 100644 --- a/app/pages/packages/router.wrn +++ b/app/pages/packages/router.wrn @@ -10,11 +10,11 @@ page wrnexusrouter {
    W WRNexusJS - +
    -
    Core · Package reference

    @wrnexus/router

    Filesystem discovery, route matching, and typed route generation.

    v0.3.6Private registryCore

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/router@0.3.6

    Request 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.
    +
    Core · Package reference

    @wrnexus/router

    Filesystem discovery, route matching, and typed route generation.

    v0.4.0Private registryCore

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/router@0.4.0

    Request 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.

    Overview

    @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.

    @@ -187,6 +187,23 @@ declare function matchRoute(routes: Route[], pathname: string): RouteMatch | nul declare function generateRoutesFile(pages: Route[]): string; +interface NamedRoute extends Route { + name: string; + metadata?: Record<string, unknown>; +} +interface RouteManifestEntry { + name: string; + path: string; + file: string; + params: ReturnType<typeof getRouteParams>; + metadata?: Record<string, unknown>; +} +declare function routeName(raw: string): string; +declare function nameRoutes(routes: readonly Route[], metadata?: Record<string, Record<string, unknown>>): NamedRoute[]; +declare function createRouteManifest(routes: readonly NamedRoute[]): RouteManifestEntry[]; +declare function routeUrl(route: Pick<NamedRoute, "raw" | "paramMeta">, params?: Record<string, string | number | Array<string | number> | null | undefined>, query?: Record<string, string | number | boolean | null | undefined>): string; +declare function findNamedRoute(routes: readonly NamedRoute[], name: string): NamedRoute; + /** * @wrnexus/router — file-based router. * @@ -199,7 +216,7 @@ declare function generateRoutesFile(pages: Route[]): string; * app/pages/*.wrn api -> embedded /api/* routes * app/pages/*.wrn realtime -> embedded /realtime/* routes * app/middleware/*.ts -> global middleware (alphabetical) - * app/components/*.wrn -> server-rendered components (by basename), + * app/components/*.wrn -> server-rendered components (by declaration), * mounted in a page via data-component="<name>" */ @@ -225,12 +242,22 @@ interface Router { matchApi(pathname: string): RouteMatch | null; matchRealtime(pathname: string): RouteMatch | null; } +interface ExternalRouteDefinition { + kind: "page" | "api" | "realtime"; + path: string; + entry: string; + name?: string; +} interface RouterOptions { /** * Extra directories to scan for `.wrn` components (e.g. `@wrnexus/ui`). * Scanned before `app/components`, so an app component of the same name wins. */ componentDirs?: string[]; + /** Package-owned routes registered by the plugin contribution system. */ + externalRoutes?: ExternalRouteDefinition[]; + /** Package-owned middleware executed before app/middleware. */ + middlewareFiles?: string[]; } /** * Convert a scanned file's relative path into a URL route pattern. @@ -242,7 +269,7 @@ declare function fileToRoute(rel: string, prefix?: string): string; /** Scan an app directory and build all route tables. */ declare function buildRouter(appDir: string, opts?: RouterOptions): Router; -export { type ComponentRef, type Route, type RouteMatch, type Router, type RouterOptions, buildRouter, compileRoutePattern, fileToRoute, findRouteConflicts, generateRoutesFile, getRouteParams, matchRoute, sortRoutes }; +export { type ComponentRef, type ExternalRouteDefinition, type NamedRoute, type Route, type RouteManifestEntry, type RouteMatch, type Router, type RouterOptions, buildRouter, compileRoutePattern, createRouteManifest, fileToRoute, findNamedRoute, findRouteConflicts, generateRoutesFile, getRouteParams, matchRoute, nameRoutes, routeName, routeUrl, sortRoutes };

    Examples

    Copy-ready examples from the installed package documentation.

    Typical usage

    import { buildRouter } from "@wrnexus/router";
     
     const router = buildRouter("./app", {
    @@ -273,7 +300,7 @@ const routes = sortRoutes([{ raw: "/posts/[slug]", file: "
     const m = matchRoute(routes, "/posts/hello"); // { route, params: { slug: "hello" } }
    - + } diff --git a/app/pages/packages/ssr.wrn b/app/pages/packages/ssr.wrn index a684f826..c4ed3138 100644 --- a/app/pages/packages/ssr.wrn +++ b/app/pages/packages/ssr.wrn @@ -10,11 +10,11 @@ page wrnexusssr {
    W WRNexusJS - +
    -
    Runtime · Package reference

    @wrnexus/ssr

    Secure HTML document rendering and SEO metadata.

    v0.3.6Private registryRuntime

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/ssr@0.3.6

    Request 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>.
    +
    Runtime · Package reference

    @wrnexus/ssr

    Secure HTML document rendering and SEO metadata.

    v0.4.0Private registryRuntime

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/ssr@0.4.0

    Request 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.

    Overview

    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.

    @@ -106,6 +106,18 @@ return new Response(html, { headers: { "content-type": " * the browser, which keeps "server-only code" genuinely server-only. */ +interface ScriptAsset { + src: string; + /** Module scripts are the default for backward compatibility. */ + type?: "module" | "classic"; + async?: boolean; + defer?: boolean; + integrity?: string; + crossOrigin?: "anonymous" | "use-credentials"; + nonce?: string; + attributes?: Record<string, string | boolean>; +} +type RenderScript = string | ScriptAsset; interface RenderOptions { /** Page metadata for the document head. */ meta: PageMeta; @@ -119,7 +131,7 @@ interface RenderOptions { * URLs of `<script type="module">` tags to load (e.g. per-island chunks or * the reactive runtime). Only the scripts a page actually needs are passed. */ - scripts?: string[]; + scripts?: RenderScript[]; /** Optional default document title used when meta.title is absent. */ defaultTitle?: string; /** Raw HTML injected at the end of `<head>` (trusted, framework-controlled). */ @@ -153,7 +165,7 @@ interface StreamRenderOptions extends Omit<RenderOptions, "body"> declare function renderDocumentStream(opts: StreamRenderOptions): ReadableStream<Uint8Array>; declare function streamDocumentResponse(opts: StreamRenderOptions, init?: ResponseInit): Response; -export { type RenderOptions, type StreamRenderOptions, renderDocument, renderDocumentStream, streamDocumentResponse }; +export { type RenderOptions, type RenderScript, type ScriptAsset, type StreamRenderOptions, renderDocument, renderDocumentStream, streamDocumentResponse };

    Examples

    Copy-ready examples from the installed package documentation.

    Render an SEO-ready application page

    import { renderDocument } from "@wrnexus/ssr";
     
     const html = renderDocument({
    @@ -186,7 +198,7 @@ return new Response(html, {
     return new Response(html, { headers: { "content-type": "text/html; charset=utf-8" } });
    - + } diff --git a/app/pages/packages/styles.wrn b/app/pages/packages/styles.wrn index 3bf72fc2..47e4bf76 100644 --- a/app/pages/packages/styles.wrn +++ b/app/pages/packages/styles.wrn @@ -10,11 +10,11 @@ page wrnexusstyles {
    W WRNexusJS - +
    -
    Frontend · Package reference

    @wrnexus/styles

    CSS pipeline, themes, fonts, profiles, and application config.

    v0.3.6Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/styles@0.3.6

    Request preview access. Never put registry tokens in source control.

    Global CSS bundling, the --wire-* design-token theme system, and the wrnexus.config.ts app-config loader for WRNexusJS apps.
    +
    Frontend · Package reference

    @wrnexus/styles

    CSS pipeline, themes, fonts, profiles, and application config.

    v0.4.0Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/styles@0.4.0

    Request preview access. Never put registry tokens in source control.

    Global CSS bundling, the --wire-* design-token theme system, and the wrnexus.config.ts app-config loader for WRNexusJS apps.

    Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.

    Overview

    This package owns three server-side concerns that shape every page a WRNexusJS app renders:

    @@ -327,6 +327,12 @@ type Mode = "development" | "production"; interface StyleProcessContext { /** Resolved absolute path to the CSS entry, or null if there is none. */ entryPath: string | null; + /** Original application entry when a package-aware wrapper was generated. */ + originalEntryPath?: string | null; + /** Package component/style directories that processors should scan. */ + sources?: string[]; + /** Package-owned CSS entries automatically imported into the application bundle. */ + entries?: string[]; appDir: string; appRoot: string; mode: Mode; @@ -340,6 +346,10 @@ interface StylesConfig { * used (which already resolves `@import`, including from node_modules). */ process?: (ctx: StyleProcessContext) => string | Promise<string>; + /** Automatically append package scan sources to custom processor input. Default true. */ + includePackageSources?: boolean; + /** Production defaults to throw; development defaults to best-effort fallback. */ + failureMode?: "throw" | "fallback"; } interface MobileConfig { enabled?: boolean; @@ -605,6 +615,27 @@ declare function findStyleEntry(appDir: string, appRoot: string, override?: stri */ declare function bundleCss(entryPath: string, mode: Mode): Promise<string>; +interface CssTokenAudit { + declared: string[]; + used: string[]; + missing: string[]; + unused: string[]; +} +/** Audit framework design-token declarations and var() references. */ +declare function auditWireTokens(css: string): CssTokenAudit; +interface StyleSource { + path: string; + reason?: string; +} +/** Normalize/dedupe Tailwind scan sources without allowing line injection. */ +declare function normalizeStyleSources(values: readonly (string | StyleSource)[]): StyleSource[]; +declare function tailwindSourceDirectives(values: readonly (string | StyleSource)[]): string; +interface ContrastResult { + ratio: number; + level: "fail" | "aa-large" | "aa" | "aaa"; +} +declare function contrast(foreground: string, background: string): ContrastResult | null; + /** * @wrnexus/styles — global stylesheet pipeline + app config. * @@ -618,13 +649,12 @@ declare function bundleCss(entryPath: string, mode: Mode): Promise<string> * Produce the final CSS for an entry: run the config's custom processor if one * is provided (Tailwind/PostCSS/Sass), otherwise use the built-in Bun bundler. * - * If a custom processor throws (e.g. Tailwind can't resolve `tailwindcss` - * because deps aren't installed), we DON'T crash every request — we log a clear, - * actionable message and fall back to best-effort CSS so the app keeps serving. + * Development can fall back to best-effort CSS. Production throws by default so + * a deployment cannot silently ship unprocessed Tailwind/PostCSS directives. */ declare function renderStyles(ctx: StyleProcessContext, styles?: StylesConfig): Promise<string>; -export { type AppConfig, type BuildConfig, type ConfigIssue, type CustomThemePalette, DEFAULT_THEMES, type DevToolbarConfig, type ExperimentalConfig, type ExplainedConfig, type FontConfig, type FontDisplay, type GoogleFont, type LocalFontFace, type MobileConfig, type Mode, type ObservabilityConfig, type PerformanceConfig, type PwaConfig, type ResolvedTheme, type StyleProcessContext, type StylesConfig, type Mode as StylesMode, THEME_COOKIE, THEME_CSS_HREF, THEME_JS_HREF, THEME_PALETTES, THEME_PALETTE_NAMES, type TenancyConfig, type ThemeConfig, type ThemePaletteName, type ThemeTokens, bundleCss, defineConfig, explainAppConfig, findStyleEntry, fontCspSources, headToString, loadAppConfig, loadEnv, loadRawConfig, renderFontHead, renderProductionFontHead, renderStyles, renderThemeCss, renderThemeRuntime, resolveProfile, resolveThemeConfig, resolveThemeName, validateAppConfig }; +export { type AppConfig, type BuildConfig, type ConfigIssue, type ContrastResult, 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 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 ThemeConfig, type ThemePaletteName, type ThemeTokens, auditWireTokens, bundleCss, contrast, defineConfig, explainAppConfig, findStyleEntry, fontCspSources, headToString, loadAppConfig, loadEnv, loadRawConfig, normalizeStyleSources, renderFontHead, renderProductionFontHead, renderStyles, renderThemeCss, renderThemeRuntime, resolveProfile, resolveThemeConfig, resolveThemeName, tailwindSourceDirectives, validateAppConfig };

    Examples

    Copy-ready examples from the installed package documentation.

    wrnexus.config.ts

    import type { AppConfig } from "@wrnexus/styles";
     
     export default {
    @@ -697,7 +727,7 @@ const themeJs = renderThemeRuntime(theme); // served at THEME_JS_HREF
    - + } diff --git a/app/pages/packages/test.wrn b/app/pages/packages/test.wrn index 542c2b34..48f7d34d 100644 --- a/app/pages/packages/test.wrn +++ b/app/pages/packages/test.wrn @@ -10,11 +10,11 @@ page wrnexustest {
    W WRNexusJS - +
    -
    Tooling · Package reference

    @wrnexus/test

    WRNexusJS-aware component, route, and browser testing utilities.

    v0.3.6Private registryTooling

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/test@0.3.6

    Request 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.
    +
    Tooling · Package reference

    @wrnexus/test

    WRNexusJS-aware component, route, and browser testing utilities.

    v0.4.0Private registryTooling

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/test@0.4.0

    Request 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.

    Overview

    @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.

    @@ -99,10 +99,45 @@ test("health endpoint", async () => {

    lazily; it's a dev dependency, not a runtime dependency of this package).

  • Works with the rest of the WRNexusJS toolchain:
  • [@wrnexus/compiler](../compiler) (compiles .wrn sources), [@wrnexus/core](../core) (Context / createContext), [@wrnexus/csr](../csr) (reactive runtime for mountHtml), [@wrnexus/dev-server](../dev-server) (startServer behind createHarness), and [@wrnexus/styles](../styles) (config/env/profile loading for the harness).

    -

    Complete TypeScript API

    Generated from the exact installed package declarations.

    import { Context } from '@wrnexus/core';
    +

    Complete TypeScript API

    Generated from the exact installed package declarations.

    import { ProblemDetails, Context } from '@wrnexus/core';
     export { createContext } from '@wrnexus/core';
     export { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, mock, spyOn, test } from 'bun:test';
     
    +interface TestRequestOptions extends Omit<RequestInit, "body"> {
    +    body?: BodyInit | Record<string, unknown> | URLSearchParams | FormData | null;
    +    baseUrl?: string;
    +}
    +/** Build a web-standard Request with convenient JSON/FormData handling. */
    +declare function testRequest(path?: string, options?: TestRequestOptions): Request;
    +/** Create a complete Context suitable for middleware and route unit tests. */
    +declare function testContext(path?: string, options?: TestRequestOptions): Context;
    +interface JsonResponse<T> {
    +    response: Response;
    +    body: T;
    +}
    +declare function readJsonResponse<T = unknown>(response: Response): Promise<JsonResponse<T>>;
    +declare function expectProblem(response: Response, status?: number): Promise<ProblemDetails>;
    +interface Deferred<T> {
    +    promise: Promise<T>;
    +    resolve(value: T | PromiseLike<T>): void;
    +    reject(reason?: unknown): void;
    +}
    +declare function deferred<T>(): Deferred<T>;
    +interface WaitForOptions {
    +    timeoutMs?: number;
    +    intervalMs?: number;
    +    signal?: AbortSignal;
    +}
    +/** Poll a condition without depending on fake timers or a browser runtime. */
    +declare function waitFor(condition: () => boolean | Promise<boolean>, options?: WaitForOptions): Promise<void>;
    +declare class MemoryCookieJar {
    +    #private;
    +    apply(response: Response): void;
    +    header(): string;
    +    request(path: string, options?: TestRequestOptions): Request;
    +    clear(): void;
    +}
    +
     /**
      * @wrnexus/test — testing utilities for WRNexusJS apps. Runs on `bun test` (via
      * `wrnexus test`). Import everything from one place:
    @@ -158,7 +193,7 @@ interface HarnessOptions {
      */
     declare function createHarness(projectRoot: string, options?: HarnessOptions): Promise<Harness>;
     
    -export { type Harness, type HarnessOptions, callRoute, createHarness, mountHtml, renderComponent };
    +export { type Deferred, type Harness, type HarnessOptions, type JsonResponse, MemoryCookieJar, type TestRequestOptions, type WaitForOptions, callRoute, createHarness, deferred, expectProblem, mountHtml, readJsonResponse, renderComponent, testContext, testRequest, waitFor };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Typical usage

    import { test, expect, renderComponent, mountHtml, createHarness } from "@wrnexus/test";
     
     test("counter renders its label", async () => {
    @@ -185,7 +220,7 @@ test("health endpoint", async () => {
     });
    - + } diff --git a/app/pages/packages/tracking.wrn b/app/pages/packages/tracking.wrn index d7b7440c..bf4950c3 100644 --- a/app/pages/packages/tracking.wrn +++ b/app/pages/packages/tracking.wrn @@ -10,11 +10,11 @@ page wrnexustracking {
    W WRNexusJS - +
    -
    Runtime · Package reference

    @wrnexus/tracking

    Error/event capture, middleware, filtering, and sinks.

    v0.3.6Private registryRuntime

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/tracking@0.3.6

    Request 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.
    +
    Runtime · Package reference

    @wrnexus/tracking

    Error/event capture, middleware, filtering, and sinks.

    v0.4.0Private registryRuntime

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/tracking@0.4.0

    Request 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.

    Overview

    @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.

    @@ -92,6 +92,42 @@ tracker.addSink(anotherSink); // add more sinks later

    sink that throws is swallowed so it can never break the app.

    Complete TypeScript API

    Generated from the exact installed package declarations.

    import { Middleware } from '@wrnexus/core';
     
    +type TelemetryKind = "error" | "event" | "metric" | "span";
    +interface TelemetryEnvelope {
    +    id: string;
    +    kind: TelemetryKind;
    +    name: string;
    +    timestamp: number;
    +    traceId?: string;
    +    userId?: string;
    +    tenantId?: string;
    +    attributes: Record<string, unknown>;
    +    payload?: unknown;
    +}
    +interface TelemetrySink {
    +    name?: string;
    +    send(events: TelemetryEnvelope[]): void | Promise<void>;
    +}
    +interface TelemetryPipeline {
    +    emit(input: Omit<TelemetryEnvelope, "id" | "timestamp"> & Partial<Pick<TelemetryEnvelope, "id" | "timestamp">>): Promise<void>;
    +    flush(): Promise<void>;
    +    close(): Promise<void>;
    +    size(): number;
    +}
    +interface TelemetryPipelineOptions {
    +    sinks: TelemetrySink[];
    +    batchSize?: number;
    +    flushIntervalMs?: number;
    +    maxQueueSize?: number;
    +    sampleRate?: number;
    +    beforeSend?: (event: TelemetryEnvelope) => TelemetryEnvelope | null;
    +    onSinkError?: (error: unknown, sink: TelemetrySink, events: readonly TelemetryEnvelope[]) => void | Promise<void>;
    +    now?: () => number;
    +    random?: () => number;
    +}
    +declare function createTelemetryPipeline(options: TelemetryPipelineOptions): TelemetryPipeline;
    +declare const telemetryConsoleSink: TelemetrySink;
    +
     /**
      * @wrnexus/tracking — error tracking with pluggable sinks. Capture exceptions
      * manually or via middleware, and fan them out to any sink (console by default;
    @@ -129,7 +165,7 @@ interface TrackerOptions {
     declare const consoleSink: ErrorSink;
     declare function createTracker(options?: TrackerOptions): Tracker;
     
    -export { type ErrorEvent, type ErrorSink, type Tracker, type TrackerOptions, consoleSink, createTracker };
    +export { type ErrorEvent, type ErrorSink, type TelemetryEnvelope, type TelemetryKind, type TelemetryPipeline, type TelemetryPipelineOptions, type TelemetrySink, type Tracker, type TrackerOptions, consoleSink, createTelemetryPipeline, createTracker, telemetryConsoleSink };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Manual capture

    import { createTracker, consoleSink } from "@wrnexus/tracking";
     
     const tracker = createTracker({ sinks: [consoleSink] });
    @@ -163,7 +199,7 @@ const tracker = createTracker({
     tracker.addSink(anotherSink); // add more sinks later
    - + } diff --git a/app/pages/packages/ui.wrn b/app/pages/packages/ui.wrn index 1305e93b..45c62b97 100644 --- a/app/pages/packages/ui.wrn +++ b/app/pages/packages/ui.wrn @@ -10,21 +10,21 @@ page wrnexusui {
    W WRNexusJS - +
    -
    Frontend · Package reference

    @wrnexus/ui

    Themeable server-rendered UI components and CSS.

    v0.3.6Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/ui@0.3.6

    Request 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.
    +
    Frontend · Package reference

    @wrnexus/ui

    Themeable server-rendered UI components and CSS.

    v0.4.0Private registryFrontend

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/ui@0.4.0

    Request 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.

    Overview

    @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.

    -

    The complete PDF-aligned catalog currently contains 891 components. The generated COMPONENTS.md and component-reference.json files document every mount name, prop, inferred type, default/required status, slot, event, category, and source file directly from the packaged .wrn source.

    +

    The complete PDF-aligned catalog currently contains 85 components. The generated COMPONENTS.md and component-reference.json files document every mount name, prop, inferred type, default/required status, slot, event, category, and source file directly from the packaged .wrn source.

    bun add @wrnexus/ui
    Private package — the machine must be authenticated to the wrnexus npm org
    (a read token in ~/.npmrc). Requires Bun (Node is not supported).

    In practice you rarely install this directly: @wrnexus/cli and @wrnexus/dev-server already depend on it and wire it into the router for you (see [Auto-discovery](#auto-discovery)).

    Components

    -

    Components live as .wrn files under packages/ui/components/. The mount name is the lowercase file basename (e.g. button.wrndata-component="button"). Each accepts a class prop (appended to its root element) and most render their body from either a named prop or the default slot.

    +

    Components live as .wrn files under packages/ui/components/. The canonical mount name comes from the component declaration (for example, component Button mounts as data-component="Button"). Component lookup is case-insensitive, so existing lowercase mounts continue to work. Each component accepts a class prop (appended to its root element), and most render their body from either a named prop or the default slot.

    Layout

    @@ -40,10 +40,10 @@ page wrnexusui {

    The authoritative, always-current list is uiComponentNames() (below), which reads the component directory at runtime.

    For the full catalog, see [COMPONENTS.md](./COMPONENTS.md). The machine-readable equivalent is exported as @wrnexus/ui/component-reference.json.

    API

    -

    The JS module (@wrnexus/ui) exposes four helpers used by the build tooling to locate the component assets. There is no component code to import — the components are .wrn files rendered server-side.

    +

    The JS module (@wrnexus/ui) exposes five helpers used by the build tooling to locate the component assets. There is no component code to import — the components are .wrn files rendered server-side.

    NamePurposeKey props
    -
    ExportSignatureReturns
    uiComponentsDir() => stringAbsolute path to the .wrn component directory (feed to buildRouter's componentDirs).
    uiCssPath() => stringAbsolute path to ui.css.
    uiCss() => stringThe ui.css file contents (all .wire-* classes, themed via tokens).
    uiComponentNames() => string[]Sorted list of built-in component names (e.g. for wrnexus eject listing).
    +uiComponentsDir() => stringAbsolute path to the .wrn component directory (feed to buildRouter's componentDirs).uiCssPath() => stringAbsolute path to ui.css.uiCss() => stringThe ui.css file contents (all .wire-* classes, themed via tokens).uiComponentNames() => string[]Sorted list of declared built-in component names.uiComponentPath(name: string) => stringAbsolute source path for a declared component name or case-insensitive alias.

    ./ui.css asset export

    package.json also exposes the raw stylesheet as a subpath asset:

    "exports": {
    @@ -96,7 +96,29 @@ const router = buildRouter(appDir, { componentDirs: [uiComponentsDir()] 
     
  • Depends on [@wrnexus/core](../core) (dependencies).
  • theme-toggle relies on the framework's theme runtime, which binds the
  • data-wire-theme-toggle attribute — no per-component JS is required.

    -

    Complete TypeScript API

    Generated from the exact installed package declarations.

    /**
    +

    Complete TypeScript API

    Generated from the exact installed package declarations.

    interface UiComponentMetadata {
    +    name: string;
    +    mount: string;
    +    category?: string;
    +    purpose?: string;
    +    props?: Array<{
    +        name: string;
    +        default?: unknown;
    +    }>;
    +    events?: string[];
    +}
    +interface UiComponentReference {
    +    count: number;
    +    components: UiComponentMetadata[];
    +}
    +declare function uiComponentReference(): UiComponentReference;
    +declare function findUiComponent(name: string): UiComponentMetadata | undefined;
    +declare function auditUiComponents(): Array<{
    +    component: string;
    +    issue: string;
    +}>;
    +
    +/**
      * @wrnexus/ui — the Wire UI component library.
      *
      * Components are `.wrn` files under `components/`, auto-discovered by the
    @@ -117,10 +139,12 @@ declare function uiComponentsDir(): string;
     declare function uiCssPath(): string;
     /** The Wire UI stylesheet contents (all `.wire-*` classes, themed via tokens). */
     declare function uiCss(): string;
    -/** Names of the built-in components (e.g. for `wrnexus eject` listing). */
    +/** Names declared by the bundled components, independent of filename casing. */
     declare function uiComponentNames(): string[];
    +/** Absolute path to a bundled component by its declared component name. */
    +declare function uiComponentPath(name: string): string;
     
    -export { uiComponentNames, uiComponentsDir, uiCss, uiCssPath };
    +export { type UiComponentMetadata, type UiComponentReference, auditUiComponents, findUiComponent, uiComponentNames, uiComponentPath, uiComponentReference, uiComponentsDir, uiCss, uiCssPath };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Auto-discovery

    import { buildRouter } from "@wrnexus/router";
     import { uiComponentsDir } from "@wrnexus/ui";
     
    @@ -131,7 +155,7 @@ const router = buildRouter(appDir, { componentDirs: [uiComponentsDir()] 
     </div>

    Explore the component library

    The component reference now has a dedicated catalog with searchable cards and one complete page per component.

    Browse all 85 components →

    - + } diff --git a/app/pages/packages/uploader.wrn b/app/pages/packages/uploader.wrn index 5e08f373..5d9c172a 100644 --- a/app/pages/packages/uploader.wrn +++ b/app/pages/packages/uploader.wrn @@ -10,11 +10,11 @@ page wrnexusuploader {
    W WRNexusJS - +
    -
    Data · Package reference

    @wrnexus/uploader

    Validated local/S3 uploads and secure file serving.

    v0.3.6Private registryData

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/uploader@0.3.6

    Request 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).

    +
    Data · Package reference

    @wrnexus/uploader

    Validated local/S3 uploads and secure file serving.

    v0.4.0Private registryData

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/uploader@0.4.0

    Request 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).

    Usage

    Configure local and S3 stores

    // wrnexus.config.ts
    @@ -371,7 +371,37 @@ declare function accepts(accept: string[] | undefined, file: {
         name: string;
     }): boolean;
     
    -export { type LocalStoreConfig, type PutMeta, type S3StoreConfig, type StorageConfig, type StorageDriver, type Store, type StoreAccess, type StoreConfig, type StoredObject, UPLOADS_PREFIX, UPLOAD_JS_HREF, UPLOAD_RUNTIME, UploadError, type UploadOptions, type UploadedFile, accepts, configureStorage, contentTypeOf, encodeKey, extForType, extOf, getStore, handleUpload, hasStorage, localDriver, s3Driver, serveFromStore, serveStoredFile, sha256Hex, signS3, storeNames, storedUrl, upload };
    +interface UploadPolicy {
    +    maxBytes?: number;
    +    accept?: string[];
    +    requireChecksum?: boolean;
    +    filenamePattern?: RegExp;
    +}
    +interface UploadInspection {
    +    filename: string;
    +    contentType: string;
    +    size: number;
    +    sha256: string;
    +    extension: string;
    +}
    +declare class UploadPolicyError extends Error {
    +    readonly code: string;
    +    constructor(message: string, code: string);
    +}
    +declare function safeObjectKey(filename: string, prefix?: string): string;
    +declare function inspectUpload(filename: string, bytes: Uint8Array, declaredType?: string): Promise<UploadInspection>;
    +declare function enforceUploadPolicy(inspection: UploadInspection, policy: UploadPolicy, expectedChecksum?: string): void;
    +declare function sniffContentType(bytes: Uint8Array): string | null;
    +interface SignedFileToken {
    +    store: string;
    +    key: string;
    +    expiresAt: number;
    +    disposition?: "inline" | "attachment";
    +}
    +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 };
     

    Examples

    Copy-ready examples from the installed package documentation.

    Configure local and S3 stores

    // wrnexus.config.ts
     import type { AppConfig } from "@wrnexus/styles";
     
    @@ -423,7 +453,7 @@ import { serveFromStore } from "@wrnexus/uploader";
     export const GET = serveFromStore("docs"); // your middleware decides who gets in
    - + } diff --git a/app/pages/packages/validation.wrn b/app/pages/packages/validation.wrn index ecf32219..3697dad0 100644 --- a/app/pages/packages/validation.wrn +++ b/app/pages/packages/validation.wrn @@ -10,11 +10,11 @@ page wrnexusvalidation {
    W WRNexusJS - +
    -
    Security · Package reference

    @wrnexus/validation

    Typed schemas, coercion, validation, and browser descriptors.

    v0.3.6Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/validation@0.3.6

    Request 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.
    +
    Security · Package reference

    @wrnexus/validation

    Typed schemas, coercion, validation, and browser descriptors.

    v0.4.0Private registrySecurity

    Install the package

    After WorkRoot approves private registry access, install the release-aligned package:

    bun add @wrnexus/validation@0.4.0

    Request 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.

    Overview

    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/.

    @@ -140,6 +140,36 @@ const head = `<script>${renderSchemasScript({ signup: signupSche declare function renderSchemasScript(descriptors: Record<string, SchemaDescriptor>): string; declare const VALIDATE_RUNTIME: string; +interface AsyncValidationContext<T> { + value: T; + addIssue(field: keyof T | string, message: string): void; + signal?: AbortSignal; +} +type AsyncRefinement<T> = (context: AsyncValidationContext<T>) => void | Promise<void>; +declare class AsyncObjectSchema<T extends Record<string, unknown> = Record<string, unknown>> { + #private; + readonly base: ObjectSchema; + constructor(base: ObjectSchema); + 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<{ + ok: true; + value: T; +} | { + ok: false; + response: Response; +}>; +interface OpenApiSchema { + type: "object"; + properties: Record<string, Record<string, unknown>>; + required?: string[]; +} +declare function schemaToOpenApi(schema: ObjectSchema | AsyncObjectSchema): OpenApiSchema; +declare function mergeValidationResults<T>(...results: ParseResult<T>[]): ParseResult<T>; + /** * @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 @@ -307,7 +337,7 @@ declare function parseBody<T = Record<string, unknown>>(schema: Obje response: Response; }>; -export { type FieldDescriptor, ObjectSchema, type ParseResult, type RuleDescriptor, type SchemaDescriptor, VALIDATE_RUNTIME, applyRule, checkField, invalid, parseBody, parseEnv, renderSchemasScript, v }; +export { AsyncObjectSchema, type AsyncRefinement, type AsyncValidationContext, type FieldDescriptor, ObjectSchema, type OpenApiSchema, type ParseResult, type RuleDescriptor, type SchemaDescriptor, VALIDATE_RUNTIME, applyRule, asyncSchema, checkField, invalid, mergeValidationResults, parseBody, parseBodyAsync, parseEnv, renderSchemasScript, schemaToOpenApi, v };

    Examples

    Copy-ready examples from the installed package documentation.

    Define a schema and validate an API body

    import { v, parseBody } from "@wrnexus/validation";
     
     export const signupSchema = v.object({
    @@ -343,7 +373,7 @@ const head = `<script>${renderSchemasScript({ signup: signupSche
     // render a <form data-schema="signup"> with [data-error="email"] etc.
    - + } diff --git a/app/pages/releases/0.4.0.wrn b/app/pages/releases/0.4.0.wrn new file mode 100644 index 00000000..00820f6c --- /dev/null +++ b/app/pages/releases/0.4.0.wrn @@ -0,0 +1,17 @@ +page Release040 { + seo { + title = "Release 0.4.0" + description = "WRNexusJS 0.4.0 release notes." + canonical = "https://wrnexusjs.dev/releases/0.4.0" + } + view { + +
    +
    W WRNexusJS
    + +

    WRNexusJS 0.4.0

    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.

    + + +
    + } +} \ No newline at end of file diff --git a/app/pages/roadmap.wrn b/app/pages/roadmap.wrn index 8a01429e..57053e74 100644 --- a/app/pages/roadmap.wrn +++ b/app/pages/roadmap.wrn @@ -7,10 +7,10 @@ page Roadmap { view {
    -
    W WRNexusJS
    +
    W WRNexusJS

    Roadmap

    Roadmap items are direction, not delivery commitments. Dates require explicit owner approval.

    Now

    • Private preview onboarding and accurate package references
    • Runnable documentation fixtures and link/accessibility checks
    • License, support, and disclosure owner decisions

    Next

    • Durable queue driver guidance
    • Expanded database/auth/realtime examples
    • Versioned release notes and migration fixtures

    Later / exploration

    • Historical documentation selector
    • Maintained reproducible benchmarks
    • Broader mobile/native coverage
    - +
    } diff --git a/app/pages/search.wrn b/app/pages/search.wrn index 7c2c0dbf..d658e3c5 100644 --- a/app/pages/search.wrn +++ b/app/pages/search.wrn @@ -7,10 +7,10 @@ page Search { view {
    -
    W WRNexusJS
    +
    W WRNexusJS
    -

    Search documentation

    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.

    Core documentation

    Get started · Packages · Components · Language · Architecture

    Guides

    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

    Package APIs

    @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/cli

    - +

    Search documentation

    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.

    Core documentation

    Get started · Packages · Components · Language · Architecture

    Guides

    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

    Package APIs

    @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/cli

    +
    } diff --git a/app/pages/security.wrn b/app/pages/security.wrn index 8c7c2aa8..f14328e8 100644 --- a/app/pages/security.wrn +++ b/app/pages/security.wrn @@ -7,10 +7,10 @@ page Security { view {
    -
    W WRNexusJS
    +
    W WRNexusJS
    -

    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.

    Supported releases

    Only the current private-preview release 0.3.6 is documented here. A formal old-release support window is not yet published.

    Report a vulnerability

    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.

    Deployment controls

    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.

    - +

    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.

    Supported releases

    Only the current private-preview release 0.4.0 is documented here. A formal old-release support window is not yet published.

    Report a vulnerability

    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.

    Deployment controls

    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.

    +
    } diff --git a/app/pages/showcase.wrn b/app/pages/showcase.wrn index ec5f044d..696f1f9d 100644 --- a/app/pages/showcase.wrn +++ b/app/pages/showcase.wrn @@ -7,10 +7,10 @@ page Showcase { view {
    -
    W WRNexusJS
    +
    W WRNexusJS
    -

    Showcase

    Only confirmed public properties are listed; no customer or traffic claims are made.

    WorkRoot

    Creator/company site demonstrating a public WRNexusJS deployment. Exact deployed version and infrastructure notes await owner confirmation.

    WRNexusJS docs

    This documentation portal, built and verified against WRNexusJS 0.3.6 on Bun.

    Screenshots are intentionally deferred until approved assets and alt text are available.

    - +

    Showcase

    Only confirmed public properties are listed; no customer or traffic claims are made.

    WorkRoot

    Creator/company site demonstrating a public WRNexusJS deployment. Exact deployed version and infrastructure notes await owner confirmation.

    WRNexusJS docs

    This documentation portal, built and verified against WRNexusJS 0.4.0 on Bun.

    Screenshots are intentionally deferred until approved assets and alt text are available.

    +
    } diff --git a/app/pages/support.wrn b/app/pages/support.wrn index 364fe9c5..c2187fc2 100644 --- a/app/pages/support.wrn +++ b/app/pages/support.wrn @@ -7,10 +7,10 @@ page Support { view {
    -
    W WRNexusJS
    +
    W WRNexusJS

    Support

    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.

    - +
    } diff --git a/app/pages/tutorial.wrn b/app/pages/tutorial.wrn index 431da51e..eef0a137 100644 --- a/app/pages/tutorial.wrn +++ b/app/pages/tutorial.wrn @@ -7,9 +7,9 @@ page Tutorial { view {
    -
    W WRNexusJS
    +
    W WRNexusJS
    -
    Preview · runnable-project extraction pending

    Secure task board

    This tutorial connects the installed 0.3.6 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";
    +      
    Preview · runnable-project extraction pending

    Secure task board

    This tutorial connects the installed 0.4.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.

    - +
    } diff --git a/docs/documentation-coverage-matrix.md b/docs/documentation-coverage-matrix.md index 57ddb2ce..17289a74 100644 --- a/docs/documentation-coverage-matrix.md +++ b/docs/documentation-coverage-matrix.md @@ -4,6 +4,7 @@ | -------------------- | --------------------- | ---------------------------- | ---------------- | ------------------ | ------------ | ------------------------ | | @wrnexus/ai | /packages/ai | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | | @wrnexus/authz | /packages/authz | /guides/authorization | Planned | Generator coverage | Preview | No standalone CI fixture | +| @wrnexus/captcha | /packages/captcha | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | | @wrnexus/cli | /packages/cli | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | | @wrnexus/compiler | /packages/compiler | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | | @wrnexus/core | /packages/core | Architecture/package guide | Planned | Generator coverage | Preview | No standalone CI fixture | diff --git a/docs/release-access-status.md b/docs/release-access-status.md index 1206aef3..aa6d4bc3 100644 --- a/docs/release-access-status.md +++ b/docs/release-access-status.md @@ -2,6 +2,6 @@ ## Decision: Mode B — Private Developer Preview -Active version: 0.3.6, derived from package.json#wrnexus.version. All 29 installed @wrnexus packages resolve to 0.3.6 and npm reports restricted access. The repository remote is a private WorkRoot Git service and no public license file exists. +Active version: 0.4.0, derived from package.json#wrnexus.version. All 30 installed @wrnexus packages resolve to 0.4.0 and npm reports restricted access. The repository remote is a private WorkRoot Git service and no public license file exists. -External users cannot execute an installation without approved private registry credentials. The truthful CTA is Request preview access. After approval, the canonical command is bunx @wrnexus/cli@0.3.6 create my-app. Tokens must never appear in documentation or source. +External users cannot execute an installation without approved private registry credentials. The truthful CTA is Request preview access. After approval, the canonical command is bunx @wrnexus/cli@0.4.0 create my-app. Tokens must never appear in documentation or source. diff --git a/docs/site-audit.md b/docs/site-audit.md index 66fb7ba2..3a17133f 100644 --- a/docs/site-audit.md +++ b/docs/site-audit.md @@ -1,18 +1,18 @@ # WRNexusJS site audit -Date: 2026-07-13. Baseline: Bun 1.3.14, framework 0.3.6. +Date: 2026-07-13. Baseline: Bun 1.3.14, framework 0.4.0. ## Baseline results - authenticated private-registry installation: pass. -- docs generation: pass (29 package pages plus portal and guide pages). +- docs generation: pass (30 package pages plus portal and guide pages). - tests, lint, formatting, and production build are required by the release check. - package access remains restricted/private. - repository: private WorkRoot Git remote; no public license file exists. ## Findings -Package documentation, discovery assets, and AI-readable references are generated from the installed release. The 0.3.6 portal includes the helpers package, workspace app addition, and safe forward-auth login redirect guidance. +Package documentation, discovery assets, and AI-readable references are generated from the installed release. The 0.4.0 portal includes the helpers package, workspace app addition, and safe forward-auth login redirect guidance. ## Audit limitations diff --git a/package-lock.json b/package-lock.json index b0ef74ff..3388ed0b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,41 +10,42 @@ "dependencies": { "@iconify-json/lucide": "^1.2.118", "@iconify/tailwind4": "^1.2.3", - "@wrnexus/ai": "^0.3.6", - "@wrnexus/authz": "^0.3.6", - "@wrnexus/compiler": "^0.3.6", - "@wrnexus/core": "^0.3.6", - "@wrnexus/csr": "^0.3.6", - "@wrnexus/db": "^0.3.6", - "@wrnexus/dev-server": "^0.3.6", - "@wrnexus/dev-toolbar": "^0.3.6", - "@wrnexus/encryption": "^0.3.6", - "@wrnexus/helpers": "^0.3.6", - "@wrnexus/i18n": "^0.3.6", - "@wrnexus/jwt": "^0.3.6", - "@wrnexus/mobile": "^0.3.6", - "@wrnexus/native": "^0.3.6", - "@wrnexus/oauth": "^0.3.6", - "@wrnexus/plugin": "^0.3.6", - "@wrnexus/pubsub": "^0.3.6", - "@wrnexus/queue": "^0.3.6", - "@wrnexus/reactive": "^0.3.6", - "@wrnexus/router": "^0.3.6", - "@wrnexus/ssr": "^0.3.6", - "@wrnexus/styles": "^0.3.6", - "@wrnexus/syntax": "^0.3.6", - "@wrnexus/test": "^0.3.6", - "@wrnexus/tracking": "^0.3.6", - "@wrnexus/ui": "^0.3.6", - "@wrnexus/uploader": "^0.3.6", - "@wrnexus/validation": "^0.3.6" + "@wrnexus/ai": "^0.4.0", + "@wrnexus/authz": "^0.4.0", + "@wrnexus/captcha": "^0.4.0", + "@wrnexus/compiler": "^0.4.0", + "@wrnexus/core": "^0.4.0", + "@wrnexus/csr": "^0.4.0", + "@wrnexus/db": "^0.4.0", + "@wrnexus/dev-server": "^0.4.0", + "@wrnexus/dev-toolbar": "^0.4.0", + "@wrnexus/encryption": "^0.4.0", + "@wrnexus/helpers": "^0.4.0", + "@wrnexus/i18n": "^0.4.0", + "@wrnexus/jwt": "^0.4.0", + "@wrnexus/mobile": "^0.4.0", + "@wrnexus/native": "^0.4.0", + "@wrnexus/oauth": "^0.4.0", + "@wrnexus/plugin": "^0.4.0", + "@wrnexus/pubsub": "^0.4.0", + "@wrnexus/queue": "^0.4.0", + "@wrnexus/reactive": "^0.4.0", + "@wrnexus/router": "^0.4.0", + "@wrnexus/ssr": "^0.4.0", + "@wrnexus/styles": "^0.4.0", + "@wrnexus/syntax": "^0.4.0", + "@wrnexus/test": "^0.4.0", + "@wrnexus/tracking": "^0.4.0", + "@wrnexus/ui": "^0.4.0", + "@wrnexus/uploader": "^0.4.0", + "@wrnexus/validation": "^0.4.0" }, "devDependencies": { "@eslint/js": "^9.0.0", "@tailwindcss/cli": "^4.0.0", "@types/bun": "latest", "@types/node": "^26.1.1", - "@wrnexus/cli": "^0.3.6", + "@wrnexus/cli": "^0.4.0", "eslint": "^9.0.0", "prettier": "latest", "tailwindcss": "^4.0.0", @@ -1304,42 +1305,56 @@ } }, "node_modules/@wrnexus/ai": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/ai/-/ai-0.3.6.tgz", - "integrity": "sha512-0FfHe5uFuZEwrNw4Q5M3EZ3T+iWPFhU8BtPT05C+FAqo1WQiSO30gDrim85lUgaqIB3s17hR5o+7AKxrGhBFOw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/ai/-/ai-0.4.0.tgz", + "integrity": "sha512-fbblrY0suzPu+mhmF7S3uVogxW/ze4Gdvlms6k2ex9McQV+w9KM0Zkv2C124ImY34HyC/uVKayL12edih0ourg==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/authz": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/authz/-/authz-0.3.6.tgz", - "integrity": "sha512-lyogAhVoFpeDTCnTtP0aVliXK8epptOb/kSvOF1p5WobR66nC/GEiuYdR463VGjcCEYD7hq29du0GXxXM/igjw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/authz/-/authz-0.4.0.tgz", + "integrity": "sha512-3mj2/DIPG0qgNsjew8GYPq0y+7XJPKxkcMxveXdOBprFSiEgqcMcqJcthX/AlJ3VZuwQcurNOFcouJPe0Y3A3w==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, + "node_modules/@wrnexus/captcha": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/captcha/-/captcha-0.4.0.tgz", + "integrity": "sha512-PFi6i6h7vMUHbReJ3tAtcGq7TrDVQLCgC+CWczT70gMszVo9+Mhh+TNkINlzUL1WUFwChnrL/K6U5xRWcYfDVg==", + "license": "MIT", + "dependencies": { + "@wrnexus/core": "^0.4.0", + "@wrnexus/plugin": "^0.4.0", + "@wrnexus/validation": "^0.4.0" + }, + "engines": { + "bun": ">=1.3.0" + } + }, "node_modules/@wrnexus/cli": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/cli/-/cli-0.3.6.tgz", - "integrity": "sha512-87XNQDTYFRpYAeiR9CbIiYjxHUQ7QEwz6dAidh0ZqQAnAKRKTgQcOAKUWTty0PiF+ttmZ4RQKUHg0Dn4y5OPWw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/cli/-/cli-0.4.0.tgz", + "integrity": "sha512-I4bE61wov5B8USlJYDlqhSutHHXo4QezUYjZesbowN/AKBqEN4rSfKGapCqFjl6VScl3llMsRr/bkYP6+aIZTg==", "dev": true, "license": "MIT", "dependencies": { - "@wrnexus/compiler": "^0.3.6", - "@wrnexus/core": "^0.3.6", - "@wrnexus/csr": "^0.3.6", - "@wrnexus/db": "^0.3.6", - "@wrnexus/dev-server": "^0.3.6", - "@wrnexus/i18n": "^0.3.6", - "@wrnexus/plugin": "^0.3.6", - "@wrnexus/router": "^0.3.6", - "@wrnexus/styles": "^0.3.6", - "@wrnexus/syntax": "^0.3.6", - "@wrnexus/ui": "^0.3.6", - "@wrnexus/validation": "^0.3.6" + "@wrnexus/compiler": "^0.4.0", + "@wrnexus/core": "^0.4.0", + "@wrnexus/csr": "^0.4.0", + "@wrnexus/db": "^0.4.0", + "@wrnexus/dev-server": "^0.4.0", + "@wrnexus/i18n": "^0.4.0", + "@wrnexus/plugin": "^0.4.0", + "@wrnexus/router": "^0.4.0", + "@wrnexus/styles": "^0.4.0", + "@wrnexus/syntax": "^0.4.0", + "@wrnexus/ui": "^0.4.0", + "@wrnexus/validation": "^0.4.0" }, "bin": { "wrnexus": "dist/index.js" @@ -1349,286 +1364,286 @@ } }, "node_modules/@wrnexus/compiler": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/compiler/-/compiler-0.3.6.tgz", - "integrity": "sha512-1tVuE3sFisiwk0pPhFB5XXguTzBi66J1vMen8LtsDp1U/+h1dELvRHLVSiU1yXaVIwOVkaKCdRMSUaT6l6S3eA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/compiler/-/compiler-0.4.0.tgz", + "integrity": "sha512-E0Uj4AYN9JcDDZhhk2QNBM3VioxtP5Q+ASYV33ivgrXPXmmHwDi0Xtfa3D1U3nn7UmdxneBnE57S7Oyy8MBM+w==", "license": "MIT", "dependencies": { - "@wrnexus/syntax": "^0.3.6" + "@wrnexus/syntax": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/core": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/core/-/core-0.3.6.tgz", - "integrity": "sha512-zz5DMlz4OeylWKwYme6g6XFpE7x2Sg8V/b8TdSUjjmEZmATyIti7D/36S3O7iK9uUZi9DZnELuwdk49QzVbQ2w==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/core/-/core-0.4.0.tgz", + "integrity": "sha512-N4Y6O0gSaNEKK24gBu4YTsXBnLnFjaY2WUlobTUOHcV2/h0MOuXjVc6dolQZnRjkza541Wg+exKu6OKmaMQDjg==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/csr": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/csr/-/csr-0.3.6.tgz", - "integrity": "sha512-ejMy+EjVrap6a2uBD0UjQZUveRRPTBf5AkZk9XwL88L08H51poPq9id8HC0UcHd3zgANCL/wg3U0MRqOW1FG0A==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/csr/-/csr-0.4.0.tgz", + "integrity": "sha512-bCu/oonwrIu7rk8F2p2hZ0ch6ijEPeEUPxv021+meOVvj/67GFAS01vaxX5B/Iia0c2Sf+saeIhCtXh/sz72QA==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.3.6" + "@wrnexus/core": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/db": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/db/-/db-0.3.6.tgz", - "integrity": "sha512-f4Q8/fsvzTkjDAav2ZKWVZlM2WLAHjbwAKnbhsw1umNlqZ9rBdqpLt6vrqxeOVz3J8SFrrGPIEoByvrMijMM9A==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/db/-/db-0.4.0.tgz", + "integrity": "sha512-FjjWEF+/mKbmpfL5hGMilcon+uvSbXdTUwuR1ehtRP8Eldg8WqHICYkQtVB5mRnBu8lqwhsfdE5uYbK/a9Jhkg==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/dev-server": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/dev-server/-/dev-server-0.3.6.tgz", - "integrity": "sha512-qqcYmWKafg1V0qIrdFjUQyI52c002Pw/PB/o9HPiHrBUD+xklSQSH7dtpBEnaTO41/e21h3IdX5HULsucEz+og==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/dev-server/-/dev-server-0.4.0.tgz", + "integrity": "sha512-g2NKtIGjWNt3iOppEjt3e7XUQIYqS+yaybzTnCI4KFU31nQwqB8lpr9wl4l7iXD6brBlo0bUBl9c4btfGufgqQ==", "license": "MIT", "dependencies": { - "@wrnexus/compiler": "^0.3.6", - "@wrnexus/core": "^0.3.6", - "@wrnexus/csr": "^0.3.6", - "@wrnexus/db": "^0.3.6", - "@wrnexus/dev-toolbar": "^0.3.6", - "@wrnexus/i18n": "^0.3.6", - "@wrnexus/plugin": "^0.3.6", - "@wrnexus/pubsub": "^0.3.6", - "@wrnexus/router": "^0.3.6", - "@wrnexus/ssr": "^0.3.6", - "@wrnexus/styles": "^0.3.6", - "@wrnexus/ui": "^0.3.6", - "@wrnexus/uploader": "^0.3.6", - "@wrnexus/validation": "^0.3.6" + "@wrnexus/compiler": "^0.4.0", + "@wrnexus/core": "^0.4.0", + "@wrnexus/csr": "^0.4.0", + "@wrnexus/db": "^0.4.0", + "@wrnexus/dev-toolbar": "^0.4.0", + "@wrnexus/i18n": "^0.4.0", + "@wrnexus/plugin": "^0.4.0", + "@wrnexus/pubsub": "^0.4.0", + "@wrnexus/router": "^0.4.0", + "@wrnexus/ssr": "^0.4.0", + "@wrnexus/styles": "^0.4.0", + "@wrnexus/ui": "^0.4.0", + "@wrnexus/uploader": "^0.4.0", + "@wrnexus/validation": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/dev-toolbar": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/dev-toolbar/-/dev-toolbar-0.3.6.tgz", - "integrity": "sha512-HasuumkjrmDVEe4pCwqFSXZBUtuRdQN3jPj4ukJMOFTSXfeewPWOVt2goZ1Z+C2l6Mc3PeP8iGglP+XI6DeMDA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/dev-toolbar/-/dev-toolbar-0.4.0.tgz", + "integrity": "sha512-O/bWHT1TZTsMvY0umVRELcaaw/CcGzjrI/2JNGjaRFrru1ahgF1oq7DNBhBTCfprot/8NI/DdxkVwbgiAfiMlw==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/encryption": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/encryption/-/encryption-0.3.6.tgz", - "integrity": "sha512-0ZtvLCLhYtZNIJsO8ULDn5sZ/sNscvoN4kB3dMc+3/9hRrIdmtYgsIJbf4XPAyUc66Jn9Jb6ZBIZL54kBZaIKg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/encryption/-/encryption-0.4.0.tgz", + "integrity": "sha512-A+fs/mhl8hmdzRrWO3c2baI9L9VZAJEMje/GXI6Z+fVbV2RgN9rjJvCxVJlFAljx8VNllqN3psPMrQEh0ge3Nw==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/helpers": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/helpers/-/helpers-0.3.6.tgz", - "integrity": "sha512-t5iRnu0CYKP1lXzGfDKdUcKtAk27Cn1rCXTwe5NGDnahJQ02qt0aMj8IXHFZOpQUe6fgDZvEr2e++mxeluHp1w==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/helpers/-/helpers-0.4.0.tgz", + "integrity": "sha512-bz5rsnKsgMC1PXqeuM7xbGnIaUsxF8vP01Is3xbUuFnftyNFy/fwb5zJVU/TPL3O2dft52e9vqOy1UbKBMH+Sg==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.3.6" + "@wrnexus/core": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/i18n": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/i18n/-/i18n-0.3.6.tgz", - "integrity": "sha512-JGK94frba8Q7aTwhuRmZpK5sk0fiEZHpMGtYkIb0j/4//fpCT8ES9LJUmtzoDkbomVJlPsNQ5+FNWUoQCimZew==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/i18n/-/i18n-0.4.0.tgz", + "integrity": "sha512-wOyLplDrweV6UO5tOjhvhr8hyFCgNNlkONnaXUPFe8i11Xj+5bOtBo4cYsKR7KqbaAHG/Xx0AceBW5ppYheAow==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.3.6" + "@wrnexus/core": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/jwt": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/jwt/-/jwt-0.3.6.tgz", - "integrity": "sha512-GWocHWynPdebjWdXo2YSuV3YauGJHBxvReB4tWF9ZeA2BwPgy8bfkSk20jFC+Jmlt9Rrj3tzubWP3+ryKo4LsQ==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/jwt/-/jwt-0.4.0.tgz", + "integrity": "sha512-TJdwiSfk5hpQCY3Jnn9XHPVjo/BAJirLn3LxOSf7oA7toPuZ0t+Zegt3lyE1YocfbwRUXBhUzayojloJF0aINw==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/mobile": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/mobile/-/mobile-0.3.6.tgz", - "integrity": "sha512-8xcRSOzCkXGgRuZgA2AzArgoN1osjo/Z6zJwTk9XQg6e32YgouOJ4DEqW653R689JDm2IzW5/TbBqBTVcYZ+sA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/mobile/-/mobile-0.4.0.tgz", + "integrity": "sha512-2IXD4WdK12y7SihqcF0iOE2zsUtIJ+SiI71k4E3LRaFjt2qFzcY/v77T8rSBHMVJLTlMJCEoYIxRcsC5NuHACA==", "license": "MIT", "dependencies": { - "@wrnexus/native": "^0.3.6" + "@wrnexus/native": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/native": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/native/-/native-0.3.6.tgz", - "integrity": "sha512-4VmYE5qZ3UJ305+8C6NpTfa86F2b4N/Ch0N0zohryCfj2ncOVYiGmsL8k3/K2frKIgAHWzLkLtCACxSPpCvs5A==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/native/-/native-0.4.0.tgz", + "integrity": "sha512-SY1PxVk7Jsaus7ag7eUaQA1E6BKeL1PW0aWyks+6YnNnqkfyu+IObSVvoX7hxaWEDnNR+um+mcwwT+38pfcpcg==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/oauth": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/oauth/-/oauth-0.3.6.tgz", - "integrity": "sha512-W2zXWxAAZp4xWuT6Vbkb/2LBJODNMuBOJimS+0PgDSn4cWwnk6u/yS89rzWXMUAHJIRTrqZp+OhTp1HA6uBTVw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/oauth/-/oauth-0.4.0.tgz", + "integrity": "sha512-eAlyvvXdJMTdbsQd5HpryjVU+jNB1RKNrYIo1RqDhiE/beApt2SlkcWkMUKub30iBZOtLDYekSZH1BJevuPtNA==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/plugin": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/plugin/-/plugin-0.3.6.tgz", - "integrity": "sha512-XXP+NoyqIMR5hL3yQ7yQQXhIdS1SxEW2v4duP561u5E3l9kl+P6vViACf603MqjV1VSZupHeuBRGl8BL9SGrYg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/plugin/-/plugin-0.4.0.tgz", + "integrity": "sha512-IOudqyNkiBUxylECudE1hpt6SG8Q3k3qffQzR+stEVTgTZz5HVWaRTaPk4d49/wC0tnzGE121HLVgDwF/KCubg==", "license": "MIT", "dependencies": { - "@wrnexus/syntax": "^0.3.6" + "@wrnexus/syntax": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/pubsub": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/pubsub/-/pubsub-0.3.6.tgz", - "integrity": "sha512-G/W14++6rQDfRQUmrqwW6guKln+beri6yHDvgMflXeA3XoUdp1MY0K4HDl36bGSXWsrfqOQ/Aa9RQEKEkn9FIg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/pubsub/-/pubsub-0.4.0.tgz", + "integrity": "sha512-SNrzUt+DFmriglzQRFbV2LysbIOV3CRQ4jUUtL9mgoX6vXtEbCrx/+nfoaYZRZgtqEk2YxEQR7gwUQ3PiiaziQ==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/queue": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/queue/-/queue-0.3.6.tgz", - "integrity": "sha512-gAeoLTwxZ0jYRf4bHEDCG1OBjh6JU5h6HQCySggpqdsJVR9a2xpJSBIwSyV4sgII1lBvjwKW3cGUtyioAvlykA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/queue/-/queue-0.4.0.tgz", + "integrity": "sha512-QoB/Hi4jnoWH+n4k2Qqiq3dPWugOxZq7blV4SfqfcrIRvDAmCuTqUzLL0p812XVvnyaXDaqeJxaMnwBA0DRFow==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/reactive": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/reactive/-/reactive-0.3.6.tgz", - "integrity": "sha512-B5tQ4KDjwfBd0ZxPBZHIvdZcteKK69pAFqYCq1MlcGIsLBdUQrhK1XOMQ5/jHTyH2q7a/t8lkrwc8l95flzJKw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/reactive/-/reactive-0.4.0.tgz", + "integrity": "sha512-XYthkvTdvILPY5ltLEP2WGRfC8/5h9td5n7bbrLGp3rzyirBRloDeiKIAtvXaw7uz1D7BiMZD6o4QdUJyXScrA==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/router": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/router/-/router-0.3.6.tgz", - "integrity": "sha512-HHpV4GR9bvUtYm6jPVLxThXH7+X5UTSFW7ri9eh8nZFEzDDV0TN9Q98x/wYxQXvOfQRUUFCyIJX4f4fZZKF26Q==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/router/-/router-0.4.0.tgz", + "integrity": "sha512-qEqN0haUkvhreGuO5DpZ+U3a7EhuBgD8rOabHb1wiK3/ltMA550W4BL1oOtEea/oAKMgrlQTjrsWniHOB9jNrg==", "license": "MIT", "dependencies": { - "@wrnexus/compiler": "^0.3.6", - "@wrnexus/core": "^0.3.6" + "@wrnexus/compiler": "^0.4.0", + "@wrnexus/core": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/ssr": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/ssr/-/ssr-0.3.6.tgz", - "integrity": "sha512-f5Gn+ZcZJsNxp0fj6oyM0X+1axH3LANKD/Ms47x3ei82MxHIn/2/EHHx+qYIGIlQyiw4zgW93oOK8qG0gCtFPg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/ssr/-/ssr-0.4.0.tgz", + "integrity": "sha512-7Slmf94KifALpkihbls5ttTsWUndxMnsCOg/OXQszvxaVDbqUS/fP9fMYRHgoFSBI4nR+e6a3J51VGjdQbnJHw==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.3.6" + "@wrnexus/core": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/styles": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/styles/-/styles-0.3.6.tgz", - "integrity": "sha512-y2/8/Ow3FAmEJexpcID2Ih/Bts9CziYJ/V1w9xWhWCRYtGP5ulVVpfnS7w8I3KFENUJYNYB5P0Q76Q5G+yE2qg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/styles/-/styles-0.4.0.tgz", + "integrity": "sha512-kEVZX/nmBjvoUBbywyhzwM/XcURfmyb6asd7VrZjM3dvcUVCW28xLpcaMIRd/V74zUVJd283J5Oa9T89w5H6CA==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.3.6", - "@wrnexus/plugin": "^0.3.6", - "@wrnexus/uploader": "^0.3.6" + "@wrnexus/core": "^0.4.0", + "@wrnexus/plugin": "^0.4.0", + "@wrnexus/uploader": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/syntax": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/syntax/-/syntax-0.3.6.tgz", - "integrity": "sha512-dkr/RNiBVsF7niZajBJnSx1JuhDTgXxIQwgBjt7aeeZM9HJoIl687GQ8u9IIY4OXattdgvAoj/vpc0r+dIqjZQ==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/syntax/-/syntax-0.4.0.tgz", + "integrity": "sha512-p2MF32Fw6jVtroSL2UwCY5S792vLogn6WATPXgcwkELadyHxHUl5vcgzAzYCb2hX9t8/qUsWFjKhNeTUZXsQmg==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/test": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/test/-/test-0.3.6.tgz", - "integrity": "sha512-GTxjKQEMuu+zL2EPvS4eCQ9ZEXNvZ5Zjh4ZTJYaPaTBxmb/npyAt9r1zrHM6qAsVqa80qUBoXoJ1fKUJh87xZw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/test/-/test-0.4.0.tgz", + "integrity": "sha512-d3pYHQQltHgWuYI6QP68TkiUIiiHybCsXXx6JIwjudvWKeSKHMwpR7W50QOYQG3nbx//rwQsXV7wmLXQV5fpOA==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/tracking": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/tracking/-/tracking-0.3.6.tgz", - "integrity": "sha512-+fuEBvtucYXGGsxYHDadd4pI4ubXGokKfsKmybA4PFEQ2NF4FL7UOfQrrmVW3/GW0tB5cI706AryRLwRHPljPg==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/tracking/-/tracking-0.4.0.tgz", + "integrity": "sha512-7mBX29IX1h9d8OhHO38jDSmpkcoKWd6Y1LCXmgFS+mCatr6jXBs1xdhMGuvsyCbQBNJ8HMqICMP4ar4SNFvlfg==", "license": "MIT", "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/ui": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/ui/-/ui-0.3.6.tgz", - "integrity": "sha512-kvClqqCBHdW8u+0kIddAoo4ccfjeMjLaT5n5PX2U3S1CsJz/NyGuD2j82Vb76CYYB6pxJsUk2SwlCnCvzvKsCw==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/ui/-/ui-0.4.0.tgz", + "integrity": "sha512-xDMyMyM066XBDgmQu1lNW/i+8caDL/4S3M9w6wfuXMXFLEDWCFkDhS2PZox5UY4E6TGWkBGYKYj54lzGZoSosg==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.3.6" + "@wrnexus/core": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/uploader": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/uploader/-/uploader-0.3.6.tgz", - "integrity": "sha512-tCQhnHjAAYZM6uLiu2byDWMMAQpPV+DmsUKfxFGwcleP0PdVI1lMp6AgFD4WtdRtmiA7M4YIocTk8BW3MK5UNA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/uploader/-/uploader-0.4.0.tgz", + "integrity": "sha512-Hc6jfPEl7jGokgNkIpP7dAQrQrwFZcUHNT1FfnN4CI1gcQfLLsx2VMZv68V84Zq9lDHYNjJOZqK768v8yUTOMQ==", "license": "MIT", "dependencies": { - "@wrnexus/core": "^0.3.6" + "@wrnexus/core": "^0.4.0" }, "engines": { "bun": ">=1.3.0" } }, "node_modules/@wrnexus/validation": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@wrnexus/validation/-/validation-0.3.6.tgz", - "integrity": "sha512-EfMgLilu0aykxdMwyc0azuoo/SVp8TatvHsg7w5yYsRE8FKYUFAWt8Ct/kC06QBAa0fvIQpkogH2rC8HAXY4wA==", + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@wrnexus/validation/-/validation-0.4.0.tgz", + "integrity": "sha512-Eytpznn0+7Q4xDGTDIdvlLezw2wOEtps1yvTHzYcoHASxpp560x11PBppd4eD+2sbhjBM5xa8wkdPsejg1Ga1g==", "license": "MIT", "engines": { "bun": ">=1.3.0" diff --git a/public/docs-index.json b/public/docs-index.json index ed2df118..8266a551 100644 --- a/public/docs-index.json +++ b/public/docs-index.json @@ -1,5 +1,5 @@ { - "version": "0.3.6", + "version": "0.4.0", "status": "private-developer-preview", "generatedAt": "2026-07-13", "documents": [ @@ -7,1099 +7,1106 @@ "url": "/", "title": "WRNexusJS", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/access", "title": "access", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/getting-started", "title": "getting started", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/tutorial", "title": "tutorial", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/architecture", "title": "architecture", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/language", "title": "language", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages", "title": "packages", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components", "title": "components", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/project-structure", "title": "project structure", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/routing", "title": "routing", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/pages-and-components", "title": "pages and components", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/server-data", "title": "server data", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/api-routes", "title": "api routes", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/middleware", "title": "middleware", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/forms-and-validation", "title": "forms and validation", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/authentication", "title": "authentication", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/authorization", "title": "authorization", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/security", "title": "security", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/database", "title": "database", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/uploads", "title": "uploads", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/realtime", "title": "realtime", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/pubsub", "title": "pubsub", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/queues", "title": "queues", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "experimental" }, { "url": "/guides/testing", "title": "testing", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/workspaces-and-gateway", "title": "workspaces and gateway", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/deployment", "title": "deployment", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/configuration-and-profiles", "title": "configuration and profiles", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/i18n-and-themes", "title": "i18n and themes", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/mobile", "title": "mobile", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "experimental" }, { "url": "/guides/observability", "title": "observability", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/upgrading", "title": "upgrading", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/guides/troubleshooting", "title": "troubleshooting", "section": "guide", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/examples", "title": "examples", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/showcase", "title": "showcase", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/benchmarks", "title": "benchmarks", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/roadmap", "title": "roadmap", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/changelog", "title": "changelog", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { - "url": "/releases/0.3.6", - "title": "0.3.6", + "url": "/releases/0.4.0", + "title": "0.4.0", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/security", "title": "security", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/support", "title": "support", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/license", "title": "license", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/search", "title": "search", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/404", "title": "404", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/ai", "title": "ai", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/authz", "title": "authz", "section": "package", - "version": "0.3.6", + "version": "0.4.0", + "stability": "preview" + }, + { + "url": "/packages/captcha", + "title": "captcha", + "section": "package", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/cli", "title": "cli", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/compiler", "title": "compiler", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/core", "title": "core", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/csr", "title": "csr", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/db", "title": "db", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/dev-server", "title": "dev server", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/dev-toolbar", "title": "dev toolbar", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/encryption", "title": "encryption", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/helpers", "title": "helpers", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/i18n", "title": "i18n", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/jwt", "title": "jwt", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/mobile", "title": "mobile", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "experimental" }, { "url": "/packages/native", "title": "native", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/oauth", "title": "oauth", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/plugin", "title": "plugin", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/pubsub", "title": "pubsub", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/queue", "title": "queue", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/reactive", "title": "reactive", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/router", "title": "router", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/ssr", "title": "ssr", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/styles", "title": "styles", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/syntax", "title": "syntax", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/test", "title": "test", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/tracking", "title": "tracking", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/ui", "title": "ui", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/uploader", "title": "uploader", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/packages/validation", "title": "validation", "section": "package", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/accordion", "title": "accordion", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/advanced-date-picker", "title": "advanced date picker", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/advanced-range-slider", "title": "advanced range slider", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/advanced-select", "title": "advanced select", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/alert", "title": "alert", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/avatar", "title": "avatar", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/avatar-group", "title": "avatar group", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/badge", "title": "badge", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/blockquote", "title": "blockquote", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/breadcrumb", "title": "breadcrumb", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/button", "title": "button", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/button-group", "title": "button group", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/card", "title": "card", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/carousel", "title": "carousel", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/chart", "title": "chart", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/chat-bubble", "title": "chat bubble", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/checkbox", "title": "checkbox", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/clipboard", "title": "clipboard", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/collapse", "title": "collapse", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/color-picker", "title": "color picker", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/columns", "title": "columns", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/combo-box", "title": "combo box", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/confetti", "title": "confetti", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/container", "title": "container", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/context-menu", "title": "context menu", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/copy-markup", "title": "copy markup", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/custom-scrollbar", "title": "custom scrollbar", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/data-map", "title": "data map", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/data-table", "title": "data table", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/date-picker", "title": "date picker", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/device-frame", "title": "device frame", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/divider", "title": "divider", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/drag-and-drop", "title": "drag and drop", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/drawer", "title": "drawer", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/dropdown", "title": "dropdown", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/file-input", "title": "file input", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/file-upload", "title": "file upload", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/file-upload-progress", "title": "file upload progress", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/grid", "title": "grid", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/image", "title": "image", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/input", "title": "input", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/input-group", "title": "input group", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/input-number", "title": "input number", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/kbd", "title": "kbd", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/layout-splitter", "title": "layout splitter", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/legend-indicator", "title": "legend indicator", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/link", "title": "link", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/list", "title": "list", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/list-group", "title": "list group", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/map", "title": "map", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/marquee", "title": "marquee", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/mega-menu", "title": "mega menu", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/modal", "title": "modal", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/nav", "title": "nav", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/navbar", "title": "navbar", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/pagination", "title": "pagination", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/pin-input", "title": "pin input", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/popover", "title": "popover", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/progress", "title": "progress", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/radio", "title": "radio", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/range-slider", "title": "range slider", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/rating", "title": "rating", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/scrollspy", "title": "scrollspy", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/search-box", "title": "search box", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/select", "title": "select", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/sidebar", "title": "sidebar", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/skeleton", "title": "skeleton", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/spinner", "title": "spinner", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/stepper", "title": "stepper", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/strong-password", "title": "strong password", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/styled-icon", "title": "styled icon", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/switch", "title": "switch", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/table", "title": "table", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/tabs", "title": "tabs", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/textarea", "title": "textarea", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/timeline", "title": "timeline", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/time-picker", "title": "time picker", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/toast", "title": "toast", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/toast-notifications", "title": "toast notifications", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/toggle-count", "title": "toggle count", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/toggle-password", "title": "toggle password", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/tooltip", "title": "tooltip", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/tree-view", "title": "tree view", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/typography", "title": "typography", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" }, { "url": "/components/wysiwyg-editor", "title": "wysiwyg editor", "section": "portal", - "version": "0.3.6", + "version": "0.4.0", "stability": "preview" } ] diff --git a/public/llms-full.txt b/public/llms-full.txt index ad8e7bce..5c1097fc 100644 --- a/public/llms-full.txt +++ b/public/llms-full.txt @@ -1,4 +1,4 @@ -# WRNexusJS 0.3.6 comprehensive documentation index +# WRNexusJS 0.4.0 comprehensive documentation index Status: Private Developer Preview. Runtime: Bun. UI language: .wrn. This is the documentation application, not the framework monorepo. @@ -40,7 +40,7 @@ This is the documentation application, not the framework monorepo. - https://wrnexusjs.dev/benchmarks - https://wrnexusjs.dev/roadmap - https://wrnexusjs.dev/changelog -- https://wrnexusjs.dev/releases/0.3.6 +- https://wrnexusjs.dev/releases/0.4.0 - https://wrnexusjs.dev/security - https://wrnexusjs.dev/support - https://wrnexusjs.dev/license @@ -48,6 +48,7 @@ This is the documentation application, not the framework monorepo. - https://wrnexusjs.dev/404 - https://wrnexusjs.dev/packages/ai - https://wrnexusjs.dev/packages/authz +- https://wrnexusjs.dev/packages/captcha - https://wrnexusjs.dev/packages/cli - https://wrnexusjs.dev/packages/compiler - https://wrnexusjs.dev/packages/core @@ -462,9 +463,9 @@ Events: none ### InputNumber Mount: data-component="InputNumber" Category: advanced-forms -Props: size: string = "default", color: string = "primary", label: string = "Input Number", name: string = "", value: string = "", placeholder: string = "", type: string = "number", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Props: size: string = "default", color: string = "primary", variant: string = "default", class: string = "", id: string = "", name: string = "quantity", value: number = 0, min: string = "", max: string = "", step: number = 1, precision: string = "auto", label: string = "", description: string = "", helpText: string = "", error: string = "", invalid: boolean = false, prefix: string = "", suffix: string = "", placeholder: string = "", autocomplete: string = "off", inputMode: string = "decimal", ariaLabel: string = "", required: boolean = false, disabled: boolean = false, inputDisabled: boolean = false, buttonsDisabled: boolean = false, readonly: boolean = false, allowInput: boolean = true, keyboard: boolean = true, wheel: boolean = false, clamp: boolean = true, fullWidth: boolean = false, showButtons: boolean = true, showValidationMessage: boolean = true, decrementLabel: string = "Decrease value", incrementLabel: string = "Increase value", controlsLabel: string = "Quantity controls", requiredMessage: string = "A value is required.", minMessage: string = "Value is below the minimum.", maxMessage: string = "Value is above the maximum." Slots: none -Events: none +Events: input, change, increment, decrement ### Kbd Mount: data-component="Kbd" diff --git a/public/llms.txt b/public/llms.txt index 490c0208..54e6a14c 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -1,4 +1,4 @@ -# WRNexusJS documentation 0.3.6 +# WRNexusJS documentation 0.4.0 Status: Private Developer Preview. This site documents 29 release-aligned packages. @@ -15311,9 +15311,1207 @@ Props: size: string = "default", color: string = "primary", title: string = "Wys Slots: default Events: none +# UI component catalog + +The installed @wrnexus/ui release contains 85 documented components. Every mount name, prop type, required/default status, slot, and event is included below and in llms-full.txt. + +### Accordion +Mount: data-component="Accordion" +Category: base +Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, class: string = "" +Slots: default +Events: none + +### AdvancedDatePicker +Mount: data-component="AdvancedDatePicker" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Advanced Date Picker", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### AdvancedRangeSlider +Mount: data-component="AdvancedRangeSlider" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Advanced Range Slider", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### AdvancedSelect +Mount: data-component="AdvancedSelect" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Advanced Select", name: string = "", value: string = "", values: string = [], options: string = [], groups: string = [], placeholder: string = "Select an option", placeholderIcon: string = "", searchPlaceholder: string = "Search options…", multiple: boolean = false, searchable: boolean = true, defaultOpen: boolean = false, clearable: boolean = true, allowEmpty: boolean = true, tags: boolean = false, disabled: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", helpText: string = "", loading: boolean = false, loadingLabel: string = "Loading options…", emptyLabel: string = "No options found", selectedOptionsLabel: string = "Selected options", clearLabel: string = "Clear selection", createLabel: string = "Create", loadMoreLabel: string = "Load more", searchMode: string = "contains", searchFields: string = "label,description", minSearchLength: number = 0, searchResultLimit: number = 0, maxSelections: number = 0, showCounter: boolean = false, counterTemplate: string = "{selected} selected", optionTemplate: string = "default", selectedTemplate: string = "default", closeOnSelect: boolean = true, scrollToSelected: boolean = true, fixed: boolean = false, placement: string = "bottom", remote: boolean = false, remoteUrl: string = "", remoteQueryParam: string = "q", remoteDebounce: number = 250, remoteAutoLoad: boolean = true, infinite: boolean = false, hasMore: boolean = false, page: number = 1, class: string = "" +Slots: none +Events: search, select, change, clear, open, close, load, error + +### Alert +Mount: data-component="Alert" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Alert", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Avatar +Mount: data-component="Avatar" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Avatar", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### AvatarGroup +Mount: data-component="AvatarGroup" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Avatar Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Badge +Mount: data-component="Badge" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Badge", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Blockquote +Mount: data-component="Blockquote" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Blockquote", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Breadcrumb +Mount: data-component="Breadcrumb" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Breadcrumb", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Button +Mount: data-component="Button" +Category: base +Props: label: string = "Button", loadingLabel: string = "Loading…", description: string = "", as: string = "", href: string = "", target: string = "", rel: string = "", type: string = "button", variant: string = "default", color: string = "primary", size: string = "default", disabled: boolean = false, loading: boolean = false, pill: boolean = false, fullWidth: boolean = false, icon: string = "", iconPosition: string = "start", ariaLabel: string = "", ariaPressed: string = "", ariaExpanded: string = "", ariaControls: string = "", title: string = "", autofocus: boolean = false, controlClass: string = "", class: string = "" +Slots: default +Events: none + +### ButtonGroup +Mount: data-component="ButtonGroup" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Button Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Card +Mount: data-component="Card" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Card", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Carousel +Mount: data-component="Carousel" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Carousel", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Chart +Mount: data-component="Chart" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Chart", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### ChatBubble +Mount: data-component="ChatBubble" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Chat Bubble", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Checkbox +Mount: data-component="Checkbox" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Checkbox", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Slots: none +Events: none + +### Clipboard +Mount: data-component="Clipboard" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Clipboard", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Collapse +Mount: data-component="Collapse" +Category: base +Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, class: string = "" +Slots: default +Events: none + +### ColorPicker +Mount: data-component="ColorPicker" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Color Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "color", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Columns +Mount: data-component="Columns" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### ComboBox +Mount: data-component="ComboBox" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "ComboBox", name: string = "", value: string = "", options: string = [], groups: string = [], placeholder: string = "Search or select an option", searchPlaceholder: string = "Start typing…", clearable: boolean = true, allowCustomValue: boolean = false, disabled: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", helpText: string = "", loading: boolean = false, loadingLabel: string = "Loading suggestions…", emptyLabel: string = "No matching options", clearLabel: string = "Clear value", toggleLabel: string = "Toggle suggestions", searchMode: string = "contains", searchFields: string = "label,description", minSearchLength: number = 0, searchResultLimit: number = 0, optionTemplate: string = "default", defaultOpen: boolean = false, closeOnSelect: boolean = true, fixed: boolean = false, placement: string = "bottom", autocomplete: string = "off", remote: boolean = false, remoteUrl: string = "", remoteQueryParam: string = "q", remoteDebounce: number = 250, remoteAutoLoad: boolean = true, infinite: boolean = false, hasMore: boolean = false, page: number = 1, loadMoreLabel: string = "Load more", class: string = "" +Slots: none +Events: search, select, change, clear, open, close, load, error + +### Confetti +Mount: data-component="Confetti" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Confetti", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Container +Mount: data-component="Container" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### ContextMenu +Mount: data-component="ContextMenu" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Context Menu", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### CopyMarkup +Mount: data-component="CopyMarkup" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Copy Markup", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### CustomScrollbar +Mount: data-component="CustomScrollbar" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### DataMap +Mount: data-component="DataMap" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Data Map", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### DataTable +Mount: data-component="DataTable" +Category: integrations +Props: size: string = "default", color: string = "primary", caption: string = "Data Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" +Slots: default +Events: none + +### DatePicker +Mount: data-component="DatePicker" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Date Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "date", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### DeviceFrame +Mount: data-component="DeviceFrame" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Device Frame", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Divider +Mount: data-component="Divider" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "", orientation: string = "horizontal", class: string = "" +Slots: none +Events: none + +### DragAndDrop +Mount: data-component="DragAndDrop" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Drag And Drop", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Drawer +Mount: data-component="Drawer" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Drawer", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### Dropdown +Mount: data-component="Dropdown" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Dropdown", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### FileInput +Mount: data-component="FileInput" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "File Input", name: string = "", value: string = "", placeholder: string = "", type: string = "file", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### FileUpload +Mount: data-component="FileUpload" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "File Upload", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### FileUploadProgress +Mount: data-component="FileUploadProgress" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, class: string = "" +Slots: none +Events: none + +### Grid +Mount: data-component="Grid" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### Image +Mount: data-component="Image" +Category: layout +Props: size: string = "default", color: string = "primary", src: string = "", alt: string = "", width: string = "", height: string = "", loading: string = "lazy", rounded: boolean = false, class: string = "" +Slots: default +Events: none + +### Input +Mount: data-component="Input" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Input", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### InputGroup +Mount: data-component="InputGroup" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Input Group", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### InputNumber +Mount: data-component="InputNumber" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", variant: string = "default", class: string = "", id: string = "", name: string = "quantity", value: number = 0, min: string = "", max: string = "", step: number = 1, precision: string = "auto", label: string = "", description: string = "", helpText: string = "", error: string = "", invalid: boolean = false, prefix: string = "", suffix: string = "", placeholder: string = "", autocomplete: string = "off", inputMode: string = "decimal", ariaLabel: string = "", required: boolean = false, disabled: boolean = false, inputDisabled: boolean = false, buttonsDisabled: boolean = false, readonly: boolean = false, allowInput: boolean = true, keyboard: boolean = true, wheel: boolean = false, clamp: boolean = true, fullWidth: boolean = false, showButtons: boolean = true, showValidationMessage: boolean = true, decrementLabel: string = "Decrease value", incrementLabel: string = "Increase value", controlsLabel: string = "Quantity controls", requiredMessage: string = "A value is required.", minMessage: string = "Value is below the minimum.", maxMessage: string = "Value is above the maximum." +Slots: none +Events: input, change, increment, decrement + +### Kbd +Mount: data-component="Kbd" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "⌘ K", class: string = "" +Slots: default +Events: none + +### LayoutSplitter +Mount: data-component="LayoutSplitter" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### LegendIndicator +Mount: data-component="LegendIndicator" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Legend Indicator", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Link +Mount: data-component="Link" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "Link", href: string = "#", target: string = "", rel: string = "", external: boolean = false, class: string = "" +Slots: default +Events: none + +### List +Mount: data-component="List" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "List", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### ListGroup +Mount: data-component="ListGroup" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "List Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Map +Mount: data-component="Map" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Map", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Marquee +Mount: data-component="Marquee" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Marquee", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### MegaMenu +Mount: data-component="MegaMenu" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Mega Menu", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Modal +Mount: data-component="Modal" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Modal", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### Nav +Mount: data-component="Nav" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Nav", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Navbar +Mount: data-component="Navbar" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Navbar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Pagination +Mount: data-component="Pagination" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Pagination", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### PinInput +Mount: data-component="PinInput" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Verification code", name: string = "pin", value: string = "", length: number = 4, pattern: string = "[0-9]", type: string = "text", inputMode: string = "numeric", placeholder: string = "○", autocomplete: string = "one-time-code", masked: boolean = false, disabled: boolean = false, readonly: boolean = false, required: boolean = false, autoFocus: boolean = false, autoSubmit: boolean = false, allowPaste: boolean = true, clearable: boolean = true, clearLabel: string = "Clear code", separator: string = "", groupSize: number = 0, helpText: string = "", invalid: boolean = false, validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, complete, paste, clear, error + +### Popover +Mount: data-component="Popover" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Popover", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### Progress +Mount: data-component="Progress" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, class: string = "" +Slots: none +Events: none + +### Radio +Mount: data-component="Radio" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Radio", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Slots: none +Events: none + +### RangeSlider +Mount: data-component="RangeSlider" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Range Slider", name: string = "", value: string = "", placeholder: string = "", type: string = "range", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Rating +Mount: data-component="Rating" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Rating", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Scrollspy +Mount: data-component="Scrollspy" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Scrollspy", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### SearchBox +Mount: data-component="SearchBox" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Search Box", name: string = "", value: string = "", placeholder: string = "", type: string = "search", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Select +Mount: data-component="Select" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Select", name: string = "", value: string = "", options: string = [], placeholder: string = "Select an option", multiple: boolean = false, disabled: boolean = false, class: string = "" +Slots: none +Events: none + +### Sidebar +Mount: data-component="Sidebar" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Sidebar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Skeleton +Mount: data-component="Skeleton" +Category: base +Props: color: string = "primary", label: string = "Loading", size: string = "md", lines: number = 3, class: string = "" +Slots: none +Events: none + +### Spinner +Mount: data-component="Spinner" +Category: base +Props: color: string = "primary", label: string = "Loading", size: string = "md", lines: number = 3, class: string = "" +Slots: none +Events: none + +### Stepper +Mount: data-component="Stepper" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Stepper", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### StrongPassword +Mount: data-component="StrongPassword" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Password", name: string = "password", value: string = "", placeholder: string = "Create a strong password", autocomplete: string = "new-password", minLength: number = 8, specialCharactersSet: string = "!@#$%^&*()_+-=[]{}|;:,.<>?", requireLowercase: boolean = true, requireUppercase: boolean = true, requireNumber: boolean = true, requireSpecialCharacter: boolean = true, showRequirements: boolean = true, presentation: string = "inline", hintText: string = "Use a unique password you do not use elsewhere.", emptyLabel: string = "Enter a password", weakLabel: string = "Weak", fairLabel: string = "Fair", goodLabel: string = "Good", strongLabel: string = "Strong", disabled: boolean = false, readonly: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, strength + +### StyledIcon +Mount: data-component="StyledIcon" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Styled Icon", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Switch +Mount: data-component="Switch" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Switch", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Slots: none +Events: none + +### Table +Mount: data-component="Table" +Category: tables +Props: size: string = "default", color: string = "primary", caption: string = "Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" +Slots: default +Events: none + +### Tabs +Mount: data-component="Tabs" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Tabs", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Textarea +Mount: data-component="Textarea" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Textarea", name: string = "", value: string = "", placeholder: string = "", rows: number = 5, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Timeline +Mount: data-component="Timeline" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Timeline", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### TimePicker +Mount: data-component="TimePicker" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Time Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "time", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Toast +Mount: data-component="Toast" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Toast", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### ToastNotifications +Mount: data-component="ToastNotifications" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Toast Notifications", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### ToggleCount +Mount: data-component="ToggleCount" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Toggle Count", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### TogglePassword +Mount: data-component="TogglePassword" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Password", name: string = "password", value: string = "", placeholder: string = "Enter your password", autocomplete: string = "current-password", minlength: string = "", maxlength: string = "", pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}", fields: string = [], visible: boolean = false, toggleable: boolean = true, toggleMode: string = "button", checkboxLabel: string = "Show password", showLabel: string = "Show password", hideLabel: string = "Hide password", disabled: boolean = false, readonly: boolean = false, required: boolean = false, invalid: boolean = false, helpText: string = "", validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, toggle + +### Tooltip +Mount: data-component="Tooltip" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Tooltip", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### TreeView +Mount: data-component="TreeView" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Tree View", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Typography +Mount: data-component="Typography" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### WysiwygEditor +Mount: data-component="WysiwygEditor" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Wysiwyg Editor", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +# UI component catalog + +The installed @wrnexus/ui release contains 85 documented components. Every mount name, prop type, required/default status, slot, and event is included below and in llms-full.txt. + +### Accordion +Mount: data-component="Accordion" +Category: base +Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, class: string = "" +Slots: default +Events: none + +### AdvancedDatePicker +Mount: data-component="AdvancedDatePicker" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Advanced Date Picker", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### AdvancedRangeSlider +Mount: data-component="AdvancedRangeSlider" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Advanced Range Slider", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### AdvancedSelect +Mount: data-component="AdvancedSelect" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Advanced Select", name: string = "", value: string = "", values: string = [], options: string = [], groups: string = [], placeholder: string = "Select an option", placeholderIcon: string = "", searchPlaceholder: string = "Search options…", multiple: boolean = false, searchable: boolean = true, defaultOpen: boolean = false, clearable: boolean = true, allowEmpty: boolean = true, tags: boolean = false, disabled: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", helpText: string = "", loading: boolean = false, loadingLabel: string = "Loading options…", emptyLabel: string = "No options found", selectedOptionsLabel: string = "Selected options", clearLabel: string = "Clear selection", createLabel: string = "Create", loadMoreLabel: string = "Load more", searchMode: string = "contains", searchFields: string = "label,description", minSearchLength: number = 0, searchResultLimit: number = 0, maxSelections: number = 0, showCounter: boolean = false, counterTemplate: string = "{selected} selected", optionTemplate: string = "default", selectedTemplate: string = "default", closeOnSelect: boolean = true, scrollToSelected: boolean = true, fixed: boolean = false, placement: string = "bottom", remote: boolean = false, remoteUrl: string = "", remoteQueryParam: string = "q", remoteDebounce: number = 250, remoteAutoLoad: boolean = true, infinite: boolean = false, hasMore: boolean = false, page: number = 1, class: string = "" +Slots: none +Events: search, select, change, clear, open, close, load, error + +### Alert +Mount: data-component="Alert" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Alert", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Avatar +Mount: data-component="Avatar" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Avatar", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### AvatarGroup +Mount: data-component="AvatarGroup" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Avatar Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Badge +Mount: data-component="Badge" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Badge", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Blockquote +Mount: data-component="Blockquote" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Blockquote", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Breadcrumb +Mount: data-component="Breadcrumb" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Breadcrumb", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Button +Mount: data-component="Button" +Category: base +Props: label: string = "Button", loadingLabel: string = "Loading…", description: string = "", as: string = "", href: string = "", target: string = "", rel: string = "", type: string = "button", variant: string = "default", color: string = "primary", size: string = "default", disabled: boolean = false, loading: boolean = false, pill: boolean = false, fullWidth: boolean = false, icon: string = "", iconPosition: string = "start", ariaLabel: string = "", ariaPressed: string = "", ariaExpanded: string = "", ariaControls: string = "", title: string = "", autofocus: boolean = false, controlClass: string = "", class: string = "" +Slots: default +Events: none + +### ButtonGroup +Mount: data-component="ButtonGroup" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Button Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Card +Mount: data-component="Card" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Card", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Carousel +Mount: data-component="Carousel" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Carousel", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Chart +Mount: data-component="Chart" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Chart", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### ChatBubble +Mount: data-component="ChatBubble" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Chat Bubble", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Checkbox +Mount: data-component="Checkbox" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Checkbox", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Slots: none +Events: none + +### Clipboard +Mount: data-component="Clipboard" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Clipboard", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Collapse +Mount: data-component="Collapse" +Category: base +Props: size: string = "default", color: string = "primary", items: string = [], multiple: boolean = false, class: string = "" +Slots: default +Events: none + +### ColorPicker +Mount: data-component="ColorPicker" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Color Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "color", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Columns +Mount: data-component="Columns" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### ComboBox +Mount: data-component="ComboBox" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "ComboBox", name: string = "", value: string = "", options: string = [], groups: string = [], placeholder: string = "Search or select an option", searchPlaceholder: string = "Start typing…", clearable: boolean = true, allowCustomValue: boolean = false, disabled: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", helpText: string = "", loading: boolean = false, loadingLabel: string = "Loading suggestions…", emptyLabel: string = "No matching options", clearLabel: string = "Clear value", toggleLabel: string = "Toggle suggestions", searchMode: string = "contains", searchFields: string = "label,description", minSearchLength: number = 0, searchResultLimit: number = 0, optionTemplate: string = "default", defaultOpen: boolean = false, closeOnSelect: boolean = true, fixed: boolean = false, placement: string = "bottom", autocomplete: string = "off", remote: boolean = false, remoteUrl: string = "", remoteQueryParam: string = "q", remoteDebounce: number = 250, remoteAutoLoad: boolean = true, infinite: boolean = false, hasMore: boolean = false, page: number = 1, loadMoreLabel: string = "Load more", class: string = "" +Slots: none +Events: search, select, change, clear, open, close, load, error + +### Confetti +Mount: data-component="Confetti" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Confetti", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Container +Mount: data-component="Container" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### ContextMenu +Mount: data-component="ContextMenu" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Context Menu", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### CopyMarkup +Mount: data-component="CopyMarkup" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Copy Markup", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### CustomScrollbar +Mount: data-component="CustomScrollbar" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### DataMap +Mount: data-component="DataMap" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Data Map", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### DataTable +Mount: data-component="DataTable" +Category: integrations +Props: size: string = "default", color: string = "primary", caption: string = "Data Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" +Slots: default +Events: none + +### DatePicker +Mount: data-component="DatePicker" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Date Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "date", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### DeviceFrame +Mount: data-component="DeviceFrame" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Device Frame", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Divider +Mount: data-component="Divider" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "", orientation: string = "horizontal", class: string = "" +Slots: none +Events: none + +### DragAndDrop +Mount: data-component="DragAndDrop" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Drag And Drop", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Drawer +Mount: data-component="Drawer" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Drawer", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### Dropdown +Mount: data-component="Dropdown" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Dropdown", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### FileInput +Mount: data-component="FileInput" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "File Input", name: string = "", value: string = "", placeholder: string = "", type: string = "file", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### FileUpload +Mount: data-component="FileUpload" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "File Upload", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### FileUploadProgress +Mount: data-component="FileUploadProgress" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, class: string = "" +Slots: none +Events: none + +### Grid +Mount: data-component="Grid" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### Image +Mount: data-component="Image" +Category: layout +Props: size: string = "default", color: string = "primary", src: string = "", alt: string = "", width: string = "", height: string = "", loading: string = "lazy", rounded: boolean = false, class: string = "" +Slots: default +Events: none + +### Input +Mount: data-component="Input" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Input", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### InputGroup +Mount: data-component="InputGroup" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Input Group", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### InputNumber +Mount: data-component="InputNumber" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", variant: string = "default", class: string = "", id: string = "", name: string = "quantity", value: number = 0, min: string = "", max: string = "", step: number = 1, precision: string = "auto", label: string = "", description: string = "", helpText: string = "", error: string = "", invalid: boolean = false, prefix: string = "", suffix: string = "", placeholder: string = "", autocomplete: string = "off", inputMode: string = "decimal", ariaLabel: string = "", required: boolean = false, disabled: boolean = false, inputDisabled: boolean = false, buttonsDisabled: boolean = false, readonly: boolean = false, allowInput: boolean = true, keyboard: boolean = true, wheel: boolean = false, clamp: boolean = true, fullWidth: boolean = false, showButtons: boolean = true, showValidationMessage: boolean = true, decrementLabel: string = "Decrease value", incrementLabel: string = "Increase value", controlsLabel: string = "Quantity controls", requiredMessage: string = "A value is required.", minMessage: string = "Value is below the minimum.", maxMessage: string = "Value is above the maximum." +Slots: none +Events: input, change, increment, decrement + +### Kbd +Mount: data-component="Kbd" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "⌘ K", class: string = "" +Slots: default +Events: none + +### LayoutSplitter +Mount: data-component="LayoutSplitter" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### LegendIndicator +Mount: data-component="LegendIndicator" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Legend Indicator", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Link +Mount: data-component="Link" +Category: layout +Props: size: string = "default", color: string = "primary", label: string = "Link", href: string = "#", target: string = "", rel: string = "", external: boolean = false, class: string = "" +Slots: default +Events: none + +### List +Mount: data-component="List" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "List", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### ListGroup +Mount: data-component="ListGroup" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "List Group", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Map +Mount: data-component="Map" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Map", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Marquee +Mount: data-component="Marquee" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Marquee", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### MegaMenu +Mount: data-component="MegaMenu" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Mega Menu", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Modal +Mount: data-component="Modal" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Modal", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### Nav +Mount: data-component="Nav" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Nav", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Navbar +Mount: data-component="Navbar" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Navbar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Pagination +Mount: data-component="Pagination" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Pagination", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### PinInput +Mount: data-component="PinInput" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Verification code", name: string = "pin", value: string = "", length: number = 4, pattern: string = "[0-9]", type: string = "text", inputMode: string = "numeric", placeholder: string = "○", autocomplete: string = "one-time-code", masked: boolean = false, disabled: boolean = false, readonly: boolean = false, required: boolean = false, autoFocus: boolean = false, autoSubmit: boolean = false, allowPaste: boolean = true, clearable: boolean = true, clearLabel: string = "Clear code", separator: string = "", groupSize: number = 0, helpText: string = "", invalid: boolean = false, validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, complete, paste, clear, error + +### Popover +Mount: data-component="Popover" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Popover", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### Progress +Mount: data-component="Progress" +Category: base +Props: size: string = "default", color: string = "primary", label: string = "Progress", value: number = 50, max: number = 100, showValue: boolean = true, class: string = "" +Slots: none +Events: none + +### Radio +Mount: data-component="Radio" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Radio", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Slots: none +Events: none + +### RangeSlider +Mount: data-component="RangeSlider" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Range Slider", name: string = "", value: string = "", placeholder: string = "", type: string = "range", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Rating +Mount: data-component="Rating" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Rating", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Scrollspy +Mount: data-component="Scrollspy" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Scrollspy", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### SearchBox +Mount: data-component="SearchBox" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Search Box", name: string = "", value: string = "", placeholder: string = "", type: string = "search", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Select +Mount: data-component="Select" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Select", name: string = "", value: string = "", options: string = [], placeholder: string = "Select an option", multiple: boolean = false, disabled: boolean = false, class: string = "" +Slots: none +Events: none + +### Sidebar +Mount: data-component="Sidebar" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Sidebar", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Skeleton +Mount: data-component="Skeleton" +Category: base +Props: color: string = "primary", label: string = "Loading", size: string = "md", lines: number = 3, class: string = "" +Slots: none +Events: none + +### Spinner +Mount: data-component="Spinner" +Category: base +Props: color: string = "primary", label: string = "Loading", size: string = "md", lines: number = 3, class: string = "" +Slots: none +Events: none + +### Stepper +Mount: data-component="Stepper" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Stepper", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### StrongPassword +Mount: data-component="StrongPassword" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Password", name: string = "password", value: string = "", placeholder: string = "Create a strong password", autocomplete: string = "new-password", minLength: number = 8, specialCharactersSet: string = "!@#$%^&*()_+-=[]{}|;:,.<>?", requireLowercase: boolean = true, requireUppercase: boolean = true, requireNumber: boolean = true, requireSpecialCharacter: boolean = true, showRequirements: boolean = true, presentation: string = "inline", hintText: string = "Use a unique password you do not use elsewhere.", emptyLabel: string = "Enter a password", weakLabel: string = "Weak", fairLabel: string = "Fair", goodLabel: string = "Good", strongLabel: string = "Strong", disabled: boolean = false, readonly: boolean = false, required: boolean = false, invalid: boolean = false, validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, strength + +### StyledIcon +Mount: data-component="StyledIcon" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Styled Icon", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Switch +Mount: data-component="Switch" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Switch", name: string = "", value: string = "on", checked: boolean = false, disabled: boolean = false, class: string = "" +Slots: none +Events: none + +### Table +Mount: data-component="Table" +Category: tables +Props: size: string = "default", color: string = "primary", caption: string = "Table", columns: string = [], rows: string = [], striped: boolean = true, class: string = "" +Slots: default +Events: none + +### Tabs +Mount: data-component="Tabs" +Category: navigation +Props: size: string = "default", color: string = "primary", label: string = "Tabs", items: string = [], active: string = "", orientation: string = "horizontal", class: string = "" +Slots: default +Events: none + +### Textarea +Mount: data-component="Textarea" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Textarea", name: string = "", value: string = "", placeholder: string = "", rows: number = 5, disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Timeline +Mount: data-component="Timeline" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Timeline", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### TimePicker +Mount: data-component="TimePicker" +Category: forms +Props: size: string = "default", color: string = "primary", label: string = "Time Picker", name: string = "", value: string = "", placeholder: string = "", type: string = "time", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### Toast +Mount: data-component="Toast" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Toast", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### ToastNotifications +Mount: data-component="ToastNotifications" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Toast Notifications", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### ToggleCount +Mount: data-component="ToggleCount" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Toggle Count", name: string = "", value: string = "", placeholder: string = "", type: string = "text", min: string = "", max: string = "", step: string = "", disabled: boolean = false, required: boolean = false, class: string = "" +Slots: none +Events: none + +### TogglePassword +Mount: data-component="TogglePassword" +Category: advanced-forms +Props: size: string = "default", color: string = "primary", label: string = "Password", name: string = "password", value: string = "", placeholder: string = "Enter your password", autocomplete: string = "current-password", minlength: string = "", maxlength: string = "", pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}", fields: string = [], visible: boolean = false, toggleable: boolean = true, toggleMode: string = "button", checkboxLabel: string = "Show password", showLabel: string = "Show password", hideLabel: string = "Hide password", disabled: boolean = false, readonly: boolean = false, required: boolean = false, invalid: boolean = false, helpText: string = "", validationMessage: string = "", class: string = "" +Slots: none +Events: input, change, toggle + +### Tooltip +Mount: data-component="Tooltip" +Category: overlays +Props: size: string = "default", color: string = "primary", title: string = "Tooltip", description: string = "", open: boolean = false, placement: string = "bottom", closeLabel: string = "Close", class: string = "" +Slots: default +Events: none + +### TreeView +Mount: data-component="TreeView" +Category: base +Props: size: string = "default", color: string = "primary", title: string = "Tree View", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + +### Typography +Mount: data-component="Typography" +Category: layout +Props: size: string = "default", color: string = "primary", columns: number = 2, gap: string = "md", maxWidth: string = "xl", class: string = "" +Slots: default +Events: none + +### WysiwygEditor +Mount: data-component="WysiwygEditor" +Category: integrations +Props: size: string = "default", color: string = "primary", title: string = "Wysiwyg Editor", description: string = "", items: string = [], variant: string = "default", class: string = "" +Slots: default +Events: none + # Installed package documentation -The following README files and declarations come from the installed private 0.3.6 release. +The following README files and declarations come from the installed private 0.4.0 release. ## @wrnexus/ai @@ -15488,6 +16686,45 @@ export const POST = async (ctx) => { ### Exported TypeScript declarations ```ts +interface AIUsage { + inputTokens?: number; + outputTokens?: number; + totalTokens?: number; +} +interface AIResult { + value: T; + provider: string; + model?: string; + usage?: AIUsage; + finishReason?: string; + raw?: unknown; +} +interface AIProvider { + name: string; + generate(prompt: string | Message[], options?: GenerateOptions): Promise>; + stream?(prompt: string | Message[], options?: GenerateOptions): AsyncGenerator; +} +interface AIClientOptions { + providers: AIProvider[]; + fallback?: boolean; + onAttempt?: (provider: string, error?: unknown) => void | Promise; +} +interface AIClient { + generate(prompt: string | Message[], options?: GenerateOptions & { + provider?: string; + }): Promise>; + generateObject(prompt: string | Message[], options?: GenerateOptions & { + provider?: string; + validate?: (value: unknown) => value is T; + }): Promise>; + stream(prompt: string | Message[], options?: GenerateOptions & { + provider?: string; + }): AsyncGenerator; +} +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 WrNexus apps. * @@ -15554,7 +16791,7 @@ interface AI { /** Create a Claude client. Reads `ANTHROPIC_API_KEY` from the environment by default. */ declare function createAI(config?: AIConfig): AI; -export { type AI, type AIConfig, AIError, type Effort, type GenerateOptions, type Message, type Role, createAI }; +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 }; ``` --- @@ -15720,6 +16957,22 @@ app.put( ```ts import { Context, Middleware } from '@wrnexus/core'; +interface AuthorizationDecision { + allowed: boolean; + reason?: string; + policy?: string; + metadata?: Record; +} +type DecisionPolicy = (subject: S, resource?: R) => AuthorizationDecision | Promise; +declare function allow(reason?: string, metadata?: Record): AuthorizationDecision; +declare function deny(reason?: string, metadata?: Record): AuthorizationDecision; +declare function decision(name: string, policy: Policy, denial?: string): DecisionPolicy; +declare function owner>(subjectKey?: keyof SubjectType, resourceKey?: keyof Resource | string): DecisionPolicy; +declare function anyDecision(...policies: DecisionPolicy[]): DecisionPolicy; +declare function allDecisions(...policies: DecisionPolicy[]): DecisionPolicy; +declare function authorizeDecision(evaluate: (ctx: Context) => AuthorizationDecision | Promise): Middleware; +declare function filterAuthorized(subject: S, values: readonly R[], policy: Policy): Promise; + /** * @wrnexus/authz — authorization: role-based (RBAC), policy-based (PBAC), and * attribute-based (ABAC). Compose freely; all three reduce to a boolean check @@ -15763,7 +17016,367 @@ declare function requireRole(...roles: string[]): Middleware; /** Guard requiring an RBAC permission. */ declare function requirePermission(rbac: Rbac, permission: string): Middleware; -export { type Policy, type Rbac, type Subject, all, any, attr, authorize, defineRbac, hasRole, requirePermission, requireRole }; +export { type AuthorizationDecision, type DecisionPolicy, type Policy, type Rbac, type Subject, all, allDecisions, allow, any, anyDecision, attr, authorize, authorizeDecision, decision, defineRbac, deny, filterAuthorized, hasRole, owner, requirePermission, requireRole }; +``` + +--- + +## @wrnexus/captcha + +Documentation URL: https://wrnexusjs.dev/packages/captcha + +# @wrnexus/captcha + +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. + +## Install + +```bash +bun add @wrnexus/captcha +``` + +WRNexusJS automatically discovers the package plugin, component, client runtime, styles, and DevToolbar audit. Use `` 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. + +## Included challenge modes + +- Number, alphabet, and alphanumeric image challenges +- Addition, subtraction, multiplication, and exact-division calculations +- Generated shape-selection image challenges +- Audio alternatives for text, numbers, and calculations +- Honeypot and minimum-completion-time invisible checks +- Self-hosted “I’m not a robot” checkbox challenge with one-time server verification +- Always, once-per-session, and adaptive page gates +- Cloudflare Turnstile, Google reCAPTCHA, hCaptcha, managed, and custom providers + +## Create the self-hosted engine + +```ts +import { + createCaptchaEngine, + createCaptchaHttpHandlers, + RedisCaptchaStore, +} from "@wrnexus/captcha/server"; + +const engine = createCaptchaEngine({ + secret: process.env.CAPTCHA_SECRET!, + store: new RedisCaptchaStore(redis), + basePath: "/api/captcha", + challengeTtlMs: 2 * 60_000, + responseTokenTtlMs: 5 * 60_000, + maxAttempts: 3, + minCompletionMs: 800, +}); + +export const handlers = createCaptchaHttpHandlers(engine); +``` + +Mount the handlers from an API catch-all route: + +```ts +import type { Context } from "@wrnexus/core"; +import { handlers } from "../../lib/captcha.ts"; + +export async function POST(ctx: Context) { + return (await handlers.handle(ctx.req, ctx)) ?? new Response("Not Found", { status: 404 }); +} +export const GET = POST; +export const HEAD = POST; +``` + +## Use the component + +```wrn + +``` + +The component uses Tailwind utilities and `--wire-*` theme variables. It has no companion component CSS file. + +### Main props + +`provider`, `siteKey`, `type`, `action`, `presentation`, `difficulty`, `disturbance`, `imageStyle`, `allowedStyles`, `excludedStyles`, `randomizeStyle`, `locale`, `size`, `color`, `class`, `name`, `endpoint`, `verifyEndpoint`, `responseField`, labels/messages, `autoLoad`, `autoVerify`, `showVerify`, `showRefresh`, `showAudio`, `showListen`, `showStatus`, `disabled`, `required`, and the backward-compatible `compact` alias. + +### Component sizes + +Use one of the three supported display modes: + +```wrn + + + +``` + +`small`/`sm` are accepted as aliases for `compact`, while `large`/`lg` are accepted as aliases for `big`. The old `compact="true"` prop still forces compact mode. + +### Listen button visibility + +Audio remains available by default. Hide the Listen and Use audio controls with either of these props: + +```wrn + + +``` + +`showListen` is the direct UI switch. `showAudio` remains the broader backward-compatible audio switch. + +### I’m not a robot checkbox + +```wrn + +``` + +The checkbox is not a client-only boolean. Clicking it completes a self-hosted invisible challenge that is time-limited, attempt-limited, one-time-use, action-bound, optionally session/hostname/IP-bound, and verified on the server. It is a low-friction anti-automation layer; use adaptive escalation to a visual or external provider for high-risk traffic. + +### Visual disturbance + +Use `disturbance` for visual and image-selection challenges. It accepts an integer from `25` through `75`: + +- `25`: light disturbance and easiest readability +- `50`: balanced default +- `75`: maximum supported dots, line crossings, glyph movement, and image-tile noise + +The browser sends this value to the challenge API, and the server validates the range before generating the challenge. It is also returned in challenge metadata. + +### Generated image renderer styles + +Text, number, alphanumeric, and calculation CAPTCHA images support 18 concrete renderers plus a random mode: + +`classic`, `collision`, `snow`, `corrosion`, `spiderweb`, `cross-shadow`, `split`, `split2`, `cut`, `darts`, `distortion`, `stitch`, `striped`, `wave`, `grid-noise`, `scribble`, `pixel`, and `broken-lines`. + +Use a fixed style: + +```wrn + +``` + +Use a new random style whenever the challenge is refreshed: + +```wrn + +``` + +Control the random pool with comma-separated component props or arrays in the TypeScript API: + +```wrn + +``` + +```ts +const challenge = await engine.create({ + action: "checkout", + type: "alphanumeric", + imageStyle: "random", + allowedStyles: ["classic", "snow", "distortion", "wave"], + excludedStyles: ["collision"], +}); +``` + +Set `randomizeStyle: true` to force random selection even when `imageStyle` names a concrete renderer. The resolved style, requested style, and active pool are returned in challenge metadata. The answer is never embedded in metadata or browser JavaScript. + +### Events + +`@ready`, `@challenge`, `@input`, `@verify`, `@success`, `@failure`, `@expired`, `@refresh`, `@audioStart`, `@audioEnd`, and `@error`. + +## Protect a validated form API + +Validate a cloned request first, then consume the CAPTCHA response token. This prevents a valid token from being consumed when ordinary field validation fails. + +```ts +import { captchaGuard } from "@wrnexus/captcha/server"; +import { parseBody } from "@wrnexus/validation"; +import contactSchema from "../schemas/contact.ts"; +import { engine } from "../lib/captcha.ts"; + +const guard = captchaGuard({ + action: "contact-submit", + engine, + bindHostname: true, + bindSession: true, +}); + +export async function POST(ctx) { + const validation = await parseBody(contactSchema, ctx.req.clone()); + if (!validation.ok) return validation.response; + + return guard(ctx, async () => Response.json({ ok: true, submission: validation.value })); +} +``` + +The CAPTCHA runtime binds its required-form check in the capture phase, so a `data-schema` validator cannot submit the form before CAPTCHA verification. After a successful form request, the component automatically creates a fresh challenge. + +## Validate a schema and CAPTCHA together + +```ts +const result = await parseWithCaptcha(signupSchema, body, ctx, { + action: "signup", + engine, +}); + +if (!result.ok) return Response.json({ ok: false, errors: result.errors }, { status: 400 }); +``` + +## Page gate + +```ts +export default captchaPageGate({ + action: "reports-access", + engine, + challengePath: "/captcha", + policy: { + mode: "session", + verifiedForMs: 15 * 60_000, + routeGroups: ["/reports"], + }, +}); +``` + +Use `mode: "always"` for every visit, `mode: "session"` for a temporary grant, or `mode: "adaptive"` with `signals(ctx)`. + +The challenge page should post the return path as a normal hidden field instead of constructing JavaScript inside the HTML `action` attribute: + +```wrn +
    + + + + +``` + +The `/api/page-grant` route reads `returnTo`, restricts it to the current origin, and redirects only after `captchaPageGate()` has verified and stored the temporary session grant. + +## External providers + +```ts +const turnstile = turnstileProvider({ + secretKey: process.env.TURNSTILE_SECRET!, + siteKey: process.env.PUBLIC_TURNSTILE_SITE_KEY!, + expectedHostnames: ["example.com"], + expectedAction: "signup", +}); +``` + +```wrn + +``` + +Use the matching provider in `captchaGuard({ provider: turnstile })`. reCAPTCHA and hCaptcha adapters follow the same pattern. + +## Managed provider + +```ts +const managed = managedCaptchaProvider({ + baseUrl: "https://captcha.example.com", + siteKey: process.env.PUBLIC_CAPTCHA_SITE_KEY!, + secretKey: process.env.CAPTCHA_SECRET_KEY!, +}); +``` + +For direct browser challenge creation, configure the component’s `endpoint` as the managed `/v1/challenges` URL and its `verifyEndpoint` as `/v1/solve`. Keep the secret key only in the server provider. + +## Stores + +- `MemoryCaptchaStore`: development and one-process applications +- `SqliteCaptchaStore`: adapter for SQLite-like `prepare().run/get/all()` clients +- `RedisCaptchaStore`: shared TTL storage with Lua-backed atomic consumption when `eval` is available +- `CaptchaStore`: implement this interface for PostgreSQL, MySQL, MongoDB, or another backend + +## Audio + +`AssetAudioRenderer` concatenates bundled English PCM WAV clips without calling an external service. Supply a custom `CaptchaAudioRenderer` for recorded voices, Hindi or other languages, or managed text-to-speech. + +## DevToolbar + +The automatically discovered CAPTCHA plugin registers its DevToolbar audit panel. It checks for likely client-side secrets, missing action bindings, missing provider site keys, optional CAPTCHA fields, accessible alternatives, and server-verification reminders. Explicit `captchaPlugin(options)` registration is needed only to override automatic configuration. + +## Testing + +Use deterministic custom generators in unit tests. Never require users or CI to solve random CAPTCHA images. The package includes engine, provider, policy, HTTP, storage, replay, expiry, binding, and audio authorization tests. + +## Custom challenge generator + +```ts +import { defineCaptchaGenerator, createCaptchaEngine } from "@wrnexus/captcha"; + +const wordChallenge = defineCaptchaGenerator({ + type: "word" as const, + generate(context) { + const answer = "NEXUS"; + return { + type: "word", + presentation: "visual", + prompt: "Enter the displayed word", + answer, + answerKind: "text", + image: renderYourImage(answer), + inputMode: "text", + }; + }, +}); + +const engine = createCaptchaEngine({ secret, generators: [wordChallenge] }); +``` + +Applications may also implement `CaptchaStore`, `CaptchaAudioRenderer`, or use `defineCaptchaProvider()` for a completely custom service. + +### Exported TypeScript declarations + +```ts +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'; +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'; +export { SqliteCaptchaStore, SqliteCaptchaStoreOptions, SqliteDatabaseLike, SqliteStatementLike, createSqliteCaptchaStore } from './stores/sqlite.js'; +export { RedisCaptchaClient, RedisCaptchaStore, RedisCaptchaStoreOptions, createRedisCaptchaStore } from './stores/redis.js'; +export { SelfHostedCaptchaProvider, selfHostedProvider } from './providers/self-hosted.js'; +export { S as SiteverifyCaptchaProvider, a as SiteverifyPreset, b as SiteverifyProviderOptions } from './siteverify-Cg3TTAp4.js'; +export { TurnstileCaptchaProvider, turnstileProvider } from './providers/turnstile.js'; +export { RecaptchaProvider, recaptchaProvider } from './providers/recaptcha.js'; +export { HcaptchaProvider, hcaptchaProvider } from './providers/hcaptcha.js'; +export { ManagedCaptchaProvider, ManagedCaptchaProviderOptions, managedCaptchaProvider } from './providers/managed.js'; +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 '@wrnexus/validation'; +import '@wrnexus/plugin'; ``` --- @@ -16273,6 +17886,39 @@ declare class NativeCompileError extends Error { /** Compile a parsed `.wrn` page to an Expo Router React Native screen. */ declare function generateNative(ast: PageAst): string; +interface CompilationCacheEntry extends CompileResult { + key: string; + file: string; + sourceHash: string; + createdAt: number; +} +interface CompilationCacheOptions { + maxEntries?: number; + now?: () => number; +} +interface CompilationCache { + compile(source: string, file?: string, salt?: string): CompilationCacheEntry; + get(key: string): CompilationCacheEntry | undefined; + invalidate(file?: string): number; + clear(): void; + size(): number; + stats(): { + hits: number; + misses: number; + entries: number; + }; +} +declare function compilationKey(source: string, file?: string, salt?: string): string; +declare function createCompilationCache(options?: CompilationCacheOptions): CompilationCache; +declare class DependencyGraph { + #private; + set(file: string, dependencies: Iterable): void; + remove(file: string): void; + dependencies(file: string): string[]; + dependents(file: string): string[]; + affected(file: string): string[]; +} + /** * @wrnexus/compiler — the `.wrn` language compiler. * @@ -16298,7 +17944,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 CompileResult, NativeCompileError, compile, compileNativeWireFile, compileWireFile, generate, generateNative }; +export { type CompilationCache, type CompilationCacheEntry, type CompilationCacheOptions, type CompileResult, DependencyGraph, NativeCompileError, compilationKey, compile, compileNativeWireFile, compileWireFile, createCompilationCache, generate, generateNative }; ``` --- @@ -17555,7 +19201,81 @@ interface BudgetViolation { } declare function checkPerformanceBudgets(budgets: PerformanceBudgets, measurement: PerformanceMeasurement): BudgetViolation[]; -export { type ActionDefinition, type AsyncSessionBackend, type Bucket, type BudgetViolation, CSRF_COOKIE, CSRF_HEADER, type CacheControlOptions, type CachePolicy, type ContentSecurityPolicyConfig, type Context, type CookieOptions, type CookieStore, type CorsConfig, type CorsOrigin, type CspDirectiveValue, type DefinedAction, type DefinedEndpoint, type DefinedLoader, type EndpointDefinition, EndpointError, type EndpointErrorBody, type FeatureFlags, type FeatureRule, type FeatureValue, type HstsConfig, type LoaderDefinition, type LocalStorageSnapshot, type Middleware, type Mode, type Next, type PageComponent, type PageMeta, type PerformanceBudgets, type PerformanceMeasurement, type PermissionsPolicyConfig, type RateLimitOptions, type RateLimitStore, type RawSocket, type RealtimeBridge, type RealtimeBus, type RealtimeConnectMeta, type RealtimeEnvelope, type RealtimeHandler, type RealtimeRegistry, type RealtimeSocket, type RequestLoggerOptions, type RequestRecord, type RequireAuthOptions, type Room, type RoomAuthInfo, type RoomClient, type RoomDefinition, type RoomHandlers, type RpcClientOptions, SESSION_USER_KEY, type SaveUploadOptions, type SavedUpload, type SchemaLike, type SecurityConfig, type SeoConfig, type ServerSentEvent, type SessionBackend, type SessionEntry, type SessionStore, type Span, type SpanRecord, type StreamResponseInit, type TFunction, TTLCache, type Target, type Tenant, type TenantMiddlewareOptions, type TenantResolver, type Tracer, type TrustedTypesConfig, UploadError, bridgeRealtime, cacheControl, checkPerformanceBudgets, collectUploads, createContext, createCorsPreflightResponse, createRealtimeRegistry, createRpcClient, createTracer, csrfProtection, csrfToken, dedupe, defaultKey, defineAction, defineEndpoint, defineFeatureFlags, defineLoader, defineRoom, escapeHtml, etag, getUser, hashPassword, isRoomDefinition, isSafeIslandName, isSafeRequestPath, isWebSocketOriginAllowed, loadSession, logIn, logOut, notModified, peerKey, proxyKey, rateLimit, renderDevError, renderError, renderNotFound, renderProdError, renderStatusPage, requestLogger, requireAuth, requireTenant, resolveRequestUrl, sanitizeFilename, saveUpload, sessionAuth, setSessionBackend, sse, streamResponse, tenantFromSubdomain, tenantMiddleware, tenantScope, tracingMiddleware, verifyCsrf, verifyPassword, withCacheControl, withContextHeaders, withSecurityHeaders, withSpan }; +interface ProblemDetails { + type: string; + title: string; + status: number; + detail?: string; + instance?: string; + code?: string; + [key: string]: unknown; +} +interface ProblemDetailsInput { + type?: string; + title: string; + status: number; + detail?: string; + instance?: string; + code?: string; + [key: string]: unknown; +} +declare function problem(details: ProblemDetailsInput, headers?: HeadersInit): Response; +type ServiceToken = string | symbol | { + readonly key: symbol; + readonly __type?: T; +}; +declare function serviceToken(description: string): ServiceToken; +declare class ServiceContainer { + #private; + private readonly parent?; + constructor(parent?: ServiceContainer | undefined); + set(token: ServiceToken, value: T): this; + has(token: ServiceToken): boolean; + get(token: ServiceToken): T; + tryGet(token: ServiceToken): T | undefined; + scope(): ServiceContainer; +} +type LifecyclePhase = "starting" | "started" | "stopping" | "stopped"; +type LifecycleHandler = (signal: AbortSignal) => void | Promise; +declare class ApplicationLifecycle { + #private; + on(phase: LifecyclePhase, handler: LifecycleHandler): () => void; + run(phase: LifecyclePhase): Promise; + get signal(): AbortSignal; +} +interface HealthCheckResult { + status: "up" | "down" | "degraded"; + message?: string; + details?: unknown; + durationMs?: number; +} +type HealthCheck = () => HealthCheckResult | Promise; +declare class HealthRegistry { + #private; + register(name: string, check: HealthCheck): () => void; + check(): Promise<{ + status: "up" | "down" | "degraded"; + checks: Record; + }>; +} +declare function requestId(headers: Headers, preferred?: string): string; +interface IdempotencyRecord { + key: string; + value: T; + expiresAt: number; +} +interface IdempotencyStore { + get(key: string): Promise | null>; + set(record: IdempotencyRecord): Promise; + delete(key: string): Promise; +} +declare function memoryIdempotencyStore(now?: () => number): IdempotencyStore; +declare function withIdempotency(store: IdempotencyStore, key: string, execute: () => Promise, ttlMs?: number): Promise<{ + value: T; + replayed: boolean; +}>; + +export { type ActionDefinition, ApplicationLifecycle, type AsyncSessionBackend, type Bucket, type BudgetViolation, CSRF_COOKIE, CSRF_HEADER, type CacheControlOptions, type CachePolicy, type ContentSecurityPolicyConfig, type Context, type CookieOptions, type CookieStore, type CorsConfig, type CorsOrigin, type CspDirectiveValue, type DefinedAction, type DefinedEndpoint, type DefinedLoader, type EndpointDefinition, EndpointError, type EndpointErrorBody, type FeatureFlags, type FeatureRule, type FeatureValue, type HealthCheck, type HealthCheckResult, HealthRegistry, type HstsConfig, type IdempotencyRecord, type IdempotencyStore, type LifecycleHandler, type LifecyclePhase, type LoaderDefinition, type LocalStorageSnapshot, type Middleware, type Mode, type Next, type PageComponent, type PageMeta, type PerformanceBudgets, type PerformanceMeasurement, type PermissionsPolicyConfig, type ProblemDetails, type ProblemDetailsInput, type RateLimitOptions, type RateLimitStore, type RawSocket, type RealtimeBridge, type RealtimeBus, type RealtimeConnectMeta, type RealtimeEnvelope, type RealtimeHandler, type RealtimeRegistry, type RealtimeSocket, type RequestLoggerOptions, type RequestRecord, type RequireAuthOptions, type Room, type RoomAuthInfo, type RoomClient, type RoomDefinition, type RoomHandlers, type RpcClientOptions, SESSION_USER_KEY, type SaveUploadOptions, type SavedUpload, type SchemaLike, type SecurityConfig, type SeoConfig, type ServerSentEvent, ServiceContainer, type ServiceToken, type SessionBackend, type SessionEntry, type SessionStore, type Span, type SpanRecord, type StreamResponseInit, type TFunction, TTLCache, type Target, type Tenant, type TenantMiddlewareOptions, type TenantResolver, type Tracer, type TrustedTypesConfig, UploadError, bridgeRealtime, cacheControl, checkPerformanceBudgets, collectUploads, createContext, createCorsPreflightResponse, createRealtimeRegistry, createRpcClient, createTracer, csrfProtection, csrfToken, dedupe, defaultKey, defineAction, defineEndpoint, defineFeatureFlags, defineLoader, defineRoom, escapeHtml, etag, getUser, hashPassword, isRoomDefinition, isSafeIslandName, isSafeRequestPath, isWebSocketOriginAllowed, loadSession, logIn, logOut, memoryIdempotencyStore, notModified, peerKey, problem, proxyKey, rateLimit, renderDevError, renderError, renderNotFound, renderProdError, renderStatusPage, requestId, requestLogger, requireAuth, requireTenant, resolveRequestUrl, sanitizeFilename, saveUpload, serviceToken, sessionAuth, setSessionBackend, sse, streamResponse, tenantFromSubdomain, tenantMiddleware, tenantScope, tracingMiddleware, verifyCsrf, verifyPassword, withCacheControl, withContextHeaders, withIdempotency, withSecurityHeaders, withSpan }; ``` --- @@ -18125,7 +19845,9 @@ declare function parseMigration(name: string, content: string): Migration; declare function loadMigrations(dir: string): Migration[]; /** Names of already-applied migrations, oldest first. */ declare function appliedMigrations(db: Db): Promise; -/** Apply all pending migrations (each in a transaction). Returns applied names. */ +/** Apply an ordered migration list (each in a transaction). Returns applied names. */ +declare function applyMigrations(db: Db, migrations: readonly Migration[]): Promise; +/** Apply all pending migrations from a directory. */ declare function migrate(db: Db, dir: string): Promise; /** Roll back the most recently applied migration. Returns its name, or null. */ declare function rollback(db: Db, dir: string): Promise; @@ -18226,7 +19948,40 @@ interface RelationOptions { */ declare function loadRelated

    (db: Db, parents: P[], opts: RelationOptions): Promise<(P & Record)[]>; -export { Db, Dialect, type Migration, Model, type ModelRef, type PageOptions, type Paginated, type QueryDef, type QueryKind, type RelationOptions, Row, appliedMigrations, closeDatabases, databaseNames, generateQueriesFile, getDb, hasDb, loadMigrations, loadRelated, migrate, paginate, parseMigration, parseQueries, registerDb, rollback, scaffoldMigration, setDb, status }; +interface CursorPageOptions { + limit?: number; + after?: string; + before?: string; + column?: string; + direction?: "asc" | "desc"; + maxLimit?: number; +} +interface CursorPage { + items: T[]; + nextCursor?: string; + previousCursor?: string; + hasMore: boolean; +} +declare function cursorPaginate(db: Db, query: { + sql: string; + params?: unknown[]; + model?: Model; +}, options?: CursorPageOptions): Promise>; +declare function optimisticUpdate(db: Db, input: { + table: string; + idColumn?: string; + id: unknown; + versionColumn?: string; + version: number; + values: Record; +}): Promise; +declare function tenantScope(sql: string, tenantId: unknown, dialect: Dialect, existingParams?: number, column?: string): { + sql: string; + params: unknown[]; +}; +declare function softDeleteClause(column?: string): string; + +export { type CursorPage, type CursorPageOptions, Db, Dialect, type Migration, Model, type ModelRef, type PageOptions, type Paginated, type QueryDef, type QueryKind, type RelationOptions, Row, appliedMigrations, applyMigrations, closeDatabases, cursorPaginate, databaseNames, generateQueriesFile, getDb, hasDb, loadMigrations, loadRelated, migrate, optimisticUpdate, paginate, parseMigration, parseQueries, registerDb, rollback, scaffoldMigration, setDb, softDeleteClause, status, tenantScope }; ``` --- @@ -18547,8 +20302,8 @@ import { Router } from '@wrnexus/router'; import { ResolvedTheme, MobileConfig, PwaConfig, ObservabilityConfig, TenancyConfig, StylesConfig, ThemeConfig } from '@wrnexus/styles'; import { ResolvedI18n, I18nConfig } from '@wrnexus/i18n'; import { StorageConfig } from '@wrnexus/uploader'; -import { DevToolbarConfig } from '@wrnexus/dev-toolbar/types'; -import { PluginInput } from '@wrnexus/plugin'; +import { DevToolbarConfig, DevToolbarPlatformSnapshot, DevToolbarPanel } from '@wrnexus/dev-toolbar/types'; +import { ClientRuntimeDefinition, PluginInput } from '@wrnexus/plugin'; import { DevToolbarCollector } from '@wrnexus/dev-toolbar/server'; import { IncomingMessage, ServerResponse, Server } from 'node:http'; @@ -18649,6 +20404,8 @@ interface RuntimeDeps { inlineStyles?: string; /** Production cache-busting version appended to framework asset URLs. */ assetVersion?: string; + /** Package browser runtimes resolved by the plugin system. */ + clientRuntimes?: ClientRuntimeDefinition[]; /** Raw HTML appended to every page head (e.g. CDN framework links). */ head?: string; /** Global SEO defaults. */ @@ -18675,6 +20432,8 @@ interface RuntimeDeps { config: DevToolbarConfig; collector: DevToolbarCollector; root: string; + platform?: DevToolbarPlatformSnapshot; + panels?: DevToolbarPanel[]; }; } interface UpgradeServer { @@ -18815,6 +20574,11 @@ interface ProdManifest { mod: RouteModule; }[]; } +interface ProductionPluginAsset { + path: string; + contentType: string; + immutable?: boolean; +} interface ProdOptions { /** Absolute path to the pre-built global stylesheet, if any. */ stylesPath?: string; @@ -18870,6 +20634,10 @@ interface ProdOptions { storage?: StorageConfig; /** Cache-busting version appended to framework asset URLs. */ assetVersion?: string; + /** Package browser runtimes already emitted by the production build. */ + clientRuntimes?: ClientRuntimeDefinition[]; + /** Public URL to emitted package asset metadata. */ + pluginAssets?: Record; /** Absolute path to copied public assets, if any. */ publicDir?: string; /** Raw HTML appended to every page head. */ @@ -19027,7 +20795,7 @@ The browser runtime exposes `window.__wrnexusDevToolbar`. ### Exported TypeScript declarations ```ts -export { DevToolbarCategory, DevToolbarClientApi, DevToolbarConfig, DevToolbarElementTarget, DevToolbarFix, DevToolbarIssue, DevToolbarMetrics, DevToolbarPageReport, DevToolbarServerMessage, DevToolbarSeverity, DevToolbarSourceLocation } from './types.js'; +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 { DEV_TOOLBAR_CSS, DEV_TOOLBAR_RUNTIME } from './client/index.js'; @@ -19123,6 +20891,26 @@ if (!ok) throw new Error("Invalid webhook signature"); ### Exported TypeScript declarations ```ts +interface EncryptionKey { + id: string; + secret: string; + active?: boolean; + createdAt?: number; +} +interface EncryptionKeyring { + active(): EncryptionKey; + get(id: string): EncryptionKey | undefined; + keys(): EncryptionKey[]; + rotate(key?: EncryptionKey): Promise; + remove(id: string): boolean; +} +declare function createKeyring(initial: EncryptionKey[]): EncryptionKeyring; +/** Versioned payload: `wrn1..`. */ +declare function seal(plaintext: string, keyring: EncryptionKeyring): Promise; +declare function open(sealed: string, keyring: EncryptionKeyring): Promise; +declare function sealedKeyId(sealed: string): string | null; +declare function needsRotation(sealed: string, keyring: EncryptionKeyring): boolean; + /** * @wrnexus/encryption — authenticated symmetric encryption (AES-256-GCM) via * WebCrypto, dependency-free. Use it to encrypt secrets, tokens, or database @@ -19152,7 +20940,7 @@ declare function decrypt(payload: string, key: string): Promise; /** Derive a base64 AES key from a password + salt (PBKDF2, 100k iterations). */ declare function deriveKey(password: string, salt: string): Promise; -export { decrypt, deriveKey, encrypt, generateKey, hmacSign, hmacVerify, sha256 }; +export { type EncryptionKey, type EncryptionKeyring, createKeyring, decrypt, deriveKey, encrypt, generateKey, hmacSign, hmacVerify, needsRotation, open, seal, sealedKeyId, sha256 }; ``` --- @@ -19254,6 +21042,25 @@ declare function currentAppName(): string | undefined; declare function currentAppOrigin(): string | undefined; declare function workspaceAppOrigins(): Readonly>; +interface RetryOptions { + attempts?: number; + minDelayMs?: number; + maxDelayMs?: number; + factor?: number; + jitter?: number; + signal?: AbortSignal; + retryIf?: (error: unknown, attempt: number) => boolean | Promise; + onRetry?: (error: unknown, attempt: number, delayMs: number) => void | Promise; +} +declare function backoffDelay(attempt: number, options?: Pick): number; +declare function sleep(ms: number, signal?: AbortSignal): Promise; +declare function retry(operation: (attempt: number, signal?: AbortSignal) => Promise, options?: RetryOptions): Promise; +declare function withTimeout(promise: Promise, timeoutMs: number, message?: string, signal?: AbortSignal): Promise; +declare function stableStringify(value: unknown): string; +declare function safeJsonParse(value: string, fallback: T): T; +declare function clamp(value: number, min: number, max: number): number; +declare function once any>(fn: T): T; + /** * @wrnexus/helpers — safe conveniences for common WrNexus application flows. * @@ -19295,7 +21102,7 @@ declare function getOriginalRequestOrigin(ctx: RequestContext, options?: Origina */ declare function redirectToLogin(ctx: RequestContext, loginUrl: string | URL, options?: LoginRedirectOptions): Response; -export { type AllowedHosts, type LoginRedirectOptions, type OriginalRequestOptions, type RequestContext, appOrigin, appUrl, currentAppName, currentAppOrigin, getOriginalRequestMethod, getOriginalRequestOrigin, getOriginalRequestPath, getOriginalRequestUrl, redirectToLogin, workspaceAppOrigins }; +export { type AllowedHosts, type LoginRedirectOptions, type OriginalRequestOptions, type RequestContext, type RetryOptions, appOrigin, appUrl, backoffDelay, clamp, currentAppName, currentAppOrigin, getOriginalRequestMethod, getOriginalRequestOrigin, getOriginalRequestPath, getOriginalRequestUrl, once, redirectToLogin, retry, safeJsonParse, sleep, stableStringify, withTimeout, workspaceAppOrigins }; ``` --- @@ -19496,6 +21303,26 @@ declare function formatRelativeTime(value: number, unit: Intl.RelativeTimeFormat */ declare function plural(count: number, forms: Partial>, lang: string): string; +declare function flattenMessages(messages: Messages, prefix?: string, output?: Record): Record; +declare function localeFallbacks(locale: string, fallback?: string): string[]; +declare function translationCoverage(i18n: ResolvedI18n): Record; +interface LocaleFormatter { + number(value: number, options?: Intl.NumberFormatOptions): string; + currency(value: number, currency: string, options?: Omit): string; + date(value: Date | number | string, options?: Intl.DateTimeFormatOptions): string; + 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 formatMessage(template: string, params: Record, locale: string): string; + /** * @wrnexus/i18n — translations for pages and API responses. * @@ -19542,7 +21369,7 @@ declare function renderI18nData(i18n: ResolvedI18n, lang: string): string; */ declare const I18N_RUNTIME: string; -export { I18N_JS_HREF, I18N_RUNTIME, type I18nConfig, LANG_COOKIE, type Messages, type ResolvedI18n, formatCurrency, formatDate, formatNumber, formatRelativeTime, loadLocales, makeT, plural, renderI18nData, resolveI18n, resolveLang, translateHtml }; +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 }; ``` --- @@ -19689,6 +21516,24 @@ app.use(jwtAuth({ secret: process.env.JWT_SECRET!, required: false })); ```ts import { Context, Middleware } from '@wrnexus/core'; +interface JwtKey { + id: string; + secret: string; + active?: boolean; +} +interface JwtKeyring { + active(): JwtKey; + resolve(id: string): JwtKey | undefined; + keys(): JwtKey[]; +} +declare function decodeJwt(token: string): { + header: Record; + claims: JwtClaims; +}; +declare function createJwtKeyring(keys: JwtKey[]): JwtKeyring; +declare function signWithKeyring(claims: JwtClaims, keyring: JwtKeyring, options?: SignOptions): Promise; +declare function verifyWithKeyring(token: string, keyring: JwtKeyring, options?: VerifyOptions): Promise; + /** * @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 @@ -19717,13 +21562,23 @@ interface SignOptions { expiresIn?: number; /** Override issued-at (seconds). */ now?: number; + issuer?: string; + audience?: string | string[]; + jwtId?: string; + /** Key identifier placed in the protected header. */ + keyId?: string; +} +interface VerifyOptions { + now?: number; + clockTolerance?: number; + issuer?: string; + audience?: string | string[]; + maxAge?: number; } /** Sign a payload into a JWT (HS256). */ declare function signJwt(payload: JwtClaims, secret: string, options?: SignOptions): Promise; /** Verify a JWT and return its claims. Throws `JwtError` on any failure. */ -declare function verifyJwt(token: string, secret: string, options?: { - now?: number; -}): Promise; +declare function verifyJwt(token: string, secret: string, options?: VerifyOptions): Promise; interface JwtAuthOptions { secret: string; /** Where to read the token. Default: `Authorization: Bearer `. */ @@ -19737,7 +21592,7 @@ interface JwtAuthOptions { */ declare function jwtAuth(options: JwtAuthOptions): Middleware; -export { type JwtAuthOptions, type JwtClaims, JwtError, type SignOptions, jwtAuth, signJwt, verifyJwt }; +export { type JwtAuthOptions, type JwtClaims, JwtError, type JwtKey, type JwtKeyring, type SignOptions, type VerifyOptions, createJwtKeyring, decodeJwt, jwtAuth, signJwt, signWithKeyring, verifyJwt, verifyWithKeyring }; ``` --- @@ -19835,6 +21690,44 @@ Unavailable required plugins throw `MobileUnavailableError` with an actionable m ```ts export { native } from '@wrnexus/native'; +interface DeepLink { + url: URL; + path: string; + query: URLSearchParams; +} +declare function parseDeepLink(value: string, schemes?: string[]): DeepLink | null; +interface OfflineTask { + id: string; + type: string; + payload: T; + createdAt: number; + attempts: number; +} +interface OfflineTaskStore { + load(): Promise; + save(tasks: OfflineTask[]): Promise; +} +declare function memoryOfflineTaskStore(): OfflineTaskStore; +declare class OfflineQueue { + #private; + private readonly store; + constructor(store?: OfflineTaskStore); + process(type: string, handler: (payload: T) => Promise): void; + add(type: string, payload: T): Promise>; + sync(limit?: number): Promise<{ + completed: number; + failed: number; + }>; + size(): Promise; +} +interface MobileEnvironment { + platform: string; + native: boolean; + online: boolean; + userAgent?: string; +} +declare function mobileEnvironment(): MobileEnvironment; + /** @wrnexus/mobile — SSR-safe access to Capacitor's native bridge. */ type MobilePlatform = "ios" | "android" | "web" | string; @@ -19870,7 +21763,7 @@ declare const mobile: { whenNative: typeof whenNative; }; -export { type CapacitorBridge, type MobilePlatform, MobileUnavailableError, invoke, isNative, mobile, platform, plugin, registerPlugin, requirePlugin, whenNative }; +export { type CapacitorBridge, type DeepLink, type MobileEnvironment, type MobilePlatform, MobileUnavailableError, OfflineQueue, type OfflineTask, type OfflineTaskStore, invoke, isNative, memoryOfflineTaskStore, mobile, mobileEnvironment, parseDeepLink, platform, plugin, registerPlugin, requirePlugin, whenNative }; ``` --- @@ -19984,6 +21877,35 @@ declare function supports(name: string, target?: NativeTarget): boolean; declare function run(name: string, options?: unknown, runOptions?: NativeRunOptions): Promise; declare function clearRegistry(): void; +interface NativeCapabilityManifestEntry { + name: string; + description?: string; + permissions?: string[]; + targets?: NativeTarget[]; + optional?: boolean; +} +interface NativeCapabilityManifest { + name: string; + version?: string; + capabilities: NativeCapabilityManifestEntry[]; +} +declare function defineNativeManifest(manifest: T): T; +declare function inspectNativeCapabilities(target?: NativeTarget): Array<{ + name: string; + supported: boolean; +}>; +declare function missingNativeCapabilities(manifest: NativeCapabilityManifest, target?: NativeTarget): NativeCapabilityManifestEntry[]; +interface PermissionAdapter { + query(name: string): Promise<"granted" | "denied" | "prompt" | "unavailable">; + request?(name: string): Promise<"granted" | "denied">; +} +declare class PermissionManager { + private readonly adapter; + constructor(adapter: PermissionAdapter); + query(name: string): Promise<"denied" | "granted" | "prompt" | "unavailable">; + ensure(name: string): Promise; +} + declare const native: { isMobile: typeof isMobile; platform: typeof platform; @@ -19993,7 +21915,7 @@ declare const native: { supports: typeof supports; }; -export { NativeCapability, NativePlatform, NativeRunOptions, NativeTarget, NativeUnavailableError, clearRegistry, isMobile, native, platform, register, registered, run, 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 }; ``` --- @@ -20202,6 +22124,33 @@ const gitlab = defineProvider({ ### Exported TypeScript declarations ```ts +interface OAuthStateRecord { + state: string; + verifier: string; + redirectUri: string; + returnTo?: string; + expiresAt: number; +} +interface OAuthStateStore { + set(record: OAuthStateRecord): Promise; + consume(state: string): Promise; +} +declare function memoryOAuthStateStore(now?: () => number): OAuthStateStore; +declare function createOAuthState(store: OAuthStateStore, input: Omit & { + ttlMs?: number; +}): Promise; +declare function refreshOAuthTokens(provider: OAuthProvider, refreshToken: string, fetchImpl?: typeof fetch): Promise; +interface OidcDiscovery { + issuer: string; + authorization_endpoint: string; + token_endpoint: string; + userinfo_endpoint?: string; + jwks_uri: string; + revocation_endpoint?: string; +} +declare function discoverOidc(issuer: string, fetchImpl?: typeof fetch): Promise; +declare function validateOAuthReturnTo(value: string | undefined, origin: string, fallback?: string): string; + /** * @wrnexus/oauth — OAuth 2.0 sign-in with any provider. Ships presets for Google, * GitHub, and Discord, and `defineProvider` for a custom one. Dependency-free @@ -20291,7 +22240,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; -export { type CompleteAuthOptions, type OAuthProfile, type OAuthProvider, type OAuthTokens, type ProviderCredentials, type StartAuthOptions, type StartAuthResult, completeAuth, defineProvider, discord, exchangeCode, fetchProfile, github, google, randomToken, startAuth }; +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 }; ``` --- @@ -20311,55 +22260,20 @@ Duplicate names and dependency cycles are rejected. ### Exported TypeScript declarations ```ts -import { PageAst, WrnDiagnostic } from '@wrnexus/syntax'; +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'; +export { assertContributionId, contentTypeForPath, defaultClientRuntimePath, defaultPackageAssetPath, definePackageManifest, normalizeClientRuntime, normalizePackageAsset, validateStyleIds } from './manifest.js'; +export { DiscoverPluginOptions, discoverPlugins } from './discovery.js'; -type PluginOrder = "pre" | "normal" | "post"; -interface PluginContext { - root: string; - mode: "development" | "production"; - command: "dev" | "build" | "test"; - profile?: string; - metadata: Map; - warn(message: string): void; -} -interface TransformContext extends PluginContext { - file: string; -} -interface WrnexusPlugin { - name: string; - version?: string; - enforce?: PluginOrder; - /** Plugin names that must execute first. */ - after?: string[]; - /** Plugin names that must execute later. */ - before?: string[]; - configure?(config: Record, context: PluginContext): void | Promise; - configResolved?(config: Readonly>, context: PluginContext): void | Promise; - transformAst?(ast: PageAst, context: TransformContext): PageAst | void | Promise; - transformCode?(code: string, context: TransformContext): string | void | Promise; - diagnostics?(ast: PageAst, context: TransformContext): WrnDiagnostic[] | Promise; - routes?(routes: unknown[], context: PluginContext): unknown[] | void | Promise; - configureServer?(server: unknown, context: PluginContext): void | Promise; - buildStart?(context: PluginContext): void | Promise; - buildEnd?(result: unknown, context: PluginContext): void | Promise; - devToolbarPanels?(context: PluginContext): unknown[] | Promise; -} -type PluginInput = WrnexusPlugin | false | null | undefined | PluginInput[]; declare function definePlugin(plugin: WrnexusPlugin): WrnexusPlugin; +declare function flattenPlugins(input: PluginInput, output?: WrnexusPlugin[]): WrnexusPlugin[]; + /** Resolve plugin order deterministically and reject duplicates/cycles. */ declare function resolvePlugins(input: PluginInput): WrnexusPlugin[]; -interface PluginRunner { - readonly plugins: readonly WrnexusPlugin[]; - configure(config: Record): Promise; - configResolved(config: Readonly>): Promise; - transformAst(ast: PageAst, file: string): Promise; - transformCode(code: string, file: string): Promise; - diagnostics(ast: PageAst, file: string): Promise; - hook(name: "buildStart" | "buildEnd" | "configureServer", value?: unknown): Promise; -} declare function createPluginRunner(input: PluginInput, context: PluginContext): PluginRunner; -export { type PluginContext, type PluginInput, type PluginOrder, type PluginRunner, type TransformContext, type WrnexusPlugin, createPluginRunner, definePlugin, resolvePlugins }; +export { PluginContext, PluginInput, PluginRunner, WrnexusPlugin, createPluginRunner, definePlugin, flattenPlugins, resolvePlugins }; ``` --- @@ -20501,6 +22415,36 @@ driver.close(); ### Exported TypeScript declarations ```ts +interface MessageEnvelope { + id: string; + topic: string; + data: T; + timestamp: number; + attempts: number; +} +interface ResilientPubSubOptions { + retries?: number; + retryDelayMs?: number; + onError?: (error: unknown, envelope: MessageEnvelope) => void; +} +declare function createResilientPubSub(driver: PubSubDriver, options?: ResilientPubSubOptions): PubSub; +interface PresenceMember { + id: string; + metadata?: Record; + joinedAt: number; + expiresAt: number; +} +declare class PresenceChannel { + #private; + private readonly ttlMs; + private readonly now; + constructor(ttlMs?: number, now?: () => number); + touch(id: string, metadata?: Record): PresenceMember; + leave(id: string): boolean; + list(): PresenceMember[]; + prune(): number; +} + /** * @wrnexus/pubsub — topic-based publish/subscribe with a pluggable driver. * The default is in-process; swap in a Redis/NATS driver for cross-instance @@ -20526,7 +22470,7 @@ declare function memoryDriver(): PubSubDriver; /** Create a pub/sub bus over a driver (in-memory by default). */ declare function createPubSub(driver?: PubSubDriver): PubSub; -export { type Handler, type PubSub, type PubSubDriver, createPubSub, memoryDriver }; +export { type Handler, type MessageEnvelope, PresenceChannel, type PresenceMember, type PubSub, type PubSubDriver, type ResilientPubSubOptions, createPubSub, createResilientPubSub, memoryDriver }; ``` --- @@ -20703,6 +22647,41 @@ const ran = await queue.drain(); // => 1 ### Exported TypeScript declarations ```ts +/** + * Persistence contract for the durable queue. + * + * Distributed drivers should implement `claim()` atomically and exclude leased + * jobs from `due()` until their lease expires. Calling `put()` must replace the + * stored record and release any previous lease for that job. + */ +interface QueueStore { + put(job: Job): Promise; + get(id: string): Promise; + remove(id: string): Promise; + due(now: number, limit: number): Promise; + list(name?: string): Promise; + claim?(id: string, worker: string, leaseUntil: number): Promise; +} +declare function memoryQueueStore(): QueueStore; +interface DurableQueueOptions { + store?: QueueStore; + workerId?: string; + maxAttempts?: number; + concurrency?: number; + leaseMs?: number; + backoff?: (attempt: number) => number; + now?: () => number; + onDeadLetter?: (job: Job, error: unknown) => void | Promise; +} +interface DurableQueue { + add(name: string, data: T, options?: AddOptions): Promise>; + process(name: string, handler: JobHandler): void; + drain(): Promise; + failed(): Job[]; + retry(id: string): Promise; +} +declare function createDurableQueue(options?: DurableQueueOptions): DurableQueue; + /** * @wrnexus/queue — a background job queue with delays, retries + backoff, and * concurrent workers. The default store is in-process; a pluggable driver lets @@ -20785,7 +22764,7 @@ declare function defineWorkflow(name: string, steps: Array void | Cleanup): Cleanup; /** Create a lazily readable derived signal with automatic dependency tracking. */ declare function computed(read: () => T): ReadonlySignal; -export { type Cleanup, type ReadonlySignal, type Signal, type Subscriber, type Unsubscribe, batch, computed, effect, signal, untrack }; +interface WatchOptions { + immediate?: boolean; + equals?: (left: T, right: T) => boolean; +} +declare function watch(read: () => T, listener: (value: T, previous: T | undefined) => void | Cleanup, options?: WatchOptions): Cleanup; +type ResourceStatus = "idle" | "pending" | "success" | "error"; +interface Resource { + data: ReadonlySignal; + error: ReadonlySignal; + status: ReadonlySignal; + loading: ReadonlySignal; + run(): Promise; + abort(reason?: unknown): void; + reset(): void; +} +interface ResourceOptions { + initial?: T; + immediate?: boolean; + keepPrevious?: boolean; +} +declare function resource(loader: (signal: AbortSignal) => Promise, options?: ResourceOptions): Resource; +interface ReactiveScope { + add(cleanup: Cleanup): Cleanup; + dispose(): void; + readonly disposed: boolean; +} +declare function createScope(): ReactiveScope; + +export { type Cleanup, type ReactiveScope, type ReadonlySignal, type Resource, type ResourceOptions, type ResourceStatus, type Signal, type Subscriber, type Unsubscribe, type WatchOptions, batch, computed, createScope, effect, resource, signal, untrack, watch }; ``` --- @@ -21171,6 +23178,23 @@ declare function matchRoute(routes: Route[], pathname: string): RouteMatch | nul declare function generateRoutesFile(pages: Route[]): string; +interface NamedRoute extends Route { + name: string; + metadata?: Record; +} +interface RouteManifestEntry { + name: string; + path: string; + file: string; + params: ReturnType; + metadata?: Record; +} +declare function routeName(raw: string): string; +declare function nameRoutes(routes: readonly Route[], metadata?: Record>): NamedRoute[]; +declare function createRouteManifest(routes: readonly NamedRoute[]): RouteManifestEntry[]; +declare function routeUrl(route: Pick, params?: Record | null | undefined>, query?: Record): string; +declare function findNamedRoute(routes: readonly NamedRoute[], name: string): NamedRoute; + /** * @wrnexus/router — file-based router. * @@ -21183,7 +23207,7 @@ declare function generateRoutesFile(pages: Route[]): string; * app/pages/*.wrn api -> embedded /api/* routes * app/pages/*.wrn realtime -> embedded /realtime/* routes * app/middleware/*.ts -> global middleware (alphabetical) - * app/components/*.wrn -> server-rendered components (by basename), + * app/components/*.wrn -> server-rendered components (by declaration), * mounted in a page via data-component="" */ @@ -21209,12 +23233,22 @@ interface Router { matchApi(pathname: string): RouteMatch | null; matchRealtime(pathname: string): RouteMatch | null; } +interface ExternalRouteDefinition { + kind: "page" | "api" | "realtime"; + path: string; + entry: string; + name?: string; +} interface RouterOptions { /** * Extra directories to scan for `.wrn` components (e.g. `@wrnexus/ui`). * Scanned before `app/components`, so an app component of the same name wins. */ componentDirs?: string[]; + /** Package-owned routes registered by the plugin contribution system. */ + externalRoutes?: ExternalRouteDefinition[]; + /** Package-owned middleware executed before app/middleware. */ + middlewareFiles?: string[]; } /** * Convert a scanned file's relative path into a URL route pattern. @@ -21226,7 +23260,7 @@ declare function fileToRoute(rel: string, prefix?: string): string; /** Scan an app directory and build all route tables. */ declare function buildRouter(appDir: string, opts?: RouterOptions): Router; -export { type ComponentRef, type Route, type RouteMatch, type Router, type RouterOptions, buildRouter, compileRoutePattern, fileToRoute, findRouteConflicts, generateRoutesFile, getRouteParams, matchRoute, sortRoutes }; +export { type ComponentRef, type ExternalRouteDefinition, type NamedRoute, type Route, type RouteManifestEntry, type RouteMatch, type Router, type RouterOptions, buildRouter, compileRoutePattern, createRouteManifest, fileToRoute, findNamedRoute, findRouteConflicts, generateRoutesFile, getRouteParams, matchRoute, nameRoutes, routeName, routeUrl, sortRoutes }; ``` --- @@ -21374,6 +23408,18 @@ import { PageMeta, SeoConfig } from '@wrnexus/core'; * the browser, which keeps "server-only code" genuinely server-only. */ +interface ScriptAsset { + src: string; + /** Module scripts are the default for backward compatibility. */ + type?: "module" | "classic"; + async?: boolean; + defer?: boolean; + integrity?: string; + crossOrigin?: "anonymous" | "use-credentials"; + nonce?: string; + attributes?: Record; +} +type RenderScript = string | ScriptAsset; interface RenderOptions { /** Page metadata for the document head. */ meta: PageMeta; @@ -21387,7 +23433,7 @@ interface RenderOptions { * URLs of `