diff --git a/.publish/ai/package.json b/.publish/ai/package.json index 6bf3dfbc..3ecef289 100644 --- a/.publish/ai/package.json +++ b/.publish/ai/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ai", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.", "license": "MIT", diff --git a/.publish/authz/package.json b/.publish/authz/package.json index a00376b8..5e957478 100644 --- a/.publish/authz/package.json +++ b/.publish/authz/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/authz", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/authz — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/cli/package.json b/.publish/cli/package.json index a62818d2..6dd32bf9 100644 --- a/.publish/cli/package.json +++ b/.publish/cli/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/cli", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/cli — part of the WrNexus framework.", "license": "MIT", @@ -44,22 +44,22 @@ "wrnexus": "./dist/index.js" }, "dependencies": { - "@wrnexus/core": "^0.8.1", - "@wrnexus/router": "^0.8.1", - "@wrnexus/csr": "^0.8.1", - "@wrnexus/compiler": "^0.8.1", - "@wrnexus/styles": "^0.8.1", - "@wrnexus/dev-server": "^0.8.1", - "@wrnexus/ui": "^0.8.1", - "@wrnexus/validation": "^0.8.1", - "@wrnexus/i18n": "^0.8.1", - "@wrnexus/mcp": "^0.8.1", - "@wrnexus/playground": "^0.8.1", - "@wrnexus/db": "^0.8.1", - "@wrnexus/plugin": "^0.8.1", - "@wrnexus/syntax": "^0.8.1", - "@wrnexus/typecheck": "^0.8.1", - "@wrnexus/security": "^0.8.1", + "@wrnexus/core": "^0.8.2", + "@wrnexus/router": "^0.8.2", + "@wrnexus/csr": "^0.8.2", + "@wrnexus/compiler": "^0.8.2", + "@wrnexus/styles": "^0.8.2", + "@wrnexus/dev-server": "^0.8.2", + "@wrnexus/ui": "^0.8.2", + "@wrnexus/validation": "^0.8.2", + "@wrnexus/i18n": "^0.8.2", + "@wrnexus/mcp": "^0.8.2", + "@wrnexus/playground": "^0.8.2", + "@wrnexus/db": "^0.8.2", + "@wrnexus/plugin": "^0.8.2", + "@wrnexus/syntax": "^0.8.2", + "@wrnexus/typecheck": "^0.8.2", + "@wrnexus/security": "^0.8.2", "selfsigned": "^5.5.0" }, "files": [ diff --git a/.publish/compiler/package.json b/.publish/compiler/package.json index ced31619..03cf97d5 100644 --- a/.publish/compiler/package.json +++ b/.publish/compiler/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/compiler", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/compiler — part of the WrNexus framework.", "license": "MIT", @@ -37,10 +37,10 @@ } }, "dependencies": { - "@wrnexus/csr": "^0.8.1", - "@wrnexus/syntax": "^0.8.1", - "@wrnexus/store": "^0.8.1", - "@wrnexus/validation": "^0.8.1" + "@wrnexus/csr": "^0.8.2", + "@wrnexus/syntax": "^0.8.2", + "@wrnexus/store": "^0.8.2", + "@wrnexus/validation": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/core/package.json b/.publish/core/package.json index d38ffda0..ab602f81 100644 --- a/.publish/core/package.json +++ b/.publish/core/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/core", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/core — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/csr/package.json b/.publish/csr/package.json index 52802cb1..7d9820f5 100644 --- a/.publish/csr/package.json +++ b/.publish/csr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/csr", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/csr — part of the WrNexus framework.", "license": "MIT", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.8.1" + "@wrnexus/core": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/db/package.json b/.publish/db/package.json index 663a2758..2429cd43 100644 --- a/.publish/db/package.json +++ b/.publish/db/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/db", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Typed database drivers, migrations, instrumentation, repositories, pagination, and transaction helpers.", "license": "MIT", diff --git a/.publish/dev-server/package.json b/.publish/dev-server/package.json index 90c60757..32506c10 100644 --- a/.publish/dev-server/package.json +++ b/.publish/dev-server/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/dev-server", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/dev-server — part of the WrNexus framework.", "license": "MIT", @@ -41,25 +41,25 @@ } }, "dependencies": { - "@wrnexus/core": "^0.8.1", - "@wrnexus/dev-toolbar": "^0.8.1", - "@wrnexus/router": "^0.8.1", - "@wrnexus/ssr": "^0.8.1", - "@wrnexus/csr": "^0.8.1", - "@wrnexus/compiler": "^0.8.1", - "@wrnexus/styles": "^0.8.1", - "@wrnexus/ui": "^0.8.1", - "@wrnexus/validation": "^0.8.1", - "@wrnexus/i18n": "^0.8.1", - "@wrnexus/db": "^0.8.1", - "@wrnexus/pubsub": "^0.8.1", - "@wrnexus/uploader": "^0.8.1", - "@wrnexus/plugin": "^0.8.1", - "@wrnexus/store": "^0.8.1", - "@wrnexus/security": "^0.8.1", - "@wrnexus/observability": "^0.8.1", - "@wrnexus/cache": "^0.8.1", - "@wrnexus/pwa": "^0.8.1" + "@wrnexus/core": "^0.8.2", + "@wrnexus/dev-toolbar": "^0.8.2", + "@wrnexus/router": "^0.8.2", + "@wrnexus/ssr": "^0.8.2", + "@wrnexus/csr": "^0.8.2", + "@wrnexus/compiler": "^0.8.2", + "@wrnexus/styles": "^0.8.2", + "@wrnexus/ui": "^0.8.2", + "@wrnexus/validation": "^0.8.2", + "@wrnexus/i18n": "^0.8.2", + "@wrnexus/db": "^0.8.2", + "@wrnexus/pubsub": "^0.8.2", + "@wrnexus/uploader": "^0.8.2", + "@wrnexus/plugin": "^0.8.2", + "@wrnexus/store": "^0.8.2", + "@wrnexus/security": "^0.8.2", + "@wrnexus/observability": "^0.8.2", + "@wrnexus/cache": "^0.8.2", + "@wrnexus/pwa": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/dev-toolbar/package.json b/.publish/dev-toolbar/package.json index e26d0684..0c19ec56 100644 --- a/.publish/dev-toolbar/package.json +++ b/.publish/dev-toolbar/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/dev-toolbar", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/dev-toolbar — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/encryption/package.json b/.publish/encryption/package.json index eb614e4a..ffa402d0 100644 --- a/.publish/encryption/package.json +++ b/.publish/encryption/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/encryption", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Authenticated encryption, key rotation, hashing, and optional application-layer encrypted HTTP envelopes.", "license": "MIT", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.8.1" + "@wrnexus/core": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/helpers/package.json b/.publish/helpers/package.json index 2ed78eaf..32dfe39d 100644 --- a/.publish/helpers/package.json +++ b/.publish/helpers/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/helpers", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Safe convenience helpers for WrNexus request contexts and common application flows.", "license": "MIT", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.8.1" + "@wrnexus/core": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/i18n/package.json b/.publish/i18n/package.json index d4ced07d..b27b98d4 100644 --- a/.publish/i18n/package.json +++ b/.publish/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/i18n", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Locale loading, fallback resolution, SSR/browser translations, formatters, and WRNexusJS language components.", "license": "MIT", @@ -42,9 +42,9 @@ "./components/*": "./components/*" }, "dependencies": { - "@wrnexus/core": "^0.8.1", - "@wrnexus/plugin": "^0.8.1", - "@wrnexus/ui": "^0.8.1" + "@wrnexus/core": "^0.8.2", + "@wrnexus/plugin": "^0.8.2", + "@wrnexus/ui": "^0.8.2" }, "wrnexus": { "plugin": { diff --git a/.publish/jwt/package.json b/.publish/jwt/package.json index 47c77b9f..18d67d25 100644 --- a/.publish/jwt/package.json +++ b/.publish/jwt/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/jwt", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "HS256 JSON Web Tokens, key rotation, access/refresh helpers, scopes, cookies, and auth middleware.", "license": "MIT", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.8.1" + "@wrnexus/core": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/mobile/package.json b/.publish/mobile/package.json index cbb961cb..2571548c 100644 --- a/.publish/mobile/package.json +++ b/.publish/mobile/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/mobile", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/mobile — part of the WrNexus framework.", "license": "MIT", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@wrnexus/native": "^0.8.1" + "@wrnexus/native": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/native/package.json b/.publish/native/package.json index 11b95e83..f28c0842 100644 --- a/.publish/native/package.json +++ b/.publish/native/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/native", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/native — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/oauth/package.json b/.publish/oauth/package.json index c3596b64..cb84605a 100644 --- a/.publish/oauth/package.json +++ b/.publish/oauth/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/oauth", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/oauth — part of the WrNexus framework.", "license": "MIT", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@wrnexus/jwt": "^0.8.1" + "@wrnexus/jwt": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/plugin/package.json b/.publish/plugin/package.json index 9360943f..d359c494 100644 --- a/.publish/plugin/package.json +++ b/.publish/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/plugin", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/plugin — part of the WrNexus framework.", "license": "MIT", @@ -49,7 +49,7 @@ } }, "dependencies": { - "@wrnexus/syntax": "^0.8.1" + "@wrnexus/syntax": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/pubsub/package.json b/.publish/pubsub/package.json index f42fb07e..d466bf27 100644 --- a/.publish/pubsub/package.json +++ b/.publish/pubsub/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/pubsub", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/pubsub — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/queue/package.json b/.publish/queue/package.json index 74a39a56..1c9c54ca 100644 --- a/.publish/queue/package.json +++ b/.publish/queue/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/queue", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/queue — part of the WrNexus framework.", "license": "MIT", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@wrnexus/core": "^0.8.1" + "@wrnexus/core": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/reactive/package.json b/.publish/reactive/package.json index e51b5f9c..854bb1b1 100644 --- a/.publish/reactive/package.json +++ b/.publish/reactive/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/reactive", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/reactive — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/router/package.json b/.publish/router/package.json index eea5445f..19692a95 100644 --- a/.publish/router/package.json +++ b/.publish/router/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/router", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/router — part of the WrNexus framework.", "license": "MIT", @@ -37,8 +37,8 @@ } }, "dependencies": { - "@wrnexus/compiler": "^0.8.1", - "@wrnexus/core": "^0.8.1" + "@wrnexus/compiler": "^0.8.2", + "@wrnexus/core": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/ssr/package.json b/.publish/ssr/package.json index 9e5fd9f2..36256453 100644 --- a/.publish/ssr/package.json +++ b/.publish/ssr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ssr", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/ssr — part of the WrNexus framework.", "license": "MIT", @@ -45,9 +45,9 @@ } }, "dependencies": { - "@wrnexus/core": "^0.8.1", - "@wrnexus/store": "^0.8.1", - "@wrnexus/security": "^0.8.1" + "@wrnexus/core": "^0.8.2", + "@wrnexus/store": "^0.8.2", + "@wrnexus/security": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/styles/package.json b/.publish/styles/package.json index d623f4f3..52b782a8 100644 --- a/.publish/styles/package.json +++ b/.publish/styles/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/styles", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/styles — part of the WrNexus framework.", "license": "MIT", @@ -37,9 +37,9 @@ } }, "dependencies": { - "@wrnexus/uploader": "^0.8.1", - "@wrnexus/core": "^0.8.1", - "@wrnexus/plugin": "^0.8.1" + "@wrnexus/uploader": "^0.8.2", + "@wrnexus/core": "^0.8.2", + "@wrnexus/plugin": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/syntax/package.json b/.publish/syntax/package.json index d0e37c86..75170a3f 100644 --- a/.publish/syntax/package.json +++ b/.publish/syntax/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/syntax", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/syntax — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/test/package.json b/.publish/test/package.json index 3a1b0dba..b13f03f6 100644 --- a/.publish/test/package.json +++ b/.publish/test/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/test", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/test — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/tracking/package.json b/.publish/tracking/package.json index 6eb228fb..af59f5ed 100644 --- a/.publish/tracking/package.json +++ b/.publish/tracking/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/tracking", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/tracking — part of the WrNexus framework.", "license": "MIT", diff --git a/.publish/ui/package.json b/.publish/ui/package.json index 6306f59e..ef06461e 100644 --- a/.publish/ui/package.json +++ b/.publish/ui/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ui", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "@wrnexus/ui — part of the WrNexus framework.", "license": "MIT", @@ -42,7 +42,7 @@ "./ui.css": "./ui.css" }, "dependencies": { - "@wrnexus/core": "^0.8.1" + "@wrnexus/core": "^0.8.2" }, "files": [ "dist", diff --git a/.publish/uploader/package.json b/.publish/uploader/package.json index 8a3fb7c4..f70979b1 100644 --- a/.publish/uploader/package.json +++ b/.publish/uploader/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/uploader", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Secure upload drivers, policies, client runtime, helper functions, and reusable upload components.", "license": "MIT", @@ -42,9 +42,9 @@ "./components/*": "./components/*" }, "dependencies": { - "@wrnexus/core": "^0.8.1", - "@wrnexus/plugin": "^0.8.1", - "@wrnexus/ui": "^0.8.1" + "@wrnexus/core": "^0.8.2", + "@wrnexus/plugin": "^0.8.2", + "@wrnexus/ui": "^0.8.2" }, "wrnexus": { "plugin": { diff --git a/.publish/validation/package.json b/.publish/validation/package.json index 4ff4c799..6821dd4f 100644 --- a/.publish/validation/package.json +++ b/.publish/validation/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/validation", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Shared server/browser schemas, validation helpers, form runtime, and reusable error components.", "license": "MIT", @@ -42,9 +42,9 @@ "./components/*": "./components/*" }, "dependencies": { - "@wrnexus/core": "^0.8.1", - "@wrnexus/plugin": "^0.8.1", - "@wrnexus/ui": "^0.8.1" + "@wrnexus/core": "^0.8.2", + "@wrnexus/plugin": "^0.8.2", + "@wrnexus/ui": "^0.8.2" }, "wrnexus": { "plugin": { diff --git a/package.json b/package.json index c32b454e..820418f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wrnexus", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "description": "An SSR-first full-stack web framework with server-rendered reactive components. Bun-first, Node-friendly.", diff --git a/packages/ai/package.json b/packages/ai/package.json index 365fe86a..278eb8d6 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ai", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "description": "Zero-dependency Claude (Anthropic) client for WrNexus apps.", diff --git a/packages/auth/package.json b/packages/auth/package.json index fbac0791..9d0388ad 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/auth", - "version": "0.8.1", + "version": "0.8.2", "description": "Complete authentication, account security, MFA, passkeys, recovery, devices, risk, and audit system for WRNexusJS.", "type": "module", "sideEffects": false, diff --git a/packages/authz/package.json b/packages/authz/package.json index 8ffc7a67..23a4312a 100644 --- a/packages/authz/package.json +++ b/packages/authz/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/authz", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/benchmark/package.json b/packages/benchmark/package.json index cc96624a..7325e6a3 100644 --- a/packages/benchmark/package.json +++ b/packages/benchmark/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/benchmark", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Deterministic benchmark runner and performance regression budgets for WRNexusJS.", "main": "src/index.ts", diff --git a/packages/cache/package.json b/packages/cache/package.json index 7bb5caa0..01b1ab0a 100644 --- a/packages/cache/package.json +++ b/packages/cache/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/cache", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Tag-aware memory and response caching with stale-while-revalidate for WRNexusJS.", "main": "src/index.ts", diff --git a/packages/captcha/package.json b/packages/captcha/package.json index 53be2453..2cb052bc 100644 --- a/packages/captcha/package.json +++ b/packages/captcha/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/captcha", - "version": "0.8.1", + "version": "0.8.2", "description": "First-class CAPTCHA challenges, providers, verification guards, page gates, and WRNexusJS UI.", "type": "module", "sideEffects": false, diff --git a/packages/cli/package.json b/packages/cli/package.json index ee98b83d..d5609e68 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/cli", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/cli/src/update.ts b/packages/cli/src/update.ts index e6290601..d9a29b6d 100644 --- a/packages/cli/src/update.ts +++ b/packages/cli/src/update.ts @@ -1980,6 +1980,15 @@ const MIGRATIONS: Migration[] = [ // Package-managed production optimizations require no application source rewrite. }, }, + { + version: "0.8.2", + id: "0.8.2-navigation-and-vitals-stability", + description: + "Stops scroll-driven route prefetch storms, batches browser vitals, and supports telemetry behind trusted reverse proxies.", + apply() { + // Runtime stability fixes require no application source rewrite. + }, + }, ]; /** Release tooling uses this to require an explicit migration entry per version. */ diff --git a/packages/compiler/package.json b/packages/compiler/package.json index 749ccd29..ebd29d3b 100644 --- a/packages/compiler/package.json +++ b/packages/compiler/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/compiler", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/content/package.json b/packages/content/package.json index 4fe74561..50b1cd5e 100644 --- a/packages/content/package.json +++ b/packages/content/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/content", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Typed Markdown content collections, loaders, indexes, feeds, and preview workflows for WRNexusJS.", "main": "./src/index.ts", diff --git a/packages/core/package.json b/packages/core/package.json index c1b13f83..e18d3ce1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/core", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/csr/package.json b/packages/csr/package.json index 62242633..6637f1e9 100644 --- a/packages/csr/package.json +++ b/packages/csr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/csr", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/csr/src/nav-runtime.ts b/packages/csr/src/nav-runtime.ts index 2840b76a..98c96e26 100644 --- a/packages/csr/src/nav-runtime.ts +++ b/packages/csr/src/nav-runtime.ts @@ -638,7 +638,10 @@ export const NAV_RUNTIME = String.raw` while (prefetched.size > 20) prefetched.delete(prefetched.keys().next().value); } - document.addEventListener("pointerover", function (event) { + // Prefetch only on explicit pointer intent. Delegated pointerover fires when + // scrolling moves links underneath a stationary pointer, which can otherwise + // download every link on a long index page. + document.addEventListener("pointerdown", function (event) { var anchor = event.target && event.target.closest ? event.target.closest("a") : null; prefetch(anchor); }, { passive: true }); diff --git a/packages/csr/test/nav.test.ts b/packages/csr/test/nav.test.ts index a074efec..7898f56f 100644 --- a/packages/csr/test/nav.test.ts +++ b/packages/csr/test/nav.test.ts @@ -82,6 +82,18 @@ test("prefetches focused routes once and reuses the document during navigation", expect(win.document.querySelector("h1")?.textContent).toBe("Prefetched"); }); +test("does not prefetch links merely passing under the pointer while scrolling", async () => { + install(`
About
`); + const link = win.document.getElementById("prefetch"); + link.dispatchEvent(new win.PointerEvent("pointerover", { bubbles: true })); + await flush(); + expect(fetchCalls).toHaveLength(0); + link.dispatchEvent(new win.PointerEvent("pointerdown", { bubbles: true })); + await flush(); + expect(fetchCalls).toHaveLength(1); + expect(fetchCalls[0]?.opts.headers["x-wrnexus-prefetch"]).toBe("1"); +}); + test("ignores cross-origin links (full navigation)", async () => { install(`
x
`); win.document.getElementById("lnk").click(); diff --git a/packages/db/package.json b/packages/db/package.json index d3fd8c66..ee5e232c 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/db", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/dev-server/package.json b/packages/dev-server/package.json index 92e4e579..b70a666e 100644 --- a/packages/dev-server/package.json +++ b/packages/dev-server/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/dev-server", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/dev-server/src/runtime.ts b/packages/dev-server/src/runtime.ts index da92456f..d14e8c79 100644 --- a/packages/dev-server/src/runtime.ts +++ b/packages/dev-server/src/runtime.ts @@ -959,7 +959,9 @@ export function createHandlers(deps: RuntimeDeps): Handlers { return secure(await readinessHandler(req)); } if (webVitalsEnabled && url.pathname === webVitalsEndpoint) { - return secure(await webVitalsHandler(req)); + // Validate same-origin telemetry against the proxy-resolved public URL, + // rather than the internal listener URL used by the hosting platform. + return secure(await webVitalsHandler(new Request(url, req))); } if (webVitalsEnabled && url.pathname === "/__wrnexus/vitals.js") { return secure( diff --git a/packages/dev-server/test/observability-runtime.test.ts b/packages/dev-server/test/observability-runtime.test.ts index 93603bb1..d068a41d 100644 --- a/packages/dev-server/test/observability-runtime.test.ts +++ b/packages/dev-server/test/observability-runtime.test.ts @@ -3,7 +3,7 @@ import { HealthRegistry } from "@wrnexus/core"; import type { Router } from "@wrnexus/router"; import { createHandlers, type RuntimeDeps } from "../src/runtime.ts"; -function runtime(health: HealthRegistry) { +function runtime(health: HealthRegistry, trustProxy = false) { const router: Router = { pages: [], api: [], @@ -25,7 +25,8 @@ function runtime(health: HealthRegistry) { getMiddleware: async () => [], assets: { serve: async () => null }, health, - observability: { enabled: true, sampleRate: 1, exporter: "none" }, + security: { trustProxy }, + observability: { enabled: true, webVitals: true, sampleRate: 1, exporter: "none" }, } satisfies RuntimeDeps); } @@ -45,6 +46,24 @@ test("runtime exposes separate liveness and dependency readiness probes", async expect(await ready?.json()).toEqual({ status: "down" }); }); +test("accepts same-origin vitals behind a trusted HTTPS proxy", async () => { + const handlers = runtime(new HealthRegistry(), true); + const response = await handlers.fetch( + new Request("http://internal:3000/__wrnexus/metrics/vitals", { + method: "POST", + headers: { + origin: "https://wrnexusjs.dev", + "x-forwarded-host": "wrnexusjs.dev", + "x-forwarded-proto": "https", + "content-type": "application/json", + }, + body: JSON.stringify({ name: "LCP", value: 1200, route: "/packages" }), + }), + server, + ); + expect(response?.status).toBe(204); +}); + test("built production responses carry the framework security-header baseline", async () => { const handlers = runtime(new HealthRegistry()); const response = await handlers.fetch(new Request("https://example.test/healthz"), server); diff --git a/packages/dev-toolbar/package.json b/packages/dev-toolbar/package.json index 78711313..91fae38e 100644 --- a/packages/dev-toolbar/package.json +++ b/packages/dev-toolbar/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/dev-toolbar", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "sideEffects": false, diff --git a/packages/encryption/package.json b/packages/encryption/package.json index a7b19f02..045f97b2 100644 --- a/packages/encryption/package.json +++ b/packages/encryption/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/encryption", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/graphql/package.json b/packages/graphql/package.json index bd37407d..a36cd98e 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/graphql", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "./src/index.ts", "exports": { diff --git a/packages/helpers/package.json b/packages/helpers/package.json index 86b9bc60..a3b4d6d2 100644 --- a/packages/helpers/package.json +++ b/packages/helpers/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/helpers", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "description": "Safe convenience helpers for WrNexus request contexts and common application flows.", diff --git a/packages/i18n/package.json b/packages/i18n/package.json index e8106236..b2545a62 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/i18n", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/identity/package.json b/packages/identity/package.json index 4b7783dd..fd49ac90 100644 --- a/packages/identity/package.json +++ b/packages/identity/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/identity", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Enterprise federation, provisioning, machine identity, and privacy governance for WRNexusJS.", "main": "src/index.ts", diff --git a/packages/image/package.json b/packages/image/package.json index b4d0f091..505b7ecf 100644 --- a/packages/image/package.json +++ b/packages/image/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/image", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Responsive image planning, secure remote image policies, and performance auditing for WRNexusJS.", "main": "./src/index.ts", diff --git a/packages/jwt/package.json b/packages/jwt/package.json index 51a090e6..6ecb82c4 100644 --- a/packages/jwt/package.json +++ b/packages/jwt/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/jwt", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/language-server/package.json b/packages/language-server/package.json index 196787a6..43f96b2e 100644 --- a/packages/language-server/package.json +++ b/packages/language-server/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/language-server", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Editor-neutral Language Server Protocol implementation for WRNexus .wrn files.", "main": "src/index.ts", diff --git a/packages/mcp/package.json b/packages/mcp/package.json index a75bf8ac..8e090447 100644 --- a/packages/mcp/package.json +++ b/packages/mcp/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/mcp", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Model Context Protocol server exposing WRNexus application and framework context.", "main": "src/index.ts", diff --git a/packages/mobile/package.json b/packages/mobile/package.json index 86542786..b1e898b0 100644 --- a/packages/mobile/package.json +++ b/packages/mobile/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/mobile", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/native/package.json b/packages/native/package.json index d70e2c64..624d657e 100644 --- a/packages/native/package.json +++ b/packages/native/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/native", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/oauth/package.json b/packages/oauth/package.json index b9f46bc0..4b5e2a24 100644 --- a/packages/oauth/package.json +++ b/packages/oauth/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/oauth", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/observability/package.json b/packages/observability/package.json index 2d1d2d88..b14de546 100644 --- a/packages/observability/package.json +++ b/packages/observability/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/observability", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Metrics, Web Vitals collection, request instrumentation, and exporter adapters for WRNexusJS.", "main": "src/index.ts", diff --git a/packages/observability/src/client.ts b/packages/observability/src/client.ts index f142c658..2fadb620 100644 --- a/packages/observability/src/client.ts +++ b/packages/observability/src/client.ts @@ -10,6 +10,9 @@ export function webVitalsClient(options: WebVitalsClientOptions = {}): string { if (!window.PerformanceObserver || Math.random() > ${sampleRate}) return; var endpoint = ${endpoint}; var cls = 0; + var lcp = 0; + var inp = 0; + var flushed = false; function rating(name, value) { if (name === "LCP") return value <= 2500 ? "good" : value <= 4000 ? "needs-improvement" : "poor"; if (name === "INP") return value <= 200 ? "good" : value <= 500 ? "needs-improvement" : "poor"; @@ -21,9 +24,17 @@ export function webVitalsClient(options: WebVitalsClientOptions = {}): string { if (navigator.sendBeacon) navigator.sendBeacon(endpoint, new Blob([body], { type: "application/json" })); else fetch(endpoint, { method: "POST", headers: { "content-type": "application/json" }, body: body, keepalive: true }).catch(function(){}); } - try { new PerformanceObserver(function(list){ var entries=list.getEntries(); var last=entries[entries.length-1]; if(last) send("LCP", last.startTime); }).observe({type:"largest-contentful-paint",buffered:true}); } catch(_) {} + function flush() { + if (flushed) return; + flushed = true; + if (lcp) send("LCP", lcp); + if (inp) send("INP", inp); + if (cls) send("CLS", cls); + } + try { new PerformanceObserver(function(list){ var entries=list.getEntries(); var last=entries[entries.length-1]; if(last) lcp = Math.max(lcp, last.startTime); }).observe({type:"largest-contentful-paint",buffered:true}); } catch(_) {} try { new PerformanceObserver(function(list){ list.getEntries().forEach(function(e){ if(!e.hadRecentInput) cls += e.value; }); }).observe({type:"layout-shift",buffered:true}); } catch(_) {} - try { new PerformanceObserver(function(list){ var max=0; list.getEntries().forEach(function(e){ max=Math.max(max,e.duration||0); }); if(max) send("INP",max); }).observe({type:"event",durationThreshold:40,buffered:true}); } catch(_) {} - addEventListener("visibilitychange", function(){ if(document.visibilityState === "hidden" && cls) send("CLS", cls); }, { once: true }); + try { new PerformanceObserver(function(list){ list.getEntries().forEach(function(e){ inp=Math.max(inp,e.duration||0); }); }).observe({type:"event",durationThreshold:40,buffered:true}); } catch(_) {} + addEventListener("visibilitychange", function(){ if(document.visibilityState === "hidden") flush(); }); + addEventListener("pagehide", flush, { once: true }); })();`; } diff --git a/packages/observability/test/observability.test.ts b/packages/observability/test/observability.test.ts index 3493d858..391c94f5 100644 --- a/packages/observability/test/observability.test.ts +++ b/packages/observability/test/observability.test.ts @@ -1,7 +1,15 @@ import { describe, expect, test } from "bun:test"; -import { createWebVitalsHandler, MetricsRegistry } from "../src/index.ts"; +import { createWebVitalsHandler, MetricsRegistry, webVitalsClient } from "../src/index.ts"; describe("@wrnexus/observability", () => { + test("aggregates browser vitals and flushes them once at page exit", () => { + const client = webVitalsClient({ sampleRate: 1 }); + expect(client).toContain("var flushed = false"); + expect(client).toContain('addEventListener("pagehide", flush'); + expect(client).not.toContain('send("INP",max)'); + expect(client).not.toContain('send("LCP", last.startTime)'); + }); + test("records deterministic counters and histograms", () => { const registry = new MetricsRegistry(() => 123); registry.increment("requests", 1, { route: "/" }); diff --git a/packages/playground/package.json b/packages/playground/package.json index d3b9c720..09774154 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/playground", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Secure, shareable WRNexus compiler and UI playground.", "main": "src/index.ts", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 48c1c0d3..59e2d7e2 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/plugin", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/pubsub/package.json b/packages/pubsub/package.json index fdc9b2d3..4ff74777 100644 --- a/packages/pubsub/package.json +++ b/packages/pubsub/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/pubsub", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/pwa/package.json b/packages/pwa/package.json index edffcb5b..4c0a162d 100644 --- a/packages/pwa/package.json +++ b/packages/pwa/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/pwa", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Service workers, manifests, offline queues, background sync, push, and conflict resolution for WRNexusJS.", "main": "./src/index.ts", diff --git a/packages/queue/package.json b/packages/queue/package.json index 925e35d6..75ee09ab 100644 --- a/packages/queue/package.json +++ b/packages/queue/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/queue", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/reactive/package.json b/packages/reactive/package.json index 4eda8466..7c139da5 100644 --- a/packages/reactive/package.json +++ b/packages/reactive/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/reactive", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/realtime/package.json b/packages/realtime/package.json index 57350d00..301de06d 100644 --- a/packages/realtime/package.json +++ b/packages/realtime/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/realtime", - "version": "0.8.1", + "version": "0.8.2", "description": "Typed realtime rooms, message helpers, presence utilities, package UI blocks, and WRNexusJS integration.", "type": "module", "sideEffects": false, diff --git a/packages/router/package.json b/packages/router/package.json index a745ea9c..f071dcf5 100644 --- a/packages/router/package.json +++ b/packages/router/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/router", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/security/package.json b/packages/security/package.json index 1ff810a3..43fec958 100644 --- a/packages/security/package.json +++ b/packages/security/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/security", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "description": "Security policies, safe serialization, SSRF protection, request limits, and secure cookie helpers for WRNexusJS.", "main": "src/index.ts", diff --git a/packages/ssr/package.json b/packages/ssr/package.json index aa35252c..6c105cde 100644 --- a/packages/ssr/package.json +++ b/packages/ssr/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ssr", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/store/package.json b/packages/store/package.json index 1592c904..7e9f7415 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/store", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/styles/package.json b/packages/styles/package.json index af3fe4f0..cf3efa4f 100644 --- a/packages/styles/package.json +++ b/packages/styles/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/styles", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/syntax/package.json b/packages/syntax/package.json index 2e44e88b..f5ec3b84 100644 --- a/packages/syntax/package.json +++ b/packages/syntax/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/syntax", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/test/package.json b/packages/test/package.json index 03e9a0a7..ca1028c4 100644 --- a/packages/test/package.json +++ b/packages/test/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/test", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/tracking/package.json b/packages/tracking/package.json index 8cc70c5f..8967b559 100644 --- a/packages/tracking/package.json +++ b/packages/tracking/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/tracking", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/typecheck/package.json b/packages/typecheck/package.json index 12fd67be..cd93cd01 100644 --- a/packages/typecheck/package.json +++ b/packages/typecheck/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/typecheck", - "version": "0.8.1", + "version": "0.8.2", "type": "module", "main": "src/index.ts", "exports": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 0e323286..636a77e5 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/ui", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "src/index.ts", diff --git a/packages/uploader/package.json b/packages/uploader/package.json index 9a286574..dbdd66da 100644 --- a/packages/uploader/package.json +++ b/packages/uploader/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/uploader", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/packages/validation/package.json b/packages/validation/package.json index 799c512e..f8356ded 100644 --- a/packages/validation/package.json +++ b/packages/validation/package.json @@ -1,6 +1,6 @@ { "name": "@wrnexus/validation", - "version": "0.8.1", + "version": "0.8.2", "private": true, "type": "module", "main": "./src/index.ts", diff --git a/update-package-versions.mjs b/update-package-versions.mjs index 592818e1..25bf9325 100644 --- a/update-package-versions.mjs +++ b/update-package-versions.mjs @@ -1,7 +1,7 @@ import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs"; import { join } from "node:path"; -const version = "0.8.1"; +const version = "0.8.2"; const dependencyGroups = [ "dependencies",