feat: make state-based attributes reactive

This commit is contained in:
2026-07-14 00:43:07 +05:30
parent 4ce087b238
commit 420706ca3b
61 changed files with 221 additions and 99 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/ai",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/authz",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/authz — part of the WrNexus framework.",
"license": "MIT",
+11 -11
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/cli",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/cli — part of the WrNexus framework.",
"license": "MIT",
@@ -28,16 +28,16 @@
"wrnexus": "./dist/index.js"
},
"dependencies": {
"@wrnexus/core": "^0.2.24",
"@wrnexus/router": "^0.2.24",
"@wrnexus/csr": "^0.2.24",
"@wrnexus/compiler": "^0.2.24",
"@wrnexus/styles": "^0.2.24",
"@wrnexus/dev-server": "^0.2.24",
"@wrnexus/ui": "^0.2.24",
"@wrnexus/validation": "^0.2.24",
"@wrnexus/i18n": "^0.2.24",
"@wrnexus/db": "^0.2.24"
"@wrnexus/core": "^0.2.25",
"@wrnexus/router": "^0.2.25",
"@wrnexus/csr": "^0.2.25",
"@wrnexus/compiler": "^0.2.25",
"@wrnexus/styles": "^0.2.25",
"@wrnexus/dev-server": "^0.2.25",
"@wrnexus/ui": "^0.2.25",
"@wrnexus/validation": "^0.2.25",
"@wrnexus/i18n": "^0.2.25",
"@wrnexus/db": "^0.2.25"
},
"files": [
"dist"
+1 -1
View File
@@ -149,7 +149,7 @@ A file opens with `page <Name>` or `component <Name>` followed by a `{ ... }` bo
- `layout = "<name>"` — selects `app/layouts/<name>.wrn` (pages only).
- `props { name = <default> ... }` — component props; each default's type drives coercion.
- `state <ident> = <expr>` — reactive state seeded from a raw JS expression.
- `view { <html> }` — plain HTML with `{expr}` interpolation, hyphenated attributes, boolean attributes, `@event="..."` client bindings, and `<!-- comments -->`.
- `view { <html> }` — plain HTML with `{expr}` interpolation in text and attributes, hyphenated attributes, boolean attributes, `@event="..."` client bindings, and `<!-- comments -->`. Attribute expressions that reference `state` keep an SSR value and update reactively in the browser.
- `seo { key = "value" ... }` — metadata merged into the generated `meta`.
- `style { <raw css> }` — inlined page/component stylesheet (repeatable).
- `functions { <raw js> }` — shared server-side helpers (repeatable).
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/compiler",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/compiler — part of the WrNexus framework.",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/core",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/core — part of the WrNexus framework.",
"license": "MIT",
+12 -1
View File
@@ -138,14 +138,25 @@ Bun.serve({
Browser side — server-rendered HTML that the reactive runtime hydrates:
```html
<div data-scope="count: 0">
<div data-scope="count: 0, showPassword: false">
<button data-on-click="count++">+1</button>
<span data-text="count"></span>
<p>Total: {{count}}</p>
<input type="{showPassword ? 'text' : 'password'}" />
<button
data-on-click="showPassword = !showPassword"
aria-label="{showPassword ? 'Hide password' : 'Show password'}"
>
Toggle password
</button>
</div>
<script src="/__wrnexus/reactive.js"></script>
```
State interpolation in ordinary attributes is reactive. The compiler keeps the
initial SSR value and emits an internal binding so attributes such as `type`,
`aria-label`, `aria-pressed`, `class`, and `href` update after state changes.
A realtime chat, fully declarative:
```html
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/csr",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/csr — part of the WrNexus framework.",
"license": "MIT",
@@ -21,7 +21,7 @@
}
},
"dependencies": {
"@wrnexus/core": "^0.2.24"
"@wrnexus/core": "^0.2.25"
},
"files": [
"dist"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/db",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/db — part of the WrNexus framework.",
"license": "MIT",
+13 -13
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/dev-server",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/dev-server — part of the WrNexus framework.",
"license": "MIT",
@@ -25,18 +25,18 @@
}
},
"dependencies": {
"@wrnexus/core": "^0.2.24",
"@wrnexus/router": "^0.2.24",
"@wrnexus/ssr": "^0.2.24",
"@wrnexus/csr": "^0.2.24",
"@wrnexus/compiler": "^0.2.24",
"@wrnexus/styles": "^0.2.24",
"@wrnexus/ui": "^0.2.24",
"@wrnexus/validation": "^0.2.24",
"@wrnexus/i18n": "^0.2.24",
"@wrnexus/db": "^0.2.24",
"@wrnexus/pubsub": "^0.2.24",
"@wrnexus/uploader": "^0.2.24"
"@wrnexus/core": "^0.2.25",
"@wrnexus/router": "^0.2.25",
"@wrnexus/ssr": "^0.2.25",
"@wrnexus/csr": "^0.2.25",
"@wrnexus/compiler": "^0.2.25",
"@wrnexus/styles": "^0.2.25",
"@wrnexus/ui": "^0.2.25",
"@wrnexus/validation": "^0.2.25",
"@wrnexus/i18n": "^0.2.25",
"@wrnexus/db": "^0.2.25",
"@wrnexus/pubsub": "^0.2.25",
"@wrnexus/uploader": "^0.2.25"
},
"files": [
"dist"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/encryption",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/encryption — part of the WrNexus framework.",
"license": "MIT",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/helpers",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "Safe convenience helpers for WrNexus request contexts and common application flows.",
"license": "MIT",
@@ -21,7 +21,7 @@
}
},
"dependencies": {
"@wrnexus/core": "^0.2.24"
"@wrnexus/core": "^0.2.25"
},
"files": [
"dist"
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/i18n",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/i18n — part of the WrNexus framework.",
"license": "MIT",
@@ -21,7 +21,7 @@
}
},
"dependencies": {
"@wrnexus/core": "^0.2.24"
"@wrnexus/core": "^0.2.25"
},
"files": [
"dist"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/jwt",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/jwt — part of the WrNexus framework.",
"license": "MIT",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/mobile",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/mobile — part of the WrNexus framework.",
"license": "MIT",
@@ -21,7 +21,7 @@
}
},
"dependencies": {
"@wrnexus/native": "^0.2.24"
"@wrnexus/native": "^0.2.25"
},
"files": [
"dist"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/native",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/native — part of the WrNexus framework.",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/oauth",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/oauth — part of the WrNexus framework.",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/pubsub",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/pubsub — part of the WrNexus framework.",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/queue",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/queue — part of the WrNexus framework.",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/reactive",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/reactive — part of the WrNexus framework.",
"license": "MIT",
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/router",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/router — part of the WrNexus framework.",
"license": "MIT",
@@ -21,8 +21,8 @@
}
},
"dependencies": {
"@wrnexus/compiler": "^0.2.24",
"@wrnexus/core": "^0.2.24"
"@wrnexus/compiler": "^0.2.25",
"@wrnexus/core": "^0.2.25"
},
"files": [
"dist"
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/ssr",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/ssr — part of the WrNexus framework.",
"license": "MIT",
@@ -21,7 +21,7 @@
}
},
"dependencies": {
"@wrnexus/core": "^0.2.24"
"@wrnexus/core": "^0.2.25"
},
"files": [
"dist"
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/styles",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/styles — part of the WrNexus framework.",
"license": "MIT",
@@ -21,7 +21,7 @@
}
},
"dependencies": {
"@wrnexus/uploader": "^0.2.24"
"@wrnexus/uploader": "^0.2.25"
},
"files": [
"dist"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/test",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/test — part of the WrNexus framework.",
"license": "MIT",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/tracking",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/tracking — part of the WrNexus framework.",
"license": "MIT",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/ui",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/ui — part of the WrNexus framework.",
"license": "MIT",
@@ -22,7 +22,7 @@
"./ui.css": "./ui.css"
},
"dependencies": {
"@wrnexus/core": "^0.2.24"
"@wrnexus/core": "^0.2.25"
},
"files": [
"dist",
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/uploader",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/uploader — part of the WrNexus framework.",
"license": "MIT",
@@ -21,7 +21,7 @@
}
},
"dependencies": {
"@wrnexus/core": "^0.2.24"
"@wrnexus/core": "^0.2.25"
},
"files": [
"dist"
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@wrnexus/validation",
"version": "0.2.24",
"version": "0.2.25",
"type": "module",
"description": "@wrnexus/validation — part of the WrNexus framework.",
"license": "MIT",